private def rawRss()

in app/controllers/Application.scala [57:130]


  private def rawRss(tagId: String, userApiKey: Option[String]): Future[Result] = {
    val client = new CustomCapiClient(apiKey)

    val maxItems = 300
    val pageSize = 100

    val query = ItemQuery(tagId)
      .showElements("audio,image")
      .showTags("keyword")
      .showFields("webTitle,webPublicationDate,standfirst,trailText,internalComposerCode")

    def fetchItemsWithPagination(query: ItemQuery, page: Int = 1, resps: Seq[ItemResponse] = Seq.empty): Future[Seq[ItemResponse]] = {
      logger.debug("Fetching page: " + page + " with page size: " + pageSize)
      val withPagination = query.page(page).pageSize(pageSize)

      client.getResponse(withPagination).flatMap { resp =>
        val responses = resps :+ resp
        // Paginate if we have not covered the required number of pages and there are more pages available
        val lastRequiredPage = (maxItems / pageSize) + (if (maxItems % pageSize > 0) { 1 } else { 0 })
        val shouldPaginate = (page < lastRequiredPage) && resp.pages.getOrElse(0) > page
        if (shouldPaginate) {
          // Recurse with the results and pagination incremented
          fetchItemsWithPagination(query, page + 1, responses)

        } else {
          logger.info("Finished fetching " + responses.map(_.results.map(_.size).getOrElse(0)).sum + " items after paginating to page " + page)
          Future.successful(responses)
        }
      }
    }

    (for {
      itemResponses <- fetchItemsWithPagination(query)
      userApiKeyTier <- userApiKey.map { userApiKey =>
        // If an external partner has identified themselves using an api-key we will query to resolve the user tier
        new CustomCapiClient(userApiKey).getResponse(ItemQuery(tagId).pageSize(0)).map { resp =>
          Some(resp.userTier)
        }
      }.getOrElse {
        Future.successful(None)
      }

    } yield {
      // If all item responses were ok then we can render a result
      if (itemResponses.forall(_.status == "ok")) {
        val isAdFree = userApiKeyTier.contains("rights-managed")
        iTunesRssFeed(itemResponses, isAdFree, imageResizerSignatureSalt) match {
          case Good(xml) =>
            val now = DateTime.now()
            val expiresTime = now.plusSeconds(maxAge)

            Ok(xml).withHeaders(
              "Surrogate-Control" -> cacheControl,
              "Cache-Control" -> cacheControl,
              "Expires" -> expiresTime.toString(HTTPDateFormat),
              "Date" -> now.toString(HTTPDateFormat))
          case Bad(failed: Failed) =>
            logger.warn(s"Failed to render XML. tagId = $tagId, ${failed.toString}")
            failed.status
        }

      } else {
        NotFound
      }

    }).recover {
      case ContentApiError(404, _, _) => NotFound
      case ContentApiError(403, _, _) => Forbidden
      case ContentApiError(401, _, _) => Unauthorized
      // maybe this generic InternalServerError could be a better representation of the CAPI failure mode
      case ContentApiError(status, msg, errorResponse) =>
        logger.warn(s"Unexpected response code from CAPI. tagId = $tagId, HTTP status = $status, error response = $errorResponse")
        InternalServerError
    }