onward/app/controllers/SeriesController.scala (114 lines of code) (raw):

package controllers import java.net.URI import com.gu.contentapi.client.model.{ContentApiError, ItemQuery} import com.gu.contentapi.client.model.v1.{Content => ApiContent} import common.{JsonComponent, _} import contentapi.ContentApiClient import implicits.Requests import layout.FaciaContainer import model.Cached.{RevalidatableResult, WithoutRevalidationResult} import model._ import play.api.libs.json.{JsArray, Json} import play.api.mvc._ import views.support.FaciaToMicroFormat2Helpers._ import models.{Series, SeriesHelper, SeriesStoriesDCR} import utils.ShortUrls import scala.concurrent.Future import scala.concurrent.duration._ class SeriesController( contentApiClient: ContentApiClient, val controllerComponents: ControllerComponents, )(implicit context: ApplicationContext) extends BaseController with GuLogging with Paging with ImplicitControllerExecutionContext with Requests { def renderSeriesStories(seriesId: String): Action[AnyContent] = Action.async { implicit request => if (request.forceDCR) { lookup(Edition(request), seriesId).map { mseries => mseries .map { series => JsonComponent.fromWritable(SeriesStoriesDCR.fromSeries(series)).result } .getOrElse(NotFound) } } else { lookup(Edition(request), seriesId) map { series => series.map(renderSeriesTrails).getOrElse(NotFound) } } } def renderMf2SeriesStories(seriesId: String): Action[AnyContent] = Action.async { implicit request => lookup(Edition(request), seriesId) map { _.map(series => Cached(15.minutes)( rendermf2Series(series), ), ).getOrElse(Cached(15.minutes)(WithoutRevalidationResult(NotFound))) } } def renderPodcastEpisodes(seriesId: String): Action[AnyContent] = Action.async { implicit request => lookup(Edition(request), seriesId, _.contentType("audio")) map { _.map(series => Cached(900) { JsonComponent(views.html.fragments.podcastEpisodes(series.trails.items.take(4).map(_.content))) }, ).getOrElse(NotFound) } } private def lookup(edition: Edition, seriesId: String, queryModifier: ItemQuery => ItemQuery = identity)(implicit request: RequestHeader, ): Future[Option[Series]] = { val currentShortUrl = request.getQueryString("shortUrl") def isCurrentStory(content: ApiContent) = content.fields .flatMap(fields => fields.shortUrl.map(ShortUrls.shortUrlToShortId)) .exists(url => currentShortUrl.exists(_.endsWith(url))) val query = queryModifier { contentApiClient.item(seriesId, edition).showFields("all") } val seriesResponse: Future[Option[Series]] = contentApiClient.getResponse(query).map { response => response.tag.flatMap { tag => val trails = response.results.getOrElse(Nil) filterNot isCurrentStory map (RelatedContentItem(_)) if (trails.nonEmpty) { Some(Series(seriesId, Tag.make(tag, None), RelatedContent(trails.toSeq))) } else { None } } } seriesResponse.recover { case ContentApiError(404, message, _) => logInfoWithRequestId(s"Got a 404 calling content api: $message") None } } private def rendermf2Series(series: Series)(implicit request: RequestHeader): RevalidatableResult = { val displayName = Some(series.displayName) val seriesStories = series.trails.items take 4 val description = series.tag.metadata.description.getOrElse("").replaceAll("<.*?>", "") JsonComponent( "items" -> JsArray( Seq( Json.obj( "displayName" -> displayName, "description" -> description, "showContent" -> seriesStories.nonEmpty, "content" -> seriesStories.map(collection => isCuratedContent(collection.faciaContent)), ), ), ), ) } private def renderSeriesTrails(series: Series)(implicit request: RequestHeader): Result = { val (containerDefinition: FaciaContainer, frontProperties: FrontProperties) = SeriesHelper.dataForContainerRendering(series) val frontId = request.referrer.map(new URI(_).getPath.stripPrefix("/")) val response = () => views.html.fragments.containers.facia_cards.container( containerDefinition = containerDefinition, frontProperties = frontProperties, frontId = frontId, ) renderFormat(response, response, 900) } }