@emgeebee/music_downcoder 1.1.8 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cleanEmptyFolders.d.ts.map +1 -1
- package/dist/cleanEmptyFolders.js +29 -5
- package/dist/cleanEmptyFolders.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/outputPaths.d.ts +10 -0
- package/dist/outputPaths.d.ts.map +1 -0
- package/dist/outputPaths.js +36 -0
- package/dist/outputPaths.js.map +1 -0
- package/dist/repairMetaYears.d.ts +8 -0
- package/dist/repairMetaYears.d.ts.map +1 -0
- package/dist/repairMetaYears.js +74 -0
- package/dist/repairMetaYears.js.map +1 -0
- package/dist/syncMetaFromLocal.d.ts +11 -0
- package/dist/syncMetaFromLocal.d.ts.map +1 -0
- package/dist/syncMetaFromLocal.js +113 -0
- package/dist/syncMetaFromLocal.js.map +1 -0
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanEmptyFolders.d.ts","sourceRoot":"","sources":["../src/cleanEmptyFolders.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cleanEmptyFolders.d.ts","sourceRoot":"","sources":["../src/cleanEmptyFolders.ts"],"names":[],"mappings":";AAyFA,eAAO,MAAM,yBAAyB,GAAI,aAAa,MAAM,KAAG,MAgC/D,CAAC"}
|
|
@@ -16,6 +16,10 @@ const MEDIA_EXTENSIONS = new Set([
|
|
|
16
16
|
".aif",
|
|
17
17
|
]);
|
|
18
18
|
const isMediaFile = (filename) => MEDIA_EXTENSIONS.has(path.extname(filename).toLowerCase());
|
|
19
|
+
const formatError = (error) => error instanceof Error ? error.message : String(error);
|
|
20
|
+
const logAccessError = (action, dirPath, error) => {
|
|
21
|
+
console.warn(`Could not ${action} ${dirPath}: ${formatError(error)}`);
|
|
22
|
+
};
|
|
19
23
|
const directoryHasMedia = (dirPath) => {
|
|
20
24
|
let entries;
|
|
21
25
|
try {
|
|
@@ -43,7 +47,14 @@ const cleanEmptyDirectories = (dirPath) => {
|
|
|
43
47
|
return 0;
|
|
44
48
|
}
|
|
45
49
|
let removed = 0;
|
|
46
|
-
|
|
50
|
+
let entries;
|
|
51
|
+
try {
|
|
52
|
+
entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
logAccessError("read", dirPath, error);
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
47
58
|
for (const entry of entries) {
|
|
48
59
|
if (!entry.isDirectory()) {
|
|
49
60
|
continue;
|
|
@@ -51,9 +62,15 @@ const cleanEmptyDirectories = (dirPath) => {
|
|
|
51
62
|
removed += cleanEmptyDirectories(path.join(dirPath, entry.name));
|
|
52
63
|
}
|
|
53
64
|
if (!directoryHasMedia(dirPath)) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
try {
|
|
66
|
+
fs.rmSync(dirPath, { recursive: true, force: true });
|
|
67
|
+
console.log(`Removed ${dirPath}`);
|
|
68
|
+
return removed + 1;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
logAccessError("remove", dirPath, error);
|
|
72
|
+
return removed;
|
|
73
|
+
}
|
|
57
74
|
}
|
|
58
75
|
return removed;
|
|
59
76
|
};
|
|
@@ -70,7 +87,14 @@ export const cleanEncoderOutputFolders = (configPath) => {
|
|
|
70
87
|
continue;
|
|
71
88
|
}
|
|
72
89
|
console.log(`Cleaning ${outputRoot}...`);
|
|
73
|
-
|
|
90
|
+
let entries;
|
|
91
|
+
try {
|
|
92
|
+
entries = fs.readdirSync(outputRoot, { withFileTypes: true });
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
logAccessError("read", outputRoot, error);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
74
98
|
for (const entry of entries) {
|
|
75
99
|
if (!entry.isDirectory()) {
|
|
76
100
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanEmptyFolders.js","sourceRoot":"","sources":["../src/cleanEmptyFolders.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAW,EAAE,CAChD,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAE7D,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAW,EAAE;IACrD,IAAI,OAAoB,CAAC;IACzB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,OAAe,EAAU,EAAE;IACxD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,
|
|
1
|
+
{"version":3,"file":"cleanEmptyFolders.js","sourceRoot":"","sources":["../src/cleanEmptyFolders.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAgBA,OAAO,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,12 @@ if (command === "serve") {
|
|
|
6
6
|
else if (command === "clean-empty") {
|
|
7
7
|
await import("./cleanEmptyFolders.js");
|
|
8
8
|
}
|
|
9
|
+
else if (command === "sync-meta") {
|
|
10
|
+
await import("./syncMetaFromLocal.js");
|
|
11
|
+
}
|
|
12
|
+
else if (command === "repair-meta-years") {
|
|
13
|
+
await import("./repairMetaYears.js");
|
|
14
|
+
}
|
|
9
15
|
else {
|
|
10
16
|
await import("./cli.js");
|
|
11
17
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAExC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IACxB,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;AAC7B,CAAC;KAAM,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;IACrC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;AACzC,CAAC;KAAM,CAAC;IACN,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;AAC3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAExC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IACxB,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;AAC7B,CAAC;KAAM,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;IACrC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;AACzC,CAAC;KAAM,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;IACnC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;AACzC,CAAC;KAAM,IAAI,OAAO,KAAK,mBAAmB,EAAE,CAAC;IAC3C,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;AACvC,CAAC;KAAM,CAAC;IACN,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const sanitiseMeta: (meta: string) => string;
|
|
2
|
+
export declare const sanitisePathSegment: (segment: string) => string;
|
|
3
|
+
export declare const buildArtistDirName: (fullArtist: string) => string;
|
|
4
|
+
export declare const buildArtistOutputDir: (outputRoot: string, genre: string, fullArtist: string) => string;
|
|
5
|
+
export interface AlbumFolderMatch {
|
|
6
|
+
folderName: string;
|
|
7
|
+
year: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const findAlbumFolderOnDisk: (artistDir: string, albumName: string) => AlbumFolderMatch | null;
|
|
10
|
+
//# sourceMappingURL=outputPaths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputPaths.d.ts","sourceRoot":"","sources":["../src/outputPaths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,MACC,CAAC;AAE9C,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,KAAG,MACxB,CAAC;AAE/B,eAAO,MAAM,kBAAkB,GAAI,YAAY,MAAM,KAAG,MAGnB,CAAC;AAEtC,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,EAClB,OAAO,MAAM,EACb,YAAY,MAAM,KACjB,MAKA,CAAC;AAKJ,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,qBAAqB,GAChC,WAAW,MAAM,EACjB,WAAW,MAAM,KAChB,gBAAgB,GAAG,IAgCrB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export const sanitiseMeta = (meta) => meta.replace(/\//g, "_").replace(/:/g, "_");
|
|
4
|
+
export const sanitisePathSegment = (segment) => sanitiseMeta(segment).trim();
|
|
5
|
+
export const buildArtistDirName = (fullArtist) => fullArtist === "Various Artists"
|
|
6
|
+
? "Compilations"
|
|
7
|
+
: sanitisePathSegment(fullArtist);
|
|
8
|
+
export const buildArtistOutputDir = (outputRoot, genre, fullArtist) => path.join(outputRoot, sanitisePathSegment(genre), buildArtistDirName(fullArtist));
|
|
9
|
+
const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10
|
+
export const findAlbumFolderOnDisk = (artistDir, albumName) => {
|
|
11
|
+
if (!fs.existsSync(artistDir)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const sanitisedAlbum = sanitisePathSegment(albumName);
|
|
15
|
+
const escapedAlbum = escapeRegex(sanitisedAlbum);
|
|
16
|
+
const yearPrefixPattern = new RegExp(`^\\((\\d{4})\\)\\s+${escapedAlbum}$`, "i");
|
|
17
|
+
const plainPattern = new RegExp(`^${escapedAlbum}$`, "i");
|
|
18
|
+
let plainMatch = null;
|
|
19
|
+
for (const entry of fs.readdirSync(artistDir, { withFileTypes: true })) {
|
|
20
|
+
if (!entry.isDirectory()) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const yearMatch = entry.name.match(yearPrefixPattern);
|
|
24
|
+
if (yearMatch) {
|
|
25
|
+
return { folderName: entry.name, year: yearMatch[1] };
|
|
26
|
+
}
|
|
27
|
+
if (plainPattern.test(entry.name)) {
|
|
28
|
+
plainMatch = entry.name;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (plainMatch) {
|
|
32
|
+
return { folderName: plainMatch, year: "" };
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=outputPaths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputPaths.js","sourceRoot":"","sources":["../src/outputPaths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAU,EAAE,CACnD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAE9C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAU,EAAE,CAC7D,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AAE/B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,UAAkB,EAAU,EAAE,CAC/D,UAAU,KAAK,iBAAiB;IAC9B,CAAC,CAAC,cAAc;IAChB,CAAC,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,UAAkB,EAClB,KAAa,EACb,UAAkB,EACV,EAAE,CACV,IAAI,CAAC,IAAI,CACP,UAAU,EACV,mBAAmB,CAAC,KAAK,CAAC,EAC1B,kBAAkB,CAAC,UAAU,CAAC,CAC/B,CAAC;AAEJ,MAAM,WAAW,GAAG,CAAC,KAAa,EAAU,EAAE,CAC5C,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAO/C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,SAAiB,EACjB,SAAiB,EACQ,EAAE;IAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,cAAc,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;IACjD,MAAM,iBAAiB,GAAG,IAAI,MAAM,CAAC,sBAAsB,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC;IACjF,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC;IAE1D,IAAI,UAAU,GAAkB,IAAI,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACvE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACtD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,CAAC;QAED,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IAC9C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repairMetaYears.d.ts","sourceRoot":"","sources":["../src/repairMetaYears.ts"],"names":[],"mappings":";AAkCA,eAAO,MAAM,uBAAuB,GAClC,aAAa,MAAM,KAClB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA8DhF,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { getConfig, loadConfig } from "./config.js";
|
|
5
|
+
import { buildArtistOutputDir, findAlbumFolderOnDisk, } from "./outputPaths.js";
|
|
6
|
+
import { createCliPrompts } from "./prompts.js";
|
|
7
|
+
const normalizeYear = (year) => year?.trim() ?? "";
|
|
8
|
+
const loadMetaCache = (metaFile) => {
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(fs.readFileSync(metaFile, "utf-8"));
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const writeLocalBackup = (sourcePath, meta) => {
|
|
17
|
+
const backupFile = path.join(sourcePath, "meta.json");
|
|
18
|
+
if (!fs.existsSync(sourcePath)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
fs.writeFileSync(backupFile, JSON.stringify(meta));
|
|
22
|
+
};
|
|
23
|
+
export const repairMetaYearsFromAlac = async (configPath) => {
|
|
24
|
+
loadConfig(configPath ? path.resolve(configPath) : undefined);
|
|
25
|
+
const config = getConfig();
|
|
26
|
+
const prompts = createCliPrompts();
|
|
27
|
+
const alacEncoder = config.encoders.find((encoder) => encoder.id === "alac");
|
|
28
|
+
if (!alacEncoder) {
|
|
29
|
+
throw new Error("No alac encoder found in config");
|
|
30
|
+
}
|
|
31
|
+
const metaData = loadMetaCache(config.metaFile);
|
|
32
|
+
const entries = Object.entries(metaData);
|
|
33
|
+
let checked = 0;
|
|
34
|
+
let updated = 0;
|
|
35
|
+
let missing = 0;
|
|
36
|
+
let matched = 0;
|
|
37
|
+
for (const [sourcePath, meta] of entries) {
|
|
38
|
+
checked++;
|
|
39
|
+
const artistDir = buildArtistOutputDir(alacEncoder.out, meta.genre, meta.fullArtist);
|
|
40
|
+
const folderMatch = findAlbumFolderOnDisk(artistDir, meta.fullAlbum);
|
|
41
|
+
if (!folderMatch) {
|
|
42
|
+
missing++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
matched++;
|
|
46
|
+
const metaYear = normalizeYear(meta.year);
|
|
47
|
+
const diskYear = normalizeYear(folderMatch.year);
|
|
48
|
+
if (metaYear === diskYear) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const accept = await prompts.confirm(`Update ${meta.fullArtist} / ${meta.fullAlbum}\n` +
|
|
52
|
+
` folder: ${folderMatch.folderName}\n` +
|
|
53
|
+
` meta year: ${metaYear || "(none)"} -> ${diskYear || "(none)"}?`, true);
|
|
54
|
+
if (!accept) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
meta.year = diskYear;
|
|
58
|
+
metaData[sourcePath] = meta;
|
|
59
|
+
writeLocalBackup(sourcePath, meta);
|
|
60
|
+
updated++;
|
|
61
|
+
}
|
|
62
|
+
if (updated > 0) {
|
|
63
|
+
fs.writeFileSync(config.metaFile, JSON.stringify(metaData, undefined, 2));
|
|
64
|
+
}
|
|
65
|
+
return { checked, updated, missing, matched };
|
|
66
|
+
};
|
|
67
|
+
const configArgIndex = process.argv.indexOf("-c");
|
|
68
|
+
const configPath = configArgIndex >= 0 ? process.argv[configArgIndex + 1] : undefined;
|
|
69
|
+
const result = await repairMetaYearsFromAlac(configPath);
|
|
70
|
+
console.log(`Checked ${result.checked} meta entries.`);
|
|
71
|
+
console.log(` matched on disk: ${result.matched}`);
|
|
72
|
+
console.log(` no album folder: ${result.missing}`);
|
|
73
|
+
console.log(` updated: ${result.updated}`);
|
|
74
|
+
//# sourceMappingURL=repairMetaYears.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repairMetaYears.js","sourceRoot":"","sources":["../src/repairMetaYears.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
interface SyncMetaResult {
|
|
3
|
+
updated: number;
|
|
4
|
+
unchanged: number;
|
|
5
|
+
missingLocal: number;
|
|
6
|
+
added: number;
|
|
7
|
+
total: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const syncMetaFromLocal: (configPath?: string) => SyncMetaResult;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=syncMetaFromLocal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syncMetaFromLocal.d.ts","sourceRoot":"","sources":["../src/syncMetaFromLocal.ts"],"names":[],"mappings":";AAQA,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAuED,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,cAkDvD,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { getConfig, loadConfig } from "./config.js";
|
|
5
|
+
import { normalizeDir } from "./paths.js";
|
|
6
|
+
const shouldSkipDir = (name) => name.startsWith("@") || name === "#recycle";
|
|
7
|
+
const isValidMetadata = (value) => {
|
|
8
|
+
if (!value || typeof value !== "object") {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const meta = value;
|
|
12
|
+
return (typeof meta.fullArtist === "string" &&
|
|
13
|
+
typeof meta.fullAlbum === "string" &&
|
|
14
|
+
typeof meta.genre === "string" &&
|
|
15
|
+
meta.year !== undefined);
|
|
16
|
+
};
|
|
17
|
+
const readLocalMeta = (dirPath) => {
|
|
18
|
+
const backupFile = path.join(dirPath, "meta.json");
|
|
19
|
+
try {
|
|
20
|
+
const parsed = JSON.parse(fs.readFileSync(backupFile, "utf-8"));
|
|
21
|
+
if (isValidMetadata(parsed)) {
|
|
22
|
+
return parsed;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// no local meta.json or invalid contents
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
};
|
|
30
|
+
const walkLocalMeta = (start, found = new Map()) => {
|
|
31
|
+
const dirPath = normalizeDir(start);
|
|
32
|
+
let entries;
|
|
33
|
+
try {
|
|
34
|
+
entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return found;
|
|
38
|
+
}
|
|
39
|
+
const localMeta = readLocalMeta(dirPath);
|
|
40
|
+
if (localMeta) {
|
|
41
|
+
found.set(dirPath, localMeta);
|
|
42
|
+
}
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
if (!entry.isDirectory() || shouldSkipDir(entry.name)) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
walkLocalMeta(path.join(dirPath, entry.name), found);
|
|
48
|
+
}
|
|
49
|
+
return found;
|
|
50
|
+
};
|
|
51
|
+
const loadCentralMeta = (metaFile) => {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(fs.readFileSync(metaFile, "utf-8"));
|
|
54
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
return parsed;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return {};
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
export const syncMetaFromLocal = (configPath) => {
|
|
64
|
+
loadConfig(configPath ? path.resolve(configPath) : undefined);
|
|
65
|
+
const config = getConfig();
|
|
66
|
+
const central = loadCentralMeta(config.metaFile);
|
|
67
|
+
const localByPath = new Map();
|
|
68
|
+
for (const folder of config.startFolders) {
|
|
69
|
+
walkLocalMeta(folder.path, localByPath);
|
|
70
|
+
}
|
|
71
|
+
let updated = 0;
|
|
72
|
+
let unchanged = 0;
|
|
73
|
+
let missingLocal = 0;
|
|
74
|
+
for (const dirPath of Object.keys(central)) {
|
|
75
|
+
const localMeta = readLocalMeta(dirPath) ?? localByPath.get(normalizeDir(dirPath));
|
|
76
|
+
if (!localMeta) {
|
|
77
|
+
missingLocal++;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (JSON.stringify(central[dirPath]) === JSON.stringify(localMeta)) {
|
|
81
|
+
unchanged++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
central[dirPath] = localMeta;
|
|
85
|
+
updated++;
|
|
86
|
+
}
|
|
87
|
+
let added = 0;
|
|
88
|
+
for (const [dirPath, localMeta] of localByPath) {
|
|
89
|
+
if (central[dirPath]) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
central[dirPath] = localMeta;
|
|
93
|
+
added++;
|
|
94
|
+
}
|
|
95
|
+
fs.writeFileSync(config.metaFile, JSON.stringify(central, undefined, 2));
|
|
96
|
+
return {
|
|
97
|
+
updated,
|
|
98
|
+
unchanged,
|
|
99
|
+
missingLocal,
|
|
100
|
+
added,
|
|
101
|
+
total: Object.keys(central).length,
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
const configArgIndex = process.argv.indexOf("-c");
|
|
105
|
+
const configPath = configArgIndex >= 0 ? process.argv[configArgIndex + 1] : undefined;
|
|
106
|
+
const result = syncMetaFromLocal(configPath);
|
|
107
|
+
console.log(`Synced ${getConfig().metaFile} from local album meta.json files.`);
|
|
108
|
+
console.log(` updated: ${result.updated}`);
|
|
109
|
+
console.log(` unchanged: ${result.unchanged}`);
|
|
110
|
+
console.log(` no local meta: ${result.missingLocal}`);
|
|
111
|
+
console.log(` added: ${result.added}`);
|
|
112
|
+
console.log(` total entries: ${result.total}`);
|
|
113
|
+
//# sourceMappingURL=syncMetaFromLocal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syncMetaFromLocal.js","sourceRoot":"","sources":["../src/syncMetaFromLocal.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emgeebee/music_downcoder",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "Scan music libraries and generate ffmpeg conversion scripts with a CLI or web UI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
"list": "find ./cmd/**/*.sh -type f 2>/dev/null | sort -nr",
|
|
20
20
|
"convert": "./batch.sh",
|
|
21
21
|
"clean-empty": "tsx src/cleanEmptyFolders.ts -c docker/conf.local.json",
|
|
22
|
+
"sync-meta": "tsx src/syncMetaFromLocal.ts -c docker/conf.local.json",
|
|
23
|
+
"repair-meta-years": "tsx src/repairMetaYears.ts -c docker/conf.local.json",
|
|
22
24
|
"type-check": "tsc --noEmit"
|
|
23
25
|
},
|
|
24
26
|
"dependencies": {
|