Skip to content

Commit

Permalink
Merge pull request #27501 from guardian/oa/audio-pages-main-media-audio
Browse files Browse the repository at this point in the history
Add audio data to main media for audio articles
  • Loading branch information
oliverabrahams authored Oct 14, 2024
2 parents 97c859d + 762bbdc commit 143b18b
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 46 deletions.
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
79 changes: 38 additions & 41 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 @@ -1818,55 +1817,53 @@ object PageElement {
}

private def audioToPageElement(element: ApiBlockElement) = {
for {
d <- element.audioTypeData
html <- d.html
mandatory = true
thirdPartyTracking = containsThirdPartyTracking(element.tracking)
} yield {

element.audioTypeData.map { d =>
val mandatory = true
val thirdPartyTracking = containsThirdPartyTracking(element.tracking)
/*
comment id: 2e5ac4fd-e7f1-4c04-bdcd-ceadd2dc5d4c
Audio is a versatile carrier. It carries both audio and, incorrectly, non audio (in legacy content).
The audioToPageElement function performs the transformation of an Audio element to the appropriate
PageElement.
The function returns either:
1. SoundcloudBlockElement
2. SpotifyBlockElement
3. EmbedBlockElement
4. AudioBlockElement (currently: an error message)
1. SoundcloudBlockElement
2. SpotifyBlockElement
3. EmbedBlockElement
4. AudioBlockElement
Note: EmbedBlockElement is returned by both extractChartDatawrapperEmbedBlockElement and extractGenericEmbedBlockElement
The former catches charts from charts-datawrapper.s3.amazonaws.com while the latter captures any iframe.
Note: AudioBlockElement is currently a catch all element which helps identify when Audio is carrying an incorrect
payload. It was decided that handling those as they come up will be an ongoing health task of the dotcom team,
and not part of the original DCR migration.
*/
extractSoundcloudBlockElement(html, mandatory, thirdPartyTracking, d.source, d.sourceDomain)
.getOrElse {
extractSpotifyBlockElement(element, thirdPartyTracking).getOrElse {
extractChartDatawrapperEmbedBlockElement(
html,
d.role,
thirdPartyTracking,
d.source,
d.sourceDomain,
d.caption,
).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")
}
d.html
.flatMap { html =>
extractSoundcloudBlockElement(html, mandatory, thirdPartyTracking, d.source, d.sourceDomain)
.orElse {
extractSpotifyBlockElement(element, thirdPartyTracking)
}
}
.orElse {
extractChartDatawrapperEmbedBlockElement(
html,
d.role,
thirdPartyTracking,
d.source,
d.sourceDomain,
d.caption,
)
}
.orElse {
extractGenericEmbedBlockElement(
html,
d.role,
thirdPartyTracking,
d.source,
d.sourceDomain,
d.caption,
)
}
}
.getOrElse {
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

0 comments on commit 143b18b

Please sign in to comment.