This commit is contained in:
LuanRT
2022-08-11 20:37:01 -03:00
6 changed files with 136 additions and 23 deletions

View File

@@ -1,22 +0,0 @@
import Parser from '../index';
import { YTNode } from '../helpers';
class MusicPlaylistShelf extends YTNode {
static type = 'MusicPlaylistShelf';
#continuations;
constructor(data) {
super();
this.playlist_id = data.playlistId;
this.contents = Parser.parse(data.contents);
this.collapsed_item_count = data.collapsedItemCount;
this.#continuations = data.continuations;
}
get continuation() {
return this.#continuations?.[0]?.nextContinuationData;
}
}
export default MusicPlaylistShelf;

View File

@@ -0,0 +1,24 @@
import Parser from '../index';
import MusicResponsiveListItem from './MusicResponsiveListItem';
import { YTNode } from '../helpers';
class MusicPlaylistShelf extends YTNode {
static type = 'MusicPlaylistShelf';
playlist_id: string;
contents;
collapsed_item_count: number;
continuation: string | null;
constructor(data: any) {
super();
this.playlist_id = data.playlistId;
this.contents = Parser.parseArray<MusicResponsiveListItem>(data.contents, MusicResponsiveListItem);
this.collapsed_item_count = data.collapsedItemCount;
this.continuation = data.continuations?.[0]?.nextContinuationData?.continuation || null;
}
}
export default MusicPlaylistShelf;

View File

@@ -43,7 +43,20 @@ export class SectionListContinuation extends YTNode {
constructor(data: any) {
super();
this.contents = Parser.parse(data.contents, true);
this.continuation = data.continuations[0].nextContinuationData.continuation;
this.continuation = data.continuations?.[0].nextContinuationData.continuation || null;
}
}
export class MusicPlaylistShelfContinuation extends YTNode {
static readonly type = 'musicPlaylistShelfContinuation';
continuation: string;
contents: ObservedArray<YTNode> | null;
constructor(data: any) {
super();
this.contents = Parser.parse(data.contents, true);
this.continuation = data.continuations?.[0].nextContinuationData.continuation || null;
}
}
@@ -220,6 +233,8 @@ export default class Parser {
return new SectionListContinuation(data.sectionListContinuation);
if (data.liveChatContinuation)
return new LiveChatContinuation(data.liveChatContinuation);
if (data.musicPlaylistShelfContinuation)
return new MusicPlaylistShelfContinuation(data.musicPlaylistShelfContinuation);
}
static parseRR(actions: any[]) {

View File

@@ -0,0 +1,80 @@
import Parser, { MusicPlaylistShelfContinuation, ParsedResponse, SectionListContinuation } from '../index';
import Actions, { AxioslikeResponse } from '../../core/Actions';
import MusicDetailHeader from '../classes/MusicDetailHeader';
import MusicCarouselShelf from '../classes/MusicCarouselShelf';
import MusicPlaylistShelf from '../classes/MusicPlaylistShelf';
import SectionList from '../classes/SectionList';
import { InnertubeError } from '../../utils/Utils';
class Playlist {
#page;
#actions;
#continuation;
header;
items;
constructor(response: AxioslikeResponse, actions: Actions) {
this.#actions = actions;
this.#page = Parser.parseResponse(response.data);
this.#actions = actions;
if (this.#page.continuation_contents) {
const data = this.#page.continuation_contents?.as(MusicPlaylistShelfContinuation);
this.items = data.contents;
this.#continuation = data.continuation;
} else {
this.header = this.#page.header.item().as(MusicDetailHeader);
this.items = this.#page.contents_memo.get('MusicPlaylistShelf')?.[0].as(MusicPlaylistShelf).contents;
this.#continuation = this.#page.contents_memo.get('MusicPlaylistShelf')?.[0].as(MusicPlaylistShelf).continuation || null;
}
}
get page(): ParsedResponse {
return this.#page;
}
get has_continuation() {
return !!this.#continuation;
}
/**
* Retrieves playlist item continuation.
*/
async getContinuation() {
if (this.#continuation) {
const response = await this.#actions.browse(this.#continuation, { is_ctoken: true, client: 'YTMUSIC' });
return new Playlist(response, this.#actions);
}
throw new InnertubeError('Continuation not found.');
}
/**
* Retrieves related playlists
*/
async getRelated() {
let section_continuation = this.#page.contents_memo.get('SectionList')?.[0].as(SectionList).continuation;
while (section_continuation) {
const response = await this.#actions.browse(section_continuation, { is_ctoken: true, client: 'YTMUSIC' });
const data = Parser.parseResponse(response.data);
const section_list = data.continuation_contents?.as(SectionListContinuation);
const sections = section_list?.contents?.as(MusicCarouselShelf);
const related = sections?.filter((section) => section.header?.title === 'Related playlists')[0];
if (related) {
return related.contents || [];
}
section_continuation = section_list?.continuation;
}
return [];
}
}
export default Playlist;