mirror of
https://github.com/Noratrieb/spotify-sorter-node.git
synced 2026-01-14 08:35:12 +01:00
v1 of sorting
This commit is contained in:
parent
8f43efb2d2
commit
805af0eb54
2 changed files with 114 additions and 22 deletions
102
src/Sort.ts
102
src/Sort.ts
|
|
@ -1,3 +1,101 @@
|
|||
export function startSort() {
|
||||
console.log("now do sorting stuff things")
|
||||
import {api} from "./index";
|
||||
|
||||
import readline from "readline";
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
const stdinIter = rl[Symbol.asyncIterator]();
|
||||
|
||||
export function initialize() {
|
||||
try {
|
||||
start().then();
|
||||
} catch (e) {
|
||||
console.error("An error occurred", e);
|
||||
}
|
||||
}
|
||||
|
||||
async function start() {
|
||||
const playlists = await api.getUserPlaylists();
|
||||
const playlist = await selectPlaylist(playlists.items);
|
||||
const tracks = await sortPlaylist(playlist);
|
||||
|
||||
}
|
||||
|
||||
|
||||
async function selectPlaylist(playlists: SpotifyApi.PlaylistObjectSimplified[]): Promise<SpotifyApi.PlaylistObjectFull> {
|
||||
let i = 0;
|
||||
for (const list of playlists) {
|
||||
console.log(`${i} - ${list.name}`)
|
||||
i++;
|
||||
}
|
||||
|
||||
const index = await readNumber(playlists.length);
|
||||
return await api.getPlaylist(playlists[index].id);
|
||||
}
|
||||
|
||||
async function sortPlaylist(playlist: SpotifyApi.PlaylistObjectFull): Promise<SpotifyApi.PlaylistTrackObject[]> {
|
||||
console.log(`Playlist to sort: ${playlist.name}`);
|
||||
|
||||
let tracks = playlist.tracks.items;
|
||||
let pagingTracks = playlist.tracks;
|
||||
while (pagingTracks.next) {
|
||||
pagingTracks = await api.getPlaylistTracks(playlist.id, {
|
||||
offset: pagingTracks.offset + pagingTracks.limit,
|
||||
});
|
||||
tracks = [...tracks, ...pagingTracks.items];
|
||||
}
|
||||
|
||||
const tracksSorted = await asyncQuickSort(tracks, compare);
|
||||
|
||||
for (const track of tracksSorted) {
|
||||
console.log(`${track.track.name} --- ${track.track.href}`)
|
||||
}
|
||||
return tracksSorted;
|
||||
}
|
||||
|
||||
|
||||
async function compare({track: track1}: SpotifyApi.PlaylistTrackObject, {track: track2}: SpotifyApi.PlaylistTrackObject): Promise<number> {
|
||||
console.log("-".repeat(20))
|
||||
console.log(`0: ${track1.name} -- ${track1.href}`);
|
||||
console.log(`1: ${track2.name} -- ${track2.href}`);
|
||||
const input = await readNumber(2);
|
||||
return input === 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
async function readNumber(max?: number): Promise<number> {
|
||||
let number;
|
||||
|
||||
const input = await stdinIter.next();
|
||||
number = Number(input.value);
|
||||
while (isNaN(number) || (max && number >= max)) {
|
||||
console.error("error: Invalid number.");
|
||||
const input = await stdinIter.next();
|
||||
number = Number(input.value);
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
type AsyncCompareFn<T> = (a: T, b: T) => Promise<number>;
|
||||
|
||||
async function asyncQuickSort<T>(array: T[], compareFn: AsyncCompareFn<T>): Promise<T[]> {
|
||||
if (array.length <= 1) {
|
||||
return array;
|
||||
}
|
||||
const pivot = array[0];
|
||||
|
||||
const left = [];
|
||||
const right = [];
|
||||
|
||||
for (let i = 1; i < array.length; i++) {
|
||||
if (await compareFn(array[i], pivot) < 0) {
|
||||
left.push(array[i])
|
||||
} else {
|
||||
right.push(array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return (await asyncQuickSort(left, compareFn)).concat(pivot, await asyncQuickSort(right, compareFn));
|
||||
}
|
||||
|
|
|
|||
34
src/index.ts
34
src/index.ts
|
|
@ -2,10 +2,12 @@ import Spotify from "spotify-web-api-js";
|
|||
import fs from "fs/promises";
|
||||
import * as http from "http";
|
||||
import open from "open";
|
||||
import {startSort} from "./Sort";
|
||||
import {initialize} from "./Sort";
|
||||
|
||||
export const api = new Spotify();
|
||||
|
||||
// using a client side library sounds dumb, and it is dumb, but we are using the client side auth flow here so idk i guess
|
||||
// it makes sense
|
||||
// @ts-ignore this is fine
|
||||
global.XMLHttpRequest = require('xhr2');
|
||||
// @ts-ignore this is fine
|
||||
|
|
@ -29,30 +31,21 @@ const webServer = http.createServer((req, res) => {
|
|||
let body = "";
|
||||
|
||||
req.on("readable", () => {
|
||||
body += req.read();
|
||||
})
|
||||
const read = req.read();
|
||||
if (read) {
|
||||
body += read;
|
||||
}
|
||||
});
|
||||
|
||||
req.on("end", () => {
|
||||
api.setAccessToken(body.trim());
|
||||
console.log(`"${body.trim()}"`)
|
||||
api.setAccessToken(body);
|
||||
res.end();
|
||||
|
||||
webServer.close();
|
||||
|
||||
console.log("Token found!");
|
||||
console.log("Connected.")
|
||||
|
||||
api.getUserPlaylists().then(lists => console.log(lists.items.map(list => list.name))).catch(err => console.error(err.response))
|
||||
|
||||
//api.getMyCurrentPlayingTrack().then(track => {
|
||||
// if (track.item) {
|
||||
// console.log(`Currently listening ${track.item.name} on ${track.item.album.name} ${track.progress_ms! / 1000}s`);
|
||||
// } else {
|
||||
// console.log("Not listening anything at the moment");
|
||||
// }
|
||||
//}).catch(console.error)
|
||||
|
||||
startSort();
|
||||
})
|
||||
initialize();
|
||||
});
|
||||
}
|
||||
});
|
||||
webServer.listen(8080);
|
||||
|
|
@ -70,4 +63,5 @@ const SCOPES = [
|
|||
const URL = `${AUTH_ENDPOINT}?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&scope=${SCOPES.join("%20")}&response_type=token&show_dialog=true`;
|
||||
open(URL).then();
|
||||
|
||||
console.log("Spotify playlist sorter")
|
||||
console.log("Spotify Playlist Sorter")
|
||||
console.log("Connect your Account in your browser...")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue