private List<Broadcast> extractBroadcasts(Iterable<Episode> episodes) {
   List<Broadcast> broadcasts = Lists.newArrayList();
   for (Episode episode : episodes) {
     for (Version version : episode.getVersions()) {
       broadcasts.addAll(version.getBroadcasts());
     }
   }
   return broadcasts;
 }
Example #2
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;
  }
 private void stitch(
     Iterable<Episode> subjectsChildren,
     Map<String, EquivalenceSummary> summaryMap,
     Multimap<Container, Episode> equivalentsChildren,
     ReadableDescription desc) {
   for (Episode episode : subjectsChildren) {
     EquivalenceSummary summary = summaryMap.get(episode.getCanonicalUri());
     if (summary != null) {
       stitch(episode, summary, equivalentsChildren, desc);
     }
   }
 }
Example #4
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));
  }
 private String extractProgrammedId(Episode episode) {
   for (Alias alias : episode.getAliases()) {
     if (alias.getNamespace().equals("gb:channel4:prod:pmlsd:programmeId")) {
       return alias.getValue();
     }
   }
   return "NONE";
 }
Example #6
0
  private ItemAndBroadcast getClosedEpisode(
      Brand brand, ProgData progData, Channel channel, DateTimeZone zone, Timestamp updatedAt) {
    String uri = CLOSED_EPISODE + getClosedPostfix(channel);
    Maybe<Identified> resolvedContent =
        contentResolver.findByCanonicalUris(ImmutableList.of(uri)).getFirstValue();

    Episode episode;
    if (resolvedContent.hasValue() && resolvedContent.requireValue() instanceof Episode) {
      episode = (Episode) resolvedContent.requireValue();
    } else {
      episode = (Episode) getBasicEpisode(progData, true);
    }
    episode.setCanonicalUri(uri);
    episode.setCurie(CLOSED_CURIE + getClosedPostfix(channel));
    episode.setTitle(progData.getTitle());
    episode.setScheduleOnly(true);
    episode.setMediaType(channel.getMediaType());

    Version version = findBestVersion(episode.getVersions());

    Broadcast broadcast = broadcast(progData, channel, zone, updatedAt);
    addBroadcast(version, broadcast);

    return new ItemAndBroadcast(episode, Maybe.just(broadcast));
  }
 private Integer duration(Episode episode) {
   for (Version version : episode.getVersions()) {
     Integer duration = version.getDuration();
     if (duration != null) {
       return duration;
     }
   }
   return null;
 }
 private DateTime extractLastAvailabilityDate(Episode episode) {
   for (Version version : episode.getVersions()) {
     for (Encoding encoding : version.getManifestedAs()) {
       for (Location location : encoding.getAvailableAt()) {
         if (location.getPolicy() != null
             && Platform.XBOX.equals(location.getPolicy().getPlatform())
             && location.getPolicy().getAvailabilityStart() != null) {
           return location.getPolicy().getAvailabilityEnd();
         }
       }
     }
   }
   return null;
 }
  private void stitch(
      Episode subjectEpisode,
      EquivalenceSummary equivalenceSummary,
      Multimap<Container, Episode> equivalentsChildren,
      ReadableDescription desc) {
    String subjectUri = subjectEpisode.getCanonicalUri();
    desc.startStage(subjectUri);
    Map<Publisher, ContentRef> equivalents = equivalenceSummary.getEquivalents();

    Set<ContentRef> additionalEquivs = Sets.newHashSet();
    for (Entry<Container, Collection<Episode>> contentHierarchy :
        equivalentsChildren.asMap().entrySet()) {
      Container container = contentHierarchy.getKey();
      for (Episode equivChild : contentHierarchy.getValue()) {
        if (matchingSequenceNumbers(subjectEpisode, equivChild)) {
          Publisher publisher = equivChild.getPublisher();
          ContentRef existingEquiv = equivalents.get(publisher);
          if (existingEquiv != null) {
            desc.appendText(
                "existing strong equiv %s not overwritten by %s", existingEquiv, equivChild);
          } else {
            desc.appendText("adding %s (%s)", equivChild, container);
            additionalEquivs.add(ContentRef.valueOf(equivChild));
          }
          break;
        }
      }
    }

    if (!additionalEquivs.isEmpty()) {
      additionalEquivs.addAll(equivalents.values());
      lookupWriter.writeLookup(ContentRef.valueOf(subjectEpisode), additionalEquivs, publishers);
    }

    desc.finishStage();
  }
 private String extractAssetId(Episode episode) {
   for (Version version : episode.getVersions()) {
     for (Encoding encoding : version.getManifestedAs()) {
       for (Location location : encoding.getAvailableAt()) {
         if (location.getTransportType().equals(TransportType.LINK)
             && location.getPolicy() != null
             && Platform.XBOX.equals(location.getPolicy().getPlatform())) {
           Pattern pattern = Pattern.compile(".*asset/(\\d+).*");
           Matcher matcher = pattern.matcher(location.getUri());
           if (matcher.matches()) {
             return matcher.group(1);
           }
         }
       }
     }
   }
   return "NONE";
 }
