CHONKY BOY

This commit is contained in:
Core 2022-08-04 05:27:29 +01:00
parent 31ed921a1a
commit c15f55d0ee
No known key found for this signature in database
GPG key ID: FE9BF1B547F8F3C6
213 changed files with 64188 additions and 55736 deletions

View file

@ -1,180 +1,197 @@
import { ProviderDB } from "./db";
import * as path from 'path';
const { readdir } = require('fs').promises;
import { utils } from '../../base/utils';
import * as mm from 'music-metadata';
import {Md5} from 'ts-md5/dist/md5';
import * as path from "path";
const { readdir } = require("fs").promises;
import { utils } from "../../base/utils";
import * as mm from "music-metadata";
import { Md5 } from "ts-md5/dist/md5";
import e from "express";
import { EventEmitter } from 'events';
import { EventEmitter } from "events";
export class LocalFiles {
static localSongs: any = [];
static localSongsArts: any = [];
public static DB = ProviderDB.db;
static eventEmitter = new EventEmitter();
static localSongs: any = [];
static localSongsArts: any = [];
public static DB = ProviderDB.db;
static eventEmitter = new EventEmitter();
static getDataType(item_id : String | any){
if ((item_id ?? ('')).startsWith('ciderlocalart'))
return 'artwork'
else if ((item_id ?? ('')).startsWith('ciderlocal'))
return 'track'
static getDataType(item_id: String | any) {
if ((item_id ?? "").startsWith("ciderlocalart")) return "artwork";
else if ((item_id ?? "").startsWith("ciderlocal")) return "track";
}
static async sendOldLibrary() {
ProviderDB.init();
let rows = (await ProviderDB.db.allDocs({ include_docs: true, attachments: true })).rows.map((item: any) => {
return item.doc;
});
let tracks = rows.filter((item: any) => {
return this.getDataType(item._id) == "track";
});
let arts = rows.filter((item: any) => {
return this.getDataType(item._id) == "artwork";
});
this.localSongs = tracks;
this.localSongsArts = arts;
return tracks;
}
static async scanLibrary() {
ProviderDB.init();
let folders = utils.getStoreValue("libraryPrefs.localPaths");
if (folders == null || folders.length == null || folders.length == 0) folders = [];
let files: any[] = [];
for (var folder of folders) {
// get files from the Music folder
files = files.concat(await LocalFiles.getFiles(folder));
}
static async sendOldLibrary() {
ProviderDB.init()
let rows = (await ProviderDB.db.allDocs({include_docs: true,
attachments: true})).rows.map((item: any)=>{return item.doc})
let tracks = rows.filter((item: any) => {return this.getDataType(item._id) == "track"})
let arts = rows.filter((item: any) => {return this.getDataType(item._id) == "artwork"})
this.localSongs = tracks;
this.localSongsArts = arts;
return tracks;
}
static async scanLibrary() {
ProviderDB.init()
let folders = utils.getStoreValue("libraryPrefs.localPaths")
if (folders == null || folders.length == null || folders.length == 0) folders = []
let files: any[] = []
for (var folder of folders) {
// get files from the Music folder
files = files.concat(await LocalFiles.getFiles(folder))
let supporttedformats = ["mp3", "aac", "webm", "flac", "m4a", "ogg", "wav", "opus"];
let audiofiles = files.filter((f) => supporttedformats.includes(f.substring(f.lastIndexOf(".") + 1)));
let metadatalist = [];
let metadatalistart = [];
let numid = 0;
for (var audio of audiofiles) {
try {
const metadata = await mm.parseFile(audio);
let lochash = Md5.hashStr(audio) ?? numid;
if (metadata != null) {
let form = {
id: "ciderlocal" + lochash,
_id: "ciderlocal" + lochash,
type: "podcast-episodes",
href: audio,
attributes: {
artwork: {
width: 3000,
height: 3000,
url: "/ciderlocalart/" + "ciderlocal" + lochash,
},
topics: [],
url: "",
subscribable: true,
mediaKind: "audio",
genreNames: [""],
// "playParams": {
// "id": "ciderlocal" + numid,
// "kind": "podcast",
// "isLibrary": true,
// "reporting": false },
trackNumber: metadata.common.track?.no ?? 0,
discNumber: metadata.common.disk?.no ?? 0,
name: metadata.common.title ?? audio.substring(audio.lastIndexOf("\\") + 1),
albumName: metadata.common.album,
artistName: metadata.common.artist,
copyright: metadata.common.copyright ?? "",
assetUrl: "file:///" + audio,
contentAdvisory: "",
releaseDateTime: `${metadata?.common?.year ?? "2022"}-05-13T00:23:00Z`,
durationInMillis: Math.floor((metadata.format.duration ?? 0) * 1000),
bitrate: Math.floor((metadata.format?.bitrate ?? 0) / 1000),
offers: [
{
kind: "get",
type: "STDQ",
},
],
contentRating: "clean",
},
flavor: Math.floor((metadata.format?.bitrate ?? 0) / 1000),
localFilesMetadata: {
lossless: metadata.format?.lossless,
container: metadata.format?.container,
bitDepth: metadata.format?.bitsPerSample ?? 0,
sampleRate: metadata.format?.sampleRate ?? 0,
},
};
let art = {
id: "ciderlocal" + lochash,
_id: "ciderlocalart" + lochash,
url: metadata.common.picture != undefined ? metadata.common.picture[0].data.toString("base64") : "",
};
metadatalistart.push(art);
numid += 1;
ProviderDB.db.putIfNotExists(form);
ProviderDB.db.putIfNotExists(art);
metadatalist.push(form);
if (this.localSongs.length === 0 && numid % 10 === 0) {
// send updated chunks only if there is no previous database
this.eventEmitter.emit("newtracks", metadatalist);
}
}
let supporttedformats = ["mp3", "aac", "webm", "flac", "m4a", "ogg", "wav", "opus"]
let audiofiles = files.filter(f => supporttedformats.includes(f.substring(f.lastIndexOf('.') + 1)));
let metadatalist = []
let metadatalistart = []
let numid = 0;
for (var audio of audiofiles) {
try {
const metadata = await mm.parseFile(audio);
let lochash = Md5.hashStr(audio) ?? numid;
if (metadata != null) {
let form = {
"id": "ciderlocal" + lochash,
"_id": "ciderlocal" + lochash,
"type": "podcast-episodes",
"href": audio,
"attributes": {
"artwork": {
"width": 3000,
"height": 3000,
"url": "/ciderlocalart/" + "ciderlocal" + lochash,
},
"topics": [],
"url": "",
"subscribable": true,
"mediaKind": "audio",
"genreNames": [
""
],
// "playParams": {
// "id": "ciderlocal" + numid,
// "kind": "podcast",
// "isLibrary": true,
// "reporting": false },
"trackNumber": metadata.common.track?.no ?? 0,
"discNumber": metadata.common.disk?.no ?? 0,
"name": metadata.common.title ?? audio.substring(audio.lastIndexOf('\\') + 1),
"albumName": metadata.common.album,
"artistName": metadata.common.artist,
"copyright": metadata.common.copyright ?? "",
"assetUrl": "file:///" + audio,
"contentAdvisory": "",
"releaseDateTime": `${metadata?.common?.year ?? '2022'}-05-13T00:23:00Z`,
"durationInMillis": Math.floor((metadata.format.duration ?? 0) * 1000),
"bitrate": Math.floor((metadata.format?.bitrate ?? 0) / 1000),
"offers": [
{
"kind": "get",
"type": "STDQ"
}
],
"contentRating": "clean"
},
flavor: Math.floor((metadata.format?.bitrate ?? 0) / 1000),
localFilesMetadata: {
lossless: metadata.format?.lossless,
container: metadata.format?.container,
bitDepth: metadata.format?.bitsPerSample ?? 0,
sampleRate: metadata.format?.sampleRate ?? 0,
},
};
let art = {
id: "ciderlocal" + lochash,
_id: "ciderlocalart" + lochash,
url: metadata.common.picture != undefined ? metadata.common.picture[0].data.toString('base64') : "",
}
metadatalistart.push(art)
numid += 1;
ProviderDB.db.putIfNotExists(form)
ProviderDB.db.putIfNotExists(art)
metadatalist.push(form)
if (this.localSongs.length === 0 && numid % 10 === 0) { // send updated chunks only if there is no previous database
this.eventEmitter.emit('newtracks', metadatalist)}
}
} catch (e) {console.error("localfiles error:", e)}
}
// console.log('metadatalist', metadatalist);
this.localSongs = metadatalist;
this.localSongsArts = metadatalistart;
return metadatalist;
}
static async getFiles(dir: any) {
const dirents = await readdir(dir, { withFileTypes: true });
const files = await Promise.all(dirents.map((dirent: any) => {
const res = path.resolve(dir, dirent.name);
return dirent.isDirectory() ? this.getFiles(res) : res;
}));
return Array.prototype.concat(...files);
} catch (e) {
console.error("localfiles error:", e);
}
}
// console.log('metadatalist', metadatalist);
this.localSongs = metadatalist;
this.localSongsArts = metadatalistart;
return metadatalist;
}
static async getFiles(dir: any) {
const dirents = await readdir(dir, { withFileTypes: true });
const files = await Promise.all(
dirents.map((dirent: any) => {
const res = path.resolve(dir, dirent.name);
return dirent.isDirectory() ? this.getFiles(res) : res;
})
);
return Array.prototype.concat(...files);
}
static async cleanUpDB(){
let folders = utils.getStoreValue("libraryPrefs.localPaths")
let rows = (await ProviderDB.db.allDocs({include_docs: true,
attachments: true})).rows.map((item: any)=>{return item.doc})
let tracks = rows.filter((item: any) => {return this.getDataType(item._id) == "track" && !folders.some((i: String) => {return item["attributes"]["assetUrl"].startsWith("file:///" + i)})})
let hashs = tracks.map((i: any) => {return i._id})
for (let hash of hashs){
try{
ProviderDB.db.get(hash).then(function (doc: any) {
return ProviderDB.db.remove(doc);
});} catch(e){}
try{
ProviderDB.db.get(hash.replace('ciderlocal','ciderlocalart')).then(function (doc: any) {
return ProviderDB.db.remove(doc);
});} catch(e){}
}
}
static setupHandlers () {
const app = utils.getExpress()
console.log("Setting up handlers for local files")
app.get("/ciderlocal/:songs", (req: any, res: any) => {
const audio = atob(req.params.songs.replace(/_/g, '/').replace(/-/g, '+'));
//console.log('auss', audio)
let data = {
data:
LocalFiles.localSongs.filter((f: any) => audio.split(',').includes(f.id))
};
res.send(data);
static async cleanUpDB() {
let folders = utils.getStoreValue("libraryPrefs.localPaths");
let rows = (await ProviderDB.db.allDocs({ include_docs: true, attachments: true })).rows.map((item: any) => {
return item.doc;
});
let tracks = rows.filter((item: any) => {
return (
this.getDataType(item._id) == "track" &&
!folders.some((i: String) => {
return item["attributes"]["assetUrl"].startsWith("file:///" + i);
})
);
});
let hashs = tracks.map((i: any) => {
return i._id;
});
for (let hash of hashs) {
try {
ProviderDB.db.get(hash).then(function (doc: any) {
return ProviderDB.db.remove(doc);
});
app.get("/ciderlocalart/:songs", (req: any, res: any) => {
const audio = req.params.songs;
// metadata.common.picture[0].data.toString('base64')
res.setHeader('Cache-Control', 'public, max-age=31536000');
res.setHeader('Expires', new Date(Date.now() + 31536000000).toUTCString());
res.setHeader('Content-Type', 'image/jpeg');
let data =
LocalFiles.localSongsArts.filter((f: any) => f.id == audio);
res.status(200).send(Buffer.from(data[0]?.url, 'base64'));
} catch (e) {}
try {
ProviderDB.db.get(hash.replace("ciderlocal", "ciderlocalart")).then(function (doc: any) {
return ProviderDB.db.remove(doc);
});
return app
} catch (e) {}
}
}
}
static setupHandlers() {
const app = utils.getExpress();
console.log("Setting up handlers for local files");
app.get("/ciderlocal/:songs", (req: any, res: any) => {
const audio = atob(req.params.songs.replace(/_/g, "/").replace(/-/g, "+"));
//console.log('auss', audio)
let data = {
data: LocalFiles.localSongs.filter((f: any) => audio.split(",").includes(f.id)),
};
res.send(data);
});
app.get("/ciderlocalart/:songs", (req: any, res: any) => {
const audio = req.params.songs;
// metadata.common.picture[0].data.toString('base64')
res.setHeader("Cache-Control", "public, max-age=31536000");
res.setHeader("Expires", new Date(Date.now() + 31536000000).toUTCString());
res.setHeader("Content-Type", "image/jpeg");
let data = LocalFiles.localSongsArts.filter((f: any) => f.id == audio);
res.status(200).send(Buffer.from(data[0]?.url, "base64"));
});
return app;
}
}