From 00a0a1f06eed8615333b699785928aa8de93a995 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Bertholon Date: Thu, 29 Oct 2020 23:44:07 +0100 Subject: [PATCH 1/3] Add related content purpose to recommended api With RTS & SRF recommendations --- .../service/RecommendationService.java | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/main/java/ch/srgssr/playfff/service/RecommendationService.java b/src/main/java/ch/srgssr/playfff/service/RecommendationService.java index 2b761a5..e20f39e 100644 --- a/src/main/java/ch/srgssr/playfff/service/RecommendationService.java +++ b/src/main/java/ch/srgssr/playfff/service/RecommendationService.java @@ -35,19 +35,38 @@ public RecommendationService() { public RecommendedList getRecommendedUrns(String purpose, String urnString, boolean standalone) { IlUrn urn = new IlUrn(urnString); - switch (urn.getMam()) { - case RTS: - if (urn.getMediaType() == MediaType.VIDEO) { - return rtsVideoRecommendedList(purpose, urnString, standalone); - } else if (urn.getMediaType() == MediaType.AUDIO) { - return pfffRecommendedList(urnString, MediaType.AUDIO, standalone); - } - break; - case RSI: - case RTR: - case SRF: - case SWI: - return pfffRecommendedList(urnString, urn.getMediaType(), standalone); + if (purpose.equals("relatedContent")) { + switch (urn.getMam()) { + case RTS: + if (urn.getMediaType() == MediaType.VIDEO) { + return rtsVideoRecommendedList(purpose, urnString, standalone); + } else if (urn.getMediaType() == MediaType.AUDIO) { + return pfffRecommendedList(urnString, MediaType.AUDIO, standalone); + } + break; + case SRF: + return srfRecommendedList(purpose, urnString, standalone); + case RSI: + case RTR: + case SWI: + return pfffRecommendedList(urnString, urn.getMediaType(), standalone); + } + } + else { + switch (urn.getMam()) { + case RTS: + if (urn.getMediaType() == MediaType.VIDEO) { + return rtsVideoRecommendedList(purpose, urnString, standalone); + } else if (urn.getMediaType() == MediaType.AUDIO) { + return pfffRecommendedList(urnString, MediaType.AUDIO, standalone); + } + break; + case RSI: + case RTR: + case SRF: + case SWI: + return pfffRecommendedList(urnString, urn.getMediaType(), standalone); + } } return new RecommendedList(); } @@ -196,7 +215,7 @@ public RecommendedList rtsPlayHomePersonalRecommendation(String userId) { return new RecommendedList(result.getTitle(), url.getHost(), result.getRecommendationId(), result.getUrns()); } - private RecommendedList srfVideoRecommendedList(String purpose, String urn, boolean standalone) { + private RecommendedList srfRecommendedList(String purpose, String urn, boolean standalone) { long timestamp = System.currentTimeMillis(); Environment environment = Environment.PROD; From 933ff0911ddc5274a67245fc820eefce8ce8d690 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Bertholon Date: Fri, 30 Oct 2020 17:52:51 +0100 Subject: [PATCH 2/3] Update recommendation documentation --- docs/README.md | 11 ++++++++--- docs/RECOMMENDATION.md | 44 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index 514c2ba..53a7ade 100644 --- a/docs/README.md +++ b/docs/README.md @@ -63,17 +63,22 @@ A wide list of parameters are available. #### Recommendation for a media -* `/api/v2/playlist/recommendation/continuousPlayback/{urn}` : get media list object. +* `/api/v2/playlist/recommendation/continuousPlayback/{urn}` : get recommended medias for a continuous playback purpose. * `standalone` (optional, boolean): Recommendation for the playback mode. Default is `false`. * Returns a `recommendedList` object. -* *Deprecated* `/api/v1/playlist/recommendation/continuousPlayback/{urn}` : get media list object. +* `/api/v2/playlist/recommendation/relatedContent/{urn}` : get recommended medias for a related content purpose. * `standalone` (optional, boolean): Recommendation for the playback mode. Default is `false`. + * Returns a `recommendedList` object. + +* *Deprecated* `/api/v1/playlist/recommendation/continuousPlayback/{urn}` : get recommended medias for a continuous playback purpose. * `standalone` (optional, boolean): Recommendation for the playback mode. Default is `false`. * `format` (optional, string): If set to `urn`, it returns an URN list. Default is `media` and redirects to an IL media list response. +More informations about the [recommendation engine](RECOMMENDATION.md) is available. + #### Personnal recommendation for a user -* `/api/v2/playlist/personalRecommendation` : get media list object. +* `/api/v2/playlist/personalRecommendation` : get personal recommended medias. * `userId` (optional, string): `UserId` to use for a personal recommendation. * Returns a `recommendedList` object. diff --git a/docs/RECOMMENDATION.md b/docs/RECOMMENDATION.md index 4977492..78d020c 100644 --- a/docs/RECOMMENDATION.md +++ b/docs/RECOMMENDATION.md @@ -9,19 +9,43 @@ Playfff is the middleware to deliver recommendations for Play SRG mobile applica Since July 2018, Play Android (2.0.207 and more) and Play iOS (2.8.3-272 and more) applications currently use this recommendation service. -## Recommendation type - -### Media recommendation list for a media +## Media recommendation list for a media The API doesn't not support paginations, therefore mobile applications didn't implement pagination. The media recommendation list must have at least 49 items, the 50th is the requested media. -#### RTS videos +### Purposes + +- `continuousPlayback` is used to display one proposition, with a count down and an autoplay. +- `relatedContent` is used to display some propositions in a swimlane or a grid, without an autoplay. + +| BU Content | Continuous playback | Related content | +| :--- | :---: | :---: | +| RSI audios | Pfff RE | Pfff RE | +| RSI videos | Pfff RE | Pfff RE | +| RTR audios | Pfff RE | Pfff RE | +| RTR videos | Pfff RE | Pfff RE | +| RTS audios | Pfff RE | Pfff RE | +| RTS videos | **RTS RE** | **RTS RE** | +| SRF audios | Pfff RE | **SRF RE** | +| SRF videos | Pfff RE | **SRF RE** | +| SWI videos | Pfff RE | Pfff RE | +| Event videos | N/A | N/A | +| Swisstxt videos | N/A | N/A | + +### Recommendation engines used + +#### RTS recommendation engine (RTS RE) -- For RTS videos, it asks `rts-datalab.azure-api` recommendation `continuous_playback_endscreen` service. +- For RTS videos, it can ask `rts-datalab.azure-api` recommendation `continuous_playback_endscreen` service, without personalization. -#### RSI, RTR, SRF, SWI videos and RSI, RTR, RTS and SRF audios +#### SRF recommendation engine (SRF RE) -- It asks Playfff recommendation. Based on IL requests, without personalization. Here is how it works: +- For SRF videos and SRF audios, it can ask `IL-MediaList` recommendation `Recommended-byUrn` service, without personalization. + +#### Playfff recommendation engine (Pfff RE) + +- 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. - Determine if the media is a full length or a clip. @@ -40,10 +64,14 @@ The API doesn't not support paginations, therefore mobile applications didn't im - No recommendation provided. It returns an empty list. -### Media recommendation list for a user +## Media recommendation list for a user The API doesn't not support paginations, therefore mobile applications didn't implement pagination. The media recommendation list must have at least 50 items. #### RTS - With and without an `userId`, it asks `rts-datalab.azure-api` recommendation `play_home_personal_rec` service. + +#### Other BUs + +- Nothing implemented. From f660f480ea817d3ad447877118cdb52a575ef327 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Bertholon Date: Tue, 1 Dec 2020 17:33:22 +0100 Subject: [PATCH 3/3] Add integration tests --- .../RecommendationIntegrationTest.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/test/java/ch/srgssr/playfff/controller/RecommendationIntegrationTest.java b/src/test/java/ch/srgssr/playfff/controller/RecommendationIntegrationTest.java index 5726fb3..8d3692a 100644 --- a/src/test/java/ch/srgssr/playfff/controller/RecommendationIntegrationTest.java +++ b/src/test/java/ch/srgssr/playfff/controller/RecommendationIntegrationTest.java @@ -30,6 +30,9 @@ public class RecommendationIntegrationTest { private MockMvc mvc; + private final String continuousplaybackPurpose = "continuousplayback"; + private final String relatedContentPurpose = "relatedContent"; + @Autowired private WebApplicationContext context; @@ -45,33 +48,39 @@ public void setup() { public void getRecommendationRTSVideo() throws Exception { String mediaURN = "urn:rts:video:9691670"; - getRecommendation(mediaURN); + getRecommendation(mediaURN, continuousplaybackPurpose); + + getRecommendation(mediaURN, relatedContentPurpose); } @Test public void getRecommendationRTSVAudioFull() throws Exception { String mediaURN = "urn:rts:audio:9866170"; - getRecommendation(mediaURN); + getRecommendation(mediaURN, continuousplaybackPurpose); + + getRecommendation(mediaURN, relatedContentPurpose); } @Test public void getRecommendationRTSVAudioClip() throws Exception { String mediaURN = "urn:rts:audio:10163388"; - getRecommendation(mediaURN); + getRecommendation(mediaURN, continuousplaybackPurpose); + + getRecommendation(mediaURN, relatedContentPurpose); } @Test public void getRecommendationSRF() throws Exception { String mediaURN = "urn:srf:video:859dc7e6-a155-41da-9d34-8f4eb800f73c"; - getRecommendation(mediaURN); - } + getRecommendation(mediaURN, continuousplaybackPurpose); - public void getRecommendation(String mediaURN) throws Exception { - String purpose = "continuousplayback"; + getRecommendation(mediaURN, relatedContentPurpose); + } + public void getRecommendation(String mediaURN, String purpose) throws Exception { mvc.perform(get("/api/v1/playlist/recommendation/" + purpose + "/" + mediaURN)).andExpect(status().isFound()).andExpect(content().string("")); checkRecommendationWithRedirect(purpose, mediaURN, "false");