Create exporter.js
This commit is contained in:
parent
5c4fff5abc
commit
1174281ed9
1 changed files with 133 additions and 0 deletions
133
exporter.js
Normal file
133
exporter.js
Normal file
|
@ -0,0 +1,133 @@
|
|||
#!/bin/node
|
||||
|
||||
// Add your details here
|
||||
const SERVER_ADDRESS = "https://jellyfin.example.com"; // Don't leave a trailing slash!!!
|
||||
const API_KEY = ""; // Get this from Administration > API Keys
|
||||
const USER_NAME = "user";
|
||||
const LIBRARY_NAME = "Music";
|
||||
|
||||
if (SERVER_ADDRESS.includes("example") || API_KEY.trim() === "" || USER_NAME.trim() === "" || LIBRARY_NAME.trim() === "") {
|
||||
console.log("Details are invalid, check the details at the top of this script file! (Lines 3 - 7)");
|
||||
return;
|
||||
}
|
||||
|
||||
const fs = require("fs");
|
||||
let outText = "";
|
||||
let albumCount = 0;
|
||||
let songCount = 0;
|
||||
|
||||
class StrippedFunkyArray {
|
||||
constructor() {
|
||||
this.items = {};
|
||||
this.itemKeys = [];
|
||||
this.undefIndex = 9999;
|
||||
}
|
||||
|
||||
set(key, item, regenerate = true) {
|
||||
this.items[key] = item;
|
||||
if (regenerate) {
|
||||
this.itemKeys = Object.keys(this.items);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
get(key) {
|
||||
return this.items[key];
|
||||
}
|
||||
}
|
||||
|
||||
async function apiRequest(url) {
|
||||
const res = await fetch(`${SERVER_ADDRESS}/${url}`, {
|
||||
headers: {
|
||||
Authorization: `Mediabrowser Token="${API_KEY}"`
|
||||
}
|
||||
});
|
||||
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
function getLargestFromNumericKey(keys) {
|
||||
let largest = 0;
|
||||
let next = 0;
|
||||
for (const key of keys) {
|
||||
next = parseInt(key);
|
||||
if (next > largest) {
|
||||
largest = next;
|
||||
}
|
||||
}
|
||||
|
||||
return largest + 1;
|
||||
}
|
||||
|
||||
console.log("=============================================")
|
||||
console.log("@ Holly's Jellyfin Library Expoter for VotV @");
|
||||
console.log("@ It shouldn't have been this hard :( @");
|
||||
console.log("=============================================\n");
|
||||
(async () => {
|
||||
console.log("Fetching users...");
|
||||
const users = await apiRequest("Users");
|
||||
let userId = "";
|
||||
for (const user of users) {
|
||||
if (user.Name === USER_NAME) {
|
||||
userId = user.Id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (userId === "") {
|
||||
console.log(`Could not find user "${USER_NAME}" on the server.`);
|
||||
return;
|
||||
}
|
||||
console.log(`Found user "${USER_NAME}", ID = ${userId}.`);
|
||||
|
||||
console.log(`Fetching Libraries for ${userId}...`);
|
||||
const libraries = await apiRequest(`Items?userId=${userId}`);
|
||||
let libraryId = "";
|
||||
for (const library of libraries.Items) {
|
||||
if (library.Type !== "CollectionFolder") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (library.Name === LIBRARY_NAME) {
|
||||
libraryId = library.Id;
|
||||
}
|
||||
}
|
||||
if (libraryId === "") {
|
||||
console.log(`Could not find library "${LIBRARY_NAME}" for user ${userId} on the server.`)
|
||||
}
|
||||
console.log(`Found library "${LIBRARY_NAME}", ID = ${libraryId}`);
|
||||
|
||||
console.log("Fetching library media...");
|
||||
const media = await apiRequest(`Items?userId=${userId}&recursive=true&parentId=${libraryId}`);
|
||||
|
||||
console.log("Exporting...");
|
||||
const groupedSongs = new StrippedFunkyArray();
|
||||
for (const item of media.Items) {
|
||||
if (item.Type !== "Audio") {
|
||||
if (item.Type === "MusicAlbum") {
|
||||
albumCount++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
let albumArray = groupedSongs.get(item.AlbumId);
|
||||
if (albumArray == null) {
|
||||
albumArray = groupedSongs.set(item.AlbumId, new StrippedFunkyArray());
|
||||
}
|
||||
albumArray.set(item.IndexNumber ?? albumArray.undefIndex++, item);
|
||||
}
|
||||
|
||||
for (const albumArrayKey of groupedSongs.itemKeys) {
|
||||
const albumArray = groupedSongs.get(albumArrayKey);
|
||||
const largestIndexNumber = getLargestFromNumericKey(albumArray.itemKeys);
|
||||
for (let i = 1; i < largestIndexNumber; i++) {
|
||||
if (albumArray.items[i] != null) {
|
||||
const item = albumArray.items[i];
|
||||
outText += `${outText.length === 0 ? "" : "\n"}${item.Name} - ${item.Album ?? item.AlbumArtist}\n${SERVER_ADDRESS}/Items/${item.Id}/Download?api_key=${API_KEY}`;
|
||||
songCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync("online.txt", outText);
|
||||
console.log(`Exported ${songCount} songs from ${albumCount} albums to online.txt`);
|
||||
})();
|
Loading…
Reference in a new issue