Пример #1
0
  private Item getBasicEpisodeWithoutBroadcast(ProgData progData, boolean isEpisode) {
    String episodeUri = PaHelper.getEpisodeUri(identifierFor(progData));

    Maybe<Identified> possiblePrevious =
        contentResolver.findByCanonicalUris(ImmutableList.of(episodeUri)).getFirstValue();

    Item item;
    if (possiblePrevious.hasValue()) {
      Item previous = (Item) possiblePrevious.requireValue();

      if (!(previous instanceof Episode) && isEpisode) {
        String message =
            String.format(
                "%s resolved as %s being ingested as Episode",
                episodeUri, previous.getClass().getSimpleName());

        adapterLog.record(warnEntry().withSource(getClass()).withDescription(message));
        log.info(message);

        item = convertItemToEpisode(previous);
      } else if (previous instanceof Episode && !isEpisode) {
        String message =
            String.format(
                "%s resolved as %s being ingested as Item",
                episodeUri, previous.getClass().getSimpleName());

        adapterLog.record(errorEntry().withSource(getClass()).withDescription(message));
        log.info(message);

        item = new Item();
        Item.copyTo(previous, item);
      } else {
        item = previous;
      }
    } else {
      item = getBasicEpisode(progData, isEpisode);
    }

    if (SCHEDULED_ONLY_EPISODE.equals(episodeUri)) {
      item.setScheduleOnly(true);
    }

    item.addAlias(PaHelper.getEpisodeAlias(identifierFor(progData)));

    try {
      if (item instanceof Episode) {
        Episode episode = (Episode) item;
        episode.setSpecial(getBooleanValue(progData.getAttr().getSpecial()));
        episode.setEpisodeNumber(episodeNumber(progData));
        episode.setSeriesNumber(seriesNumber(progData));
      }
    } catch (NumberFormatException e) {
      // sometimes we don't get valid numbers
      log.warn("Failed to parse a numeric field for PA episode {}", episodeUri, e);
    }
    return item;
  }
Пример #2
0
  private Optional<Series> getSeriesWithoutChannel(ProgData progData, Timestamp updatedAt) {
    if (Strings.isNullOrEmpty(progData.getSeriesNumber())
        || Strings.isNullOrEmpty(progData.getSeriesId())) {
      return Optional.absent();
    }
    String seriesUri = PaHelper.getSeriesUri(progData.getSeriesId(), progData.getSeriesNumber());
    Alias seriesAlias = PaHelper.getSeriesAlias(progData.getSeriesId(), progData.getSeriesNumber());

    Maybe<Identified> possiblePrevious =
        contentResolver.findByCanonicalUris(ImmutableList.of(seriesUri)).getFirstValue();

    Series series =
        possiblePrevious.hasValue()
            ? (Series) possiblePrevious.requireValue()
            : new Series(
                seriesUri,
                "pa:s-" + progData.getSeriesId() + "-" + progData.getSeriesNumber(),
                Publisher.PA);

    series.addAlias(seriesAlias);

    if (progData.getEpisodeTotal() != null && progData.getEpisodeTotal().trim().length() > 0) {
      try {
        series.setTotalEpisodes(Integer.parseInt(progData.getEpisodeTotal().trim()));
      } catch (NumberFormatException e) {
        adapterLog.record(
            warnEntry()
                .withCause(e)
                .withSource(getClass())
                .withDescription(
                    "Couldn't parse episode_total %s", progData.getEpisodeTotal().trim()));
      }
    }

    if (progData.getSeriesNumber() != null && progData.getSeriesNumber().trim().length() > 0) {
      try {
        series.withSeriesNumber(Integer.parseInt(progData.getSeriesNumber().trim()));
      } catch (NumberFormatException e) {
        adapterLog.record(
            warnEntry()
                .withCause(e)
                .withSource(getClass())
                .withDescription(
                    "Couldn't parse series_number %s", progData.getSeriesNumber().trim()));
      }
    }

    series.setPublisher(Publisher.PA);
    setCertificate(progData, series);
    setGenres(progData, series);
    setTopicRefs(series);

    series.setLastUpdated(updatedAt.toDateTimeUTC());

    return Optional.of(series);
  }
Пример #3
0
  private ItemAndBroadcast getEpisode(
      ProgData progData,
      Channel channel,
      DateTimeZone zone,
      boolean isEpisode,
      Timestamp updatedAt) {

    String episodeUri = PaHelper.getEpisodeUri(identifierFor(progData));
    Maybe<Identified> possiblePrevious =
        contentResolver.findByCanonicalUris(ImmutableList.of(episodeUri)).getFirstValue();

    Item item;
    if (possiblePrevious.hasValue()) {
      item = (Item) possiblePrevious.requireValue();
      if (!(item instanceof Episode) && isEpisode) {
        log.record(
            warnEntry()
                .withSource(getClass())
                .withDescription(
                    "%s resolved as %s being ingested as Episode",
                    episodeUri, item.getClass().getSimpleName()));
        item = convertItemToEpisode(item);
      } else if (item instanceof Episode && !isEpisode) {
        log.record(
            errorEntry()
                .withSource(getClass())
                .withDescription(
                    "%s resolved as %s being ingested as Item",
                    episodeUri, item.getClass().getSimpleName()));
      }
    } else {
      item = getBasicEpisode(progData, isEpisode);
    }

    item.addAlias(PaHelper.getEpisodeAlias(identifierFor(progData)));

    Broadcast broadcast = setCommonDetails(progData, channel, zone, item, updatedAt);

    try {
      if (item instanceof Episode) {
        Episode episode = (Episode) item;
        episode.setSpecial(getBooleanValue(progData.getAttr().getSpecial()));
        episode.setEpisodeNumber(episodeNumber(progData));
        episode.setSeriesNumber(seriesNumber(progData));
      }
    } catch (NumberFormatException e) {
      // sometimes we don't get valid numbers
      // log.
    }

    return new ItemAndBroadcast(item, Maybe.just(broadcast));
  }
Пример #4
0
  @Override
  public Optional<ContentHierarchyAndSummaries> process(
      ProgData progData, Channel channel, DateTimeZone zone, Timestamp updatedAt) {
    try {
      log.trace("Channel: {} ProgData: {} UpdatedAt: {}", channel, progData, updatedAt);
      if (shouldNotProcess(progData)) {
        return Optional.absent();
      }

      Optional<Brand> possibleBrand = getBrand(progData, channel, updatedAt);
      Brand brandSummary = null;
      if (possibleBrand.isPresent() && hasBrandSummary(progData)) {
        brandSummary = getBrandSummary(progData, possibleBrand.get(), updatedAt);
      }

      Optional<Series> possibleSeries = getSeries(progData, channel, updatedAt);
      Series seriesSummary = null;
      if (possibleSeries.isPresent() && hasSeriesSummary(progData)) {
        seriesSummary = getSeriesSummary(progData, possibleSeries.get(), updatedAt);
      }

      boolean isEpisode = possibleBrand.isPresent() || possibleSeries.isPresent();

      ItemAndBroadcast itemAndBroadcast =
          isClosedBrand(possibleBrand)
              ? getClosedEpisode(progData, channel, zone, updatedAt)
              : getFilmOrEpisode(progData, channel, zone, isEpisode, updatedAt);

      Item item = itemAndBroadcast.getItem();

      // TODO: there is an unknown bug preventing this from working (MBST-17174)
      if (!isEpisode) {
        item.setParentRef(null);
      }

      item.setGenericDescription(isGenericDescription(progData));
      item.addAlias(PaHelper.getProgIdAlias(progData.getProgId()));
      item.setLastUpdated(updatedAt.toDateTimeUTC());

      return Optional.of(
          new ContentHierarchyAndSummaries(
              possibleBrand,
              possibleSeries,
              item,
              itemAndBroadcast.getBroadcast().requireValue(),
              Optional.fromNullable(brandSummary),
              Optional.fromNullable(seriesSummary)));
    } catch (Exception e) {
      log.error("Failed to process PA programme data", e);
      adapterLog.record(
          new AdapterLogEntry(Severity.ERROR)
              .withCause(e)
              .withSource(PaProgrammeProcessor.class)
              .withDescription(e.getMessage()));
    }
    return Optional.absent();
  }
Пример #5
0
 public @Bean XMLValidator lakeViewValidator() {
   try {
     return XMLValidator.forSchemas(
         ImmutableSet.of(
             Resources.getResource("xml.xsd").openStream(),
             Resources.getResource("Lakeview_Content_Catalog_Feed.xsd").openStream()));
   } catch (Exception e) {
     log.record(
         new AdapterLogEntry(Severity.WARN)
             .withDescription("Couldn't load schemas for Lakeview XML validation")
             .withCause(e));
     return null;
   }
 }
