Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/guardian/frontend into dbla…
Browse files Browse the repository at this point in the history
…tcher/newsletter-id-snaps
  • Loading branch information
dblatcher committed Nov 26, 2024
2 parents a125476 + fd198dd commit 3ac3628
Show file tree
Hide file tree
Showing 26 changed files with 276 additions and 1,203 deletions.
48 changes: 33 additions & 15 deletions applications/app/controllers/CrosswordsController.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package controllers

import com.gu.contentapi.client.model.v1.CrosswordType.{Cryptic, Quick}
import com.gu.contentapi.client.model.v1.{Crossword, ItemResponse, Content => ApiContent, Section => ApiSection}
import common.{Edition, GuLogging, ImplicitControllerExecutionContext}
import conf.Static
import contentapi.ContentApiClient
import pages.{CrosswordHtmlPage, IndexHtmlPage, PrintableCrosswordHtmlPage}
import crosswords.{
AccessibleCrosswordPage,
AccessibleCrosswordRows,
Expand All @@ -14,18 +14,20 @@ import crosswords.{
CrosswordSearchPageWithResults,
CrosswordSvg,
}
import html.HtmlPageHelpers.ContentCSSFile
import model.Cached.{RevalidatableResult, WithoutRevalidationResult}
import model._
import model.dotcomrendering.pageElements.EditionsCrosswordRenderingDataModel
import model.dotcomrendering.{DotcomRenderingDataModel, PageType}
import org.joda.time.{DateTime, LocalDate}
import pages.{CrosswordHtmlPage, IndexHtmlPage, PrintableCrosswordHtmlPage}
import play.api.data.Forms._
import play.api.data._
import play.api.mvc.{Action, RequestHeader, Result, _}
import services.{IndexPage, IndexPageItem}
import html.HtmlPageHelpers.ContentCSSFile
import model.dotcomrendering.{DotcomRenderingDataModel, PageType}
import play.api.libs.ws.WSClient
import play.api.mvc._
import renderers.DotcomRenderingService
import services.dotcomrendering.{CrosswordsPicker, RemoteRender}
import services.{IndexPage, IndexPageItem}

import scala.concurrent.Future
import scala.concurrent.duration._
Expand Down Expand Up @@ -290,17 +292,33 @@ class CrosswordSearchController(
case class CrosswordLookup(crosswordType: String, id: Int)
}

class CrosswordEditionsController(val controllerComponents: ControllerComponents)
extends BaseController
class CrosswordEditionsController(
val contentApiClient: ContentApiClient,
val controllerComponents: ControllerComponents,
val remoteRenderer: DotcomRenderingService = DotcomRenderingService(),
val wsClient: WSClient,
) extends BaseController
with GuLogging
with ImplicitControllerExecutionContext {

def digitalEdition: Action[AnyContent] =
Action.async { implicit request =>
Future.successful(
Cached(CacheTime.Default)(
RevalidatableResult.Ok("Digital Edition Crossword Entry Point"),
),
)
}
def digitalEdition: Action[AnyContent] = Action.async { implicit request =>
getCrosswords
.map(parseCrosswords)
.flatMap {
case Some(crosswordPage) =>
remoteRenderer.getEditionsCrossword(wsClient, crosswordPage)
case None => Future.successful(NotFound)
}
}

private lazy val crosswordsQuery = contentApiClient.item("crosswords")

private def getCrosswords: Future[ItemResponse] = contentApiClient.getResponse(crosswordsQuery)

private def parseCrosswords(response: ItemResponse): Option[EditionsCrosswordRenderingDataModel] =
for {
results <- response.results
quick <- results.find(_.crossword.exists(_.`type` == Quick)).flatMap(_.crossword)
cryptic <- results.find(_.crossword.exists(_.`type` == Cryptic)).flatMap(_.crossword)
} yield EditionsCrosswordRenderingDataModel(quick, cryptic)
}
25 changes: 13 additions & 12 deletions applications/app/controllers/GalleryController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ class GalleryController(
lookup(path, index, isTrail) flatMap {
case Right((model, _)) if model.gallery.content.isExpired =>
Future.successful(RenderOtherStatus(Gone)) // TODO - delete this line after switching to new content api
case Right((model, blocks)) if request.isJson && request.forceDCR =>
val pageType = PageType(model, request, context)

Future.successful(
common.renderJson(getDCRJson(model, pageType, blocks), model).as("application/json"),
)
case Right((model, blocks)) if GalleryPicker.getTier(model) == RemoteRender =>
remoteRender(model, blocks)
case Right((model, _)) => Future.successful(renderGallery(model))
Expand All @@ -48,18 +54,13 @@ class GalleryController(
request: RequestHeader,
) = {
val pageType = PageType(model, request, context)
if (request.isJson) {
Future.successful(
common.renderJson(getDCRJson(model, pageType, blocks), model).as("application/json"),
)
} else {
remoteRenderer.getGallery(
wsClient,
model,
pageType,
blocks,
)
}

remoteRenderer.getGallery(
wsClient,
model,
pageType,
blocks,
)
}

def lightboxJson(path: String): Action[AnyContent] =
Expand Down
3 changes: 0 additions & 3 deletions applications/app/views/fragments/galleryBody.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
page,
page.item.lightbox.containsAffiliateableLinks && AffiliateLinksCleaner.shouldAddAffiliateLinks(
switchedOn = Switches.AffiliateLinks.isSwitchedOn,
section = page.gallery.content.metadata.sectionId,
showAffiliateLinks = page.gallery.content.fields.showAffiliateLinks,
supportedSections = Configuration.affiliateLinks.affiliateLinkSections,
defaultOffTags = Configuration.affiliateLinks.defaultOffTags,
alwaysOffTags = Configuration.affiliateLinks.alwaysOffTags,
tagPaths = page.gallery.content.tags.tags.map(_.id),
)
Expand Down
1 change: 0 additions & 1 deletion applications/app/views/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ object GalleryCaptionCleaners {
GalleryCaptionCleaner,
AffiliateLinksCleaner(
request.uri,
page.gallery.content.metadata.sectionId,
page.gallery.content.fields.showAffiliateLinks,
appendDisclaimer = Some(isFirstRow && page.item.lightbox.containsAffiliateableLinks),
tags = page.gallery.content.tags.tags.map(_.id),
Expand Down
1 change: 0 additions & 1 deletion article/app/views/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ object BodyProcessor {
GarnettQuoteCleaner,
AffiliateLinksCleaner(
pageUrl = request.uri,
sectionId = article.content.metadata.sectionId,
showAffiliateLinks = article.content.fields.showAffiliateLinks,
tags = article.content.tags.tags.map(_.id),
),
Expand Down
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ val common = library("common")
eTagCachingS3,
nettyCodecHttp2,
contentApiClient,
contentApiModelsJson,
enumeratumPlayJson,
filters,
commonsLang,
Expand Down
4 changes: 0 additions & 4 deletions common/app/common/configuration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,6 @@ class GuardianConfiguration extends GuLogging {
lazy val bucket: Option[String] = configuration.getStringProperty("skimlinks.bucket")
lazy val domainsKey = "skimlinks/skimlinks-domains.csv"
lazy val skimlinksId = configuration.getMandatoryStringProperty("skimlinks.id")
lazy val affiliateLinkSections: Set[String] =
configuration.getStringProperty("affiliatelinks.sections").getOrElse("").split(",").toSet
lazy val defaultOffTags: Set[String] =
configuration.getStringProperty("affiliatelinks.default.off.tags").getOrElse("").split(",").toSet
lazy val alwaysOffTags: Set[String] =
configuration.getStringProperty("affiliatelinks.always.off.tags").getOrElse("").split(",").toSet
}
Expand Down
23 changes: 22 additions & 1 deletion common/app/conf/switches/ABTestSwitches.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,18 @@ trait ABTestSwitches {
"Test the impact of showing the user a component that highlights the Guardians journalism",
owners = Seq(Owner.withEmail("[email protected]")),
safeState = Off,
sellByDate = Some(LocalDate.of(2024, 12, 18)),
sellByDate = Some(LocalDate.of(2025, 1, 29)),
exposeClientSide = true,
highImpact = false,
)

Switch(
ABTests,
"ab-onwards-content-article",
"Test the impact of showing the galleries onwards content component on article pages",
owners = Seq(Owner.withEmail("[email protected]")),
safeState = Off,
sellByDate = Some(LocalDate.of(2025, 1, 29)),
exposeClientSide = true,
highImpact = false,
)
Expand All @@ -70,4 +81,14 @@ trait ABTestSwitches {
exposeClientSide = true,
highImpact = false,
)
Switch(
ABTests,
"ab-gpid-prebid-ad-units",
"Test new GPID prebid ad units",
owners = Seq(Owner.withEmail("[email protected]")),
safeState = Off,
sellByDate = Some(LocalDate.of(2024, 12, 18)),
exposeClientSide = true,
highImpact = false,
)
}
12 changes: 0 additions & 12 deletions common/app/conf/switches/CommercialSwitches.scala
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,6 @@ trait CommercialSwitches {
impactFullMessage = Some("Warning: Disabling this switch will prevent us from being able to monetize The Filter"),
)

val AffiliateLinkSections: Switch = Switch(
group = Commercial,
name = "affiliate-links-sections",
description =
"Add affiliate links to all content in sections in affiliateLinkSections config property when no override exists in capi (showAffiliateLinks field).",
owners = group(Commercial),
safeState = Off,
sellByDate = never,
exposeClientSide = false,
highImpact = false,
)

val confiantAdVerification: Switch = Switch(
group = Commercial,
name = "confiant-ad-verification",
Expand Down
4 changes: 2 additions & 2 deletions common/app/conf/switches/PerformanceSwitches.scala
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ trait PerformanceSwitches {
"Shorten the surrogate cache time for recent articles for load testing",
owners = Seq(Owner.withEmail("[email protected]")),
safeState = Off,
sellByDate = LocalDate.of(2024, 11, 19),
sellByDate = LocalDate.of(2025, 1, 20),
exposeClientSide = false,
highImpact = false,
)
Expand All @@ -244,7 +244,7 @@ trait PerformanceSwitches {
"Shorten the surrogate cache time for older articles for load testing",
owners = Seq(Owner.withEmail("[email protected]")),
safeState = Off,
sellByDate = LocalDate.of(2024, 11, 19),
sellByDate = LocalDate.of(2025, 1, 20),
exposeClientSide = false,
highImpact = false,
)
Expand Down
28 changes: 21 additions & 7 deletions common/app/model/CollectionConfig.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package model.pressed

import com.gu.facia.api.{models => fapi}
import com.gu.facia.client.models.{Backfill, CollectionConfigJson, Metadata, CollectionPlatform, Primary, Secondary}
import com.gu.facia.client.models.{Backfill, CollectionConfigJson, Metadata, CollectionPlatform, Secondary}

final case class CollectionConfig(
displayName: Option[String],
Expand Down Expand Up @@ -29,14 +29,28 @@ object CollectionConfig {

def make(config: fapi.CollectionConfig): CollectionConfig = {

/** Extract `primary` or `secondary` collection level tag from metadata if present. Collection level is a concept
* that allows the platforms to style containers differently based on their "level"
val betaCollections = List(
"flexible/special",
"flexible/general",
"scrollable/highlights",
"scrollable/small",
"scrollable/medium",
"scrollable/feature",
"static/medium/4",
"static/feature/2",
)

/** Collection level is a concept that allows the platforms to style containers differently based on their "level".
* Beta collections are "Secondary" if tagged as such or "Primary" otherwise. Legacy containers have no container
* level set.
*/
val collectionLevel: Option[String] = config.metadata.flatMap { metadataList =>
metadataList.collectFirst {
case Primary => "Primary"
case Secondary => "Secondary"
val collectionLevel: Option[String] = if (betaCollections.contains(config.collectionType)) {
config.metadata.getOrElse(List.empty).find(_ == Secondary) match {
case Some(_) => Some("Secondary")
case None => Some("Primary")
}
} else {
None
}

CollectionConfig(
Expand Down
3 changes: 0 additions & 3 deletions common/app/model/dotcomrendering/DotcomRenderingUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,7 @@ object DotcomRenderingUtils {
if (firstEl.tagName == "p" && secondEl.tagName == "p" && secondEl.text().length >= 150) {
AffiliateLinksCleaner.shouldAddAffiliateLinks(
switchedOn = Switches.AffiliateLinks.isSwitchedOn,
section = content.metadata.sectionId,
showAffiliateLinks = content.content.fields.showAffiliateLinks,
supportedSections = Configuration.affiliateLinks.affiliateLinkSections,
defaultOffTags = Configuration.affiliateLinks.defaultOffTags,
alwaysOffTags = Configuration.affiliateLinks.alwaysOffTags,
tagPaths = content.content.tags.tags.map(_.id),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package model.dotcomrendering.pageElements

import com.gu.contentapi.client.model.v1.Crossword
import com.gu.contentapi.json.CirceEncoders._
import io.circe.JsonObject
import io.circe.syntax._

case class EditionsCrosswordRenderingDataModel(
quick: Crossword,
cryptic: Crossword,
)

object EditionsCrosswordRenderingDataModel {
def toJson(model: EditionsCrosswordRenderingDataModel): String = {
JsonObject(
"quick" -> model.quick.asJson.dropNullValues,
"cryptic" -> model.cryptic.asJson.dropNullValues,
).asJson.dropNullValues.noSpaces
}
}
12 changes: 7 additions & 5 deletions common/app/navigation/NavLinks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object NavLinks {
val indigenousAustralia = NavLink("Indigenous Australia", "/australia-news/indigenous-australians")
val indigenousAustraliaOpinion = NavLink("Indigenous", "/commentisfree/series/indigenousx")
val usNews = NavLink("US", "/us-news", longTitle = Some("US news"))
val usElections2024 = NavLink("US elections 2024", "/us-news/us-elections-2024")
val usPolitics = NavLink("US politics", "/us-news/us-politics")

val education = {
val teachers = NavLink("Teachers", "/teacher-network")
Expand Down Expand Up @@ -279,16 +279,16 @@ object NavLinks {
iconName = Some("home"),
List(
ukNews,
usElections2024,
usPolitics,
world,
climateCrisis,
middleEast,
ukraine,
football,
newsletters,
ukBusiness,
ukEnvironment,
politics,
education,
society,
science,
tech,
Expand Down Expand Up @@ -317,9 +317,10 @@ object NavLinks {
val usNewsPillar = ukNewsPillar.copy(children =
List(
usNews,
usElections2024,
usPolitics,
world,
usEnvironment,
middleEast,
ukraine,
usSoccer,
usBusiness,
Expand All @@ -332,9 +333,10 @@ object NavLinks {
val intNewsPillar = ukNewsPillar.copy(
children = List(
world,
usElections2024,
usPolitics,
ukNews,
climateCrisis,
middleEast,
ukraine,
ukEnvironment,
science,
Expand Down
11 changes: 10 additions & 1 deletion common/app/renderers/DotcomRenderingService.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package renderers

import org.apache.pekko.actor.{ActorSystem => PekkoActorSystem}
import com.gu.contentapi.client.model.v1.{Block, Blocks, Content}
import com.gu.contentapi.client.model.v1.{Block, Blocks, Content, Crossword}
import common.{DCRMetrics, GuLogging}
import concurrent.CircuitBreakerRegistry
import conf.Configuration
Expand All @@ -10,6 +10,7 @@ import crosswords.CrosswordPageWithContent
import http.{HttpPreconnections, ResultWithPreconnectPreload}
import model.Cached.{RevalidatableResult, WithoutRevalidationResult}
import model.dotcomrendering._
import model.dotcomrendering.pageElements.EditionsCrosswordRenderingDataModel
import model.{
CacheTime,
Cached,
Expand Down Expand Up @@ -419,6 +420,14 @@ class DotcomRenderingService extends GuLogging with ResultWithPreconnectPreload
val json = DotcomRenderingDataModel.toJson(dataModel)
post(ws, json, Configuration.rendering.articleBaseURL + "/Article", CacheTime.Facia)
}

def getEditionsCrossword(
ws: WSClient,
crosswords: EditionsCrosswordRenderingDataModel,
)(implicit request: RequestHeader): Future[Result] = {
val json = EditionsCrosswordRenderingDataModel.toJson(crosswords)
post(ws, json, Configuration.rendering.articleBaseURL + "/EditionsCrossword", CacheTime.Default)
}
}

object DotcomRenderingService {
Expand Down
Loading

0 comments on commit 3ac3628

Please sign in to comment.