Skip to content

Commit

Permalink
Merge branch 'main' into dina/update-logo-styling-for-advertising-par…
Browse files Browse the repository at this point in the history
…tner
  • Loading branch information
deedeeh authored May 21, 2024
2 parents bc5ddf1 + 72752c8 commit ce976f6
Show file tree
Hide file tree
Showing 29 changed files with 452 additions and 2,770 deletions.
6 changes: 2 additions & 4 deletions applications/app/services/dotcomrendering/MediaPicker.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import model.Cors.RichRequestHeader
import model.{MediaPage, Video, Audio}
import play.api.mvc.RequestHeader
import utils.DotcomponentsLogger
import experiments.DCRVideoPages
import navigation.NavLinks.media
import experiments.ActiveExperiments
import conf.switches.Switches.DCRVideoPages

object MediaPicker extends GuLogging {

Expand Down Expand Up @@ -40,15 +40,13 @@ object MediaPicker extends GuLogging {
request: RequestHeader,
): RenderType = {

// defaulting to false until we are ready to release and create a 0% test
val participatingInTest = ActiveExperiments.isParticipating(DCRVideoPages)
val dcrCanRender = dcrCouldRender(mediaPage)
val flags = dcrLogFlags(mediaPage)

val tier = {
if (request.forceDCROff) LocalRender
else if (request.forceDCR) RemoteRender
else if (dcrCanRender && participatingInTest) RemoteRender
else if (dcrCanRender && DCRVideoPages.isSwitchedOn) RemoteRender
else LocalRender
}

Expand Down
10 changes: 0 additions & 10 deletions common/app/conf/switches/ABTestSwitches.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,6 @@ trait ABTestSwitches {
exposeClientSide = true,
)

Switch(
ABTests,
"ab-onward-journeys",
"Test click through rate when there is only one onward journey container shown.",
owners = Seq(Owner.withEmail("[email protected]")),
safeState = Off,
sellByDate = Some(LocalDate.of(2024, 6, 7)),
exposeClientSide = true,
)

Switch(
ABTests,
"ab-deeply-read-right-column",
Expand Down
11 changes: 11 additions & 0 deletions common/app/conf/switches/FeatureSwitches.scala
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ trait FeatureSwitches {
sellByDate = Some(LocalDate.of(2024, 6, 5)),
exposeClientSide = true,
)

val DiscussionInApps = Switch(
SwitchGroup.Feature,
"discussion-in-apps",
Expand All @@ -513,4 +514,14 @@ trait FeatureSwitches {
sellByDate = Some(LocalDate.of(2024, 6, 5)),
exposeClientSide = true,
)

val DCRVideoPages = Switch(
SwitchGroup.Feature,
"dcr-video-pages",
"If this switch is on, we will render video pages with DCR",
owners = Seq(Owner.withEmail("[email protected]"), Owner.withEmail("[email protected]")),
safeState = Off,
sellByDate = never,
exposeClientSide = false,
)
}
10 changes: 10 additions & 0 deletions common/app/conf/switches/JournalismSwitches.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,14 @@ trait JournalismSwitches {
sellByDate = never,
exposeClientSide = true,
)

val AbsoluteServerTimes = Switch(
SwitchGroup.Journalism,
name = "absolute-server-times",
description = "Force times on the server to be absolute to improve caching",
owners = Seq(Owner.withEmail("[email protected]")),
safeState = Off,
sellByDate = never,
exposeClientSide = true,
)
}
17 changes: 7 additions & 10 deletions common/app/experiments/Experiments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ object ActiveExperiments extends ExperimentsDefinition {
Set(
DarkModeWeb,
DCRTagPages,
DCRVideoPages,
UpdatedHeaderDesign,
UpdateLogoAdPartner,
MastheadWithHighlights,
AffiliateLinksDCR,
)
implicit val canCheckExperiment: CanCheckExperiment = new CanCheckExperiment(this)
}
Expand Down Expand Up @@ -58,16 +58,13 @@ object UpdateLogoAdPartner
participationGroup = Perc0A,
)

object DCRVideoPages
object AffiliateLinksDCR
extends Experiment(
name = "dcr-video-pages",
description = "Render video pages with DCR",
owners = Seq(
Owner.withGithub("[email protected]"),
Owner.withGithub("[email protected]"),
),
sellByDate = LocalDate.of(2024, 5, 30),
participationGroup = Perc10A,
name = "affiliate-links-dcr",
description = "Display affiliate links on all eligible DCR articles",
owners = Seq(Owner.withGithub("[email protected]")),
sellByDate = LocalDate.of(2024, 7, 30),
participationGroup = Perc0E,
)

object DCRTagPages
Expand Down
17 changes: 6 additions & 11 deletions common/app/http/GuardianAuthWithExemptions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import common.Environment.stage
import conf.Configuration.aws.mandatoryCredentials
import model.ApplicationContext
import org.apache.pekko.stream.Materializer
import org.slf4j.LoggerFactory
import play.api.Mode
import play.api.libs.ws.WSClient
import play.api.mvc._
Expand All @@ -35,8 +34,6 @@ class GuardianAuthWithExemptions(

private val outer = this

val logger = LoggerFactory.getLogger(this.getClass)

private val permissions: PermissionsProvider = PermissionsProvider(
PermissionsConfig(
stage = if (stage == "PROD") "PROD" else "CODE",
Expand Down Expand Up @@ -105,14 +102,12 @@ class GuardianAuthWithExemptions(
if (permissions.hasPermission(requiredPermission, user.email)) {
nextFilter(request)
} else {
// Future.successful(
// Results.Forbidden(
// s"You do not have permission to access $system. " +
// s"You should contact Central Production to request '$requiredEditorialPermissionName' permission.",
// ),
// )
logger.warn(s"${user.email} used $system, but didn't have '$requiredEditorialPermissionName' permission.")
nextFilter(request)
Future.successful(
Results.Forbidden(
s"You do not have permission to access $system. " +
s"You should contact Central Production to request '$requiredEditorialPermissionName' permission.",
),
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ object DotcomBlocksRenderingDataModel {
bodyBlocks: Seq[APIBlock],
): DotcomBlocksRenderingDataModel = {
val content = page.item
val shouldAddAffiliateLinks = DotcomRenderingUtils.shouldAddAffiliateLinks(content)
val shouldAddAffiliateLinks = DotcomRenderingUtils.shouldAddAffiliateLinks(content)(request)
val contentDateTimes = DotcomRenderingUtils.contentDateTimes(content)

val edition = Edition(request)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ object DotcomRenderingDataModel {
blocks.exists(block => DotcomRenderingUtils.stringContainsAffiliateableLinks(block.bodyHtml))
}

val shouldAddAffiliateLinks = DotcomRenderingUtils.shouldAddAffiliateLinks(content)
val shouldAddAffiliateLinks = DotcomRenderingUtils.shouldAddAffiliateLinks(content)(request)
val shouldAddDisclaimer = hasAffiliateLinks(bodyBlocks)

val contentDateTimes: ArticleDateTimes = ArticleDateTimes(
Expand Down
35 changes: 22 additions & 13 deletions common/app/model/dotcomrendering/DotcomRenderingUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import model.{
Pillar,
}
import org.joda.time.format.DateTimeFormat
import org.jsoup.Jsoup
import play.api.libs.json._
import play.api.mvc.RequestHeader
import views.support.AffiliateLinksCleaner
Expand Down Expand Up @@ -241,19 +242,27 @@ object DotcomRenderingUtils {
}
}

def shouldAddAffiliateLinks(content: ContentType): Boolean = {
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),
firstPublishedDate = content.content.fields.firstPublicationDate,
pageUrl = content.metadata.id,
contentType = "article",
)
def shouldAddAffiliateLinks(content: ContentType)(implicit request: RequestHeader): Boolean = {
val contentHtml = Jsoup.parse(content.fields.body)
val bodyElements = contentHtml.select("body").first().children()
if (bodyElements.size >= 2) {
val firstEl = bodyElements.get(0)
val secondEl = bodyElements.get(1)
if (firstEl.tagName == "p" && secondEl.tagName == "p" && secondEl.text().length >= 250) {
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),
firstPublishedDate = content.content.fields.firstPublicationDate,
pageUrl = content.metadata.id,
contentType = "article",
)
} else false
} else false
}

def contentDateTimes(content: ContentType): ArticleDateTimes = {
Expand Down
3 changes: 3 additions & 0 deletions common/app/services/ConfigAgentTrait.scala
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ object ConfigAgent extends GuLogging {
def shouldServeFront(id: String)(implicit context: ApplicationContext): Boolean =
getPathIds.contains(id) && (context.isPreview || !isFrontHidden(id))

def frontExistsInConfig(id: String)(implicit context: ApplicationContext): Boolean =
getPathIds.contains(id)

def shouldServeEditionalisedFront(edition: Edition, id: String)(implicit context: ApplicationContext): Boolean = {
shouldServeFront(s"${edition.id.toLowerCase}/$id")
}
Expand Down
2 changes: 0 additions & 2 deletions common/app/services/DynamoDB.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package services

import com.amazonaws.regions.{Region, Regions}
import com.amazonaws.services.dynamodbv2.{
AmazonDynamoDB,
AmazonDynamoDBAsync,
Expand All @@ -11,7 +10,6 @@ import conf.Configuration

object DynamoDB {
private lazy val credentials = Configuration.aws.mandatoryCredentials
private lazy val region = Region.getRegion(Regions.fromName(Configuration.aws.region))

lazy val asyncClient: AmazonDynamoDBAsync = AmazonDynamoDBAsyncClient
.asyncBuilder()
Expand Down
10 changes: 6 additions & 4 deletions common/app/views/support/HtmlCleaner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import common.{Edition, GuLogging, LinkTo}
import conf.Configuration.affiliateLinks._
import conf.Configuration.site.host
import conf.switches.Switches._
import experiments.{ActiveExperiments, AffiliateLinksDCR}
import layout.ContentWidths
import layout.ContentWidths._
import model._
Expand Down Expand Up @@ -873,7 +874,8 @@ case class AffiliateLinksCleaner(
tags: List[String],
publishedDate: Option[DateTime],
contentType: String,
) extends HtmlCleaner
)(implicit request: RequestHeader)
extends HtmlCleaner
with GuLogging {

override def clean(document: Document): Document = {
Expand Down Expand Up @@ -946,7 +948,7 @@ object AffiliateLinksCleaner {
firstPublishedDate: Option[DateTime],
pageUrl: String,
contentType: String,
): Boolean = {
)(implicit request: RequestHeader): Boolean = {
val publishedCutOffDate = new DateTime(2020, 8, 14, 0, 0)

val cleanedPageUrl = if (pageUrl.charAt(0) == '/') {
Expand All @@ -973,11 +975,11 @@ object AffiliateLinksCleaner {

// Never include affiliate links if it is tagged with an always off tag, or if it was published before our cut off date.
// The cut off date is temporary while we are working on improving the compliance of affiliate links.
// The cut off date does not apply to any URL on the allow list
// The cut off date does not apply to any URL on the allow list or to galleries
if (
!contentHasAlwaysOffTag(tagPaths, alwaysOffTags) && (firstPublishedDate.exists(
_.isBefore(publishedCutOffDate),
) || urlIsInAllowList || contentType == "gallery")
) || urlIsInAllowList || contentType == "gallery" || ActiveExperiments.isParticipating(AffiliateLinksDCR))
) {
if (showAffiliateLinks.isDefined) {
showAffiliateLinks.contains(true)
Expand Down
Loading

0 comments on commit ce976f6

Please sign in to comment.