Преглед изворни кода

refactor: improve youtube module channel URL parsing to support more formats

Kristian Vos пре 9 часа
родитељ
комит
7d09ea6e91
1 измењених фајлова са 33 додато и 17 уклоњено
  1. 33 17
      backend/logic/youtube.js

+ 33 - 17
backend/logic/youtube.js

@@ -83,6 +83,12 @@ const isQuotaExceeded = apiCalls => {
 	return quotaExceeded;
 };
 
+const youtubeChannelRegex =
+	// eslint-disable-next-line max-len
+	/\.[\w]+\/(?:(?:channel\/(?<channelId>UC[0-9A-Za-z_-]{21}[AQgw]))|(?:user\/?(?<channelUsername>[\w-]+))|(?:c\/?(?<channelCustomUrl>[\w-]+))|(?:\/?(?<channelUsernameOrCustomUrl>@?[\w-]+)))/;
+
+// TODO maybe make use of the forHandle/forUsername for YouTube channel list queries, instead of doing a search
+
 class _YouTubeModule extends CoreClass {
 	// eslint-disable-next-line require-jsdoc
 	constructor() {
@@ -554,6 +560,21 @@ class _YouTubeModule extends CoreClass {
 	 * @returns {Promise} - returns promise (reject, resolve)
 	 */
 	GET_CHANNEL_ID_FROM_CUSTOM_URL(payload) {
+		/**
+		 * Example URLs
+		 * # Caravan Palace
+		 * https://www.youtube.com/channel/UCKH9HfYY_GEcyltl2mbD5lA
+		 * https://www.youtube.com/user/CaravanPalace
+		 * https://www.youtube.com/c/CaravanPalace # Doesn't exist
+		 * https://www.youtube.com/@CaravanPalace
+		 * https://www.youtube.com/CaravanPalace
+		 * # Pogo
+		 * https://www.youtube.com/channel/UCn-K7GIs62ENvdQe6ZZk9-w
+		 * https://www.youtube.com/user/PogoMusic # Doesn't exist
+		 * https://www.youtube.com/c/PogoMusic
+		 * https://www.youtube.com/@PogoMusic # Redirects to /pogomusic
+		 * https://www.youtube.com/PogoMusic
+		 */
 		return new Promise((resolve, reject) => {
 			async.waterfall(
 				[
@@ -564,7 +585,12 @@ class _YouTubeModule extends CoreClass {
 							maxResults: 50
 						};
 
-						params.q = payload.customUrl;
+						const { customUrl } = payload;
+
+						// Force query to YouTube to start with @, so it will search for "@PogoMusic" for example
+						const query = customUrl.startsWith("@") ? customUrl : `@${customUrl}`;
+
+						params.q = query;
 
 						YouTubeModule.runJob(
 							"API_SEARCH",
@@ -904,19 +930,14 @@ class _YouTubeModule extends CoreClass {
 	 */
 	GET_CHANNEL_ID(payload) {
 		return new Promise((resolve, reject) => {
-			const regex =
-				/\.[\w]+\/(?:(?:channel\/(UC[0-9A-Za-z_-]{21}[AQgw]))|(?:user\/?([\w-]+))|(?:c\/?([\w-]+))|(?:\/?([\w-]+)))/;
-			const splitQuery = regex.exec(payload.url);
+			const splitQuery = youtubeChannelRegex.exec(payload.url);
 
-			if (!splitQuery) {
+			if (!splitQuery.groups) {
 				YouTubeModule.log("ERROR", "GET_CHANNEL_ID", "Invalid YouTube channel URL query.");
 				reject(new Error("Invalid playlist URL."));
 				return;
 			}
-			const channelId = splitQuery[1];
-			const channelUsername = splitQuery[2];
-			const channelCustomUrl = splitQuery[3];
-			const channelUsernameOrCustomUrl = splitQuery[4];
+			const { channelId, channelUsername, channelCustomUrl, channelUsernameOrCustomUrl } = splitQuery.groups;
 
 			const disableSearch = payload.disableSearch || false;
 
@@ -977,19 +998,14 @@ class _YouTubeModule extends CoreClass {
 	 */
 	GET_CHANNEL_VIDEOS(payload) {
 		return new Promise((resolve, reject) => {
-			const regex =
-				/\.[\w]+\/(?:(?:channel\/(UC[0-9A-Za-z_-]{21}[AQgw]))|(?:user\/?([\w-]+))|(?:c\/?([\w-]+))|(?:\/?([\w-]+)))/;
-			const splitQuery = regex.exec(payload.url);
+			const splitQuery = youtubeChannelRegex.exec(payload.url);
 
-			if (!splitQuery) {
+			if (!splitQuery.groups) {
 				YouTubeModule.log("ERROR", "GET_CHANNEL_VIDEOS", "Invalid YouTube channel URL query.");
 				reject(new Error("Invalid playlist URL."));
 				return;
 			}
-			const channelId = splitQuery[1];
-			const channelUsername = splitQuery[2];
-			const channelCustomUrl = splitQuery[3];
-			const channelUsernameOrCustomUrl = splitQuery[4];
+			const { channelId, channelUsername, channelCustomUrl, channelUsernameOrCustomUrl } = splitQuery.groups;
 
 			const disableSearch = payload.disableSearch || false;