@groovenet/cli 2.0.0 → 2.2.0
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/README.md +27 -0
- package/build/bin/groovenet.js +4 -0
- package/build/bin/groovenet.js.map +1 -1
- package/build/commands/albums.d.ts.map +1 -1
- package/build/commands/albums.js +7 -6
- package/build/commands/albums.js.map +1 -1
- package/build/commands/fingerprintLibrary.d.ts +74 -0
- package/build/commands/fingerprintLibrary.d.ts.map +1 -0
- package/build/commands/fingerprintLibrary.js +166 -0
- package/build/commands/fingerprintLibrary.js.map +1 -0
- package/build/commands/tracks.d.ts.map +1 -1
- package/build/commands/tracks.js +12 -11
- package/build/commands/tracks.js.map +1 -1
- package/build/commands/vinyl.d.ts +23 -0
- package/build/commands/vinyl.d.ts.map +1 -0
- package/build/commands/vinyl.js +229 -0
- package/build/commands/vinyl.js.map +1 -0
- package/build/options.d.ts +20 -0
- package/build/options.d.ts.map +1 -0
- package/build/options.js +35 -0
- package/build/options.js.map +1 -0
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -27,6 +27,7 @@ groovenet albums search "kind of blue" # browse albums
|
|
|
27
27
|
groovenet playlists list # list playlists
|
|
28
28
|
groovenet friends list # manage the friends system
|
|
29
29
|
groovenet play <track-id> # play a track via MPD on the server
|
|
30
|
+
groovenet fingerprint-library # index reference audio for matching
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
Every command accepts `--json` for machine-readable output:
|
|
@@ -46,6 +47,32 @@ Run `groovenet --help` (or `groovenet <command> --help`) for the full command re
|
|
|
46
47
|
| `albums` | Browse and manage albums |
|
|
47
48
|
| `playlists` | Manage playlists |
|
|
48
49
|
| `friends` | Manage the friends system |
|
|
50
|
+
| `fingerprint-library` | Build the reference fingerprint index used to recognise vinyl as it plays |
|
|
51
|
+
|
|
52
|
+
### fingerprint-library
|
|
53
|
+
|
|
54
|
+
Fingerprints the library's reference audio so live vinyl playback can be
|
|
55
|
+
recognised against it. Safe to re-run: each track's audio is hashed and skipped
|
|
56
|
+
when nothing has changed.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
groovenet fingerprint-library # only tracks not yet indexed
|
|
60
|
+
groovenet fingerprint-library --changed # re-check already-indexed files
|
|
61
|
+
groovenet fingerprint-library --all --force # regenerate everything
|
|
62
|
+
groovenet fingerprint-library --track 12345-1 # one track
|
|
63
|
+
groovenet fingerprint-library --release 12345 # one release
|
|
64
|
+
groovenet fingerprint-library --no-wait # queue it and return
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
Indexing missing — chromaprint 1
|
|
69
|
+
3653 queued, 241 without reference audio
|
|
70
|
+
✗ 12345-2: ffmpeg exited 1: Invalid data found when processing input
|
|
71
|
+
✓ 3412 indexed ⤼ 0 skipped ✗ 2 failed – 241 no audio
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Tracks with no local audio are counted, not failed — only the part of the
|
|
75
|
+
library you have downloaded can be fingerprinted. Exits 1 if any track failed.
|
|
49
76
|
|
|
50
77
|
## Related
|
|
51
78
|
|
package/build/bin/groovenet.js
CHANGED
|
@@ -6,6 +6,8 @@ import { addTracksCommands } from "../commands/tracks.js";
|
|
|
6
6
|
import { addAlbumsCommands } from "../commands/albums.js";
|
|
7
7
|
import { addPlaylistsCommands } from "../commands/playlists.js";
|
|
8
8
|
import { addFriendsCommands } from "../commands/friends.js";
|
|
9
|
+
import { addFingerprintLibraryCommand } from "../commands/fingerprintLibrary.js";
|
|
10
|
+
import { addVinylCommands } from "../commands/vinyl.js";
|
|
9
11
|
const require = createRequire(import.meta.url);
|
|
10
12
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
11
13
|
const { version } = require("../../package.json");
|
|
@@ -19,6 +21,8 @@ addTracksCommands(program);
|
|
|
19
21
|
addAlbumsCommands(program);
|
|
20
22
|
addPlaylistsCommands(program);
|
|
21
23
|
addFriendsCommands(program);
|
|
24
|
+
addFingerprintLibraryCommand(program);
|
|
25
|
+
addVinylCommands(program);
|
|
22
26
|
program.parseAsync(process.argv).catch((err) => {
|
|
23
27
|
process.stderr.write(`Fatal: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
24
28
|
process.exit(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groovenet.js","sourceRoot":"","sources":["../../src/bin/groovenet.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"groovenet.js","sourceRoot":"","sources":["../../src/bin/groovenet.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,sEAAsE;AACtE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEzE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,sCAAsC,CAAC;KACnD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,4BAA4B,CAAC,OAAO,CAAC,CAAC;AACtC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAE1B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC/D,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"albums.d.ts","sourceRoot":"","sources":["../../src/commands/albums.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"albums.d.ts","sourceRoot":"","sources":["../../src/commands/albums.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmDpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwJxD"}
|
package/build/commands/albums.js
CHANGED
|
@@ -2,6 +2,7 @@ import { GroovenetClient, loadConfig } from "@groovenet/client";
|
|
|
2
2
|
import Table from "cli-table3";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { printJson, printSuccess, printError, printTracks } from "../output.js";
|
|
5
|
+
import { intOption } from "../options.js";
|
|
5
6
|
function makeClient() {
|
|
6
7
|
const cfg = loadConfig();
|
|
7
8
|
return new GroovenetClient({ baseUrl: cfg.api_base, apiKey: cfg.api_key, insecureTls: cfg.insecure_tls });
|
|
@@ -49,9 +50,9 @@ export function addAlbumsCommands(program) {
|
|
|
49
50
|
.description("Search/list albums")
|
|
50
51
|
.argument("[query]", "Search query", "")
|
|
51
52
|
.option("--sort <s>", "Sort (created_at:desc, date_added:desc, year:desc, title:asc, album_rating:desc)", "created_at:desc")
|
|
52
|
-
.option("--limit <n>", "Number of results",
|
|
53
|
-
.option("--offset <n>", "Offset",
|
|
54
|
-
.option("--friend-id <n>", "Friend ID",
|
|
53
|
+
.option("--limit <n>", "Number of results", intOption, 20)
|
|
54
|
+
.option("--offset <n>", "Offset", intOption, 0)
|
|
55
|
+
.option("--friend-id <n>", "Friend ID", intOption)
|
|
55
56
|
.option("--json", "Output as JSON")
|
|
56
57
|
.action(async (query, opts) => {
|
|
57
58
|
try {
|
|
@@ -82,7 +83,7 @@ export function addAlbumsCommands(program) {
|
|
|
82
83
|
albums
|
|
83
84
|
.command("show <release-id>")
|
|
84
85
|
.description("Show album details and track list")
|
|
85
|
-
.option("--friend-id <n>", "Friend ID",
|
|
86
|
+
.option("--friend-id <n>", "Friend ID", intOption)
|
|
86
87
|
.option("--json", "Output as JSON")
|
|
87
88
|
.action(async (releaseId, opts) => {
|
|
88
89
|
try {
|
|
@@ -123,7 +124,7 @@ export function addAlbumsCommands(program) {
|
|
|
123
124
|
albums
|
|
124
125
|
.command("update <release-id>")
|
|
125
126
|
.description("Update album metadata")
|
|
126
|
-
.option("--friend-id <n>", "Friend ID",
|
|
127
|
+
.option("--friend-id <n>", "Friend ID", intOption)
|
|
127
128
|
.option("--rating <n>", "Album rating (0-5)", parseFloat)
|
|
128
129
|
.option("--notes <text>", "Album notes")
|
|
129
130
|
.option("--price <n>", "Purchase price", parseFloat)
|
|
@@ -159,7 +160,7 @@ export function addAlbumsCommands(program) {
|
|
|
159
160
|
albums
|
|
160
161
|
.command("download <release-id>")
|
|
161
162
|
.description("Queue all missing tracks in an album for download")
|
|
162
|
-
.option("--friend-id <n>", "Friend ID",
|
|
163
|
+
.option("--friend-id <n>", "Friend ID", intOption)
|
|
163
164
|
.action(async (releaseId, opts) => {
|
|
164
165
|
try {
|
|
165
166
|
const client = makeClient();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"albums.js","sourceRoot":"","sources":["../../src/commands/albums.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEhE,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"albums.js","sourceRoot":"","sources":["../../src/commands/albums.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { GroovenetClient } from "@groovenet/client";
|
|
3
|
+
import type { FingerprintIndexRequest, FingerprintIndexRun } from "@groovenet/client";
|
|
4
|
+
export declare function makeClient(): GroovenetClient;
|
|
5
|
+
/** Just enough of the client for one run, so a test can pass two functions. */
|
|
6
|
+
export type FingerprintLibraryClient = Pick<GroovenetClient, "startFingerprintIndex" | "getFingerprintIndexRun">;
|
|
7
|
+
/**
|
|
8
|
+
* Where the command's output goes.
|
|
9
|
+
*
|
|
10
|
+
* Injected rather than reaching for `console` and `process.stdout` directly, so
|
|
11
|
+
* the whole run — header, per-failure lines, the rewritten progress line and
|
|
12
|
+
* the summary — can be asserted without a terminal.
|
|
13
|
+
*/
|
|
14
|
+
export interface FingerprintLibraryIO {
|
|
15
|
+
/** A whole line, newline appended. */
|
|
16
|
+
log: (line: string) => void;
|
|
17
|
+
/** Raw, no newline — the progress line rewrites itself with \r. */
|
|
18
|
+
write: (text: string) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare const consoleIO: FingerprintLibraryIO;
|
|
21
|
+
export interface FingerprintLibraryOptions {
|
|
22
|
+
missing?: boolean;
|
|
23
|
+
changed?: boolean;
|
|
24
|
+
all?: boolean;
|
|
25
|
+
track?: string;
|
|
26
|
+
release?: string;
|
|
27
|
+
friendId?: number;
|
|
28
|
+
force?: boolean;
|
|
29
|
+
wait?: boolean;
|
|
30
|
+
pollInterval?: number;
|
|
31
|
+
json?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Turn the scope flags into one request.
|
|
35
|
+
*
|
|
36
|
+
* Exactly one scope, so `--missing --all` is refused rather than silently
|
|
37
|
+
* resolved to whichever the parser happened to see last. With no scope flag at
|
|
38
|
+
* all it is `--missing`: the cheap, common case, since the alternatives re-read
|
|
39
|
+
* and re-hash every already-indexed file.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resolveScope(opts: FingerprintLibraryOptions): FingerprintIndexRequest;
|
|
42
|
+
/** How many of the queued tracks have reached a terminal state. */
|
|
43
|
+
export declare function settledCount(run: FingerprintIndexRun): number;
|
|
44
|
+
/** `indexing 3412/3653 ██████████░░` — one line, rewritten in place. */
|
|
45
|
+
export declare function formatProgress(run: FingerprintIndexRun, width?: number): string;
|
|
46
|
+
/**
|
|
47
|
+
* The four counters the run reports.
|
|
48
|
+
*
|
|
49
|
+
* `unindexable` is listed apart from `failed` on purpose: a track with no
|
|
50
|
+
* `local_audio_url` has no reference audio to fingerprint, which is a fact
|
|
51
|
+
* about how much of the library has been downloaded, not a failure of the run.
|
|
52
|
+
*/
|
|
53
|
+
export declare function formatSummary(run: FingerprintIndexRun): string;
|
|
54
|
+
/**
|
|
55
|
+
* Poll until every queued track has settled.
|
|
56
|
+
*
|
|
57
|
+
* `onProgress` is called with each poll so the caller owns the rendering — the
|
|
58
|
+
* loop itself stays testable without a terminal.
|
|
59
|
+
*/
|
|
60
|
+
export declare function waitForRun(client: Pick<GroovenetClient, "getFingerprintIndexRun">, runId: string, opts: {
|
|
61
|
+
pollIntervalMs: number;
|
|
62
|
+
onProgress?: (run: FingerprintIndexRun) => void;
|
|
63
|
+
}): Promise<FingerprintIndexRun>;
|
|
64
|
+
/**
|
|
65
|
+
* One `fingerprint-library` run, start to finish. Returns the process exit
|
|
66
|
+
* code: non-zero when any track failed, so the command composes in a script.
|
|
67
|
+
*
|
|
68
|
+
* Separate from the commander wiring because everything interesting happens
|
|
69
|
+
* here — scope resolution, the two output modes, the polling and the exit code
|
|
70
|
+
* — and a commander action is not callable from a test.
|
|
71
|
+
*/
|
|
72
|
+
export declare function runFingerprintLibrary(client: FingerprintLibraryClient, opts: FingerprintLibraryOptions, io?: FingerprintLibraryIO): Promise<number>;
|
|
73
|
+
export declare function addFingerprintLibraryCommand(program: Command): void;
|
|
74
|
+
//# sourceMappingURL=fingerprintLibrary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprintLibrary.d.ts","sourceRoot":"","sources":["../../src/commands/fingerprintLibrary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAc,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAKtF,wBAAgB,UAAU,IAAI,eAAe,CAO5C;AAED,+EAA+E;AAC/E,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,eAAe,EACf,uBAAuB,GAAG,wBAAwB,CACnD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,mEAAmE;IACnE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,SAAS,EAAE,oBAGvB,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,yBAAyB,GAC9B,uBAAuB,CAwBzB;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAE7D;AAED,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,GAAG,EAAE,mBAAmB,EAAE,KAAK,SAAK,GAAG,MAAM,CAM3E;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAQ9D;AAMD;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,wBAAwB,CAAC,EACvD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,IAAI,CAAA;CAAE,GAChF,OAAO,CAAC,mBAAmB,CAAC,CAO9B;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,wBAAwB,EAChC,IAAI,EAAE,yBAAyB,EAC/B,EAAE,GAAE,oBAAgC,GACnC,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwBnE"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { GroovenetClient, loadConfig } from "@groovenet/client";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { printError } from "../output.js";
|
|
4
|
+
import { intOption } from "../options.js";
|
|
5
|
+
export function makeClient() {
|
|
6
|
+
const cfg = loadConfig();
|
|
7
|
+
return new GroovenetClient({
|
|
8
|
+
baseUrl: cfg.api_base,
|
|
9
|
+
apiKey: cfg.api_key,
|
|
10
|
+
insecureTls: cfg.insecure_tls,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export const consoleIO = {
|
|
14
|
+
log: (line) => console.log(line),
|
|
15
|
+
write: (text) => process.stdout.write(text),
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Turn the scope flags into one request.
|
|
19
|
+
*
|
|
20
|
+
* Exactly one scope, so `--missing --all` is refused rather than silently
|
|
21
|
+
* resolved to whichever the parser happened to see last. With no scope flag at
|
|
22
|
+
* all it is `--missing`: the cheap, common case, since the alternatives re-read
|
|
23
|
+
* and re-hash every already-indexed file.
|
|
24
|
+
*/
|
|
25
|
+
export function resolveScope(opts) {
|
|
26
|
+
const chosen = [
|
|
27
|
+
opts.missing ? "missing" : null,
|
|
28
|
+
opts.changed ? "changed" : null,
|
|
29
|
+
opts.all ? "all" : null,
|
|
30
|
+
opts.track ? "track" : null,
|
|
31
|
+
opts.release ? "release" : null,
|
|
32
|
+
].filter((scope) => scope !== null);
|
|
33
|
+
if (chosen.length > 1) {
|
|
34
|
+
throw new Error(`Choose one scope, not ${chosen.length}: ${chosen.map((s) => `--${s}`).join(" ")}`);
|
|
35
|
+
}
|
|
36
|
+
const scope = (chosen[0] ?? "missing");
|
|
37
|
+
const request = { scope };
|
|
38
|
+
if (scope === "track")
|
|
39
|
+
request.track_id = opts.track;
|
|
40
|
+
if (scope === "release")
|
|
41
|
+
request.release_id = opts.release;
|
|
42
|
+
if (opts.friendId !== undefined)
|
|
43
|
+
request.friend_id = opts.friendId;
|
|
44
|
+
if (opts.force)
|
|
45
|
+
request.force = true;
|
|
46
|
+
return request;
|
|
47
|
+
}
|
|
48
|
+
/** How many of the queued tracks have reached a terminal state. */
|
|
49
|
+
export function settledCount(run) {
|
|
50
|
+
return run.indexed + run.skipped + run.failed;
|
|
51
|
+
}
|
|
52
|
+
/** `indexing 3412/3653 ██████████░░` — one line, rewritten in place. */
|
|
53
|
+
export function formatProgress(run, width = 24) {
|
|
54
|
+
const done = settledCount(run);
|
|
55
|
+
const ratio = run.queued > 0 ? Math.min(done / run.queued, 1) : 1;
|
|
56
|
+
const filled = Math.round(ratio * width);
|
|
57
|
+
const bar = "█".repeat(filled) + "░".repeat(width - filled);
|
|
58
|
+
return ` indexing ${done}/${run.queued} ${bar}`;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The four counters the run reports.
|
|
62
|
+
*
|
|
63
|
+
* `unindexable` is listed apart from `failed` on purpose: a track with no
|
|
64
|
+
* `local_audio_url` has no reference audio to fingerprint, which is a fact
|
|
65
|
+
* about how much of the library has been downloaded, not a failure of the run.
|
|
66
|
+
*/
|
|
67
|
+
export function formatSummary(run) {
|
|
68
|
+
const parts = [
|
|
69
|
+
chalk.green(`✓ ${run.indexed} indexed`),
|
|
70
|
+
chalk.gray(`⤼ ${run.skipped} skipped`),
|
|
71
|
+
run.failed > 0 ? chalk.red(`✗ ${run.failed} failed`) : chalk.gray("✗ 0 failed"),
|
|
72
|
+
chalk.gray(`– ${run.unindexable} no audio`),
|
|
73
|
+
];
|
|
74
|
+
return ` ${parts.join(" ")}`;
|
|
75
|
+
}
|
|
76
|
+
function sleep(ms) {
|
|
77
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Poll until every queued track has settled.
|
|
81
|
+
*
|
|
82
|
+
* `onProgress` is called with each poll so the caller owns the rendering — the
|
|
83
|
+
* loop itself stays testable without a terminal.
|
|
84
|
+
*/
|
|
85
|
+
export async function waitForRun(client, runId, opts) {
|
|
86
|
+
for (;;) {
|
|
87
|
+
const run = await client.getFingerprintIndexRun(runId);
|
|
88
|
+
opts.onProgress?.(run);
|
|
89
|
+
if (run.complete)
|
|
90
|
+
return run;
|
|
91
|
+
await sleep(opts.pollIntervalMs);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* One `fingerprint-library` run, start to finish. Returns the process exit
|
|
96
|
+
* code: non-zero when any track failed, so the command composes in a script.
|
|
97
|
+
*
|
|
98
|
+
* Separate from the commander wiring because everything interesting happens
|
|
99
|
+
* here — scope resolution, the two output modes, the polling and the exit code
|
|
100
|
+
* — and a commander action is not callable from a test.
|
|
101
|
+
*/
|
|
102
|
+
export async function runFingerprintLibrary(client, opts, io = consoleIO) {
|
|
103
|
+
const request = resolveScope(opts);
|
|
104
|
+
const started = await client.startFingerprintIndex(request);
|
|
105
|
+
if (!opts.json) {
|
|
106
|
+
io.log(chalk.bold(`Indexing ${started.scope}`) +
|
|
107
|
+
chalk.gray(` — ${started.fingerprint_type} ${started.fingerprint_version}`));
|
|
108
|
+
io.log(chalk.gray(` ${started.queued} queued, ${started.unindexable} without reference audio`));
|
|
109
|
+
}
|
|
110
|
+
if (!opts.wait) {
|
|
111
|
+
if (opts.json)
|
|
112
|
+
io.write(JSON.stringify(started, null, 2) + "\n");
|
|
113
|
+
else
|
|
114
|
+
io.log(chalk.gray(` run ${started.run_id}`));
|
|
115
|
+
return 0;
|
|
116
|
+
}
|
|
117
|
+
const seen = new Set();
|
|
118
|
+
const finished = await waitForRun(client, started.run_id, {
|
|
119
|
+
pollIntervalMs: opts.pollInterval ?? 1000,
|
|
120
|
+
onProgress: (run) => {
|
|
121
|
+
if (opts.json)
|
|
122
|
+
return;
|
|
123
|
+
// Failures scroll above the progress line as they happen, so a long run
|
|
124
|
+
// does not hide them until the very end.
|
|
125
|
+
for (const failure of run.errors) {
|
|
126
|
+
if (seen.has(failure))
|
|
127
|
+
continue;
|
|
128
|
+
seen.add(failure);
|
|
129
|
+
io.log(chalk.red(` ✗ ${failure}`));
|
|
130
|
+
}
|
|
131
|
+
io.write(`\r${formatProgress(run)}`);
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
if (opts.json) {
|
|
135
|
+
io.write(JSON.stringify(finished, null, 2) + "\n");
|
|
136
|
+
return finished.failed > 0 ? 1 : 0;
|
|
137
|
+
}
|
|
138
|
+
io.write("\r\x1b[2K");
|
|
139
|
+
io.log(formatSummary(finished));
|
|
140
|
+
return finished.failed > 0 ? 1 : 0;
|
|
141
|
+
}
|
|
142
|
+
export function addFingerprintLibraryCommand(program) {
|
|
143
|
+
program
|
|
144
|
+
.command("fingerprint-library")
|
|
145
|
+
.description("Build the reference fingerprint index the live vinyl matcher searches")
|
|
146
|
+
.option("--missing", "Only tracks with no fingerprint yet (default)")
|
|
147
|
+
.option("--changed", "Only tracks already indexed, re-checked for edits")
|
|
148
|
+
.option("--all", "Every track with reference audio")
|
|
149
|
+
.option("--track <id>", "One track")
|
|
150
|
+
.option("--release <id>", "Every track on one release")
|
|
151
|
+
.option("--friend-id <n>", "Narrow to one friend's library", intOption)
|
|
152
|
+
.option("--force", "Re-fingerprint even when the audio is unchanged")
|
|
153
|
+
.option("--no-wait", "Queue the run and exit without waiting")
|
|
154
|
+
.option("--poll-interval <ms>", "How often to poll progress", intOption, 1000)
|
|
155
|
+
.option("--json", "Output as JSON")
|
|
156
|
+
.action(async (opts) => {
|
|
157
|
+
try {
|
|
158
|
+
process.exitCode = await runFingerprintLibrary(makeClient(), opts);
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=fingerprintLibrary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprintLibrary.js","sourceRoot":"","sources":["../../src/commands/fingerprintLibrary.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracks.d.ts","sourceRoot":"","sources":["../../src/commands/tracks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"tracks.d.ts","sourceRoot":"","sources":["../../src/commands/tracks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuTxD"}
|
package/build/commands/tracks.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { GroovenetClient, loadConfig } from "@groovenet/client";
|
|
2
2
|
import { printTracks, printTrack, printJson, printSuccess, printError, } from "../output.js";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
+
import { intOption } from "../options.js";
|
|
4
5
|
function makeClient() {
|
|
5
6
|
const cfg = loadConfig();
|
|
6
7
|
return new GroovenetClient({ baseUrl: cfg.api_base, apiKey: cfg.api_key, insecureTls: cfg.insecure_tls });
|
|
@@ -14,7 +15,7 @@ export function addTracksCommands(program) {
|
|
|
14
15
|
.option("--bpm-max <n>", "Maximum BPM", parseFloat)
|
|
15
16
|
.option("--key <k>", "Musical key (e.g. 'A minor')")
|
|
16
17
|
.option("--rating <n>", "Filter by star rating (0-5)", parseFloat)
|
|
17
|
-
.option("--limit <n>", "Number of results",
|
|
18
|
+
.option("--limit <n>", "Number of results", intOption, 20)
|
|
18
19
|
.option("--json", "Output as JSON")
|
|
19
20
|
.action(async (query, opts) => {
|
|
20
21
|
try {
|
|
@@ -52,7 +53,7 @@ export function addTracksCommands(program) {
|
|
|
52
53
|
tracks
|
|
53
54
|
.command("show <id>")
|
|
54
55
|
.description("Show details for a track")
|
|
55
|
-
.option("--friend-id <n>", "Friend ID (defaults to config default_friend_id)",
|
|
56
|
+
.option("--friend-id <n>", "Friend ID (defaults to config default_friend_id)", intOption)
|
|
56
57
|
.option("--json", "Output as JSON")
|
|
57
58
|
.action(async (id, opts) => {
|
|
58
59
|
try {
|
|
@@ -109,8 +110,8 @@ export function addTracksCommands(program) {
|
|
|
109
110
|
tracks
|
|
110
111
|
.command("missing-apple-music")
|
|
111
112
|
.description("List tracks missing Apple Music URLs")
|
|
112
|
-
.option("--page <n>", "Page number",
|
|
113
|
-
.option("--page-size <n>", "Results per page",
|
|
113
|
+
.option("--page <n>", "Page number", intOption, 1)
|
|
114
|
+
.option("--page-size <n>", "Results per page", intOption, 50)
|
|
114
115
|
.option("--username <u>", "Username")
|
|
115
116
|
.option("--json", "Output as JSON")
|
|
116
117
|
.action(async (opts) => {
|
|
@@ -133,9 +134,9 @@ export function addTracksCommands(program) {
|
|
|
133
134
|
tracks
|
|
134
135
|
.command("deleted")
|
|
135
136
|
.description("List soft-deleted tracks")
|
|
136
|
-
.option("--friend-id <n>", "Filter by friend ID",
|
|
137
|
-
.option("--limit <n>", "Max results",
|
|
138
|
-
.option("--offset <n>", "Offset",
|
|
137
|
+
.option("--friend-id <n>", "Filter by friend ID", intOption)
|
|
138
|
+
.option("--limit <n>", "Max results", intOption, 100)
|
|
139
|
+
.option("--offset <n>", "Offset", intOption, 0)
|
|
139
140
|
.option("--json", "Output as JSON")
|
|
140
141
|
.action(async (opts) => {
|
|
141
142
|
try {
|
|
@@ -160,7 +161,7 @@ export function addTracksCommands(program) {
|
|
|
160
161
|
tracks
|
|
161
162
|
.command("restore <id>")
|
|
162
163
|
.description("Restore a soft-deleted track")
|
|
163
|
-
.option("--friend-id <n>", "Friend ID (defaults to config default_friend_id)",
|
|
164
|
+
.option("--friend-id <n>", "Friend ID (defaults to config default_friend_id)", intOption)
|
|
164
165
|
.action(async (id, opts) => {
|
|
165
166
|
try {
|
|
166
167
|
const cfg = loadConfig();
|
|
@@ -177,7 +178,7 @@ export function addTracksCommands(program) {
|
|
|
177
178
|
tracks
|
|
178
179
|
.command("recommend <id>")
|
|
179
180
|
.description("Get combined recommendations using both identity and audio vibe embeddings")
|
|
180
|
-
.option("--limit <n>", "Number of candidates to return",
|
|
181
|
+
.option("--limit <n>", "Number of candidates to return", intOption, 20)
|
|
181
182
|
.option("--json", "Output as JSON")
|
|
182
183
|
.action(async (id, opts) => {
|
|
183
184
|
try {
|
|
@@ -204,7 +205,7 @@ export function addTracksCommands(program) {
|
|
|
204
205
|
tracks
|
|
205
206
|
.command("similar-identity <id>")
|
|
206
207
|
.description("Find tracks with similar identity (genre, era, style, tags)")
|
|
207
|
-
.option("--limit <n>", "Number of results",
|
|
208
|
+
.option("--limit <n>", "Number of results", intOption, 10)
|
|
208
209
|
.option("--era <era>", "Filter by era (e.g. '1970s')")
|
|
209
210
|
.option("--country <country>", "Filter by country")
|
|
210
211
|
.option("--tags <tags>", "Comma-separated tags to filter by")
|
|
@@ -235,7 +236,7 @@ export function addTracksCommands(program) {
|
|
|
235
236
|
tracks
|
|
236
237
|
.command("similar-vibe <id>")
|
|
237
238
|
.description("Find tracks with similar audio vibe (BPM, mood, danceability)")
|
|
238
|
-
.option("--limit <n>", "Number of results",
|
|
239
|
+
.option("--limit <n>", "Number of results", intOption, 10)
|
|
239
240
|
.option("--json", "Output as JSON")
|
|
240
241
|
.action(async (id, opts) => {
|
|
241
242
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracks.js","sourceRoot":"","sources":["../../src/commands/tracks.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tracks.js","sourceRoot":"","sources":["../../src/commands/tracks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { GroovenetClient } from "@groovenet/client";
|
|
3
|
+
import type { DetectionWindow, IngestPipelineStats } from "@groovenet/client";
|
|
4
|
+
export declare function makeClient(): GroovenetClient;
|
|
5
|
+
/** `47.2s` → `0:47`, which is how anyone thinks about a position in a track. */
|
|
6
|
+
export declare function formatOffset(seconds: number | null): string;
|
|
7
|
+
/**
|
|
8
|
+
* One window as a line.
|
|
9
|
+
*
|
|
10
|
+
* A no-match is rendered plainly rather than as an error: it is the expected
|
|
11
|
+
* state between tracks, and colouring it red would train you to ignore red.
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatDetection(d: DetectionWindow): string[];
|
|
14
|
+
/**
|
|
15
|
+
* The health summary.
|
|
16
|
+
*
|
|
17
|
+
* Leads with the index because an empty one is the failure that looks like
|
|
18
|
+
* success: chunks arrive, decode, and are reported `processed`, every one of
|
|
19
|
+
* them matching nothing.
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatStats(s: IngestPipelineStats): string;
|
|
22
|
+
export declare function addVinylCommands(program: Command): void;
|
|
23
|
+
//# sourceMappingURL=vinyl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vinyl.d.ts","sourceRoot":"","sources":["../../src/commands/vinyl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAc,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EAEpB,MAAM,mBAAmB,CAAC;AAM3B,wBAAgB,UAAU,IAAI,eAAe,CAO5C;AAOD,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAI3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAY5D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,CA+D1D;AAoDD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0FvD"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { GroovenetClient, loadConfig } from "@groovenet/client";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import Table from "cli-table3";
|
|
4
|
+
import { printJson, printError } from "../output.js";
|
|
5
|
+
import { intOption } from "../options.js";
|
|
6
|
+
export function makeClient() {
|
|
7
|
+
const cfg = loadConfig();
|
|
8
|
+
return new GroovenetClient({
|
|
9
|
+
baseUrl: cfg.api_base,
|
|
10
|
+
apiKey: cfg.api_key,
|
|
11
|
+
insecureTls: cfg.insecure_tls,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function clock(iso) {
|
|
15
|
+
if (!iso)
|
|
16
|
+
return "—";
|
|
17
|
+
return new Date(iso).toLocaleTimeString();
|
|
18
|
+
}
|
|
19
|
+
/** `47.2s` → `0:47`, which is how anyone thinks about a position in a track. */
|
|
20
|
+
export function formatOffset(seconds) {
|
|
21
|
+
if (seconds === null)
|
|
22
|
+
return "—";
|
|
23
|
+
const whole = Math.floor(seconds);
|
|
24
|
+
return `${Math.floor(whole / 60)}:${String(whole % 60).padStart(2, "0")}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* One window as a line.
|
|
28
|
+
*
|
|
29
|
+
* A no-match is rendered plainly rather than as an error: it is the expected
|
|
30
|
+
* state between tracks, and colouring it red would train you to ignore red.
|
|
31
|
+
*/
|
|
32
|
+
export function formatDetection(d) {
|
|
33
|
+
if (!d.matched) {
|
|
34
|
+
return [clock(d.window_start_at), chalk.gray("no match"), "—", "—"];
|
|
35
|
+
}
|
|
36
|
+
const confidence = d.confidence ?? 0;
|
|
37
|
+
const paint = confidence >= 0.85 ? chalk.green : chalk.yellow;
|
|
38
|
+
return [
|
|
39
|
+
clock(d.window_start_at),
|
|
40
|
+
`${d.artist ?? "?"} — ${d.title ?? "?"}`,
|
|
41
|
+
paint(confidence.toFixed(3)),
|
|
42
|
+
formatOffset(d.offset_seconds),
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The health summary.
|
|
47
|
+
*
|
|
48
|
+
* Leads with the index because an empty one is the failure that looks like
|
|
49
|
+
* success: chunks arrive, decode, and are reported `processed`, every one of
|
|
50
|
+
* them matching nothing.
|
|
51
|
+
*/
|
|
52
|
+
export function formatStats(s) {
|
|
53
|
+
const lines = [];
|
|
54
|
+
if (!s.index.engine_registered) {
|
|
55
|
+
lines.push(chalk.red("✗ no fingerprint engine registered") +
|
|
56
|
+
chalk.gray(" — is fingerprint-service running?"));
|
|
57
|
+
}
|
|
58
|
+
else if (s.index.empty) {
|
|
59
|
+
lines.push(chalk.red("✗ reference index is EMPTY") +
|
|
60
|
+
chalk.gray(" — nothing can match; run `groovenet fingerprint-library`"));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
lines.push(chalk.green(`✓ index: ${s.index.indexed_tracks} tracks`) +
|
|
64
|
+
chalk.gray(` (${s.index.fingerprint_type} ${s.index.fingerprint_version})`));
|
|
65
|
+
}
|
|
66
|
+
const q = s.queue_depth;
|
|
67
|
+
lines.push(q === null
|
|
68
|
+
? chalk.yellow("? queue depth unavailable (redis unreachable)")
|
|
69
|
+
: chalk.gray(` queue depth: ${q}`));
|
|
70
|
+
const st = s.ingests.by_status;
|
|
71
|
+
const counts = Object.entries(st)
|
|
72
|
+
.map(([k, v]) => `${k} ${v}`)
|
|
73
|
+
.join(" ");
|
|
74
|
+
lines.push(chalk.gray(` ingests (${s.window_minutes}m): ${counts || "none"}`));
|
|
75
|
+
for (const f of s.ingests.failures) {
|
|
76
|
+
lines.push(chalk.red(` ✗ ${f.count}× ${f.error}`));
|
|
77
|
+
}
|
|
78
|
+
const d = s.detections;
|
|
79
|
+
if (d.windows === 0) {
|
|
80
|
+
lines.push(chalk.gray(" detections: none in this window"));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const rate = d.match_rate === null ? "—" : `${(d.match_rate * 100).toFixed(1)}%`;
|
|
84
|
+
lines.push(chalk.gray(` detections: ${d.windows} windows, ${d.matched} matched, ` +
|
|
85
|
+
`${d.no_match} no-match (${rate})`));
|
|
86
|
+
for (const b of d.confidence_bands) {
|
|
87
|
+
lines.push(chalk.gray(` ${b.band} ${b.count}`));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (s.ingests.oldest_in_flight) {
|
|
91
|
+
const o = s.ingests.oldest_in_flight;
|
|
92
|
+
lines.push(chalk.yellow(` oldest in flight: ${o.status} since ${clock(o.received_at)}`));
|
|
93
|
+
}
|
|
94
|
+
return lines.join("\n");
|
|
95
|
+
}
|
|
96
|
+
function printDetections(rows) {
|
|
97
|
+
if (rows.length === 0) {
|
|
98
|
+
console.log(chalk.yellow("No detections yet."));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const table = new Table({
|
|
102
|
+
head: [chalk.cyan("Time"), chalk.cyan("Track"), chalk.cyan("Conf"), chalk.cyan("At")],
|
|
103
|
+
colWidths: [12, 52, 8, 8],
|
|
104
|
+
wordWrap: true,
|
|
105
|
+
});
|
|
106
|
+
for (const row of rows)
|
|
107
|
+
table.push(formatDetection(row));
|
|
108
|
+
console.log(table.toString());
|
|
109
|
+
}
|
|
110
|
+
function printIngests(rows) {
|
|
111
|
+
if (rows.length === 0) {
|
|
112
|
+
console.log(chalk.yellow("No ingests yet — is the listener posting?"));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const table = new Table({
|
|
116
|
+
head: [
|
|
117
|
+
chalk.cyan("Received"),
|
|
118
|
+
chalk.cyan("Source"),
|
|
119
|
+
chalk.cyan("Seq"),
|
|
120
|
+
chalk.cyan("Status"),
|
|
121
|
+
chalk.cyan("Dur"),
|
|
122
|
+
chalk.cyan("Error"),
|
|
123
|
+
],
|
|
124
|
+
colWidths: [12, 20, 7, 12, 7, 34],
|
|
125
|
+
wordWrap: true,
|
|
126
|
+
});
|
|
127
|
+
for (const r of rows) {
|
|
128
|
+
const paint = r.status === "failed"
|
|
129
|
+
? chalk.red
|
|
130
|
+
: r.status === "processed"
|
|
131
|
+
? chalk.green
|
|
132
|
+
: chalk.yellow;
|
|
133
|
+
table.push([
|
|
134
|
+
clock(r.received_at),
|
|
135
|
+
r.source_id,
|
|
136
|
+
r.sequence ?? "—",
|
|
137
|
+
paint(r.status),
|
|
138
|
+
r.duration_seconds ? `${r.duration_seconds.toFixed(0)}s` : "—",
|
|
139
|
+
r.error ?? "",
|
|
140
|
+
]);
|
|
141
|
+
}
|
|
142
|
+
console.log(table.toString());
|
|
143
|
+
}
|
|
144
|
+
export function addVinylCommands(program) {
|
|
145
|
+
const vinyl = program
|
|
146
|
+
.command("vinyl")
|
|
147
|
+
.description("Inspect the automatic vinyl play tracking pipeline");
|
|
148
|
+
vinyl
|
|
149
|
+
.command("status")
|
|
150
|
+
.description("Is the pipeline working? Index, queue, ingests, match rate")
|
|
151
|
+
.option("--minutes <n>", "Window to summarise", intOption, 60)
|
|
152
|
+
.option("--source <id>", "Limit to one listener source")
|
|
153
|
+
.option("--json", "Output as JSON")
|
|
154
|
+
.action(async (opts) => {
|
|
155
|
+
try {
|
|
156
|
+
const stats = await makeClient().getIngestStats({
|
|
157
|
+
minutes: opts.minutes,
|
|
158
|
+
source_id: opts.source,
|
|
159
|
+
});
|
|
160
|
+
if (opts.json)
|
|
161
|
+
printJson(stats);
|
|
162
|
+
else
|
|
163
|
+
console.log(formatStats(stats));
|
|
164
|
+
// A pipeline that cannot match is a failure worth an exit code, so
|
|
165
|
+
// this composes in a health check.
|
|
166
|
+
if (!stats.index.engine_registered || stats.index.empty) {
|
|
167
|
+
process.exitCode = 1;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
vinyl
|
|
176
|
+
.command("detections")
|
|
177
|
+
.description("Recent matcher windows, including the no-match ones")
|
|
178
|
+
.option("--source <id>", "Limit to one listener source")
|
|
179
|
+
.option("--session <id>", "Limit to one listening session")
|
|
180
|
+
.option("--matched", "Only windows that matched something")
|
|
181
|
+
.option("--no-match", "Only windows that matched nothing")
|
|
182
|
+
.option("--limit <n>", "How many", intOption, 30)
|
|
183
|
+
.option("--json", "Output as JSON")
|
|
184
|
+
.action(async (opts) => {
|
|
185
|
+
try {
|
|
186
|
+
// commander turns --no-match into `match: false`.
|
|
187
|
+
const matched = opts.match === false ? false : opts.matched ? true : undefined;
|
|
188
|
+
const result = await makeClient().listDetections({
|
|
189
|
+
source_id: opts.source,
|
|
190
|
+
session_id: opts.session,
|
|
191
|
+
matched,
|
|
192
|
+
limit: opts.limit,
|
|
193
|
+
});
|
|
194
|
+
if (opts.json)
|
|
195
|
+
printJson(result);
|
|
196
|
+
else
|
|
197
|
+
printDetections(result.detections);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
vinyl
|
|
205
|
+
.command("ingests")
|
|
206
|
+
.description("Recent audio chunks and what became of them")
|
|
207
|
+
.option("--source <id>", "Limit to one listener source")
|
|
208
|
+
.option("--status <s>", "received | processing | processed | failed")
|
|
209
|
+
.option("--limit <n>", "How many", intOption, 30)
|
|
210
|
+
.option("--json", "Output as JSON")
|
|
211
|
+
.action(async (opts) => {
|
|
212
|
+
try {
|
|
213
|
+
const result = await makeClient().listIngests({
|
|
214
|
+
source_id: opts.source,
|
|
215
|
+
status: opts.status,
|
|
216
|
+
limit: opts.limit,
|
|
217
|
+
});
|
|
218
|
+
if (opts.json)
|
|
219
|
+
printJson(result);
|
|
220
|
+
else
|
|
221
|
+
printIngests(result.ingests);
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=vinyl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vinyl.js","sourceRoot":"","sources":["../../src/commands/vinyl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a numeric option.
|
|
3
|
+
*
|
|
4
|
+
* Commander calls a coercion function as `(value, previous)`, so passing bare
|
|
5
|
+
* `parseInt` alongside a default silently turns that default into the **radix**:
|
|
6
|
+
*
|
|
7
|
+
* .option("--limit <n>", "…", parseInt, 20) // parseInt("15", 20) === 25
|
|
8
|
+
* .option("--minutes <n>", "…", parseInt, 60) // radix out of range -> NaN
|
|
9
|
+
*
|
|
10
|
+
* Neither fails loudly. The first quietly returns the wrong number of results,
|
|
11
|
+
* the second yields NaN and whatever that does downstream — `setTimeout(NaN)`
|
|
12
|
+
* fires immediately, so a poll interval becomes a busy loop.
|
|
13
|
+
*
|
|
14
|
+
* This ignores `previous`, parses base 10, and rejects nonsense outright rather
|
|
15
|
+
* than letting NaN travel.
|
|
16
|
+
*/
|
|
17
|
+
export declare function intOption(value: string): number;
|
|
18
|
+
/** `intOption`, refusing anything below `min` (default 0). */
|
|
19
|
+
export declare function boundedIntOption(min?: number): (value: string) => number;
|
|
20
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,GAAG,SAAI,WACvB,MAAM,KAAG,MAAM,CAO/B"}
|
package/build/options.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { InvalidArgumentError } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* Parse a numeric option.
|
|
4
|
+
*
|
|
5
|
+
* Commander calls a coercion function as `(value, previous)`, so passing bare
|
|
6
|
+
* `parseInt` alongside a default silently turns that default into the **radix**:
|
|
7
|
+
*
|
|
8
|
+
* .option("--limit <n>", "…", parseInt, 20) // parseInt("15", 20) === 25
|
|
9
|
+
* .option("--minutes <n>", "…", parseInt, 60) // radix out of range -> NaN
|
|
10
|
+
*
|
|
11
|
+
* Neither fails loudly. The first quietly returns the wrong number of results,
|
|
12
|
+
* the second yields NaN and whatever that does downstream — `setTimeout(NaN)`
|
|
13
|
+
* fires immediately, so a poll interval becomes a busy loop.
|
|
14
|
+
*
|
|
15
|
+
* This ignores `previous`, parses base 10, and rejects nonsense outright rather
|
|
16
|
+
* than letting NaN travel.
|
|
17
|
+
*/
|
|
18
|
+
export function intOption(value) {
|
|
19
|
+
const parsed = Number.parseInt(value, 10);
|
|
20
|
+
if (Number.isNaN(parsed)) {
|
|
21
|
+
throw new InvalidArgumentError("expected a number");
|
|
22
|
+
}
|
|
23
|
+
return parsed;
|
|
24
|
+
}
|
|
25
|
+
/** `intOption`, refusing anything below `min` (default 0). */
|
|
26
|
+
export function boundedIntOption(min = 0) {
|
|
27
|
+
return (value) => {
|
|
28
|
+
const parsed = intOption(value);
|
|
29
|
+
if (parsed < min) {
|
|
30
|
+
throw new InvalidArgumentError(`must be ${min} or greater`);
|
|
31
|
+
}
|
|
32
|
+
return parsed;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAAC,GAAG,GAAG,CAAC;IACtC,OAAO,CAAC,KAAa,EAAU,EAAE;QAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,oBAAoB,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@groovenet/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "CLI for managing your Groovenet DJ collection",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc",
|
|
14
14
|
"dev": "tsc --watch",
|
|
15
|
-
"start": "node build/bin/groovenet.js"
|
|
15
|
+
"start": "node build/bin/groovenet.js",
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"test:coverage": "vitest run --coverage --coverage.reporter=lcov",
|
|
18
|
+
"test:watch": "vitest"
|
|
16
19
|
},
|
|
17
20
|
"files": [
|
|
18
21
|
"build/"
|
|
@@ -36,13 +39,15 @@
|
|
|
36
39
|
"homepage": "https://github.com/Public-Vinyl-Radio/groovenet/tree/main/packages/groovenet-cli#readme",
|
|
37
40
|
"bugs": "https://github.com/Public-Vinyl-Radio/groovenet/issues",
|
|
38
41
|
"dependencies": {
|
|
39
|
-
"@groovenet/client": "^2.
|
|
42
|
+
"@groovenet/client": "^2.2.0",
|
|
40
43
|
"chalk": "^6",
|
|
41
44
|
"cli-table3": "^0.6",
|
|
42
45
|
"commander": "^15"
|
|
43
46
|
},
|
|
44
47
|
"devDependencies": {
|
|
45
48
|
"@types/node": "^26.4.1",
|
|
46
|
-
"
|
|
49
|
+
"@vitest/coverage-v8": "^5.0.0",
|
|
50
|
+
"typescript": "^7.0",
|
|
51
|
+
"vitest": "^5.0.0"
|
|
47
52
|
}
|
|
48
53
|
}
|