mirror of
https://github.com/musix-org/musix-oss
synced 2025-06-17 07:36:01 +00:00
fix
This commit is contained in:
212
node_modules/simple-youtube-api/src/structures/Channel.js
generated
vendored
Normal file
212
node_modules/simple-youtube-api/src/structures/Channel.js
generated
vendored
Normal file
@ -0,0 +1,212 @@
|
||||
const { parseURL } = require('../util');
|
||||
const Constants = require('../util/Constants');
|
||||
|
||||
/**
|
||||
* Represents a YouTube channel
|
||||
* @class
|
||||
*/
|
||||
class Channel {
|
||||
/**
|
||||
* @param {YouTube} youtube The YouTube instance creating this
|
||||
* @param {Object} data The data of the channel
|
||||
*/
|
||||
constructor(youtube, data) {
|
||||
/**
|
||||
* The YouTube instance that created this
|
||||
* @type {YouTube}
|
||||
*/
|
||||
this.youtube = youtube;
|
||||
Object.defineProperty(this, 'youtube', { enumerable: false });
|
||||
|
||||
/**
|
||||
* The type to filter search results
|
||||
* @type {string}
|
||||
*/
|
||||
this.type = 'channel';
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
if (!data) return;
|
||||
|
||||
/**
|
||||
* Raw data from the YouTube API
|
||||
* @type {object}
|
||||
*/
|
||||
this.raw = data;
|
||||
|
||||
/**
|
||||
* Whether this is a full channel object.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.full = data.kind === Constants.KINDS.Channel;
|
||||
|
||||
/**
|
||||
* The YouTube resource from which this channel was created.
|
||||
* @type {string}
|
||||
*/
|
||||
this.kind = data.kind;
|
||||
|
||||
/**
|
||||
* This channel's ID
|
||||
* @type {string}
|
||||
* @name Channel#id
|
||||
*/
|
||||
|
||||
/**
|
||||
* This channel's title
|
||||
* @type {?string}
|
||||
* @name Channel#title
|
||||
*/
|
||||
|
||||
switch (data.kind) {
|
||||
case Constants.KINDS.Playlist:
|
||||
case Constants.KINDS.PlaylistItem:
|
||||
case Constants.KINDS.Video:
|
||||
if (data.snippet) {
|
||||
this.id = data.snippet.channelId;
|
||||
this.title = data.snippet.channelTitle;
|
||||
break;
|
||||
} else {
|
||||
throw new Error('Attempted to make a channel out of a resource with no channel data.');
|
||||
}
|
||||
case Constants.KINDS.SearchResult:
|
||||
if (data.id.kind === Constants.KINDS.Channel) {
|
||||
this.id = data.id.channelId;
|
||||
break;
|
||||
} else if (data.snippet) {
|
||||
this.id = data.snippet.channelId;
|
||||
this.title = data.snippet.channelTitle;
|
||||
break;
|
||||
} else {
|
||||
throw new Error('Attempted to make a channel out of a search result with no channel data.');
|
||||
}
|
||||
case Constants.KINDS.Channel:
|
||||
this.id = data.id;
|
||||
if (data.snippet) {
|
||||
this.title = data.snippet.title;
|
||||
|
||||
/**
|
||||
* This channel's description
|
||||
* @type {?string}
|
||||
* @name Channel#description
|
||||
*/
|
||||
this.description = data.snippet.description;
|
||||
|
||||
/**
|
||||
* The channel's custom URL if it has one
|
||||
* @type {?string}
|
||||
*/
|
||||
this.customURL = data.snippet.customUrl;
|
||||
|
||||
/**
|
||||
* The channel's creation date
|
||||
* @type {?Date}
|
||||
* @name Channel#publishedAt
|
||||
*/
|
||||
this.publishedAt = new Date(data.snippet.publishedAt);
|
||||
|
||||
/**
|
||||
* The channel's thumbnails: available types are 'default', 'medium', and 'high'
|
||||
* @type {?Object.<string, Thumbnail>}
|
||||
*/
|
||||
this.thumbnails = data.snippet.thumbnails;
|
||||
|
||||
/**
|
||||
* The channel's default language
|
||||
* @type {?string}
|
||||
*/
|
||||
this.defaultLanguage = data.snippet.defaultLanguage;
|
||||
|
||||
/**
|
||||
* Information about the channel as specified in the `hl` query parameter
|
||||
* @type {?{title: string, description: string}}
|
||||
*/
|
||||
this.localized = data.snippet.localized;
|
||||
|
||||
/**
|
||||
* The country of the channel
|
||||
* @type {?string}
|
||||
*/
|
||||
this.country = data.snippet.country;
|
||||
}
|
||||
|
||||
if (data.contentDetails) {
|
||||
/**
|
||||
* Playlists associated with this channel; all values are playlist IDs
|
||||
* @type {?Object}
|
||||
* @property {?string} likes The channel's liked videos
|
||||
* @property {?string} favorites The channel's favorited videos (note: favorited videos are deprecated)
|
||||
* @property {?string} uploads The channel's uploaded videos
|
||||
*/
|
||||
this.relatedPlaylists = data.contentDetails.relatedPlaylists;
|
||||
}
|
||||
|
||||
if (data.statistics) {
|
||||
/**
|
||||
* The number of times the channel has been viewed
|
||||
* @type {?number}
|
||||
*/
|
||||
this.viewCount = data.statistics.viewCount;
|
||||
|
||||
/**
|
||||
* The number of comments on the channel
|
||||
* @type {?number}
|
||||
*/
|
||||
this.commentCount = data.statistics.commentCount;
|
||||
|
||||
/**
|
||||
* The number of subscribers the channel has
|
||||
* @type {?number}
|
||||
*/
|
||||
this.subscriberCount = data.statistics.subscriberCount;
|
||||
|
||||
/**
|
||||
* Whether the channel's subscriber count is public
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.hiddenSubscriberCount = data.statistics.hiddenSubscriberCount;
|
||||
|
||||
/**
|
||||
* The number of videos this channel has uploaded
|
||||
* @type {?number}
|
||||
*/
|
||||
this.videoCount = data.statistics.videoCount;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown channel kind: ${data.kind}.`);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the full representation of this channel.
|
||||
* @param {object} [options] Any extra query params
|
||||
* @returns {Channel}
|
||||
*/
|
||||
fetch(options) {
|
||||
return this.youtube.request.getChannel(this.id, options).then(this._patch.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL to this channel
|
||||
* @type {string}
|
||||
*/
|
||||
get url() {
|
||||
return `https://www.youtube.com/channel/${this.id}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a channel ID from a string (URL or ID)
|
||||
* @param {string} url The string to get the ID from
|
||||
* @returns {?string}
|
||||
*/
|
||||
static extractID(url) {
|
||||
return parseURL(url).channel;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Channel;
|
180
node_modules/simple-youtube-api/src/structures/Playlist.js
generated
vendored
Normal file
180
node_modules/simple-youtube-api/src/structures/Playlist.js
generated
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
const { parseURL } = require('../util');
|
||||
const Constants = require('../util/Constants');
|
||||
const Video = require('./Video');
|
||||
const Channel = require('./Channel');
|
||||
|
||||
/** Represents a YouTube playlist */
|
||||
class Playlist {
|
||||
/**
|
||||
* @param {YouTube} youtube The YouTube instance creating this
|
||||
* @param {Object} data The data of the playlist
|
||||
*/
|
||||
constructor(youtube, data) {
|
||||
/**
|
||||
* The YouTube instance that created this
|
||||
* @type {YouTube}
|
||||
*/
|
||||
this.youtube = youtube;
|
||||
Object.defineProperty(this, 'youtube', { enumerable: false });
|
||||
|
||||
/**
|
||||
* The type to filter search results
|
||||
* @type {string}
|
||||
*/
|
||||
this.type = 'playlist';
|
||||
|
||||
/**
|
||||
* Videos in this playlist. Available after calling {@link Playlist#getVideos}.
|
||||
* @type {Array<Video>}
|
||||
*/
|
||||
this.videos = [];
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
if (!data) return;
|
||||
|
||||
this.raw = data;
|
||||
|
||||
/**
|
||||
* The channel this playlist is in
|
||||
* @type {Channel}
|
||||
*/
|
||||
this.channel = new Channel(this.youtube, data);
|
||||
|
||||
/**
|
||||
* This playlist's ID
|
||||
* @type {string}
|
||||
* @name Playlist#id
|
||||
*/
|
||||
|
||||
switch (data.kind) {
|
||||
case Constants.KINDS.SearchResult:
|
||||
if (data.id.kind === Constants.KINDS.Playlist) this.id = data.id.playlistId;
|
||||
else throw new Error('Attempted to make a playlist out of a non-playlist search result.');
|
||||
break;
|
||||
case Constants.KINDS.Playlist:
|
||||
this.id = data.id;
|
||||
break;
|
||||
case Constants.KINDS.PlaylistItem:
|
||||
if (data.snippet) this.id = data.snippet.playlistId;
|
||||
else throw new Error('Attempted to make a playlist out of a resource with no playlist data.');
|
||||
return this; // don't pull extra info from playlist item info
|
||||
default:
|
||||
throw new Error(`Unknown playlist kind: ${data.kind}.`);
|
||||
}
|
||||
|
||||
if (data.snippet) {
|
||||
/**
|
||||
* This playlist's title
|
||||
* @type {?string}
|
||||
*/
|
||||
this.title = data.snippet.title;
|
||||
|
||||
/**
|
||||
* This playlist's description
|
||||
* @type {?string}
|
||||
*/
|
||||
this.description = data.snippet.description;
|
||||
|
||||
/**
|
||||
* The date/time this playlist was published
|
||||
* @type {?Date}
|
||||
*/
|
||||
this.publishedAt = new Date(data.snippet.publishedAt);
|
||||
|
||||
/**
|
||||
* Thumbnails for this playlist
|
||||
* @type {?Object.<string, Thumbnail>}
|
||||
*/
|
||||
this.thumbnails = data.snippet.thumbnails;
|
||||
|
||||
/**
|
||||
* Channel title of this playlist
|
||||
* @type {?string}
|
||||
*/
|
||||
this.channelTitle = data.snippet.channelTitle;
|
||||
|
||||
/**
|
||||
* The language in this playlist's title and description
|
||||
* @type {?string}
|
||||
*/
|
||||
this.defaultLanguage = data.snippet.defaultLanguage;
|
||||
|
||||
/**
|
||||
* Information about the playlist as specified in the `hl` parameter
|
||||
* @type {?{title: string, description: string}}
|
||||
*/
|
||||
this.localized = data.snippet.localized;
|
||||
}
|
||||
|
||||
if (data.status) {
|
||||
/**
|
||||
* The privacy status of this video
|
||||
* @type {string}
|
||||
*/
|
||||
this.privacy = data.status.privacyStatus;
|
||||
}
|
||||
|
||||
if (data.contentDetails) {
|
||||
/**
|
||||
* The total number of videos in this playlist
|
||||
* @type {number}
|
||||
*/
|
||||
this.length = data.contentDetails.itemCount;
|
||||
}
|
||||
|
||||
if (data.player) {
|
||||
/**
|
||||
* A string with an iframe tag for embedding this playlist
|
||||
* @type {string}
|
||||
*/
|
||||
this.embedHTML = data.player.embedHtml;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL to this playlist
|
||||
* @type {string}
|
||||
*/
|
||||
get url() {
|
||||
return `https://www.youtube.com/playlist?list=${this.id}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the full representation of this playlist.
|
||||
* @param {object} [options] Any extra query params
|
||||
* @returns {Playlist}
|
||||
*/
|
||||
fetch(options) {
|
||||
return this.youtube.request.getPlaylist(this.id, options).then(this._patch.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets videos in the playlist
|
||||
* @param {Number} [limit] Maximum number of videos to obtain. Fetches all if not provided.
|
||||
* @param {Object} [options] Options to retrieve for each video.
|
||||
* @returns {Promise<Video[]>}
|
||||
*/
|
||||
getVideos(limit, options) {
|
||||
return this.youtube.request.getPaginated(
|
||||
Constants.ENDPOINTS.PlaylistItems,
|
||||
limit,
|
||||
Object.assign({ playlistId: this.id, part: Constants.PARTS.PlaylistItems }, options)
|
||||
).then(items => this.videos = items.map(i => new Video(this.youtube, i)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a playlist ID from a string (URL or ID)
|
||||
* @param {string} url The string to get the ID from
|
||||
* @returns {?string}
|
||||
*/
|
||||
static extractID(url) {
|
||||
return parseURL(url).playlist;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Playlist;
|
181
node_modules/simple-youtube-api/src/structures/Video.js
generated
vendored
Normal file
181
node_modules/simple-youtube-api/src/structures/Video.js
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
const duration = require('iso8601-duration');
|
||||
const { parseURL } = require('../util');
|
||||
const Constants = require('../util/Constants');
|
||||
const Channel = require('./Channel');
|
||||
|
||||
/** Represents a YouTube video */
|
||||
class Video {
|
||||
/**
|
||||
* @param {YouTube} youtube The YouTube instance creating this
|
||||
* @param {Object} data The data of the video
|
||||
*/
|
||||
constructor(youtube, data) {
|
||||
/**
|
||||
* The YouTube instance that created this
|
||||
* @type {YouTube}
|
||||
*/
|
||||
this.youtube = youtube;
|
||||
Object.defineProperty(this, 'youtube', { enumerable: false });
|
||||
|
||||
/**
|
||||
* The type to filter search results
|
||||
* @type {string}
|
||||
*/
|
||||
this.type = 'video';
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
if (!data) return;
|
||||
|
||||
/**
|
||||
* The raw data from the YouTube API.
|
||||
* @type {object}
|
||||
*/
|
||||
this.raw = data;
|
||||
|
||||
/**
|
||||
* Whether this is a full (returned from the videos API end point) or partial video (returned
|
||||
* as part of another resource).
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.full = data.kind === Constants.KINDS.Video;
|
||||
|
||||
/**
|
||||
* The resource that this video was created from.
|
||||
* @type {string}
|
||||
*/
|
||||
this.kind = data.kind;
|
||||
|
||||
/**
|
||||
* This video's ID
|
||||
* @type {string}
|
||||
* @name Video#id
|
||||
*/
|
||||
|
||||
switch (data.kind) {
|
||||
case Constants.KINDS.PlaylistItem:
|
||||
if (data.snippet) {
|
||||
if (data.snippet.resourceId.kind === Constants.KINDS.Video) this.id = data.snippet.resourceId.videoId;
|
||||
else throw new Error('Attempted to make a video out of a non-video playlist item.');
|
||||
break;
|
||||
} else {
|
||||
throw new Error('Attempted to make a video out of a playlist item with no video data.');
|
||||
}
|
||||
case Constants.KINDS.Video:
|
||||
this.id = data.id;
|
||||
break;
|
||||
case Constants.KINDS.SearchResult:
|
||||
if (data.id.kind === Constants.KINDS.Video) this.id = data.id.videoId;
|
||||
else throw new Error('Attempted to make a video out of a non-video search result.');
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown video kind: ${data.kind}.`);
|
||||
}
|
||||
|
||||
if (data.snippet) {
|
||||
/**
|
||||
* This video's title
|
||||
* @type {string}
|
||||
*/
|
||||
this.title = data.snippet.title;
|
||||
|
||||
/**
|
||||
* This video's description
|
||||
* @type {string}
|
||||
*/
|
||||
this.description = data.snippet.description;
|
||||
|
||||
/**
|
||||
* The thumbnails of this video.
|
||||
* @type {Object.<'default', 'medium', 'high', 'standard', 'maxres'>}
|
||||
*/
|
||||
this.thumbnails = data.snippet.thumbnails;
|
||||
|
||||
/**
|
||||
* The date/time this video was published
|
||||
* @type {Date}
|
||||
*/
|
||||
this.publishedAt = new Date(data.snippet.publishedAt);
|
||||
|
||||
/**
|
||||
* The channel this video is in.
|
||||
* @type {Channel}
|
||||
*/
|
||||
this.channel = new Channel(this.youtube, data);
|
||||
}
|
||||
|
||||
if(data.contentDetails) {
|
||||
/**
|
||||
* An object containing time period information. All properties are integers, and do not include the lower
|
||||
* precision ones.
|
||||
* @typedef {Object} DurationObject
|
||||
* @property {number} [hours] How many hours the video is long
|
||||
* @property {number} [minutes] How many minutes the video is long
|
||||
* @property {number} [seconds] How many seconds the video is long
|
||||
*/
|
||||
|
||||
/**
|
||||
* The duration of the video
|
||||
* @type {?DurationObject}
|
||||
*/
|
||||
this.duration = data.contentDetails.duration ? duration.parse(data.contentDetails.duration) : null;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maxiumum available resolution thumbnail.
|
||||
* @type {object}
|
||||
*/
|
||||
get maxRes() {
|
||||
const t = this.thumbnails;
|
||||
return t.maxres || t.standard || t.high || t.medium || t.default;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL to this video
|
||||
* @type {string}
|
||||
*/
|
||||
get url() {
|
||||
return `https://www.youtube.com/watch?v=${this.id}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* The short URL to this video
|
||||
* @type {string}
|
||||
*/
|
||||
get shortURL() {
|
||||
return `https://youtu.be/${this.id}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* The duration of the video in seconds
|
||||
* @type {number}
|
||||
*/
|
||||
get durationSeconds() {
|
||||
return this.duration ? duration.toSeconds(this.duration) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the full representation of this video.
|
||||
* @param {object} [options] Any extra query params
|
||||
* @returns {Video}
|
||||
*/
|
||||
fetch(options) {
|
||||
return this.youtube.request.getVideo(this.id, options).then(this._patch.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a video ID from a string (URL or ID)
|
||||
* @param {string} url The string to get the ID from
|
||||
* @returns {?string}
|
||||
*/
|
||||
static extractID(url) {
|
||||
return parseURL(url).video;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Video;
|
Reference in New Issue
Block a user