Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

newsletter id snaps #27608

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 72 additions & 5 deletions common/app/layout/SnapStuff.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package layout

import java.net.URI
import model.pressed._
import views.support._
import services.NewsletterService
import conf.Configuration.newsletterApi

case class SnapStuff(
dataAttributes: String,
Expand All @@ -10,6 +13,7 @@ case class SnapStuff(
embedHtml: Option[String],
embedCss: Option[String] = None,
embedJs: Option[String] = None,
newsletterId: Option[String] = None,
) {
def cssClasses: Seq[String] =
Seq(
Expand Down Expand Up @@ -43,13 +47,76 @@ object SnapStuff {
case _ => None
}

val newsletterId = faciaContent.properties.href match {
case Some(href) => {
extractNewsletterId(href)
}
case None => None
}

faciaContent.properties.embedType match {
case Some("latest") => Some(SnapStuff(snapData, faciaContent.properties.embedCss, FrontendLatestSnap, embedHtml))
case Some("link") => Some(SnapStuff(snapData, faciaContent.properties.embedCss, FrontendLinkSnap, embedHtml))
case Some("latest") =>
Some(SnapStuff(snapData, faciaContent.properties.embedCss, FrontendLatestSnap, embedHtml, newsletterId = None))
case Some("link") =>
newsletterId match {
case Some(id) =>
Some(
SnapStuff(
snapData,
faciaContent.properties.embedCss,
FrontendNewsletterSnap,
embedHtml,
newsletterId = Some(id),
),
)
case None =>
Some(
SnapStuff(snapData, faciaContent.properties.embedCss, FrontendLinkSnap, embedHtml, newsletterId = None),
)
}
case Some("interactive") =>
Some(SnapStuff(snapData, faciaContent.properties.embedCss, FrontendLinkSnap, embedHtml, embedCss, embedJs))
case Some(_) => Some(SnapStuff(snapData, faciaContent.properties.embedCss, FrontendOtherSnap, embedHtml))
case None => None
Some(
SnapStuff(
snapData,
faciaContent.properties.embedCss,
FrontendLinkSnap,
embedHtml,
embedCss,
embedJs,
newsletterId = None,
),
)
case Some(_) =>
Some(SnapStuff(snapData, faciaContent.properties.embedCss, FrontendOtherSnap, embedHtml, newsletterId = None))
case None => None
}
}

private def isNewsletterApiUri(href: String): Boolean = {
val prefix: Option[String] = for {
host <- newsletterApi.host
origin <- newsletterApi.origin
} yield {
s"$host/api/newsletters"
}
prefix match {
case Some(url) => {
href.startsWith(prefix)
}
case None => {
println("newsletters API not configured!")
false
}
}
}

private def extractNewsletterId(newsleterApiUri: String): Option[String] = {
isNewsletterApiUri(newsleterApiUri) match {
case true => {
val lastPartofPath: String = new URI(newsleterApiUri).getPath.tail
Some(lastPartofPath)
}
case _ => None
}
}
}
1 change: 1 addition & 0 deletions common/app/layout/SnapType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ sealed trait SnapType
case object FrontendLatestSnap extends SnapType
case object FrontendLinkSnap extends SnapType
case object FrontendOtherSnap extends SnapType
case object FrontendNewsletterSnap extends SnapType
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ import com.gu.contentapi.client.model.v1.Content
import experiments.ActiveExperiments
import layout.ContentCard
import model.{PressedPage, RelatedContentItem}
import services.NewsletterData
import services.newsletters.model.NewsletterResponseV2
import navigation.{FooterLinks, Nav}
import play.api.libs.json.{JsObject, JsValue, Json, OWrites}
import play.api.mvc.RequestHeader
import views.support.{CamelCase, JavaScriptPage}
import conf.Configuration.newsletterApi

case class DotcomFrontsRenderingDataModel(
pressedPage: PressedPage,
Expand All @@ -33,6 +36,8 @@ case class DotcomFrontsRenderingDataModel(
deeplyRead: Option[Seq[Trail]],
contributionsServiceUrl: String,
canonicalUrl: String,
newsletters: List[NewsletterData],
newsletterApiUri: Option[String],
)

object DotcomFrontsRenderingDataModel {
Expand All @@ -46,6 +51,7 @@ object DotcomFrontsRenderingDataModel {
mostCommented: Option[Content],
mostShared: Option[Content],
deeplyRead: Option[Seq[Trail]],
newsletters: List[NewsletterResponseV2],
): DotcomFrontsRenderingDataModel = {
val edition = Edition.edition(request)
val nav = Nav(page, edition)
Expand Down Expand Up @@ -75,6 +81,14 @@ object DotcomFrontsRenderingDataModel {
.map { _.perEdition.mapKeys(_.id) }
.getOrElse(Map.empty[String, EditionCommercialProperties])

// TO DO - could reduce payload size to DCR by only including the
// live newsletters for which there is some some item in some collection
// in the page which has a FrontendNewsletterSnap for which the
// newsletterId is the identityName of the newsletter
val newsletterData = newsletters
.filter((newsletter) => newsletter.status.equalsIgnoreCase(("live")))
.map((newsletter) => convertNewsletterResponseToData(newsletter))

DotcomFrontsRenderingDataModel(
pressedPage = page,
nav = nav,
Expand All @@ -95,11 +109,37 @@ object DotcomFrontsRenderingDataModel {
deeplyRead = deeplyRead,
contributionsServiceUrl = Configuration.contributionsService.url,
canonicalUrl = CanonicalLink(request, page.metadata.webUrl),
newsletters = newsletterData,
newsletterApiUri = getNewsletterApiUri(),
)
}

def toJson(model: DotcomFrontsRenderingDataModel): String = {
val jsValue = Json.toJson(model)
Json.stringify(DotcomRenderingUtils.withoutNull(jsValue))
}

// TO DO - refactor. this function is repeated in 3 places now
private def convertNewsletterResponseToData(response: NewsletterResponseV2): NewsletterData = {
NewsletterData(
response.identityName,
response.name,
response.theme,
response.signUpDescription,
response.frequency,
response.listId,
response.group,
response.mailSuccessDescription.getOrElse("You are subscribed"),
response.regionFocus,
response.illustrationCard,
)
}

private def getNewsletterApiUri(): Option[String] = {
for {
host <- newsletterApi.host
} yield {
s"$host/api/newsletters"
}
}
}
2 changes: 2 additions & 0 deletions common/app/renderers/DotcomRenderingService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ class DotcomRenderingService extends GuLogging with ResultWithPreconnectPreload
mostCommented: Option[Content],
mostShared: Option[Content],
deeplyRead: Option[Seq[Trail]],
newsletters: List[NewsletterResponseV2],
)(implicit request: RequestHeader): Future[Result] = {
val dataModel = DotcomFrontsRenderingDataModel(
page,
Expand All @@ -275,6 +276,7 @@ class DotcomRenderingService extends GuLogging with ResultWithPreconnectPreload
mostCommented,
mostShared,
deeplyRead,
newsletters,
)

val json = DotcomFrontsRenderingDataModel.toJson(dataModel)
Expand Down
3 changes: 3 additions & 0 deletions facia/app/AppLoader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import play.api.libs.ws.WSClient
import services._
import services.fronts.{FrontJsonFapiDraft, FrontJsonFapiLive}
import router.Routes
import services.newsletters.{NewsletterSignupAgent, NewsletterApi}

import scala.concurrent.ExecutionContext

Expand All @@ -44,11 +45,13 @@ trait AppComponents extends FrontendComponents with FaciaControllers with FapiSe

lazy val capiHttpClient: HttpClient = wire[CapiHttpClient]
lazy val contentApiClient = wire[ContentApiClient]
lazy val newsletterApi = wire[NewsletterApi]
lazy val healthCheck = wire[HealthCheck]
lazy val devAssetsController = wire[DevAssetsController]
lazy val ophanApi = wire[OphanApi]
lazy val mostViewedAgent = wire[MostViewedAgent]
lazy val deeplyReadAgent = wire[DeeplyReadAgent]
lazy val newsletterSignupAgent = wire[NewsletterSignupAgent]

override lazy val lifecycleComponents = List(
wire[ConfigAgentLifecycle],
Expand Down
11 changes: 11 additions & 0 deletions facia/app/controllers/FaciaController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import play.twirl.api.Html
import renderers.DotcomRenderingService
import services.dotcomrendering.{FaciaPicker, RemoteRender}
import services.fronts.{FrontJsonFapi, FrontJsonFapiLive}
import services.newsletters.NewsletterSignupAgent
import services.{CollectionConfigWithId, ConfigAgent}
import utils.TargetedCollections
import views.html.fragments.containers.facia_cards.container
Expand All @@ -41,6 +42,7 @@ trait FaciaController
val frontJsonFapi: FrontJsonFapi
val ws: WSClient
val mostViewedAgent: MostViewedAgent
val newsletterSignupAgent: NewsletterSignupAgent
val deeplyReadAgent: DeeplyReadAgent
val remoteRenderer: DotcomRenderingService = DotcomRenderingService()
val assets: Assets
Expand Down Expand Up @@ -272,6 +274,10 @@ trait FaciaController
mostCommented = mostViewedAgent.mostCommented,
mostShared = mostViewedAgent.mostShared,
deeplyRead = deeplyRead,
newsletters = newsletterSignupAgent.getV2Newsletters() match {
case Right(newsletters) => newsletters
case Left(_) => List.empty
},
)(request),
targetedTerritories,
)
Expand All @@ -297,6 +303,10 @@ trait FaciaController
mostCommented = mostViewedAgent.mostCommented,
mostShared = mostViewedAgent.mostShared,
deeplyRead = deeplyRead,
newsletters = newsletterSignupAgent.getV2Newsletters() match {
case Right(newsletters) => newsletters
case Left(_) => List.empty
},
),
)
} else JsonFront(faciaPage)
Expand Down Expand Up @@ -551,5 +561,6 @@ class FaciaControllerImpl(
val mostViewedAgent: MostViewedAgent,
val deeplyReadAgent: DeeplyReadAgent,
val assets: Assets,
val newsletterSignupAgent: NewsletterSignupAgent,
)(implicit val context: ApplicationContext)
extends FaciaController
2 changes: 2 additions & 0 deletions facia/app/controllers/FaciaControllers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import model.ApplicationContext
import play.api.libs.ws.WSClient
import play.api.mvc.ControllerComponents
import services.fronts.FrontJsonFapiLive
import services.newsletters.NewsletterSignupAgent

