Aurora SpotiRip desktop and web app
- Spotify playlist, library, album and artist browsing with in-app playback - Song, playlist and album downloads via spotdl with YouTube and Bandcamp fallbacks - Electron desktop app (castLabs Widevine) with a permanent sidebar layout - Linux and Windows packaging scripts
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import superjson from "superjson";
|
||||
import { appendSetCookies, ensureSpotifyAccessToken } from "../helpers/spotifyServer";
|
||||
import type { OutputType, SpotifyPlaylistSummary } from "./spotify-playlists_GET.schema";
|
||||
|
||||
type SpotifyPlaylistPage = {
|
||||
items?: Array<{
|
||||
id?: string;
|
||||
name?: string;
|
||||
owner?: { display_name?: string; id?: string };
|
||||
collaborative?: boolean;
|
||||
images?: Array<{ url?: string }>;
|
||||
external_urls?: { spotify?: string };
|
||||
items?: { total?: number };
|
||||
tracks?: { total?: number };
|
||||
}>;
|
||||
next?: string | null;
|
||||
};
|
||||
|
||||
async function spotifyGet<T>(url: string, accessToken: string) {
|
||||
const response = await fetch(url, {
|
||||
headers: { Authorization: `Bearer ${accessToken}` },
|
||||
});
|
||||
if (!response.ok) {
|
||||
const message = await response.text();
|
||||
throw new Error(`Spotify returned ${response.status}: ${message.slice(0, 220)}`);
|
||||
}
|
||||
return (await response.json()) as T;
|
||||
}
|
||||
|
||||
export async function handle(request: Request) {
|
||||
try {
|
||||
const session = await ensureSpotifyAccessToken(request);
|
||||
if (!session.accessToken) {
|
||||
return new Response(superjson.stringify({ error: "Connect Spotify first." }), { status: 401 });
|
||||
}
|
||||
|
||||
let next: string | null = "https://api.spotify.com/v1/me/playlists?limit=50";
|
||||
const playlists: SpotifyPlaylistSummary[] = [];
|
||||
|
||||
while (next) {
|
||||
const page: SpotifyPlaylistPage = await spotifyGet<SpotifyPlaylistPage>(next, session.accessToken);
|
||||
for (const playlist of page.items ?? []) {
|
||||
if (!playlist.id) continue;
|
||||
playlists.push({
|
||||
id: playlist.id,
|
||||
name: playlist.name || "Untitled playlist",
|
||||
owner: playlist.owner?.display_name || playlist.owner?.id,
|
||||
ownerId: playlist.owner?.id,
|
||||
collaborative: Boolean(playlist.collaborative),
|
||||
imageUrl: playlist.images?.find((image) => image.url)?.url,
|
||||
total: playlist.items?.total ?? playlist.tracks?.total ?? 0,
|
||||
externalUrl: playlist.external_urls?.spotify,
|
||||
});
|
||||
}
|
||||
next = page.next || null;
|
||||
}
|
||||
|
||||
const headers = new Headers({ "Content-Type": "application/json", "Cache-Control": "no-store" });
|
||||
appendSetCookies(headers, session.setCookies);
|
||||
return new Response(superjson.stringify({ playlists } satisfies OutputType), { headers });
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unable to list Spotify playlists.";
|
||||
return new Response(superjson.stringify({ error: message }), { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user