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

still yield the audio element if there is no html. Currently CAPI is not sending html for audio articles. #27461

Closed
wants to merge 9 commits into from
19 changes: 16 additions & 3 deletions common/app/model/Asset.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package model

import com.gu.contentapi.client.model.v1.{Asset, AssetType, CartoonImage}
import com.gu.contentapi.client.model.v1.{Asset, AssetType, CartoonImage, AudioElementFields}
import play.api.libs.json.{Json, Writes}
import views.support.{ImgSrc, Naked, Orientation}

Expand Down Expand Up @@ -29,6 +29,14 @@ object Helpers {
"html" -> asset.typeData.flatMap(_.html),
"embedType" -> asset.typeData.flatMap(_.embedType),
).collect { case (k, Some(v)) => (k, v) }

def audioElementFieldsToMap(audioElementFields: AudioElementFields): Map[String, String] =
Map(
"durationMinutes" -> audioElementFields.durationMinutes.map(_.toString),
"durationSeconds" -> audioElementFields.durationSeconds.map(_.toString),
"explicit" -> audioElementFields.explicit.map(_.toString),
"source" -> audioElementFields.source,
).collect { case (k, Some(v)) => (k, v) }
}

object ImageAsset {
Expand Down Expand Up @@ -138,9 +146,14 @@ case class VideoAsset(fields: Map[String, String], url: Option[String], mimeType
}

object AudioAsset {
def make(asset: Asset): AudioAsset = {
def make(asset: Asset, audioElementFields: Option[AudioElementFields] = None): AudioAsset = {
val fields = if (asset.typeData.isEmpty) {
Helpers.assetFieldsToMap(asset)
} else {
audioElementFields.map(Helpers.audioElementFieldsToMap).getOrElse(Map.empty)
}
AudioAsset(
fields = Helpers.assetFieldsToMap(asset),
fields = fields,
mimeType = asset.mimeType,
url = asset.typeData.flatMap(_.secureFile).orElse(asset.file),
)
Expand Down
2 changes: 1 addition & 1 deletion common/app/model/Element.scala
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ final case class VideoMedia(videoAssets: List[VideoAsset]) {
object AudioMedia {
def make(capiElement: ApiElement): AudioMedia =
AudioMedia(
audioAssets = capiElement.assets.filter(_.`type`.name == "Audio").map(AudioAsset.make).toList,
audioAssets = capiElement.assets.filter(_.`type`.name == "Audio").map(asset => AudioAsset.make(asset)).toList,
)
}
final case class AudioMedia(audioAssets: List[AudioAsset]) {
Expand Down
59 changes: 53 additions & 6 deletions common/app/model/dotcomrendering/DotcomRenderingDataModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,31 @@ import com.gu.contentapi.client.utils.AdvertisementFeature
import com.gu.contentapi.client.utils.format.{ImmersiveDisplay, InteractiveDesign}
import common.Maps.RichMap
import common.commercial.EditionCommercialProperties
import common.{CanonicalLink, Chronos, Edition, Localisation, RichRequestHeader}
import conf.Configuration
import crosswords.CrosswordPageWithContent
import experiments.ActiveExperiments
import model.dotcomrendering.DotcomRenderingUtils._
import model.dotcomrendering.pageElements.{PageElement, TextCleaner}
import model.{
ArticleDateTimes,
Badges,
CanonicalLiveBlog,
ContentFormat,
ContentPage,
CrosswordData,
DotcomContentType,
GUDateTimeFormatNew,
GalleryPage,
ImageContentPage,
ImageMedia,
InteractivePage,
LiveBlogPage,
MediaPage,
PageWithStoryPackage,
Trail,
}
import common.{CanonicalLink, Chronos, Edition, Localisation, RichRequestHeader}
import conf.Configuration
import crosswords.CrosswordPageWithContent
import experiments.ActiveExperiments
import model.dotcomrendering.DotcomRenderingUtils._
import model.dotcomrendering.pageElements.{ImageBlockElement, PageElement, Role, TextCleaner}
import model.liveblog.BlockAttributes
import navigation._
import play.api.libs.json._
import play.api.mvc.RequestHeader
Expand Down Expand Up @@ -87,6 +91,7 @@ case class DotcomRenderingDataModel(
commercialProperties: Map[String, EditionCommercialProperties],
pageType: PageType,
starRating: Option[Int],
thumbnailImage: Option[Block],
trailText: String,
nav: Nav,
showBottomSocialButtons: Boolean,
Expand Down Expand Up @@ -164,6 +169,7 @@ object DotcomRenderingDataModel {
"commercialProperties" -> model.commercialProperties,
"pageType" -> model.pageType,
"starRating" -> model.starRating,
"thumbnailImage" -> model.thumbnailImage,
"trailText" -> model.trailText,
"nav" -> model.nav,
"showBottomSocialButtons" -> model.showBottomSocialButtons,
Expand Down Expand Up @@ -500,6 +506,46 @@ object DotcomRenderingDataModel {

val dcrTags = content.tags.tags.map(Tag.apply)

val audioImageBlock: Option[Block] =
if (page.metadata.contentType.contains(DotcomContentType.Audio)) {
for {
thumbnail <- page.item.elements.thumbnail
} yield {
val articleDateTimes = ArticleDateTimes.makeDisplayedDateTimesDCR(contentDateTimes, request)
new Block(
id = thumbnail.properties.id,
elements = List(
ImageBlockElement(
thumbnail.images,
Map.empty,
Some(true),
Role(Some("thumbnail")),
Seq.empty,
),
),
attributes = BlockAttributes(
pinned = false,
keyEvent = false,
summary = false,
None,
),
blockCreatedOn = None,
blockCreatedOnDisplay = None,
blockLastUpdated = None,
blockLastUpdatedDisplay = None,
blockFirstPublished = None,
blockFirstPublishedDisplay = None,
blockFirstPublishedDisplayNoTimezone = None,
title = None,
contributors = Seq.empty[Contributor],
primaryDateLine = articleDateTimes.primaryDateLine,
secondaryDateLine = articleDateTimes.secondaryDateLine,
)
}
} else {
None
}

def toDCRBlock(isMainBlock: Boolean = false) = { block: APIBlock =>
Block(
block = block,
Expand Down Expand Up @@ -619,6 +665,7 @@ object DotcomRenderingDataModel {
subMetaSectionLinks =
content.content.submetaLinks.sectionLabels.map(SubMetaLink.apply).filter(_.title.trim.nonEmpty),
tags = dcrTags,
thumbnailImage = audioImageBlock,
trailText = TextCleaner.sanitiseLinks(edition)(content.trail.fields.trailText.getOrElse("")),
twitterData = page.getTwitterProperties,
version = 3,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.gu.contentapi.client.utils.format.ImmersiveDisplay
import common.commercial.{CommercialProperties, EditionCommercialProperties, PrebidIndexSite}
import model.dotcomrendering.pageElements.PageElement
import model.liveblog.{MembershipPlaceholder, BlockAttributes}
import model.{ArticleDateTimes, ContentPage, GUDateTimeFormatNew}
import model.{ArticleDateTimes, ContentPage, GUDateTimeFormatNew, Podcast}
import navigation._
import org.joda.time.DateTime
import play.api.libs.json._
Expand All @@ -25,6 +25,7 @@ case class Tag(
twitterHandle: Option[String],
bylineImageUrl: Option[String],
bylineLargeImageUrl: Option[String],
podcast: Option[Podcast],
)

object Tag {
Expand All @@ -38,6 +39,7 @@ object Tag {
t.properties.twitterHandle,
t.properties.bylineImageUrl.map(src => ImgSrc(src, Item300)),
t.properties.contributorLargeImagePath.map(src => ImgSrc(src, Item300)),
t.properties.podcast,
)
}
}
Expand Down
14 changes: 4 additions & 10 deletions common/app/model/dotcomrendering/pageElements/PageElement.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import layout.ContentWidths.{BodyMedia, ImmersiveMedia, MainMedia}
import model.content._
import model.dotcomrendering.InteractiveSwitchOver
import model.dotcomrendering.pageElements.CartoonExtraction._
import model.{ImageAsset, ImageElement, ImageMedia, VideoAsset}
import model.{AudioAsset, ImageAsset, ImageElement, ImageMedia, VideoAsset}
import org.joda.time.DateTime
import org.jsoup.Jsoup
import play.api.libs.json._
Expand Down Expand Up @@ -120,8 +120,7 @@ object AudioAtomBlockElement {

// We are currently using AudioBlockElement as a catch all for audio errors, skipping the first definition
// See comment: 2e5ac4fd-e7f1-4c04-bdcd-ceadd2dc5d4c
// case class AudioBlockElement(assets: Seq[AudioAsset]) extends PageElement
case class AudioBlockElement(message: String) extends PageElement
case class AudioBlockElement(assets: Seq[AudioAsset]) extends PageElement
object AudioBlockElement {
implicit val AudioBlockElementWrites: Writes[AudioBlockElement] = Json.writes[AudioBlockElement]
}
Expand Down Expand Up @@ -1820,7 +1819,7 @@ object PageElement {
private def audioToPageElement(element: ApiBlockElement) = {
for {
d <- element.audioTypeData
html <- d.html
html = d.html.getOrElse("")
mandatory = true
thirdPartyTracking = containsThirdPartyTracking(element.tracking)
} yield {
Expand Down Expand Up @@ -1858,12 +1857,7 @@ object PageElement {
).getOrElse {
extractGenericEmbedBlockElement(html, d.role, thirdPartyTracking, d.source, d.sourceDomain, d.caption)
.getOrElse {
// This version of AudioBlockElement is not currently supported in DCR
// AudioBlockElement(element.assets.map(AudioAsset.make))

// AudioBlockElement is currently a catch all element which helps identify when Audio is carrying an
// incorrect payload.
AudioBlockElement("This audio element cannot be displayed at this time")
AudioBlockElement(element.assets.toList.map(asset => AudioAsset.make(asset, Some(d))))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion common/app/model/liveblog/BlockElement.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ object BlockElement {
),
)

case Audio => Some(AudioBlockElement(element, element.assets.map(AudioAsset.make).toSeq))
case Audio => Some(AudioBlockElement(element, element.assets.map(asset => AudioAsset.make(asset)).toSeq))

case Video =>
if (element.assets.nonEmpty) {
Expand Down