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; }
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); } } }
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"; }
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"; }
private Alias generateAliasFor(Episode content) { return PaHelper.getEpisodeAlias(content.getId().toString()); }
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()); }
@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); }