com.gu.facia.api.FAPI.scala Maven / Gradle / Ivy
The newest version!
package com.gu.facia.api
import com.gu.contentapi.client.ContentApiClient
import com.gu.contentapi.client.model.v1.Content
import com.gu.facia.api.contentapi.ContentApi.{AdjustItemQuery, AdjustSearchQuery}
import com.gu.facia.api.contentapi.{ContentApi, LatestSnapsRequest, LinkSnapsRequest}
import com.gu.facia.api.models._
import com.gu.facia.api.utils.BackfillResolver
import com.gu.facia.client.ApiClient
import scala.collection.compat._
import scala.concurrent.{ExecutionContext, Future}
object FAPI {
def getFronts()(implicit capiClient: ContentApiClient, faciaClient: ApiClient, ec: ExecutionContext): Response[Set[Front]] = {
for {
config <- Response.Async.Right(faciaClient.config)
} yield Front.frontsFromConfig(config)
}
def frontForPath(path: String)(implicit capiClient: ContentApiClient, faciaClient: ApiClient, ec: ExecutionContext): Response[Front] = {
for {
fronts <- getFronts()
front <- Response.fromOption(fronts.find(_.id == path), NotFound(s"Not front found for $path"))
} yield front
}
/**
* Fetches the collection information for the given id by resolving info out of the fronts config
* and the collection's own config JSON.
*/
def getCollection(collectionId: String)
(implicit capiClient: ContentApiClient, faciaClient: ApiClient, ec: ExecutionContext): Response[Collection] = {
val fCollectionJson = faciaClient.collection(collectionId)
val fConfigJson = faciaClient.config
for {
collectionJson <- Response.Async.Right(fCollectionJson)
configJson <- Response.Async.Right(fConfigJson)
collectionConfigJson <- Response.fromOption(configJson.collections.get(collectionId), NotFound(s"Collection config not found for $collectionId"))
collectionConfig = CollectionConfig.fromCollectionJson(collectionConfigJson)
} yield {
Collection.fromCollectionJsonConfigAndContent(collectionId, collectionJson, collectionConfig)
}
}
/**
* Fetch all the collections for a front in one go
*/
def frontCollections(frontId: String)
(implicit capiClient: ContentApiClient, faciaClient: ApiClient, ec: ExecutionContext): Response[List[Collection]] = {
for {
configJson <- Response.Async.Right(faciaClient.config)
frontJson <- Response.fromOption(configJson.fronts.get(frontId), NotFound(s"No front found for $frontId"))
collectionIds = frontJson.collections
collectionsJsons <- Response.Async.Right(Future.traverse(collectionIds)(faciaClient.collection))
collectionConfigJsons <- Response.traverse(
collectionIds.map(id => Response.fromOption(configJson.collections.get(id), NotFound(s"Collection config not found for $id")))
)
collectionConfigs = collectionConfigJsons.map(CollectionConfig.fromCollectionJson)
} yield {
collectionIds.lazyZip(collectionsJsons).lazyZip(collectionConfigs).toList.map { case (collectionId, collectionJson, collectionConfig) =>
Collection.fromCollectionJsonConfigAndContent(collectionId, collectionJson, collectionConfig)
}
}
}
private def getLiveContentForCollection(collection: Collection, adjustSearchQuery: AdjustSearchQuery = identity)
(implicit capiClient: ContentApiClient, ec: ExecutionContext): Response[Set[Content]] = {
val itemIdsForRequest = Collection.liveIdsWithoutSnaps(collection)
val supportingIdsForRequest = Collection.liveSupportingIdsWithoutSnaps(collection)
val allItemIdsForRequest = itemIdsForRequest ::: supportingIdsForRequest
for {
hydrateQueries <- ContentApi.buildHydrateQueries(capiClient, allItemIdsForRequest, adjustSearchQuery)
hydrateResponses <- ContentApi.getHydrateResponse(capiClient, hydrateQueries)
content = ContentApi.itemsFromSearchResponses(hydrateResponses)}
yield content
}
private def getDraftContentForCollection(collection: Collection, adjustSearchQuery: AdjustSearchQuery = identity)
(implicit capiClient: ContentApiClient, ec: ExecutionContext): Response[Set[Content]] = {
val itemIdsForRequest =
Collection.draftIdsWithoutSnaps(collection)
.getOrElse(Collection.liveIdsWithoutSnaps(collection))
val supportingIdsForRequest =
Collection.draftSupportingIdsWithoutSnaps(collection)
.getOrElse(Collection.liveSupportingIdsWithoutSnaps(collection))
val allItemIdsForRequest = itemIdsForRequest ::: supportingIdsForRequest
for {
hydrateQueries <- ContentApi.buildHydrateQueries(capiClient, allItemIdsForRequest, adjustSearchQuery)
hydrateResponses <- ContentApi.getHydrateResponse(capiClient, hydrateQueries)
content = ContentApi.itemsFromSearchResponses(hydrateResponses)}
yield content
}
private def getLiveLatestSnapContentForCollection(collection: Collection, adjustItemQuery: AdjustItemQuery)
(implicit capiClient: ContentApiClient, ec: ExecutionContext) = {
val latestSnapsRequest: LatestSnapsRequest = Collection.liveLatestSnapsRequestFor(collection)
val latestSupportingSnaps: LatestSnapsRequest = Collection.liveSupportingSnaps(collection)
val allSnaps = latestSnapsRequest.join(latestSupportingSnaps)
for(snapContent <- ContentApi.latestContentFromLatestSnaps(capiClient, allSnaps, adjustItemQuery))
yield snapContent}
private def getDraftLatestSnapContentForCollection(collection: Collection, adjustItemQuery: AdjustItemQuery)
(implicit capiClient: ContentApiClient, ec: ExecutionContext): Response[Map[String, Option[Content]]] = {
val latestSnapsRequest: LatestSnapsRequest =
Collection.draftLatestSnapsRequestFor(collection)
.getOrElse(Collection.liveLatestSnapsRequestFor(collection))
val latestSupportingSnaps: LatestSnapsRequest =
Collection.draftSupportingSnaps(collection)
.getOrElse(Collection.liveSupportingSnaps(collection))
val allSnaps = latestSnapsRequest.join(latestSupportingSnaps)
for(snapContent <- ContentApi.latestContentFromLatestSnaps(capiClient, allSnaps, adjustItemQuery))
yield snapContent}
private def getLiveLinkSnapBrandingsForCollection(collection: Collection)
(
implicit capiClient: ContentApiClient,
ec: ExecutionContext
): Response[Map[String, BrandingByEdition]] =
getLinkSnapBrandings(Collection.liveLinkSnapsRequestFor(collection))
private def getDraftLinkSnapBrandingsForCollection(collection: Collection)
(
implicit capiClient: ContentApiClient,
ec: ExecutionContext
): Response[Map[String, BrandingByEdition]] =
getLinkSnapBrandings(
Collection.draftLinkSnapsRequestFor(collection).getOrElse(Collection.liveLinkSnapsRequestFor(collection))
)
private def getLinkSnapBrandings(request: LinkSnapsRequest)(
implicit capiClient: ContentApiClient, ec: ExecutionContext
): Response[Map[String, BrandingByEdition]] =
for (snapContent <- ContentApi.linkSnapBrandingsByEdition(capiClient, request)) yield snapContent
def getTreatsForCollection(collection: Collection, adjustSearchQuery: AdjustSearchQuery = identity, adjustItemQuery: AdjustItemQuery = identity)
(implicit capiClient: ContentApiClient, ec: ExecutionContext) = {
val (treatIds, treatsSnapsRequest) = Collection.treatsRequestFor(collection)
for {
hydrateQueries <- ContentApi.buildHydrateQueries(capiClient, treatIds, adjustSearchQuery)
hydrateResponses <- ContentApi.getHydrateResponse(capiClient, hydrateQueries)
snapContent <- ContentApi.latestContentFromLatestSnaps(capiClient, treatsSnapsRequest, adjustItemQuery)
setOfContent = ContentApi.itemsFromSearchResponses(hydrateResponses)}
yield Collection.treatContent(collection, setOfContent, snapContent)
}
def liveCollectionContentWithoutSnaps(collection: Collection, adjustSearchQuery: AdjustSearchQuery = identity)
(implicit capiClient: ContentApiClient, ec: ExecutionContext): Response[List[FaciaContent]] = {
val collectionWithoutSnaps = Collection.withoutSnaps(collection)
for(setOfContent <- getLiveContentForCollection(collection, adjustSearchQuery))
yield Collection.liveContent(collectionWithoutSnaps, setOfContent)
}
def liveCollectionContentWithSnaps(collection: Collection, adjustSearchQuery: AdjustSearchQuery = identity, adjustSnapItemQuery: AdjustItemQuery = identity)
(implicit capiClient: ContentApiClient, ec: ExecutionContext): Response[List[FaciaContent]] = {
for {
setOfContent <- getLiveContentForCollection(collection, adjustSearchQuery)
snapContent <- getLiveLatestSnapContentForCollection(collection, adjustSnapItemQuery)
linkSnapBrandingsByEdition <- getLiveLinkSnapBrandingsForCollection(collection)
} yield Collection.liveContent(collection, setOfContent, snapContent, linkSnapBrandingsByEdition)
}
def draftCollectionContentWithoutSnaps(collection: Collection, adjustSearchQuery: AdjustSearchQuery = identity)
(implicit capiClient: ContentApiClient, ec: ExecutionContext): Response[List[FaciaContent]] = {
val collectionWithoutSnaps = Collection.withoutSnaps(collection)
for(setOfContent <- getDraftContentForCollection(collection, adjustSearchQuery))
yield Collection.draftContent(collectionWithoutSnaps, setOfContent)
}
def draftCollectionContentWithSnaps(collection: Collection, adjustSearchQuery: AdjustSearchQuery = identity, adjustSnapItemQuery: AdjustItemQuery = identity)
(implicit capiClient: ContentApiClient, ec: ExecutionContext): Response[List[FaciaContent]] = {
for {
setOfContent <- getDraftContentForCollection(collection, adjustSearchQuery)
snapContent <- getDraftLatestSnapContentForCollection(collection, adjustSnapItemQuery)
linkSnapBrandingsByEdition <- getDraftLinkSnapBrandingsForCollection(collection)
} yield Collection.draftContent(collection, setOfContent, snapContent, linkSnapBrandingsByEdition)
}
/**
* Fetches content for the configured backfill query. The query can be manipulated for different
* requirements by providing adjustment functions. The results then have their facia metadata
* resolved using the collection information.
*/
def backfillFromConfig(collectionConfig: CollectionConfig,
adjustSearchQuery: AdjustSearchQuery = identity, adjustItemQuery: AdjustItemQuery = identity)
(implicit capiClient: ContentApiClient, faciaClient: ApiClient, ec: ExecutionContext): Response[List[FaciaContent]] = {
val backfillRequest = BackfillResolver.resolveFromConfig(collectionConfig)
BackfillResolver.backfill(backfillRequest, adjustSearchQuery, adjustItemQuery)
}
}