Skip to content
This repository was archived by the owner on Jan 20, 2024. It is now read-only.

Commit a3d516e

Browse files
authored
Merge pull request #173 from karyeet/file-ingest-dev
Improvements to file ingestion
2 parents d085d30 + 8acfce7 commit a3d516e

File tree

7 files changed

+137
-70
lines changed

7 files changed

+137
-70
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77
branches:
88
- 'main'
99
- 'Dockerfile'
10+
- 'file-ingest-dev'
1011
release:
1112
types:
1213
- created

Docker/docker-compose.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,5 @@ services:
1414
- ./playdlData:/Mandarine/.data
1515
environment:
1616
- "arl=5a2e"
17-
- "runIndexer=True"
1817
restart: unless-stopped
1918

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ services:
5555
- ./playdlData:/Mandarine/.data
5656
environment:
5757
- "arl=5a2e"
58-
- "runIndexer=True"
5958
restart: unless-stopped
6059
```
6160

config.json.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"token":"abcdefghfdfdgsgfsgsdgds"
3+
"additionalMusicDirs":["H:\\WindowsFolder\\Music","/linux/folder"],
4+
"runIndexerOnStart": true,
35
"voiceCommands": {
46
"enabled": true
57
"picoAccessKey": "abcdefghijklmnopqrstuvwxyz=",

index.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,36 @@
1-
if (process.env.runIndexer === "True") {
2-
require("./music/indexer.js");
3-
}
4-
51
const { Intents, Client } = require("discord.js");
62

7-
const { reactions, guildsMeta } = require("./general.js");
8-
93
// Intents: Guilds, VoiceStates, GuildMesssages
104
const intents = [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_VOICE_STATES, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS, Intents.FLAGS.GUILD_PRESENCES];
115

12-
// Create Client with discord commando
6+
// Create Client
137
const client = new Client({ intents });
148

9+
let DIY_COMMANDO;
10+
11+
const { reactions, guildsMeta } = require("./general.js");
12+
13+
const config = require("./config.json");
14+
15+
// Login
16+
console.log("runIndexer is set to " + config.runIndexerOnStart);
17+
if (config.runIndexerOnStart == true) {
18+
require("./music/indexer.js").index().then(() => {
19+
client.login(config.token);
20+
});
21+
}
22+
else {
23+
client.login(config.token);
24+
}
25+
1526
// table of command names and their corresponding files/functions
16-
const DIY_COMMANDO = require("./diy_commando.js");
1727

1828
client.once("ready", () => {
1929
console.log("Ready in " + client.guilds.cache.size + " guild(s).");
2030
client.user.setActivity("Prefix: >", { type: "WATCHING" });
31+
DIY_COMMANDO = require("./diy_commando.js");
2132
});
2233

23-
const config = require("./config.json");
24-
25-
// Login
26-
client.login(config.token);
2734

2835
// check if prefix is ">", and if so return the command back
2936
function checkCommand(content) {

music/indexer.js

Lines changed: 74 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,104 @@
11
/*
2-
Only to be run seperatly when importing new music files
2+
Only needs to be run seperatly when importing new music files
33
Very basic
44
55
*/
66

77

8-
const fs = require("fs");
9-
const localLibrary = require("./localLibrary.json");
8+
const fs = require("fs/promises");
9+
const localLibrary = {};
1010

1111
const homedir = require("os").homedir();
12-
const pathToFiles = homedir + "/mandarineFiles/";
13-
1412
const path = require("path");
1513

14+
const pathToDLFiles = path.join(homedir, "mandarineFiles");
15+
16+
const config = require("../config.json");
17+
1618
let parseFile;
19+
let fileCount = 0;
20+
let dirCount = 0;
21+
1722
// import('music-metadata').then((mmModule)=>{console.log("mm: " + mmModule); parseFile = mmModule.parseFile});
1823

19-
fs.readdir(pathToFiles, async function(err, files) {
2024

21-
let filecount = 0;
22-
if (err) throw err;
23-
// console.log(files);
24-
const musicmetadata = await import("music-metadata");
25-
parseFile = musicmetadata.parseFile;
26-
for (let i = 0; i < files.length; i++) {
27-
const fileName = files[i];
28-
// console.log(fileName);
29-
// only support mp3
30-
if (fileName.endsWith(".mp3")) {
31-
await addFile(fileName);
32-
filecount++;
25+
async function indexDirectory(directory) {
26+
const files = await fs.readdir(directory, { withFileTypes: true });
27+
for (const file of files) {
28+
if (file.isDirectory()) {
29+
await indexDirectory(path.join(directory, file.name));
30+
dirCount++;
3331
}
34-
if (i == files.length - 1) {
35-
console.log("write");
36-
setTimeout(() => {
37-
console.log("Indexed " + filecount + " files.");
38-
write();
39-
}, 3_000);
32+
else if (file.name.endsWith(".mp3")) {
33+
await addFile(path.join(directory, file.name));
34+
fileCount++;
4035
}
4136
}
42-
});
37+
return true;
38+
}
4339

44-
async function addFile(fileName) {
40+
async function addFile(filePath) {
4541

46-
if (!localLibrary[fileName]) {
47-
const metadata = await parseFile(path.join(pathToFiles, fileName));
42+
if (!localLibrary[filePath]) {
43+
const metadata = await parseFile(filePath);
4844
// console.log("metadata:" + JSON.stringify(metadata.common.title));
4945
const title = metadata.common.title;
5046
const artist = metadata.common.artist;
51-
localLibrary[fileName] = {
47+
const search = [
48+
(title).replace(/\.|'|-/g, ""),
49+
(artist + " " + title).replace(/\.|'|-/g, ""),
50+
(title + " " + artist).replace(/\.|'|-/g, ""),
51+
];
52+
53+
if (artist.split(" ").length > 1) {
54+
// if the artist has spaces in their names, chances are people will only add one part of their name
55+
for (const artistNameSplit of artist.split(" ")) {
56+
search.push((title + " " + artistNameSplit).replace(/\.|'|-/g, ""));
57+
search.push((artistNameSplit + " " + title).replace(/\.|'|-/g, ""));
58+
}
59+
}
60+
61+
if (search[2] != (title).replace(/\(.*\)|\.|'|-/g, "")) {
62+
search.push((title).replace(/\(.*\)|\.|'|-/g, ""));
63+
}
64+
65+
localLibrary[filePath] = {
5266
"title": title,
5367
"artist": artist,
54-
"search": [
55-
(title + " " + artist).replace(/\.|'|-/g, ""),
56-
(artist + " " + title).replace(/\.|'|-/g, ""),
57-
(title).replace(/\.|'|-/g, ""),
58-
(title).replace(/\(.*\)|\.|'|-/g, ""),
59-
],
68+
"search": search,
6069
};
6170

62-
6371
}
6472
}
6573

66-
function write() {
74+
async function write() {
6775
// console.log(localLibrary);
68-
fs.writeFileSync(path.join(__dirname, "localLibrary.json"), JSON.stringify(localLibrary));
69-
}
76+
await fs.writeFile(path.join(__dirname, "localLibrary.json"), JSON.stringify(localLibrary));
77+
return true;
78+
}
79+
80+
async function index() {
81+
const musicmetadata = await import("music-metadata");
82+
parseFile = musicmetadata.parseFile;
83+
84+
if (config.additionalMusicDirs) {
85+
for (const dir of config.additionalMusicDirs) {
86+
console.log("Indexing " + dir + " and its subdirectories.");
87+
await indexDirectory(dir);
88+
}
89+
}
90+
console.log("Indexing " + pathToDLFiles + " and its subdirectories.");
91+
await indexDirectory(pathToDLFiles);
92+
console.log("write");
93+
console.log("Indexed " + fileCount + " files in " + dirCount + " folders.");
94+
await write();
95+
return 1;
96+
}
97+
98+
99+
if (require.main === module) {
100+
// called directly
101+
index();
102+
}
103+
104+
module.exports = { index };

music/libraryManager.js

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import("music-metadata").then((mmModule) => {
1818
const meezer = require("./meezer.js");
1919
const path = require("path");
2020

21-
const pathToFiles = path.join(homedir, "/mandarineFiles/");
21+
const pathToDLFiles = path.join(homedir, "/mandarineFiles/");
2222

2323
/*
2424
@@ -47,21 +47,27 @@ function createFuzzySetArr() {
4747
return fzpromise;
4848
}
4949

50+
// get array of files and create new fuzzy object, only use search key
51+
let fuzzySet;
52+
createFuzzySetArr().then((arr) => {
53+
fuzzySet = new FuzzySet(arr);
54+
});
55+
56+
5057
async function requestTrack(query) {
51-
// get array of files and create new fuzzy object, only use search key
52-
const fuzzyArr = await createFuzzySetArr();
53-
const fuzzySet = new FuzzySet(fuzzyArr);
5458

5559
// perform search
56-
const fuzzyResult = fuzzySet.get(query);
60+
console.log("fuzzy search");
61+
const fuzzyResult = await fuzzySet.get(query);
62+
console.log(fuzzyResult);
5763

5864
// if valid match, return filename
59-
if (fuzzyResult && fuzzyResult[0] && (console.log(fuzzyResult[0][0]) || true) && fuzzyResult[0][0] > 0.75) {
65+
if (fuzzyResult && fuzzyResult[0] && (console.log(fuzzyResult[0][0]) || true) && fuzzyResult[0][0] > 0.77) {
6066
console.log("fuzzy found");
61-
console.log(fuzzyResult);
6267
for (const key in localLibrary) {
6368
if (localLibrary[key].search.find(pattern => pattern == fuzzyResult[0][1])) {
64-
const fuzzyfilepath = path.join(pathToFiles, key);
69+
// const fuzzyfilepath = path.join(pathToFiles, key);
70+
const fuzzyfilepath = path.join(key);
6571
console.log(fuzzyfilepath);
6672
return {
6773
"path":fuzzyfilepath,
@@ -79,7 +85,7 @@ async function requestTrack(query) {
7985
console.log("Track not found");
8086
return false;
8187
}
82-
// see if track exists and fuse missed it
88+
// before download, see if track exists and fuzzy missed it
8389
const trackExists = meezer.trackExists(result.artist.name, result.title);
8490
if (trackExists) {
8591
console.log("track exist");
@@ -123,20 +129,38 @@ async function requestTrack(query) {
123129
};*/
124130

125131
function addToLibrary(artist, title, fileName) {
126-
localLibrary[fileName] = {
132+
const search = [
133+
(title).replace(/\.|'|-/g, ""),
134+
(artist + " " + title).replace(/\.|'|-/g, ""),
135+
(title + " " + artist).replace(/\.|'|-/g, ""),
136+
];
137+
138+
if (artist.split(" ").length > 1) {
139+
// if the artist has spaces in their names, chances are people will only add one part of their name
140+
for (const artistNameSplit of artist.split(" ")) {
141+
search.push((title + " " + artistNameSplit).replace(/\.|'|-/g, ""));
142+
search.push((artistNameSplit + " " + title).replace(/\.|'|-/g, ""));
143+
}
144+
}
145+
146+
if (search[2] != (title).replace(/\(.*\)|\.|'|-/g, "")) {
147+
search.push((title).replace(/\(.*\)|\.|'|-/g, ""));
148+
}
149+
150+
localLibrary[path.join(pathToDLFiles, fileName)] = {
127151
"title": title,
128152
"artist": artist,
129-
"search": [
130-
(title + " " + artist).replace(/\.|'|-/g, ""),
131-
(artist + " " + title).replace(/\.|'|-/g, ""),
132-
(title).replace(/\.|'|-/g, ""),
133-
(title).replace(/\(.*\)|\.|'|-/g, ""),
134-
],
153+
"search": search,
135154
};
155+
// add to fuzzy set
156+
for (const searchItem of search) {
157+
fuzzySet.add(searchItem);
158+
}
159+
136160
fs.writeFileSync(path.join(__dirname, "localLibrary.json"), JSON.stringify(localLibrary));
137161
}
138162

139-
console.log(pathToFiles);
163+
console.log(pathToDLFiles);
140164
/* async function test() {
141165
console.log(await requestTrack("metro boomin superhero"));
142166
}*/

0 commit comments

Comments
 (0)