Example #11
0
 private Alias generateAliasFor(Episode content) {
   return PaHelper.getEpisodeAlias(content.getId().toString());
 }
Example #12
0
 private Item convertItemToEpisode(Item item) {
   Episode episode = new Episode(item.getCanonicalUri(), item.getCurie(), item.getPublisher());
   episode.setAliases(item.getAliases());
   episode.setAliasUrls(item.getAliasUrls());
   episode.setBlackAndWhite(item.getBlackAndWhite());
   episode.setClips(item.getClips());
   episode.setParentRef(item.getContainer());
   episode.setCountriesOfOrigin(item.getCountriesOfOrigin());
   episode.setDescription(item.getDescription());
   episode.setFirstSeen(item.getFirstSeen());
   episode.setGenres(item.getGenres());
   episode.setImage(item.getImage());
   episode.setImages(item.getImages());
   episode.setIsLongForm(item.getIsLongForm());
   episode.setLastFetched(item.getLastFetched());
   episode.setLastUpdated(item.getLastUpdated());
   episode.setMediaType(item.getMediaType());
   episode.setPeople(item.getPeople());
   episode.setScheduleOnly(item.isScheduleOnly());
   episode.setSpecialization(item.getSpecialization());
   episode.setTags(item.getTags());
   episode.setThisOrChildLastUpdated(item.getThisOrChildLastUpdated());
   episode.setThumbnail(item.getThumbnail());
   episode.setTitle(item.getTitle());
   episode.setVersions(item.getVersions());
   return episode;
 }
  Element createEpisodeElem(
      Episode episode,
      Brand container,
      Series series,
      DateTime originalPublicationDate,
      String lastModified) {
    Element element = createElement("TVEpisode", LAKEVIEW);

    Comment comment = new Comment("Atlas ID: " + episode.getCanonicalUri());
    element.appendChild(comment);

    String assetId = extractAssetId(episode);
    String programmedId = extractProgrammedId(episode);
    String applicationSpecificData =
        episodeAtomUri(brandAtomUri(findTagAlias(container)), programmedId);

    String providerMediaId;
    if (series != null) {
      providerMediaId = providerMediaId(series) + "#" + assetId;
    } else {
      providerMediaId = providerMediaId(container) + "#" + assetId;
    }
    addIdElements(element, episodeId(episode), providerMediaId);

    if (genericTitlesEnabled) {
      if (episode.getEpisodeNumber() != null) {
        addTitleElements(element, String.format("Episode %d", episode.getEpisodeNumber()));
      } else if (!Strings.isNullOrEmpty(episode.getTitle())) {
        addTitleElements(element, episode.getTitle());
      } else {
        addTitleElements(element, container.getTitle());
      }
    } else if (Strings.isNullOrEmpty(episode.getTitle())
        || episode.getTitle().matches("(?i)(series \\d+)? episode \\d+")) {
      addTitleElements(
          element,
          String.format(
              "%s Series %s Episode %s",
              container.getTitle(), episode.getSeriesNumber(), episode.getEpisodeNumber()));
    } else {
      addTitleElements(element, episode.getTitle());
    }

    Element instances = createElement("Instances", LAKEVIEW);
    Element videoInstance = createElement("VideoInstance", LAKEVIEW);

    Element availabilities = createElement("Availabilities", LAKEVIEW);
    Element availability = createAvailabilityElement(episode, "Xbox360", PROVIDER_ID);

    if (addXboxOneAvailability) {
      availabilities.appendChild(
          createAvailabilityElement(episode, "XboxOne", XBOX_ONE_PROVIDER_ID));
    }

    availabilities.appendChild(availability);
    videoInstance.appendChild(availabilities);
    videoInstance.appendChild(stringElement("ResolutionFormat", LAKEVIEW, "SD"));
    videoInstance.appendChild(stringElement("DeliveryFormat", LAKEVIEW, "Streaming"));
    videoInstance.appendChild(stringElement("PrimaryAudioLanguage", LAKEVIEW, "en-GB"));
    videoInstance.appendChild(stringElement("VideoInstanceType", LAKEVIEW, "Full"));

    instances.appendChild(videoInstance);

    appendCommonElements(
        element,
        episode,
        originalPublicationDate,
        lastModified,
        applicationSpecificData,
        episode.getGenres(),
        instances);

    element.appendChild(
        stringElement("EpisodeNumber", LAKEVIEW, String.valueOf(episode.getEpisodeNumber())));
    element.appendChild(
        stringElement("DurationInSeconds", LAKEVIEW, String.valueOf(duration(episode))));
    element.appendChild(stringElement("SeriesId", LAKEVIEW, brandId(container)));
    if (episode.getSeriesRef() != null) {
      element.appendChild(stringElement("SeasonId", LAKEVIEW, seriesId(series)));
    }

    return element;
  }
 public boolean matchingSequenceNumbers(Episode target, Episode ep) {
   return target.getEpisodeNumber() != null
       && target.getEpisodeNumber().equals(ep.getEpisodeNumber())
       && target.getSeriesNumber() != null
       && target.getSeriesNumber().equals(ep.getSeriesNumber());
 }
Example #15
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);
  }