From dd650cf6b9a7c8478255cc07e8351b8639c874f3 Mon Sep 17 00:00:00 2001 From: MadeYoga Date: Sun, 18 Oct 2020 17:03:50 +0700 Subject: [PATCH 1/4] Add readFile method --- src/main/java/YouTubeSearchApi/utility/Utils.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/YouTubeSearchApi/utility/Utils.java b/src/main/java/YouTubeSearchApi/utility/Utils.java index eeaee36..dfc3e90 100644 --- a/src/main/java/YouTubeSearchApi/utility/Utils.java +++ b/src/main/java/YouTubeSearchApi/utility/Utils.java @@ -6,6 +6,8 @@ import java.net.URL; import java.net.URLConnection; import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; public class Utils { @@ -42,4 +44,9 @@ public static String httpRequest(String url) throws IOException { return stringBuilder.toString(); } + + public static String readFile(String path, Charset encoding) throws IOException { + byte[] encoded = Files.readAllBytes(Paths.get(path)); + return new String(encoded, encoding); + } } From d23161cfbf673925360009a228b88fb48e6d0081 Mon Sep 17 00:00:00 2001 From: MadeYoga Date: Sun, 18 Oct 2020 17:04:09 +0700 Subject: [PATCH 2/4] Add YoutubePlaylist object --- .../entity/YoutubePlaylist.java | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/main/java/YouTubeSearchApi/entity/YoutubePlaylist.java diff --git a/src/main/java/YouTubeSearchApi/entity/YoutubePlaylist.java b/src/main/java/YouTubeSearchApi/entity/YoutubePlaylist.java new file mode 100644 index 0000000..2bff031 --- /dev/null +++ b/src/main/java/YouTubeSearchApi/entity/YoutubePlaylist.java @@ -0,0 +1,94 @@ +package YouTubeSearchApi.entity; + +import com.google.gson.JsonObject; + +public class YoutubePlaylist { + + private String id; + private String url; + private String title; + private String thumbnailUrl; + private String metadataUrl; + + public YoutubePlaylist(String id, String url, String title, String thumbnailUrl, String metaDataUrl) { + this.id = id; + this.url = url; + this.title = title; + this.thumbnailUrl = thumbnailUrl; + this.metadataUrl = metaDataUrl; + } + + public static YoutubePlaylist parseCompactRadioRenderer(JsonObject compactRadioRendererObject) { + String playlistId = compactRadioRendererObject.get("playlistId").getAsString(); + + String thumbnailUrl = compactRadioRendererObject.get("thumbnail").getAsJsonObject() + .get("thumbnails").getAsJsonArray() + .get(0).getAsJsonObject() + .get("url").getAsString(); + + String title = compactRadioRendererObject.get("title").getAsJsonObject() + .get("simpleText").getAsString(); + + String playlistUrl = compactRadioRendererObject.get("shareUrl").getAsString() + .replace("\\u0026", "&"); + + String metaDataUrl = compactRadioRendererObject.get("navigationEndpoint").getAsJsonObject() + .get("commandMetadata").getAsJsonObject() + .get("webCommandMetadata").getAsJsonObject() + .get("url").getAsString() + .replace("\\u0026", "&"); + + return new YoutubePlaylist(playlistId, playlistUrl, title, thumbnailUrl, metaDataUrl); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getThumbnailUrl() { + return thumbnailUrl; + } + + public void setThumbnailUrl(String thumbnailUrl) { + this.thumbnailUrl = thumbnailUrl; + } + + public String getMetadataUrl() { + return metadataUrl; + } + + public void setMetadataUrl(String metadataUrl) { + this.metadataUrl = metadataUrl; + } + + @Override + public String toString() { + return "YoutubePlaylist{" + + "id='" + id + '\'' + + ", url='" + url + '\'' + + ", title='" + title + '\'' + + ", thumbnailUrl='" + thumbnailUrl + '\'' + + ", metadataUrl='" + metadataUrl + '\'' + + '}'; + } +} From 7e53c0d5c16a61bddf21657ef2813dbb78adf568 Mon Sep 17 00:00:00 2001 From: MadeYoga Date: Sun, 18 Oct 2020 17:04:43 +0700 Subject: [PATCH 3/4] Add YoutubeClient.getRecommendationPlaylist & Add Test case --- .../java/YouTubeSearchApi/YoutubeClient.java | 37 ++++++++++++++++++- .../TestYoutubeClientGetRecommendation.java | 18 +++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/test/java/YouTubeSearchApi/TestYoutubeClientGetRecommendation.java diff --git a/src/main/java/YouTubeSearchApi/YoutubeClient.java b/src/main/java/YouTubeSearchApi/YoutubeClient.java index d833a47..a40dcac 100644 --- a/src/main/java/YouTubeSearchApi/YoutubeClient.java +++ b/src/main/java/YouTubeSearchApi/YoutubeClient.java @@ -1,5 +1,6 @@ package YouTubeSearchApi; +import YouTubeSearchApi.entity.YoutubePlaylist; import YouTubeSearchApi.entity.YoutubeVideo; import YouTubeSearchApi.exception.NoResultFoundException; import YouTubeSearchApi.utility.Utils; @@ -13,6 +14,8 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class YoutubeClient { @@ -39,7 +42,7 @@ public List search(String keywords, int maxResults) throws IOExcep } if (!foundFeatureFlag) { - throw new NoResultFoundException("what you searched was unfortunately not found or doesn't exist. keywords: " + keywords); + throw new NoResultFoundException("What you searched was unfortunately not found or doesn't exist. keywords: " + keywords); } @@ -112,4 +115,36 @@ public YoutubeVideo getInfoByVideoUrl(String videoUrl) throws IOException { return YoutubeVideo.getParsedOEmbedObject(videoObject); } + + public YoutubePlaylist getRecommendationPlaylist(String videoId) throws IOException, NoResultFoundException { + String requestUrl = this.YOUTUBE_BASE_URL + "watch?v=" + videoId; + + String pageContent = Utils.httpRequest(requestUrl); + + Pattern pattern = Pattern.compile( + "\"compactRadioRenderer\"(.+?)\"compactVideoRenderer\"", + Pattern.CASE_INSENSITIVE + ); + Matcher matcher = pattern.matcher(pageContent); + + if (matcher.find()) { + String compactRadioRenderer = matcher.group(); + compactRadioRenderer = "{" + compactRadioRenderer.substring(0, + compactRadioRenderer.length() - ",{\"compactVideoRenderer\"".length()); + + System.out.println(compactRadioRenderer); + + Gson gson = new Gson(); + + JsonObject compactRadioRendererObject = gson.fromJson(compactRadioRenderer, JsonObject.class) + .get("compactRadioRenderer") + .getAsJsonObject(); + YoutubePlaylist youtubePlaylist = YoutubePlaylist.parseCompactRadioRenderer(compactRadioRendererObject); + + return youtubePlaylist; + } + else { + throw new NoResultFoundException("What you searched was unfortunately not found or doesn't exist. keywords: " + videoId); + } + } } diff --git a/src/test/java/YouTubeSearchApi/TestYoutubeClientGetRecommendation.java b/src/test/java/YouTubeSearchApi/TestYoutubeClientGetRecommendation.java new file mode 100644 index 0000000..c91e953 --- /dev/null +++ b/src/test/java/YouTubeSearchApi/TestYoutubeClientGetRecommendation.java @@ -0,0 +1,18 @@ +package YouTubeSearchApi; + +import YouTubeSearchApi.entity.YoutubePlaylist; +import YouTubeSearchApi.exception.NoResultFoundException; + +import java.io.IOException; + +public class TestYoutubeClientGetRecommendation { + public static void main(String[] args) { + YoutubeClient client = new YoutubeClient(); + try { + YoutubePlaylist youtubePlaylist = client.getRecommendationPlaylist("oCrwzN6eb4Q"); + System.out.println(youtubePlaylist); + } catch (IOException | NoResultFoundException e) { + e.printStackTrace(); + } + } +} From 05d050eca407db9b59af6bb6bfe3bbdf6529d4a7 Mon Sep 17 00:00:00 2001 From: MadeYoga Date: Sun, 18 Oct 2020 17:26:31 +0700 Subject: [PATCH 4/4] Rename getRecommendationPlaylist to getRecommendation --- src/main/java/YouTubeSearchApi/YoutubeClient.java | 4 ++-- .../YouTubeSearchApi/TestYoutubeClientGetRecommendation.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/YouTubeSearchApi/YoutubeClient.java b/src/main/java/YouTubeSearchApi/YoutubeClient.java index a40dcac..1d5a30e 100644 --- a/src/main/java/YouTubeSearchApi/YoutubeClient.java +++ b/src/main/java/YouTubeSearchApi/YoutubeClient.java @@ -116,7 +116,7 @@ public YoutubeVideo getInfoByVideoUrl(String videoUrl) throws IOException { return YoutubeVideo.getParsedOEmbedObject(videoObject); } - public YoutubePlaylist getRecommendationPlaylist(String videoId) throws IOException, NoResultFoundException { + public YoutubePlaylist getRecommendation(String videoId) throws IOException, NoResultFoundException { String requestUrl = this.YOUTUBE_BASE_URL + "watch?v=" + videoId; String pageContent = Utils.httpRequest(requestUrl); @@ -144,7 +144,7 @@ public YoutubePlaylist getRecommendationPlaylist(String videoId) throws IOExcept return youtubePlaylist; } else { - throw new NoResultFoundException("What you searched was unfortunately not found or doesn't exist. keywords: " + videoId); + throw new NoResultFoundException("Cannot find any recommendation for videoId: " + videoId); } } } diff --git a/src/test/java/YouTubeSearchApi/TestYoutubeClientGetRecommendation.java b/src/test/java/YouTubeSearchApi/TestYoutubeClientGetRecommendation.java index c91e953..d3db684 100644 --- a/src/test/java/YouTubeSearchApi/TestYoutubeClientGetRecommendation.java +++ b/src/test/java/YouTubeSearchApi/TestYoutubeClientGetRecommendation.java @@ -9,7 +9,7 @@ public class TestYoutubeClientGetRecommendation { public static void main(String[] args) { YoutubeClient client = new YoutubeClient(); try { - YoutubePlaylist youtubePlaylist = client.getRecommendationPlaylist("oCrwzN6eb4Q"); + YoutubePlaylist youtubePlaylist = client.getRecommendation("oCrwzN6eb4Q"); System.out.println(youtubePlaylist); } catch (IOException | NoResultFoundException e) { e.printStackTrace();