From 69eb28d2298d3d6770c10cc6a61b24cd66d6fb57 Mon Sep 17 00:00:00 2001 From: Angelo Verlain Date: Sun, 2 Jul 2023 01:04:52 +0200 Subject: [PATCH] add get_add_to_playlist --- client.ts | 16 +------ mixins/playlist.ts | 115 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 111 insertions(+), 20 deletions(-) diff --git a/client.ts b/client.ts index 997c8f3..b225b25 100644 --- a/client.ts +++ b/client.ts @@ -1,16 +1,4 @@ -import { - get_history, - get_library_playlists, - get_library_songs, - get_option, - get_queue, - get_queue_ids, - get_search_suggestions, - get_song, - remove_search_history, - search, - setup, -} from "./mod.ts"; +import { get_add_to_playlist, get_option, setup } from "./mod.ts"; import { FetchClient, RequestInit } from "./request.ts"; import { DenoFileStore } from "./store.ts"; import { debug } from "./util.ts"; @@ -131,7 +119,7 @@ auth.addEventListener("requires-login", (event) => { // console.log(await data.text()); // }); -get_library_playlists() +get_add_to_playlist(["9HsfhHLD9h0"]) // get_playlist("PLCwfwQhurMOukOqbFmYRidZ81ng_2iSUE") // .then((data) => { // return get_queue(null, data.playlistId, { autoplay: true }); diff --git a/mixins/playlist.ts b/mixins/playlist.ts index 1031cd3..8c937ea 100644 --- a/mixins/playlist.ts +++ b/mixins/playlist.ts @@ -14,6 +14,7 @@ import { SUBTITLE, SUBTITLE3, THUMBNAIL_CROPPED, + THUMBNAIL_RENDERER, TITLE_TEXT, } from "../nav.ts"; import { @@ -35,6 +36,7 @@ import { } from "./utils.ts"; import { request_json } from "./_request.ts"; import { ArtistRun, parse_song_artists_runs } from "../parsers/songs.ts"; +import { ERROR_CODE, MuseError } from "../errors.ts"; export type { PlaylistItem }; @@ -330,7 +332,7 @@ export interface EditPlaylistOptions extends AbortOptions { privacy_status?: PlaylistPrivacyStatus; move_items?: { setVideoId: string; positionBefore?: string }[]; add_videos?: string[]; - remove_videos?: { videoId: string; setVideoId: string }[]; + remove_videos?: { videoId: string; setVideoId?: string }[]; add_source_playlists?: string[]; } @@ -398,11 +400,19 @@ export async function edit_playlist( if (remove_videos) { remove_videos.forEach((remove_video) => { - actions.push({ - action: "ACTION_REMOVE_VIDEO", - removedVideoId: remove_video.videoId, - setVideoId: remove_video.setVideoId, - }); + if (remove_video.setVideoId != null) { + actions.push({ + action: "ACTION_REMOVE_VIDEO", + removedVideoId: remove_video.videoId, + setVideoId: remove_video.setVideoId, + }); + } else { + actions.push({ + action: "ACTION_REMOVE_VIDEO_BY_VIDEO_ID", + removedVideoId: remove_video.videoId, + setVideoId: remove_video.setVideoId, + }); + } }); } @@ -469,3 +479,96 @@ export function remove_playlist_items( ...options, }); } + +export interface AddToPlaylistItem { + playlistId: string; + title: string; + thumbnails: Thumbnail[]; + songs: string; +} + +export interface AddToPlaylist { + recents: AddToPlaylistItem[]; + playlists: AddToPlaylistItem[]; +} + +export async function get_add_to_playlist( + videoIds: string[] | null, + playlistId: string | null = null, + options: AbortOptions = {}, +) { + await check_auth(); + + const { signal } = options; + + const endpoint = "playlist/get_add_to_playlist"; + const data: Record = { + excludeWatchLater: true, + }; + + if (videoIds != null) { + data.videoIds = videoIds; + } else if (playlistId != null) { + data.playlistId = playlistId; + } else { + throw new MuseError( + ERROR_CODE.INVALID_PARAMETER, + "Either videoIds or playlistId must be provided", + ); + } + + const result: AddToPlaylist = { + recents: [], + playlists: [], + }; + + const json = await request_json(endpoint, { data, signal }); + + const contents = j(json, "contents.0.addToPlaylistRenderer"); + + const recents = j( + contents, + "topShelf.musicCarouselShelfRenderer.contents", + ); + + for (const recent of recents) { + const item = recent.musicTwoRowItemRenderer; + + if (!item) { + continue; + } + + result.recents.push({ + thumbnails: j(item, THUMBNAIL_RENDERER), + playlistId: j(item, "navigationEndpoint.playlistEditEndpoint.playlistId"), + songs: j(item, SUBTITLE), + title: j(item, TITLE_TEXT), + }); + } + + const playlists = j(contents, "playlists"); + + for (const playlist of playlists) { + const item = playlist.playlistAddToOptionRenderer; + + if (!item) { + continue; + } + + // Liked songs "LM" doesn't have a playlistId + + result.playlists.push({ + thumbnails: j(item, THUMBNAIL_RENDERER), + playlistId: jo( + item, + "navigationEndpoint.playlistEditEndpoint.playlistId", + ) ?? "LM", + songs: j(item, "shortBylineText.runs").map((run: any) => run.text).join( + "", + ), + title: j(item, TITLE_TEXT), + }); + } + + return result; +}