Skip to content

Commit

Permalink
Get latest published episodes in a known sorting order for recommenda…
Browse files Browse the repository at this point in the history
…tions (#73)
  • Loading branch information
pyby authored Mar 15, 2023
1 parent 54839ee commit 6227956
Show file tree
Hide file tree
Showing 5 changed files with 578 additions and 29 deletions.
2 changes: 1 addition & 1 deletion docs/RECOMMENDATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ By default, here are the used recommendation engines (RE). `RTS_RECOMMENDATION_U
- For RSI, RTR, RTS, SRF, SWI videos and RSI, RTR, RTS, SRF audios, it can ask `Playfff` recommendation.
- Based on IL requests, without personalization. Here is how it works:
- Get `IL-Media`. It returns an empty list if it's a `LIVESTREAM` or a `SCHEDULED_LIVESTREAM`.
- Get `IL-EpisodeComposition` with last 100 episodes. Sort episodes with a date ascending order.
- Get `IL-EpisodeComposition` with last 100 episodes. Sort episodes with a published date ascending order, then episode ascending order if same published date. It's assumed that clips are ascendant sorting.
- Determine if the media is a full length or a clip.
- Separate in a full length list and a clip (audio only) list.
- Get the requested media position in the related list. Split oldests and newests.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -111,7 +112,12 @@ private RecommendedList pfffRecommendedList(String urn, MediaType mediaType, Boo
return new RecommendedList();
}

List<EpisodeWithMedias> episodes = new ArrayList<>(episodeComposition.getList());
List<EpisodeWithMedias> episodes = episodeComposition.getList().stream()
// Don't trust the LatestByShow episode sorting, apply a common one.
.sorted(Comparator.comparing(EpisodeWithMedias::getPublishedDate).thenComparing(EpisodeWithMedias::getId).reversed())
.collect(Collectors.toList());

// Use episodes and clips with the same ascendant sorting. It's assumed that clips are ascendant sorting.
Collections.reverse(episodes);
List<String> fullLengthUrns = episodes.stream().map(EpisodeWithMedias::getFullLengthUrn).collect(Collectors.toList());
List<String> clipUrns = episodes.stream().flatMap(e -> e.getMediaList().stream().filter(m -> m.getMediaType() == mediaType)).map(Media::getUrn).collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,16 @@ public void videoFullLengthAndShortPodcastForOldestEpisodeTest() throws URISynta
List<String> expectedUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3");

testVideoRecommendation(urn, true,true, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,true, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoFullLengthforOldestEpisodeTest() throws URISyntaxException {
public void videoFullLengthForOldestEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:1";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3", "urn:rtr:video:4");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3", "urn:rtr:video:4");

testVideoRecommendation(urn, true,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,false, false, expectedUrns, expectedStandaloneUrns);
}

@Test
Expand All @@ -85,25 +85,25 @@ public void videoFullLengthAndShortPodcastForSecondEpisodeTest() throws URISynta
List<String> expectedUrns = Arrays.asList("urn:rtr:video:3", "urn:rtr:video:1");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:3", "urn:rtr:video:1");

testVideoRecommendation(urn, true,true, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,true, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoFullLengthforSecondEpisodeTest() throws URISyntaxException {
public void videoFullLengthForSecondEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:2";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:3", "urn:rtr:video:4", "urn:rtr:video:1");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:3", "urn:rtr:video:4", "urn:rtr:video:1");

testVideoRecommendation(urn, true,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,false, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoFullLengthforThirdEpisodeTest() throws URISyntaxException {
public void videoFullLengthForThirdEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:3";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:4", "urn:rtr:video:2", "urn:rtr:video:1");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:4", "urn:rtr:video:2", "urn:rtr:video:1");

testVideoRecommendation(urn, true,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,false, false, expectedUrns, expectedStandaloneUrns);
}

@Test
Expand All @@ -112,16 +112,16 @@ public void videoFullLengthAndShortPodcastForNewestEpisodeTest() throws URISynta
List<String> expectedUrns = Arrays.asList("urn:rtr:video:1", "urn:rtr:video:2");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:1", "urn:rtr:video:2");

testVideoRecommendation(urn, true,true, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,true, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoFullLengthforNewestEpisodeTest() throws URISyntaxException {
public void videoFullLengthForNewestEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:4";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:3", "urn:rtr:video:2", "urn:rtr:video:1");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:3", "urn:rtr:video:2", "urn:rtr:video:1");

testVideoRecommendation(urn, true,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,false, false, expectedUrns, expectedStandaloneUrns);
}

@Test
Expand All @@ -130,16 +130,16 @@ public void videoFullLengthAndShortPodcastForNotFoundEpisodeTest() throws URISyn
List<String> expectedUrns = Arrays.asList("urn:rtr:video:1", "urn:rtr:video:2", "urn:rtr:video:3");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:1", "urn:rtr:video:2", "urn:rtr:video:3");

testVideoRecommendation(urn, true,true, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,true, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoFullLengthforNotFoundEpisodeTest() throws URISyntaxException {
public void videoFullLengthForNotFoundEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:0";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:4", "urn:rtr:video:3", "urn:rtr:video:2", "urn:rtr:video:1");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:4", "urn:rtr:video:3", "urn:rtr:video:2", "urn:rtr:video:1");

testVideoRecommendation(urn, true,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, true,false, false, expectedUrns, expectedStandaloneUrns);
}


Expand All @@ -149,25 +149,25 @@ public void videoClipAndShortPodcastForOldestEpisodeTest() throws URISyntaxExcep
List<String> expectedUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:12", "urn:rtr:video:13", "urn:rtr:video:21", "urn:rtr:video:22", "urn:rtr:video:23", "urn:rtr:video:31", "urn:rtr:video:32", "urn:rtr:video:33");

testVideoRecommendation(urn, false,true, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, false,true, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoClipforOldestEpisodeTest() throws URISyntaxException {
public void videoClipForOldestEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:11";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3", "urn:rtr:video:4");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:12", "urn:rtr:video:13", "urn:rtr:video:21", "urn:rtr:video:22", "urn:rtr:video:23", "urn:rtr:video:31", "urn:rtr:video:32", "urn:rtr:video:33", "urn:rtr:video:41", "urn:rtr:video:42", "urn:rtr:video:43");

testVideoRecommendation(urn, false,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, false,false, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoClipforThirdEpisodeTest() throws URISyntaxException {
public void videoClipForThirdEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:31";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:4", "urn:rtr:video:2", "urn:rtr:video:1");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:32", "urn:rtr:video:33", "urn:rtr:video:41", "urn:rtr:video:42", "urn:rtr:video:43", "urn:rtr:video:23", "urn:rtr:video:22", "urn:rtr:video:21", "urn:rtr:video:13", "urn:rtr:video:12", "urn:rtr:video:11");

testVideoRecommendation(urn, false,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, false,false, false, expectedUrns, expectedStandaloneUrns);
}

@Test
Expand All @@ -176,16 +176,16 @@ public void videoClipAndShortPodcastForNewestEpisodeTest() throws URISyntaxExcep
List<String> expectedUrns = Arrays.asList("urn:rtr:video:1", "urn:rtr:video:2");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:11", "urn:rtr:video:12", "urn:rtr:video:13", "urn:rtr:video:21", "urn:rtr:video:22", "urn:rtr:video:23", "urn:rtr:video:31", "urn:rtr:video:32");

testVideoRecommendation(urn, false,true, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, false,true, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoClipforNewestEpisodeTest() throws URISyntaxException {
public void videoClipForNewestEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:43";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:3", "urn:rtr:video:2", "urn:rtr:video:1");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:42", "urn:rtr:video:41", "urn:rtr:video:33", "urn:rtr:video:32", "urn:rtr:video:31", "urn:rtr:video:23", "urn:rtr:video:22", "urn:rtr:video:21", "urn:rtr:video:13", "urn:rtr:video:12", "urn:rtr:video:11");

testVideoRecommendation(urn, false,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, false,false, false, expectedUrns, expectedStandaloneUrns);
}

@Test
Expand All @@ -194,19 +194,39 @@ public void videoClipAndShortPodcastForNotFoundEpisodeTest() throws URISyntaxExc
List<String> expectedUrns = Arrays.asList("urn:rtr:video:1", "urn:rtr:video:2", "urn:rtr:video:3");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:11", "urn:rtr:video:12", "urn:rtr:video:13", "urn:rtr:video:21", "urn:rtr:video:22", "urn:rtr:video:23", "urn:rtr:video:31", "urn:rtr:video:32", "urn:rtr:video:33");

testVideoRecommendation(urn, false,true, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, false,true, false, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoClipforNotFoundEpisodeTest() throws URISyntaxException {
public void videoClipForNotFoundEpisodeTest() throws URISyntaxException {
String urn = "urn:rtr:video:01";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:4", "urn:rtr:video:3", "urn:rtr:video:2", "urn:rtr:video:1");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:43", "urn:rtr:video:42", "urn:rtr:video:41", "urn:rtr:video:33", "urn:rtr:video:32", "urn:rtr:video:31", "urn:rtr:video:23", "urn:rtr:video:22", "urn:rtr:video:21", "urn:rtr:video:13", "urn:rtr:video:12", "urn:rtr:video:11");

testVideoRecommendation(urn, false,false, expectedUrns, expectedStandaloneUrns);
testVideoRecommendation(urn, false,false, false, expectedUrns, expectedStandaloneUrns);
}

private void testVideoRecommendation(String urn, boolean isFullLength, boolean isShortPodcast, List<String> expectedUrns, List<String> expectedStandaloneUrns) throws URISyntaxException {
@Test
public void videoFullLengthAndShortPodcastWithBingeWatchingSortedForOldestEpisodeTest() throws URISyntaxException {
// Should have same returned list as `videoFullLengthAndShortPodcastForOldestEpisodeTest`.
String urn = "urn:rtr:video:1";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3");

testVideoRecommendation(urn, true,true, true, expectedUrns, expectedStandaloneUrns);
}

@Test
public void videoFullLengthWithBingeWatchingSortedForOldestEpisodeTest() throws URISyntaxException {
// Should have same returned list as `videoFullLengthForOldestEpisodeTest`.
String urn = "urn:rtr:video:1";
List<String> expectedUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3", "urn:rtr:video:4");
List<String> expectedStandaloneUrns = Arrays.asList("urn:rtr:video:2", "urn:rtr:video:3", "urn:rtr:video:4");

testVideoRecommendation(urn, true,false, true, expectedUrns, expectedStandaloneUrns);
}

private void testVideoRecommendation(String urn, boolean isFullLength, boolean isShortPodcast, boolean isBingeWatching, List<String> expectedUrns, List<String> expectedStandaloneUrns) throws URISyntaxException {
String mediaFileName = urn.replace(":", "-") + ".json";
String mediaJson = BaseResourceString.getString(applicationContext, mediaFileName);
mockServer.expect(ExpectedCount.times(2),
Expand All @@ -217,7 +237,8 @@ private void testVideoRecommendation(String urn, boolean isFullLength, boolean i
.body(mediaJson)
);

String episodeCompositionFileName = isShortPodcast ? "episode-composition-rtr-tv-short-podcast.json" : "episode-composition-rtr-tv.json";
String episodeCompositionFileName = isShortPodcast ? "episode-composition-rtr-tv-short-podcast" : "episode-composition-rtr-tv";
episodeCompositionFileName += isBingeWatching ? "-binge-watching.json" : ".json";
String episodeCompositionJson = BaseResourceString.getString(applicationContext, episodeCompositionFileName);
mockServer.expect(ExpectedCount.times(2),
requestTo(new URI("http://il.srgssr.ch:80/integrationlayer/2.0/episodeComposition/latestByShow/byUrn/urn:rtr:show:tv:1234?pageSize=100")))
Expand Down
Loading

0 comments on commit 6227956

Please sign in to comment.