refactor playlist adders
This commit is contained in:
5
src/lib/server/playlist/playlistAdder.ts
Normal file
5
src/lib/server/playlist/playlistAdder.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import type { SongInfo } from '$lib/odesliResponse';
|
||||
|
||||
export interface PlaylistAdder {
|
||||
addToPlaylist(song: SongInfo): Promise<void>;
|
||||
}
|
@ -3,8 +3,9 @@ import { Logger } from '$lib/log';
|
||||
import type { OauthResponse } from '$lib/mastodon/response';
|
||||
import type { SongInfo } from '$lib/odesliResponse';
|
||||
import { OauthPlaylistAdder } from './oauthPlaylistAdder';
|
||||
import type { PlaylistAdder } from './playlistAdder';
|
||||
|
||||
export class SpotifyPlaylistAdder extends OauthPlaylistAdder {
|
||||
export class SpotifyPlaylistAdder extends OauthPlaylistAdder implements PlaylistAdder {
|
||||
public constructor() {
|
||||
super('https://api.spotify.com/v1', 'spotify_auth_token');
|
||||
this.logger = new Logger('SpotifyPlaylistAdder');
|
@ -8,8 +8,9 @@ import { log } from '$lib/log';
|
||||
import type { OauthResponse } from '$lib/mastodon/response';
|
||||
import type { SongInfo } from '$lib/odesliResponse';
|
||||
import { OauthPlaylistAdder } from './oauthPlaylistAdder';
|
||||
import type { PlaylistAdder } from './playlistAdder';
|
||||
|
||||
export class YoutubePlaylistAdder extends OauthPlaylistAdder {
|
||||
export class YoutubePlaylistAdder extends OauthPlaylistAdder implements PlaylistAdder {
|
||||
public constructor() {
|
||||
super('https://www.googleapis.com/youtube/v3', 'yt_auth_token');
|
||||
}
|
@ -25,8 +25,9 @@ import {
|
||||
savePost,
|
||||
saveSongThumbnail
|
||||
} from '$lib/server/db';
|
||||
import { SpotifyPlaylistAdder } from '$lib/server/playlist/spotifyPlaylistAdder';
|
||||
import { YoutubePlaylistAdder } from '$lib/server/playlist/ytPlaylistAdder';
|
||||
import { createFeed, saveAtomFeed } from '$lib/server/rss';
|
||||
import { YoutubePlaylistAdder } from '$lib/server/ytPlaylistAdder';
|
||||
import { sleep } from '$lib/sleep';
|
||||
import crypto from 'crypto';
|
||||
import fs from 'fs/promises';
|
||||
@ -34,7 +35,7 @@ import { console } from 'inspector/promises';
|
||||
import sharp from 'sharp';
|
||||
import { URL, URLSearchParams } from 'url';
|
||||
import { WebSocket } from 'ws';
|
||||
import { SpotifyPlaylistAdder } from './spotifyPlaylistAdder';
|
||||
import type { PlaylistAdder } from './playlist/playlistAdder';
|
||||
|
||||
const URL_REGEX = new RegExp(/href="(?<postUrl>[^>]+?)" target="_blank"/gm);
|
||||
const INVIDIOUS_REGEX = new RegExp(/invidious.*?watch.*?v=(?<videoId>[a-zA-Z_0-9-]+)/gm);
|
||||
@ -45,8 +46,7 @@ const YOUTUBE_REGEX = new RegExp(
|
||||
export class TimelineReader {
|
||||
private static _instance: TimelineReader;
|
||||
private lastPosts: string[] = [];
|
||||
private youtubePlaylistAdder: YoutubePlaylistAdder;
|
||||
private spotifyPlaylistAdder: SpotifyPlaylistAdder;
|
||||
private playlistAdders: PlaylistAdder[];
|
||||
|
||||
private static async isMusicVideo(videoId: string) {
|
||||
if (!YOUTUBE_API_KEY || YOUTUBE_API_KEY === 'CHANGE_ME') {
|
||||
@ -190,86 +190,10 @@ export class TimelineReader {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private async addToYoutubePlaylist(song: SongInfo) {
|
||||
log.debug('addToYoutubePlaylist');
|
||||
let token: OauthResponse;
|
||||
try {
|
||||
const youtube_token_file = await fs.readFile('yt_auth_token', { encoding: 'utf8' });
|
||||
token = JSON.parse(youtube_token_file);
|
||||
log.debug('read youtube access token', token);
|
||||
} catch (e) {
|
||||
log.error('Could not read youtube access token', e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!YOUTUBE_PLAYLIST_ID || YOUTUBE_PLAYLIST_ID === 'CHANGE_ME') {
|
||||
log.debug('no playlist ID configured');
|
||||
return;
|
||||
}
|
||||
if (!song.youtubeUrl) {
|
||||
log.debug('Skip adding song to YT playlist, no youtube Url', song);
|
||||
return;
|
||||
}
|
||||
|
||||
const songUrl = new URL(song.youtubeUrl);
|
||||
const youtubeId = songUrl.searchParams.get('v');
|
||||
if (!youtubeId) {
|
||||
log.debug(
|
||||
'Skip adding song to YT playlist, could not extract YT id from URL',
|
||||
song.youtubeUrl
|
||||
);
|
||||
return;
|
||||
}
|
||||
log.debug('Found YT id from URL', song.youtubeUrl, youtubeId);
|
||||
|
||||
const playlistItemsUrl = new URL('https://www.googleapis.com/youtube/v3/playlistItems');
|
||||
playlistItemsUrl.searchParams.append('videoId', youtubeId);
|
||||
playlistItemsUrl.searchParams.append('playlistId', YOUTUBE_PLAYLIST_ID);
|
||||
playlistItemsUrl.searchParams.append('part', 'id');
|
||||
const existingPlaylistItem = await fetch(
|
||||
'https://www.googleapis.com/youtube/v3/playlistItems',
|
||||
{
|
||||
headers: { Authorization: `${token.token_type} ${token.access_token}` }
|
||||
}
|
||||
).then((r) => r.json());
|
||||
log.debug('existingPlaylistItem', existingPlaylistItem);
|
||||
if (existingPlaylistItem.pageInfo && existingPlaylistItem.pageInfo.totalResults > 0) {
|
||||
log.info('Item already in playlist');
|
||||
return;
|
||||
}
|
||||
|
||||
const searchParams = new URLSearchParams([
|
||||
['part', 'snippet']
|
||||
//['key', token.access_token]
|
||||
]);
|
||||
const options: RequestInit = {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `${token.token_type} ${token.access_token}` },
|
||||
body: JSON.stringify({
|
||||
snippet: {
|
||||
playlistId: YOUTUBE_PLAYLIST_ID,
|
||||
resourceId: {
|
||||
videoId: youtubeId,
|
||||
kind: 'youtube#video'
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
const youtubeApiUrl = new URL(
|
||||
`https://www.googleapis.com/youtube/v3/playlistItems?${searchParams}`
|
||||
);
|
||||
const resp = await fetch(youtubeApiUrl, options);
|
||||
const respObj = await resp.json();
|
||||
log.debug('Added to playlist', options, respObj);
|
||||
if (respObj.error) {
|
||||
log.debug('Add to playlist failed', respObj.error.errors);
|
||||
}
|
||||
}
|
||||
*/
|
||||
private async addToPlaylist(song: SongInfo) {
|
||||
await this.youtubePlaylistAdder.addToPlaylist(song);
|
||||
await this.spotifyPlaylistAdder.addToPlaylist(song);
|
||||
for (let adder of this.playlistAdders) {
|
||||
await adder.addToPlaylist(song);
|
||||
}
|
||||
}
|
||||
|
||||
private static async resizeAvatar(
|
||||
@ -554,8 +478,7 @@ export class TimelineReader {
|
||||
|
||||
private constructor() {
|
||||
log.log('Constructing timeline object');
|
||||
this.youtubePlaylistAdder = new YoutubePlaylistAdder();
|
||||
this.spotifyPlaylistAdder = new SpotifyPlaylistAdder();
|
||||
this.playlistAdders = [new YoutubePlaylistAdder(), new SpotifyPlaylistAdder()];
|
||||
this.startWebsocket();
|
||||
|
||||
this.loadPostsSinceLastRun()
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { log } from '$lib/log';
|
||||
import { SpotifyPlaylistAdder } from '$lib/server/spotifyPlaylistAdder';
|
||||
import { SpotifyPlaylistAdder } from '$lib/server/playlist/spotifyPlaylistAdder';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { log } from '$lib/log';
|
||||
import { YoutubePlaylistAdder } from '$lib/server/ytPlaylistAdder';
|
||||
import { YoutubePlaylistAdder } from '$lib/server/playlist/ytPlaylistAdder';
|
||||
import { redirect } from '@sveltejs/kit';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
|
Reference in New Issue
Block a user