| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,7 +46,8 @@ case class DfpDataExtractor( | |||
| 46 | 46 | countries = countriesTargeted(lineItem), | |
| 47 | 47 | isR2Only = lineItem.targeting.targetsR2Only, | |
| 48 | 48 | targetsAdTest = lineItem.targeting.hasAdTestTargetting, | |
| 49 | - adTestValue = lineItem.targeting.adTestValue | ||
| 49 | + adTestValue = lineItem.targeting.adTestValue, | ||
| 50 | + keywords = lineItem.targeting.keyValues | ||
| 50 | 51 | ) | |
| 51 | 52 | } | |
| 52 | 53 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,7 @@ | |||
| 1 | 1 | package tools | |
| 2 | 2 | ||
| 3 | - import common.dfp.PageSkin | ||
| 4 | 3 | import conf.Configuration.commercial.dfpAccountId | |
| 5 | - import conf.Configuration.{commercial, site} | ||
| 4 | + import conf.Configuration.site | ||
| 6 | 5 | ||
| 7 | 6 | import scala.language.postfixOps | |
| 8 | 7 | ||
@@ -27,20 +26,6 @@ object DfpLink { | |||
| 27 | 26 | ||
| 28 | 27 | object SiteLink { | |
| 29 | 28 | ||
| 30 | - def adUnit(path: String, adTest: Option[String]): Option[String] = { | ||
| 31 | - | ||
| 32 | - lazy val domain = if (adTest.isDefined) commercial.testDomain else site.host | ||
| 33 | - val relativePath = PageSkin.getRelativePath(path) | ||
| 34 | - val domainAndPath = relativePath map { path => s"$domain/$path" } | ||
| 35 | - val domainAndPathWithAdTest = | ||
| 36 | - for { | ||
| 37 | - id <- adTest | ||
| 38 | - baseUrl <- domainAndPath | ||
| 39 | - } yield s"$baseUrl?adtest=$id" | ||
| 40 | - | ||
| 41 | - domainAndPathWithAdTest orElse domainAndPath | ||
| 42 | - } | ||
| 43 | - | ||
| 44 | 29 | def contributorTagPage(contributor: String): String = s"${site.host}/profile/$contributor" | |
| 45 | 30 | ||
| 46 | 31 | def page(pageId: String):String = s"${site.host}/$pageId" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,6 @@ | |||
| 1 | 1 | @(pageSkinnedAdUnits: common.dfp.PageSkinSponsorshipReport)(implicit request: RequestHeader, context: model.ApplicationContext) | |
| 2 | 2 | @import common.dfp._ | |
| 3 | - @import tools.{DfpLink, SiteLink} | ||
| 3 | + @import tools.DfpLink | ||
| 4 | 4 | ||
| 5 | 5 | @flaggableProperty(label: String, values: Seq[String], textWhenEmpty: String, flagErrors: Boolean) = { | |
| 6 | 6 | @if(values.isEmpty) { | |
@@ -24,11 +24,17 @@ | |||
| 24 | 24 | <ul> | |
| 25 | 25 | @if(sponsorship.adUnits.isEmpty) { <li>Run of network</li> } | |
| 26 | 26 | @for(adUnit <- sponsorship.adUnits) { | |
| 27 | - <li> | ||
| 28 | - <a href="@SiteLink.adUnit(adUnit, sponsorship.adTestValue)">@adUnit</a> | ||
| 29 | - </li> | ||
| 27 | + <li>@adUnit</li> | ||
| 30 | 28 | } | |
| 31 | 29 | </ul> | |
| 30 | + @if(sponsorship.keywords.nonEmpty) { | ||
| 31 | + <small>Keywords:</small> | ||
| 32 | + <ul> | ||
| 33 | + @for(keyword <- sponsorship.keywords) { | ||
| 34 | + <li>@keyword</li> | ||
| 35 | + } | ||
| 36 | + </ul> | ||
| 37 | + } | ||
| 32 | 38 | </li> | |
| 33 | 39 | } | |
| 34 | 40 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -404,7 +404,7 @@ class GuardianConfiguration extends Logging { | |||
| 404 | 404 | private lazy val dfpRoot = s"$commercialRoot/dfp" | |
| 405 | 405 | lazy val dfpInlineMerchandisingTagsDataKey = s"$dfpRoot/inline-merchandising-tags-v3.json" | |
| 406 | 406 | lazy val dfpHighMerchandisingTagsDataKey = s"$dfpRoot/high-merchandising-tags.json" | |
| 407 | - lazy val dfpPageSkinnedAdUnitsKey = s"$dfpRoot/pageskinned-adunits-v6.json" | ||
| 407 | + lazy val dfpPageSkinnedAdUnitsKey = s"$dfpRoot/pageskinned-adunits-v7.json" | ||
| 408 | 408 | lazy val dfpLineItemsKey = s"$dfpRoot/lineitems-v6.json" | |
| 409 | 409 | lazy val dfpActiveAdUnitListKey = s"$dfpRoot/active-ad-units.csv" | |
| 410 | 410 | lazy val dfpMobileAppsAdUnitListKey = s"$dfpRoot/mobile-active-ad-units.csv" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -148,6 +148,14 @@ case class GuTargeting(adUnitsIncluded: Seq[GuAdUnit], | |||
| 148 | 148 | geoTargetsExcluded: Seq[GeoTarget], | |
| 149 | 149 | customTargetSets: Seq[CustomTargetSet]) { | |
| 150 | 150 | ||
| 151 | + val keyValues: Seq[String] = { | ||
| 152 | + for { | ||
| 153 | + targetSet <- customTargetSets | ||
| 154 | + target <- targetSet.targets if target.isKeywordTag | ||
| 155 | + targetValue <- target.values | ||
| 156 | + } yield targetValue | ||
| 157 | + } | ||
| 158 | + | ||
| 151 | 159 | val adTestValue: Option[String] = { | |
| 152 | 160 | val testValues = for { | |
| 153 | 161 | targetSet <- customTargetSets | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,78 +1,41 @@ | |||
| 1 | 1 | package common.dfp | |
| 2 | 2 | ||
| 3 | 3 | import common.{Edition, Logging} | |
| 4 | - import play.api.libs.functional.syntax._ | ||
| 5 | 4 | import play.api.libs.json._ | |
| 6 | 5 | ||
| 7 | - | ||
| 8 | 6 | case class PageSkinSponsorship(lineItemName: String, | |
| 9 | 7 | lineItemId: Long, | |
| 10 | 8 | adUnits: Seq[String], | |
| 11 | 9 | editions: Seq[Edition], | |
| 12 | 10 | countries: Seq[String], | |
| 13 | 11 | isR2Only: Boolean, | |
| 14 | 12 | targetsAdTest: Boolean, | |
| 15 | - adTestValue: Option[String]) | ||
| 13 | + adTestValue: Option[String], | ||
| 14 | + keywords: Seq[String]) | ||
| 16 | 15 | ||
| 17 | 16 | object PageSkinSponsorship { | |
| 18 | - | ||
| 19 | - implicit val pageskinSponsorShipFormat: Format[PageSkinSponsorship] = ( | ||
| 20 | - (JsPath \ "lineItem").format[String] and | ||
| 21 | - (JsPath \ "lineItemId").format[Long] and | ||
| 22 | - (JsPath \ "adUnits").format[Seq[String]] and | ||
| 23 | - (JsPath \ "editions").format[Seq[Edition]] and | ||
| 24 | - (JsPath \ "countries").format[Seq[String]] and | ||
| 25 | - (JsPath \ "isR2Only").format[Boolean] and | ||
| 26 | - (JsPath \ "isAdTest").format[Boolean] and | ||
| 27 | - (JsPath \ "adTestValue").formatNullable[String] | ||
| 28 | - )(PageSkinSponsorship.apply, unlift(PageSkinSponsorship.unapply)) | ||
| 17 | + implicit val pageskinSponsorShipFormat: Format[PageSkinSponsorship] = Json.format[PageSkinSponsorship] | ||
| 29 | 18 | } | |
| 30 | 19 | ||
| 31 | 20 | case class PageSkinSponsorshipReport(updatedTimeStamp: String, sponsorships: Seq[PageSkinSponsorship]) { | |
| 32 | 21 | val (testSponsorships, deliverableSponsorships) = sponsorships partition (_.targetsAdTest) | |
| 33 | 22 | } | |
| 34 | 23 | ||
| 35 | 24 | object PageSkinSponsorshipReport { | |
| 36 | - | ||
| 37 | - implicit val pageSkinSponsorshipReportWrites = new Writes[PageSkinSponsorshipReport] { | ||
| 38 | - def writes(report: PageSkinSponsorshipReport): JsValue = { | ||
| 39 | - Json.obj( | ||
| 40 | - "updatedTimeStamp" -> report.updatedTimeStamp, | ||
| 41 | - "sponsorships" -> report.sponsorships | ||
| 42 | - ) | ||
| 43 | - } | ||
| 44 | - } | ||
| 45 | - | ||
| 25 | + implicit val pageSkinSponsorshipReportFormat: Format[PageSkinSponsorshipReport] = Json.format[PageSkinSponsorshipReport] | ||
| 46 | 26 | } | |
| 47 | 27 | ||
| 48 | 28 | object PageSkin { | |
| 29 | + private val ngFrontSuffix = "/front/ng" | ||
| 30 | + private val frontSuffix = "/front" | ||
| 49 | 31 | ||
| 50 | - def isValidAdUnit(adUnitPath: String): Boolean = getRelativePath(adUnitPath).isDefined | ||
| 51 | - | ||
| 52 | - def getRelativePath(adUnitPath: String): Option[String] = { | ||
| 53 | - | ||
| 54 | - def trimPath(dropFromRight: Int) = adUnitPath.split("/").drop(1).dropRight(dropFromRight).mkString("/") | ||
| 55 | - | ||
| 56 | - if (adUnitPath endsWith "/front/ng") | ||
| 57 | - Some(trimPath(2)) | ||
| 58 | - else if (adUnitPath endsWith "/front") | ||
| 59 | - Some(trimPath(1)) | ||
| 60 | - else | ||
| 61 | - None | ||
| 62 | - } | ||
| 63 | - | ||
| 64 | - | ||
| 32 | + def isValidAdUnit(adUnitPath: String): Boolean = (adUnitPath endsWith ngFrontSuffix) || (adUnitPath endsWith frontSuffix) | ||
| 65 | 33 | } | |
| 66 | 34 | ||
| 67 | 35 | object PageSkinSponsorshipReportParser extends Logging { | |
| 68 | 36 | ||
| 69 | 37 | def apply(jsonString: String): Option[PageSkinSponsorshipReport] = { | |
| 70 | 38 | ||
| 71 | - implicit val reportReads: Reads[PageSkinSponsorshipReport] = ( | ||
| 72 | - (JsPath \ "updatedTimeStamp").read[String] and | ||
| 73 | - (JsPath \ "sponsorships").read[Seq[PageSkinSponsorship]] | ||
| 74 | - )(PageSkinSponsorshipReport.apply _) | ||
| 75 | - | ||
| 76 | 39 | val result: JsResult[PageSkinSponsorshipReport] = Json.parse(jsonString).validate[PageSkinSponsorshipReport] | |
| 77 | 40 | result match { | |
| 78 | 41 | case s: JsSuccess[PageSkinSponsorshipReport] => Some(s.get) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,42 +1,51 @@ | |||
| 1 | 1 | package common.dfp | |
| 2 | 2 | ||
| 3 | 3 | import common.Edition | |
| 4 | - import conf.Configuration.commercial._ | ||
| 4 | + import com.gu.commercial.display.AdTargetParam.toMap | ||
| 5 | + import com.gu.commercial.display.MultipleValues | ||
| 6 | + import model.MetaData | ||
| 5 | 7 | ||
| 6 | 8 | trait PageskinAdAgent { | |
| 7 | 9 | ||
| 8 | 10 | protected val environmentIsProd: Boolean | |
| 9 | 11 | ||
| 10 | 12 | protected def pageSkinSponsorships: Seq[PageSkinSponsorship] | |
| 11 | 13 | ||
| 12 | - private def findSponsorships(adUnitWithoutRoot: String, edition: Edition): Seq[PageSkinSponsorship] = { | ||
| 14 | + // There are two forms of pageskins: | ||
| 15 | + // - pageskins that target through ad unit (for pressed fronts) | ||
| 16 | + // - pageskins that target through a keyword (for index page fronts) | ||
| 17 | + private def findSponsorships(adUnitPath: String, metaData: MetaData, edition: Edition): Seq[PageSkinSponsorship] = { | ||
| 13 | 18 | ||
| 14 | - if (PageSkin.isValidAdUnit(adUnitWithoutRoot)) { | ||
| 15 | - val adUnitWithRoot = s"$dfpAdUnitGuRoot/$adUnitWithoutRoot" | ||
| 19 | + val candidates = pageSkinSponsorships filter { sponsorship => | ||
| 20 | + sponsorship.editions.contains(edition) && !sponsorship.isR2Only } | ||
| 16 | 21 | ||
| 17 | - def targetsAdUnitAndMatchesTheEdition(sponsorship: PageSkinSponsorship) = { | ||
| 18 | - val adUnits = sponsorship.adUnits map (_.stripSuffix("/ng")) | ||
| 19 | - adUnits.contains(adUnitWithRoot) && | ||
| 20 | - sponsorship.editions.contains(edition) && | ||
| 21 | - !sponsorship.isR2Only | ||
| 22 | - } | ||
| 23 | - | ||
| 24 | - pageSkinSponsorships filter { sponsorship => | ||
| 25 | - targetsAdUnitAndMatchesTheEdition(sponsorship) | ||
| 26 | - } | ||
| 22 | + if (metaData.isPressedPage) { | ||
| 23 | + if (PageSkin.isValidAdUnit(adUnitPath)) { | ||
| 24 | + candidates filter { sponsorship => sponsorship.adUnits.exists(adUnitPath.endsWith) } | ||
| 25 | + } else Seq.empty | ||
| 27 | 26 | } else { | |
| 28 | - Seq.empty | ||
| 27 | + val targetingMap = toMap(metaData.commercial.map(_.adTargeting(edition)).getOrElse(Set.empty)) | ||
| 28 | + val keywordTargeting = targetingMap.get("k") match { | ||
| 29 | + case Some(values: MultipleValues) => values.values.toSeq | ||
| 30 | + case _ => Seq.empty | ||
| 31 | + } | ||
| 32 | + candidates filter { sponsorship => sponsorship.keywords.intersect(keywordTargeting).nonEmpty } | ||
| 29 | 33 | } | |
| 30 | 34 | } | |
| 31 | 35 | ||
| 32 | 36 | // The ad unit is considered to have a page skin if it has a corresponding sponsorship. | |
| 33 | 37 | // If the sponsorship is an adTest, it is only considered outside of production. | |
| 34 | - def hasPageSkin(adUnitWithoutRoot: String, edition: Edition): Boolean = { | ||
| 35 | - findSponsorships(adUnitWithoutRoot, edition) exists (sponsorship => !(environmentIsProd && sponsorship.targetsAdTest)) | ||
| 38 | + def hasPageSkin(fullAdUnitPath: String, metaData: MetaData, edition: Edition): Boolean = { | ||
| 39 | + if (metaData.isFront) { | ||
| 40 | + findSponsorships(fullAdUnitPath, metaData, edition) exists (sponsorship => | ||
| 41 | + !(environmentIsProd && sponsorship.targetsAdTest)) | ||
| 42 | + } else false | ||
| 36 | 43 | } | |
| 37 | 44 | ||
| 38 | 45 | // True if there is any candidate sponsorship for this ad unit. Used to decide when to render the out-of-page ad slot. | |
| 39 | - def hasPageSkinOrAdTestPageSkin(adUnitWithoutRoot: String, edition: Edition): Boolean = { | ||
| 40 | - findSponsorships(adUnitWithoutRoot, edition).nonEmpty | ||
| 46 | + def hasPageSkinOrAdTestPageSkin(fullAdUnitPath: String, metaData: MetaData, edition: Edition): Boolean = { | ||
| 47 | + if (metaData.isFront) { | ||
| 48 | + findSponsorships(fullAdUnitPath, metaData, edition).nonEmpty | ||
| 49 | + } else false | ||
| 41 | 50 | } | |
| 42 | 51 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -222,7 +222,7 @@ final case class MetaData ( | |||
| 222 | 222 | openGraphImages: Seq[String] = Seq(), | |
| 223 | 223 | membershipAccess: Option[String] = None, | |
| 224 | 224 | isFront: Boolean = false, | |
| 225 | - isPressedPage: Boolean = true, | ||
| 225 | + isPressedPage: Boolean = false, | ||
| 226 | 226 | hideUi: Boolean = false, | |
| 227 | 227 | canonicalUrl: Option[String] = None, | |
| 228 | 228 | shouldGoogleIndex: Boolean = true, | |
@@ -237,13 +237,11 @@ final case class MetaData ( | |||
| 237 | 237 | isNewRecipeDesign: Boolean = false | |
| 238 | 238 | ){ | |
| 239 | 239 | val sectionId = section map (_.value) getOrElse "" | |
| 240 | + private val fullAdUnitPath = AdUnitMaker.make(id, adUnitSuffix) | ||
| 241 | + | ||
| 242 | + def hasPageSkin(edition: Edition): Boolean = DfpAgent.hasPageSkin(fullAdUnitPath, this, edition) | ||
| 243 | + def hasPageSkinOrAdTestPageSkin(edition: Edition): Boolean = DfpAgent.hasPageSkinOrAdTestPageSkin(fullAdUnitPath, this, edition) | ||
| 240 | 244 | ||
| 241 | - def hasPageSkin(edition: Edition): Boolean = if (isPressedPage){ | ||
| 242 | - DfpAgent.hasPageSkin(adUnitSuffix, edition) | ||
| 243 | - } else false | ||
| 244 | - def hasPageSkinOrAdTestPageSkin(edition: Edition): Boolean = if (isPressedPage){ | ||
| 245 | - DfpAgent.hasPageSkinOrAdTestPageSkin(adUnitSuffix, edition) | ||
| 246 | - } else false | ||
| 247 | 245 | def omitMPUsFromContainers(edition: Edition): Boolean = if (isPressedPage) { | |
| 248 | 246 | DfpAgent.omitMPUsFromContainers(id, edition) | |
| 249 | 247 | } else false | |
@@ -267,7 +265,7 @@ final case class MetaData ( | |||
| 267 | 265 | ("pageId", JsString(id)), | |
| 268 | 266 | ("section", JsString(sectionId)), | |
| 269 | 267 | ("webTitle", JsString(webTitle)), | |
| 270 | - ("adUnit", JsString(AdUnitMaker.make(id, adUnitSuffix))), | ||
| 268 | + ("adUnit", JsString(fullAdUnitPath)), | ||
| 271 | 269 | ("buildNumber", JsString(buildNumber)), | |
| 272 | 270 | ("revisionNumber", JsString(revision)), | |
| 273 | 271 | ("isFront", JsBoolean(isFront)), | |
| Back | FazBrowse Home | New Git URL |
0 commit comments