Пример #6
0
  @Override
  public ContentHierarchyAndSummaries process(
      ProgData progData, Channel channel, DateTimeZone zone, Timestamp updatedAt) {
    try {
      if (!Strings.isNullOrEmpty(progData.getSeriesId())
          && IGNORED_BRANDS.contains(progData.getSeriesId())) {
        return null;
      }

      Brand brandSummary = null;
      Series seriesSummary = null;

      Optional<Brand> possibleBrand = getBrand(progData, channel, updatedAt);
      if (possibleBrand.isPresent()) {
        Brand originalBrand = possibleBrand.get();
        if (hasBrandSummary(progData)) {
          brandSummary = extractSummaryBrand(progData, originalBrand.getCanonicalUri(), updatedAt);
          brandSummary.setEquivalentTo(ImmutableSet.of(LookupRef.from(originalBrand)));
        }
      }

      Optional<Series> possibleSeries = getSeries(progData, channel, updatedAt);
      if (possibleSeries.isPresent()) {
        Series originalSeries = possibleSeries.get();
        if (hasSeriesSummary(progData)) {
          seriesSummary =
              extractSummarySeries(progData, originalSeries.getCanonicalUri(), updatedAt);
          seriesSummary.setEquivalentTo(ImmutableSet.of(LookupRef.from(originalSeries)));
        }
      }

      ItemAndBroadcast itemAndBroadcast =
          isClosedBrand(possibleBrand)
              ? getClosedEpisode(possibleBrand.get(), progData, channel, zone, updatedAt)
              : getFilmOrEpisode(
                  progData,
                  channel,
                  zone,
                  possibleBrand.isPresent() || possibleSeries.isPresent(),
                  updatedAt);

      Item item = itemAndBroadcast.getItem();
      item.setGenericDescription(isGenericDescription(progData));
      item.setLastUpdated(updatedAt.toDateTimeUTC());

      return new ContentHierarchyAndSummaries(
          possibleBrand,
          possibleSeries,
          item,
          itemAndBroadcast.getBroadcast().requireValue(),
          Optional.fromNullable(brandSummary),
          Optional.fromNullable(seriesSummary));
    } catch (Exception e) {
      e.printStackTrace();
      log.record(
          new AdapterLogEntry(Severity.ERROR)
              .withCause(e)
              .withSource(PaProgrammeProcessor.class)
              .withDescription(e.getMessage()));
    }
    return null;
  }
Пример #7
0
  @Override
  public void handle(WsProgramme programme, Iterable<WsAudioItem> audioItems) {
    checkNotNull(programme.getProgId());
    checkNotNull(programme.getSeriesId());

    String episodeUri = uriFor(programme);

    Maybe<Identified> possibleEpisode =
        resolver.findByCanonicalUris(ImmutableSet.of(episodeUri)).get(episodeUri);

    Episode episode = null;

    if (possibleEpisode.hasValue()) {
      Identified resolved = possibleEpisode.requireValue();
      if (resolved instanceof Episode) {
        episode = (Episode) resolved;
      } else {
        log.record(
            errorEntry()
                .withDescription(
                    "Resolved %s for episode %s", resolved.getClass().getSimpleName(), episodeUri));
        return;
      }
    } else {
      episode = new Episode(episodeUri, curieFor(programme), WORLD_SERVICE);
    }

    episode.setParentRef(new ParentRef(uriForBrand(programme.getSeriesId())));
    episode.setTitle(titleFrom(programme, audioItems));
    episode.setDescription(programme.getSynopsis());
    if (!Strings.isNullOrEmpty(programme.getEpisodeNo())
        && programme.getEpisodeNo().matches("\\d+")) {
      episode.setEpisodeNumber(Integer.parseInt(programme.getEpisodeNo()));
    }
    episode.setGenres(WsGenre.genresForCode(programme.getGenreCode()));
    episode.setMediaType(AUDIO);
    episode.setSpecialization(RADIO);

    if (!Iterables.isEmpty(audioItems)) {
      for (WsAudioItem audioItem : audioItems) {
        Version version = new Version();

        if (!Strings.isNullOrEmpty(audioItem.getDuration())
            && audioItem.getDuration().matches("\\d+")) {
          version.setDuration(new Duration(Long.parseLong(audioItem.getDuration())));
        }

        Policy policy = policyFor(audioItem);

        String broadcastUri = audioItem.getLinkAudioBroadcastQuality();
        if (!Strings.isNullOrEmpty(broadcastUri)) {
          version.addManifestedAs(encodingFrom(policy, broadcastUri, MimeType.AUDIO_WAV));
        }

        String thumbnailUri = audioItem.getLinkAudioThumbnail();
        if (!Strings.isNullOrEmpty(thumbnailUri)) {
          version.addManifestedAs(encodingFrom(policy, thumbnailUri, MimeType.AUDIO_MP3));
        }
        if (!version.getManifestedAs().isEmpty()) {
          episode.addVersion(version);
        }
      }
    }

    Broadcast broadcast = broadcastFrom(programme);
    if (broadcast != null) {
      Version version = Iterables.getFirst(episode.getVersions(), new Version());
      if (version.getDuration() == null) {
        version.setDuration(Duration.standardSeconds(broadcast.getBroadcastDuration()));
      }
      version.addBroadcast(broadcast);
    }

    writer.createOrUpdate(episode);
  }