diff --git a/.env.EXAMPLE b/.env.EXAMPLE index 3f21ad8..729f514 100644 --- a/.env.EXAMPLE +++ b/.env.EXAMPLE @@ -1,5 +1,5 @@ HASHTAG_FILTER = ichlausche,music,musik,nowplaying,tunetuesday -URL_FILTER = song.link,album.link,youtube.com,youtu.be,spotify.com,music.apple.com,bandcamp.com +URL_FILTER = song.link,album.link,spotify.com,music.apple.com,bandcamp.com YOUTUBE_API_KEY = CHANGE_ME VERBOSE = false diff --git a/src/hooks.server.ts b/src/hooks.server.ts new file mode 100644 index 0000000..3b835c8 --- /dev/null +++ b/src/hooks.server.ts @@ -0,0 +1,12 @@ +import type { HandleServerError } from '@sveltejs/kit'; + +export const handleError = (({ error }) => { + if (error instanceof Error) { + console.error('Something went wrong: ', error.name, error.message); + } + + return { + message: 'Whoops!', + code: (error as any)?.code ?? 'UNKNOWN' + }; +}) satisfies HandleServerError; \ No newline at end of file diff --git a/src/lib/server/timeline.ts b/src/lib/server/timeline.ts index c861180..7d6af5f 100644 --- a/src/lib/server/timeline.ts +++ b/src/lib/server/timeline.ts @@ -3,7 +3,7 @@ import type { Post, Tag, TimelineEvent } from '$lib/mastodon/response'; import { savePost } from '$lib/server/db'; import { WebSocket } from "ws"; -const YOUTUBE_REGEX = new RegExp('https?:\/\/(www\.)?youtu((be.com\/.*v=)|(\.be\/))(?[a-zA-Z_0-9-]+)'); +const YOUTUBE_REGEX = new RegExp(/https?:\/\/(www\.)?youtu((be.com\/.*v=)|(\.be\/))(?[a-zA-Z_0-9-]+)/gm); export class TimelineReader { private static _instance: TimelineReader; @@ -16,10 +16,16 @@ export class TimelineReader { const youtubeVideoUrl = new URL(`https://www.googleapis.com/youtube/v3/videos?${searchParams}`); const resp = await fetch(youtubeVideoUrl); const respObj = await resp.json(); + if (!respObj.items.length) { + console.warn('Could not find video with id', videoId); + return false; + } + const item = respObj.items[0]; if (item.tags?.includes('music')) { return true; } + const categorySearchParams = new URLSearchParams([ ['part', 'snippet'], ['id', item.categoryId], @@ -29,8 +35,26 @@ export class TimelineReader { return categoryTitle === 'Music'; } + private static async checkYoutubeMatches(postContent: string): Promise { + const matches = postContent.matchAll(YOUTUBE_REGEX); + for (let match of matches) { + if (match === undefined || match.groups === undefined) { + continue; + } + const videoId = match.groups.videoId.toString(); + try { + const isMusic = await TimelineReader.isMusicVideo(videoId); + if (isMusic) { + return true; + } + } catch (e) { + console.error('Could not check if', videoId, 'is a music video', e); + } + } + return false; + } + private constructor() { - //const socket = new WebSocket("wss://metalhead.club/api/v1/streaming/public/local") const socket = new WebSocket("wss://metalhead.club/api/v1/streaming") socket.onopen = (_event) => { socket.send('{ "type": "subscribe", "stream": "public:local"}'); @@ -48,33 +72,13 @@ export class TimelineReader { const urls: string[] = URL_FILTER.split(','); const found_urls = urls.filter(t => post.content.includes(t)); - if (found_urls.length === 0 && found_tags.length === 0) { + // If we don't have any tags or non-youtube urls, check youtube + // YT is handled separately, because it requires an API call and therefore is slower + if (found_urls.length === 0 && + found_tags.length === 0 && + !await TimelineReader.checkYoutubeMatches(post.content)) { return; } - - const youtubeMatches = found_urls.map(u => u.match(YOUTUBE_REGEX)).filter(i => i !== null); - let hasMusicLink = false; - // Only check url if no tags are present and if no other matched URLs (e.g. to bandcamp) are found - if (found_tags.length === 0 && found_urls.length > 0 && youtubeMatches.length === found_urls.length) { - for (let match of youtubeMatches) { - if (match === null) { - continue; - } - try { - const isMusic = await TimelineReader.isMusicVideo(match.groups?.videoId ?? ''); - if (isMusic) { - hasMusicLink = true; - break; - } - } catch (e) { - console.error('Could not check if', youtubeMatches, 'is a music video', e); - } - } - if (!hasMusicLink) { - console.info('Found youtube urls, but none is music', youtubeMatches); - return; - } - } savePost(post); } catch (e) {