trait FaciaControllers {
def frontJsonFapiLive: FrontJsonFapiLive
Expand All @@ -14,6 +15,7 @@ trait FaciaControllers {
def mostViewedAgent: MostViewedAgent
def deeplyReadAgent: DeeplyReadAgent
def assets: Assets
def newsletterSignupAgent: NewsletterSignupAgent
implicit def appContext: ApplicationContext
lazy val faciaController = wire[FaciaControllerImpl]
}
4 changes: 4 additions & 0 deletions preview/app/AppLoader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import services.fronts.FrontJsonFapiDraft
import services.newsletters.NewsletterSignupLifecycle
import services.{ConfigAgentLifecycle, OphanApi, SkimLinksCacheLifeCycle}
import conf.Configuration.aws.mandatoryCredentials
import services.newsletters.{NewsletterSignupAgent, NewsletterApi}

trait PreviewLifecycleComponents
extends SportServices
Expand Down Expand Up @@ -141,6 +142,9 @@ trait AppComponents
)

override lazy val httpErrorHandler: HttpErrorHandler = wire[PreviewErrorHandler]

override lazy val newsletterApi = wire[NewsletterApi]
override lazy val newsletterSignupAgent = wire[NewsletterSignupAgent]
}

class AppLoader extends FrontendApplicationLoader {
Expand Down
2 changes: 2 additions & 0 deletions preview/app/controllers/FaciaDraftController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import play.api.libs.ws.WSClient
import play.api.mvc._
import services.ConfigAgent
import services.fronts.FrontJsonFapiDraft
import services.newsletters.NewsletterSignupAgent

import scala.concurrent.Future

Expand All @@ -19,6 +20,7 @@ class FaciaDraftController(
sectionsLookUp: SectionsLookUp,
val controllerComponents: ControllerComponents,
val ws: WSClient,
val newsletterSignupAgent: NewsletterSignupAgent,
val mostViewedAgent: MostViewedAgent,
val deeplyReadAgent: DeeplyReadAgent,
val assets: Assets,
Expand Down
Loading