From 0fee3ba17eaaf6cefa9e1410fc52f57d8814da27 Mon Sep 17 00:00:00 2001 From: Stefan Cruz <17972991+stefancruz@users.noreply.github.com> Date: Wed, 17 Jul 2024 00:23:55 +0100 Subject: [PATCH] fix: migrating "Favorites", "Recently Watched" and "Liked Videos" added a query param to private playlists on source.getUserPlaylists so source.getPlaylist uses the authenticated context. --- src/DailymotionScript.ts | 69 ++++++++++++++++++++++------------------ src/constants.ts | 11 ++++--- src/gqlQueries.ts | 1 + 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/DailymotionScript.ts b/src/DailymotionScript.ts index 48a4e6f..938405b 100644 --- a/src/DailymotionScript.ts +++ b/src/DailymotionScript.ts @@ -25,14 +25,15 @@ import { BASE_URL_COMMENTS, BASE_URL_COMMENTS_AUTH, BASE_URL_COMMENTS_THUMBNAILS, - FAVORITES_PLAYLIST_ID, - LIKE_PLAYLIST_ID, - RECENTLY_WATCHED_PLAYLIST_ID, + FAVORITE_VIDEOS_PLAYLIST_ID, + LIKED_VIDEOS_PLAYLIST_ID, + RECENTLY_WATCHED_VIDEOS_PLAYLIST_ID, REGEX_VIDEO_CHANNEL_URL, REGEX_VIDEO_PLAYLIST_URL, REGEX_VIDEO_URL, REGEX_VIDEO_URL_1, REGEX_VIDEO_URL_EMBED, + PRIVATE_PLAYLIST_QUERY_PARAM_FLAGGER, } from './constants'; import { @@ -96,9 +97,6 @@ import { getTokenFromClientCredentials, } from './extraction'; -// Will be used to store private playlists that require authentication -const authenticatedPlaylistCollection: string[] = []; - source.setSettings = function (settings) { _settings = settings; }; @@ -443,10 +441,11 @@ class PlatformCommentPager extends CommentPager { //Playlist source.isPlaylistUrl = (url): boolean => { return ( - REGEX_VIDEO_PLAYLIST_URL.test(url) || - url === LIKE_PLAYLIST_ID || - url === FAVORITES_PLAYLIST_ID || - url === RECENTLY_WATCHED_PLAYLIST_ID + REGEX_VIDEO_PLAYLIST_URL.test(url) || [ + LIKED_VIDEOS_PLAYLIST_ID, + FAVORITE_VIDEOS_PLAYLIST_ID, + RECENTLY_WATCHED_VIDEOS_PLAYLIST_ID + ].includes(url) ); }; @@ -455,37 +454,42 @@ source.searchPlaylists = (query, type, order, filters) => { }; source.getPlaylist = (url: string): PlatformPlaylistDetails => { - const usePlatformAuth = authenticatedPlaylistCollection.includes(url); const thumbnailResolutionIndex = _settings.thumbnailResolutionOptionIndex; - if (url === LIKE_PLAYLIST_ID) { + if (url === LIKED_VIDEOS_PLAYLIST_ID) { return getLikePlaylist( config.id, http, - usePlatformAuth, + true, //usePlatformAuth, thumbnailResolutionIndex, ); } - if (url === FAVORITES_PLAYLIST_ID) { + if (url === FAVORITE_VIDEOS_PLAYLIST_ID) { return getFavoritesPlaylist( config.id, http, - usePlatformAuth, + true, //usePlatformAuth, thumbnailResolutionIndex, ); } - if (url === RECENTLY_WATCHED_PLAYLIST_ID) { + if (url === RECENTLY_WATCHED_VIDEOS_PLAYLIST_ID) { return getRecentlyWatchedPlaylist( config.id, http, - usePlatformAuth, + true, //usePlatformAuth, thumbnailResolutionIndex, ); } + const isPrivatePlaylist = url.includes(PRIVATE_PLAYLIST_QUERY_PARAM_FLAGGER); + + if(isPrivatePlaylist){ + url = url.replace(PRIVATE_PLAYLIST_QUERY_PARAM_FLAGGER, ''); //remove the private flag + } + const xid = url.split('/').pop(); const variables = { @@ -498,7 +502,7 @@ source.getPlaylist = (url: string): PlatformPlaylistDetails => { operationName: 'PLAYLIST_VIDEO_QUERY', variables, query: PLAYLIST_DETAILS_QUERY, - usePlatformAuth, + usePlatformAuth: isPrivatePlaylist, }); const videos: PlatformVideo[] = @@ -619,15 +623,13 @@ source.getUserPlaylists = (): string[] => { const playlists = getPlaylistsByUsername(userName, headers, true); + // Used to trick migration "Import Playlists" to import "Favorites", "Recently Watched" and "Liked Videos" [ - LIKE_PLAYLIST_ID, - FAVORITES_PLAYLIST_ID, - RECENTLY_WATCHED_PLAYLIST_ID, - ].forEach((playlistId) => { - if (!authenticatedPlaylistCollection.includes(playlistId)) { - authenticatedPlaylistCollection.push(playlistId); - } - + LIKED_VIDEOS_PLAYLIST_ID, + FAVORITE_VIDEOS_PLAYLIST_ID, + RECENTLY_WATCHED_VIDEOS_PLAYLIST_ID, + ] + .forEach((playlistId) => { if (!playlists.includes(playlistId)) { playlists.push(playlistId); } @@ -666,15 +668,20 @@ function getPlaylistsByUsername( usePlatformAuth, }); - const playlists: string[] = collections.data.channel.collections.edges.map( + const playlists: string[] = (collections.data.channel as Maybe<Channel>)?.collections?.edges?.map( (edge) => { - const playlistUrl = `${BASE_URL_PLAYLIST}/${edge.node.xid}`; - if (!authenticatedPlaylistCollection.includes(playlistUrl)) { - authenticatedPlaylistCollection.push(playlistUrl); + + let playlistUrl = `${BASE_URL_PLAYLIST}/${edge?.node?.xid}`; + + const isPrivatePlaylist = edge?.node?.isPrivate ?? false; + + if(isPrivatePlaylist){ + playlistUrl += PRIVATE_PLAYLIST_QUERY_PARAM_FLAGGER; } + return playlistUrl; }, - ); + ) || []; return playlists; } diff --git a/src/constants.ts b/src/constants.ts index 9506801..b837f10 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -31,7 +31,7 @@ export const REGEX_VIDEO_CHANNEL_URL = /^https:\/\/(?:www\.)?dailymotion\.com\/[a-zA-Z0-9-]+$/i; export const REGEX_VIDEO_PLAYLIST_URL = - /^https:\/\/(?:www\.)?dailymotion\.com\/playlist\/[a-zA-Z0-9]+$/i; + /^https:\/\/(?:www\.)?dailymotion\.com\/playlist\/[a-zA-Z0-9]+(?:\?[a-zA-Z0-9_\-=&%]*)?$/i; export const REGEX_INITIAL_DATA_API_AUTH_1 = /(?<=window\.__LOADABLE_LOADED_CHUNKS__=.*)\b[a-f0-9]{20}\b|\b[a-f0-9]{40}\b/g; @@ -69,9 +69,9 @@ DURATION_THRESHOLDS[FIVE_TO_THIRTY_MINUTES] = { min: 300, max: 1800 }; DURATION_THRESHOLDS[THIRTY_TO_ONE_HOUR] = { min: 1800, max: 3600 }; DURATION_THRESHOLDS[MORE_THAN_ONE_HOUR] = { min: 3600, max: null }; -export const LIKE_PLAYLIST_ID = 'LIKE_PLAYLIST'; -export const FAVORITES_PLAYLIST_ID = 'FAVORITES_PLAYLIST'; -export const RECENTLY_WATCHED_PLAYLIST_ID = 'RECENTLY_WATCHED_PLAYLIST'; +export const LIKED_VIDEOS_PLAYLIST_ID = 'LIKE_PLAYLIST'; +export const FAVORITE_VIDEOS_PLAYLIST_ID = 'FAVORITES_PLAYLIST'; +export const RECENTLY_WATCHED_VIDEOS_PLAYLIST_ID = 'RECENTLY_WATCHED_PLAYLIST'; /** The possible values which liked media connections can be sorted by. */ export const LikedMediaSort = { @@ -147,3 +147,6 @@ export const SEARCH_CAPABILITIES = { }, ], }; + +// Used to on source.getUserPlaylists to specify if the playlist is private or not. This is read by source.getPlaylist to enable the authentication context. +export const PRIVATE_PLAYLIST_QUERY_PARAM_FLAGGER = '&private=1'; \ No newline at end of file diff --git a/src/gqlQueries.ts b/src/gqlQueries.ts index ec582a1..aeb7606 100644 --- a/src/gqlQueries.ts +++ b/src/gqlQueries.ts @@ -687,6 +687,7 @@ query CHANNEL_PLAYLISTS_QUERY( edges { node { xid + isPrivate } } } -- GitLab