@psychout98/tadaima 1.0.2 → 1.0.4
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/chunk-6O3GWKMO.js +16979 -0
- package/dist/chunk-7TPZ4T2V.js +37 -0
- package/dist/chunk-KDW3UEKL.js +105 -0
- package/dist/config-YQZEYLLR.js +7 -0
- package/dist/daemon-YZQZNLEX.js +14 -0
- package/dist/download-handler-R6AJCG4O.js +462 -0
- package/dist/index.js +253 -257
- package/dist/logger-XTDECBFK.js +85 -0
- package/dist/service-GBG6YHQW.js +199 -0
- package/dist/setup-OLV7C7ON.js +100 -0
- package/dist/status-writer-RGH2PULB.js +31 -0
- package/dist/tui-ZE4672PT.js +77 -0
- package/dist/updater-HXBNBU36.js +163 -0
- package/dist/ws-client-CLD6QAFC.js +178 -0
- package/package.json +6 -5
- package/dist/config.d.ts +0 -23
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -25
- package/dist/config.js.map +0 -1
- package/dist/daemon.d.ts +0 -8
- package/dist/daemon.d.ts.map +0 -1
- package/dist/daemon.js +0 -91
- package/dist/daemon.js.map +0 -1
- package/dist/download-handler.d.ts +0 -15
- package/dist/download-handler.d.ts.map +0 -1
- package/dist/download-handler.js +0 -203
- package/dist/download-handler.js.map +0 -1
- package/dist/downloader.d.ts +0 -11
- package/dist/downloader.d.ts.map +0 -1
- package/dist/downloader.js +0 -65
- package/dist/downloader.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/logger.d.ts +0 -2
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -74
- package/dist/logger.js.map +0 -1
- package/dist/organizer.d.ts +0 -12
- package/dist/organizer.d.ts.map +0 -1
- package/dist/organizer.js +0 -42
- package/dist/organizer.js.map +0 -1
- package/dist/rd-client.d.ts +0 -25
- package/dist/rd-client.d.ts.map +0 -1
- package/dist/rd-client.js +0 -129
- package/dist/rd-client.js.map +0 -1
- package/dist/service.d.ts +0 -3
- package/dist/service.d.ts.map +0 -1
- package/dist/service.js +0 -187
- package/dist/service.js.map +0 -1
- package/dist/setup.d.ts +0 -2
- package/dist/setup.d.ts.map +0 -1
- package/dist/setup.js +0 -92
- package/dist/setup.js.map +0 -1
- package/dist/status-writer.d.ts +0 -20
- package/dist/status-writer.d.ts.map +0 -1
- package/dist/status-writer.js +0 -34
- package/dist/status-writer.js.map +0 -1
- package/dist/tui.d.ts +0 -14
- package/dist/tui.d.ts.map +0 -1
- package/dist/tui.js +0 -73
- package/dist/tui.js.map +0 -1
- package/dist/updater.d.ts +0 -27
- package/dist/updater.d.ts.map +0 -1
- package/dist/updater.js +0 -191
- package/dist/updater.js.map +0 -1
- package/dist/ws-client.d.ts +0 -26
- package/dist/ws-client.d.ts.map +0 -1
- package/dist/ws-client.js +0 -155
- package/dist/ws-client.js.map +0 -1
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
createMessageId,
|
|
4
|
+
createTimestamp
|
|
5
|
+
} from "./chunk-6O3GWKMO.js";
|
|
6
|
+
import {
|
|
7
|
+
config
|
|
8
|
+
} from "./chunk-7TPZ4T2V.js";
|
|
9
|
+
|
|
10
|
+
// src/ws-client.ts
|
|
11
|
+
import WebSocket from "ws";
|
|
12
|
+
import { platform } from "os";
|
|
13
|
+
import { statfs } from "fs/promises";
|
|
14
|
+
var HEARTBEAT_INTERVAL = 3e4;
|
|
15
|
+
var MAX_BACKOFF = 3e4;
|
|
16
|
+
async function getDiskFreeBytes(dirPath) {
|
|
17
|
+
try {
|
|
18
|
+
const stats = await statfs(dirPath);
|
|
19
|
+
return stats.bavail * stats.bsize;
|
|
20
|
+
} catch {
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
var AgentWebSocket = class {
|
|
25
|
+
ws = null;
|
|
26
|
+
backoff = 1e3;
|
|
27
|
+
heartbeatTimer = null;
|
|
28
|
+
reconnectTimer = null;
|
|
29
|
+
messageQueue = [];
|
|
30
|
+
onMessage = null;
|
|
31
|
+
stopped = false;
|
|
32
|
+
startTime = Date.now();
|
|
33
|
+
activeJobs = 0;
|
|
34
|
+
mediaDir;
|
|
35
|
+
constructor() {
|
|
36
|
+
this.mediaDir = config.get("directories.movies") || config.get("directories.tv") || "/";
|
|
37
|
+
}
|
|
38
|
+
connect() {
|
|
39
|
+
this.stopped = false;
|
|
40
|
+
const relayUrl = config.get("relay");
|
|
41
|
+
const deviceToken = config.get("deviceToken");
|
|
42
|
+
if (!relayUrl || !deviceToken) {
|
|
43
|
+
console.error("Not configured. Run `tadaima-agent setup` first.");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const wsUrl = relayUrl.replace(/^http/, "ws").replace(/\/$/, "");
|
|
47
|
+
const url = `${wsUrl}/ws/agent?token=${deviceToken}`;
|
|
48
|
+
this.ws = new WebSocket(url);
|
|
49
|
+
this.ws.on("open", () => {
|
|
50
|
+
console.log("Connected to relay");
|
|
51
|
+
this.backoff = 1e3;
|
|
52
|
+
this.sendHello().catch(() => {
|
|
53
|
+
});
|
|
54
|
+
this.startHeartbeat();
|
|
55
|
+
this.drainQueue();
|
|
56
|
+
});
|
|
57
|
+
this.ws.on("message", (data) => {
|
|
58
|
+
try {
|
|
59
|
+
const msg = JSON.parse(data.toString());
|
|
60
|
+
if (this.onMessage) {
|
|
61
|
+
this.onMessage(msg);
|
|
62
|
+
}
|
|
63
|
+
} catch (err) {
|
|
64
|
+
const raw = data.toString().slice(0, 200);
|
|
65
|
+
console.error("Failed to parse WebSocket message:", err, "raw:", raw);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
this.ws.on("close", () => {
|
|
69
|
+
console.log("Disconnected from relay");
|
|
70
|
+
this.cleanup();
|
|
71
|
+
this.scheduleReconnect();
|
|
72
|
+
});
|
|
73
|
+
this.ws.on("error", (err) => {
|
|
74
|
+
console.error("WebSocket error:", err.message);
|
|
75
|
+
this.cleanup();
|
|
76
|
+
this.scheduleReconnect();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
stop() {
|
|
80
|
+
this.stopped = true;
|
|
81
|
+
this.cleanup();
|
|
82
|
+
if (this.ws) {
|
|
83
|
+
this.ws.close(1e3, "Agent stopped");
|
|
84
|
+
this.ws = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
setMessageHandler(handler) {
|
|
88
|
+
this.onMessage = handler;
|
|
89
|
+
}
|
|
90
|
+
send(message) {
|
|
91
|
+
const data = JSON.stringify(message);
|
|
92
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
93
|
+
try {
|
|
94
|
+
this.ws.send(data);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error("Send failed, re-queuing message:", err);
|
|
97
|
+
this.messageQueue.push(data);
|
|
98
|
+
this.cleanup();
|
|
99
|
+
this.scheduleReconnect();
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
this.messageQueue.push(data);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
setActiveJobs(count) {
|
|
106
|
+
this.activeJobs = count;
|
|
107
|
+
}
|
|
108
|
+
async sendHello() {
|
|
109
|
+
this.send({
|
|
110
|
+
id: createMessageId(),
|
|
111
|
+
type: "agent:hello",
|
|
112
|
+
timestamp: createTimestamp(),
|
|
113
|
+
payload: {
|
|
114
|
+
version: "0.0.0",
|
|
115
|
+
platform: platform(),
|
|
116
|
+
activeJobs: this.activeJobs,
|
|
117
|
+
diskFreeBytes: await getDiskFreeBytes(this.mediaDir)
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async sendHeartbeat() {
|
|
122
|
+
this.send({
|
|
123
|
+
id: createMessageId(),
|
|
124
|
+
type: "agent:heartbeat",
|
|
125
|
+
timestamp: createTimestamp(),
|
|
126
|
+
payload: {
|
|
127
|
+
activeJobs: this.activeJobs,
|
|
128
|
+
diskFreeBytes: await getDiskFreeBytes(this.mediaDir),
|
|
129
|
+
uptimeSeconds: Math.floor((Date.now() - this.startTime) / 1e3)
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
startHeartbeat() {
|
|
134
|
+
this.stopHeartbeat();
|
|
135
|
+
this.heartbeatTimer = setInterval(
|
|
136
|
+
() => {
|
|
137
|
+
this.sendHeartbeat().catch(() => {
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
HEARTBEAT_INTERVAL
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
stopHeartbeat() {
|
|
144
|
+
if (this.heartbeatTimer) {
|
|
145
|
+
clearInterval(this.heartbeatTimer);
|
|
146
|
+
this.heartbeatTimer = null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
drainQueue() {
|
|
150
|
+
while (this.messageQueue.length > 0 && this.ws?.readyState === WebSocket.OPEN) {
|
|
151
|
+
try {
|
|
152
|
+
this.ws.send(this.messageQueue[0]);
|
|
153
|
+
this.messageQueue.shift();
|
|
154
|
+
} catch (err) {
|
|
155
|
+
console.error("Drain failed, will retry on reconnect:", err);
|
|
156
|
+
this.cleanup();
|
|
157
|
+
this.scheduleReconnect();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
cleanup() {
|
|
163
|
+
this.stopHeartbeat();
|
|
164
|
+
if (this.reconnectTimer) {
|
|
165
|
+
clearTimeout(this.reconnectTimer);
|
|
166
|
+
this.reconnectTimer = null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
scheduleReconnect() {
|
|
170
|
+
if (this.stopped) return;
|
|
171
|
+
this.backoff = Math.min(this.backoff * 2, MAX_BACKOFF);
|
|
172
|
+
console.log(`Reconnecting in ${this.backoff / 1e3}s...`);
|
|
173
|
+
this.reconnectTimer = setTimeout(() => this.connect(), this.backoff);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
export {
|
|
177
|
+
AgentWebSocket
|
|
178
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@psychout98/tadaima",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "CLI download agent for Tadaima — a self-hosted media download orchestrator",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,19 +40,20 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"conf": "^15.1.0",
|
|
42
42
|
"prompts": "^2.4.2",
|
|
43
|
-
"ws": "^8.20.0"
|
|
44
|
-
"@tadaima/shared": "0.0.0"
|
|
43
|
+
"ws": "^8.20.0"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
46
|
"@types/node": "^25.5.2",
|
|
48
47
|
"@types/prompts": "^2.4.9",
|
|
49
48
|
"@types/ws": "^8.18.1",
|
|
49
|
+
"tsup": "^8.0.0",
|
|
50
50
|
"tsx": "^4.19.0",
|
|
51
51
|
"typescript": "^5.7.0",
|
|
52
|
-
"vitest": "^4.1.2"
|
|
52
|
+
"vitest": "^4.1.2",
|
|
53
|
+
"@tadaima/shared": "0.0.0"
|
|
53
54
|
},
|
|
54
55
|
"scripts": {
|
|
55
|
-
"build": "
|
|
56
|
+
"build": "tsup",
|
|
56
57
|
"dev": "tsx watch src/index.ts",
|
|
57
58
|
"lint": "eslint src/ --ignore-pattern src/__tests__/",
|
|
58
59
|
"test": "vitest run",
|
package/dist/config.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import Conf from "conf";
|
|
2
|
-
export interface AgentConfig {
|
|
3
|
-
relay: string;
|
|
4
|
-
deviceToken: string;
|
|
5
|
-
deviceId: string;
|
|
6
|
-
deviceName: string;
|
|
7
|
-
profileName: string;
|
|
8
|
-
directories: {
|
|
9
|
-
movies: string;
|
|
10
|
-
tv: string;
|
|
11
|
-
staging: string;
|
|
12
|
-
};
|
|
13
|
-
realDebrid: {
|
|
14
|
-
apiKey: string;
|
|
15
|
-
};
|
|
16
|
-
maxConcurrentDownloads: number;
|
|
17
|
-
rdPollInterval: number;
|
|
18
|
-
lastUpdateCheck: string;
|
|
19
|
-
updateChannel: "stable";
|
|
20
|
-
previousBinaryPath: string;
|
|
21
|
-
}
|
|
22
|
-
export declare const config: Conf<AgentConfig>;
|
|
23
|
-
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,MAAM,EAAE,MAAM,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,QAAQ,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,MAAM,mBAsBjB,CAAC"}
|
package/dist/config.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import Conf from "conf";
|
|
2
|
-
export const config = new Conf({
|
|
3
|
-
projectName: "tadaima",
|
|
4
|
-
defaults: {
|
|
5
|
-
relay: "",
|
|
6
|
-
deviceToken: "",
|
|
7
|
-
deviceId: "",
|
|
8
|
-
deviceName: "",
|
|
9
|
-
profileName: "",
|
|
10
|
-
directories: {
|
|
11
|
-
movies: "",
|
|
12
|
-
tv: "",
|
|
13
|
-
staging: "",
|
|
14
|
-
},
|
|
15
|
-
realDebrid: {
|
|
16
|
-
apiKey: "",
|
|
17
|
-
},
|
|
18
|
-
maxConcurrentDownloads: 2,
|
|
19
|
-
rdPollInterval: 30,
|
|
20
|
-
lastUpdateCheck: "",
|
|
21
|
-
updateChannel: "stable",
|
|
22
|
-
previousBinaryPath: "",
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAuBxB,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAc;IAC1C,WAAW,EAAE,SAAS;IACtB,QAAQ,EAAE;QACR,KAAK,EAAE,EAAE;QACT,WAAW,EAAE,EAAE;QACf,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,EAAE;QACd,WAAW,EAAE,EAAE;QACf,WAAW,EAAE;YACX,MAAM,EAAE,EAAE;YACV,EAAE,EAAE,EAAE;YACN,OAAO,EAAE,EAAE;SACZ;QACD,UAAU,EAAE;YACV,MAAM,EAAE,EAAE;SACX;QACD,sBAAsB,EAAE,CAAC;QACzB,cAAc,EAAE,EAAE;QAClB,eAAe,EAAE,EAAE;QACnB,aAAa,EAAE,QAAQ;QACvB,kBAAkB,EAAE,EAAE;KACvB;CACF,CAAC,CAAC"}
|
package/dist/daemon.d.ts
DELETED
package/dist/daemon.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAoBA,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,WAAW,IAAI,IAAI,CAsClC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAuBjC;AAED,wBAAgB,eAAe,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAqBpE"}
|
package/dist/daemon.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, unlinkSync, existsSync, mkdirSync, createWriteStream, } from "node:fs";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { spawn } from "node:child_process";
|
|
4
|
-
import { config } from "./config.js";
|
|
5
|
-
function getPidPath() {
|
|
6
|
-
return join(dirname(config.path), "tadaima.pid");
|
|
7
|
-
}
|
|
8
|
-
function getLogDir() {
|
|
9
|
-
return join(dirname(config.path), "logs");
|
|
10
|
-
}
|
|
11
|
-
export function getLogPath() {
|
|
12
|
-
return join(getLogDir(), "tadaima.log");
|
|
13
|
-
}
|
|
14
|
-
export function startDaemon() {
|
|
15
|
-
const pidPath = getPidPath();
|
|
16
|
-
if (existsSync(pidPath)) {
|
|
17
|
-
const oldPid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
18
|
-
if (Number.isNaN(oldPid)) {
|
|
19
|
-
console.log("Stale PID file (invalid contents). Removing.");
|
|
20
|
-
unlinkSync(pidPath);
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
try {
|
|
24
|
-
process.kill(oldPid, 0);
|
|
25
|
-
console.log(`Agent already running (PID ${oldPid})`);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
unlinkSync(pidPath);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
const logDir = getLogDir();
|
|
34
|
-
mkdirSync(logDir, { recursive: true });
|
|
35
|
-
const logPath = getLogPath();
|
|
36
|
-
const logStream = createWriteStream(logPath, { flags: "a" });
|
|
37
|
-
const child = spawn(process.execPath, [process.argv[1], "start"], {
|
|
38
|
-
detached: true,
|
|
39
|
-
stdio: ["ignore", logStream, logStream],
|
|
40
|
-
env: { ...process.env, TADAIMA_DAEMON: "1" },
|
|
41
|
-
});
|
|
42
|
-
child.unref();
|
|
43
|
-
if (child.pid) {
|
|
44
|
-
writeFileSync(pidPath, String(child.pid));
|
|
45
|
-
console.log(`Agent started in background (PID ${child.pid})`);
|
|
46
|
-
console.log(`Logs: ${logPath}`);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export function stopDaemon() {
|
|
50
|
-
const pidPath = getPidPath();
|
|
51
|
-
if (!existsSync(pidPath)) {
|
|
52
|
-
console.log("Agent is not running.");
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
56
|
-
if (Number.isNaN(pid)) {
|
|
57
|
-
console.log("Stale PID file (invalid contents). Removing.");
|
|
58
|
-
unlinkSync(pidPath);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
try {
|
|
62
|
-
process.kill(pid, "SIGTERM");
|
|
63
|
-
console.log(`Sent SIGTERM to PID ${pid}`);
|
|
64
|
-
unlinkSync(pidPath);
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
console.log(`Process ${pid} not found. Cleaning up PID file.`);
|
|
68
|
-
unlinkSync(pidPath);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
export function getDaemonStatus() {
|
|
72
|
-
const pidPath = getPidPath();
|
|
73
|
-
if (!existsSync(pidPath)) {
|
|
74
|
-
return { running: false };
|
|
75
|
-
}
|
|
76
|
-
const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
77
|
-
if (Number.isNaN(pid)) {
|
|
78
|
-
console.log("Stale PID file (invalid contents). Removing.");
|
|
79
|
-
unlinkSync(pidPath);
|
|
80
|
-
return { running: false };
|
|
81
|
-
}
|
|
82
|
-
try {
|
|
83
|
-
process.kill(pid, 0);
|
|
84
|
-
return { running: true, pid };
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
unlinkSync(pidPath);
|
|
88
|
-
return { running: false };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=daemon.js.map
|
package/dist/daemon.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { AgentWebSocket } from "./ws-client.js";
|
|
2
|
-
export declare class DownloadHandler {
|
|
3
|
-
private ws;
|
|
4
|
-
private activeJobs;
|
|
5
|
-
private semaphore;
|
|
6
|
-
constructor(ws: AgentWebSocket);
|
|
7
|
-
get activeCount(): number;
|
|
8
|
-
handleRequest(msg: Record<string, unknown>): Promise<void>;
|
|
9
|
-
handleCancel(msg: Record<string, unknown>): void;
|
|
10
|
-
handleCacheCheck(msg: Record<string, unknown>): Promise<void>;
|
|
11
|
-
private executeDownload;
|
|
12
|
-
private sendProgress;
|
|
13
|
-
private sendMessage;
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=download-handler.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"download-handler.d.ts","sourceRoot":"","sources":["../src/download-handler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAsBrD,qBAAa,eAAe;IAC1B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,SAAS,CAAS;gBAEd,EAAE,EAAE,cAAc;IAK9B,IAAI,WAAW,IAAI,MAAM,CAExB;IAEK,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA4EhE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAS1C,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAcrD,eAAe;IA0G7B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;CAQpB"}
|
package/dist/download-handler.js
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { rm } from "node:fs/promises";
|
|
3
|
-
import { createMessageId, createTimestamp } from "@tadaima/shared";
|
|
4
|
-
import { config } from "./config.js";
|
|
5
|
-
import { rdClient } from "./rd-client.js";
|
|
6
|
-
import { downloadFile } from "./downloader.js";
|
|
7
|
-
import { organizeFile } from "./organizer.js";
|
|
8
|
-
export class DownloadHandler {
|
|
9
|
-
ws;
|
|
10
|
-
activeJobs = new Map();
|
|
11
|
-
semaphore;
|
|
12
|
-
constructor(ws) {
|
|
13
|
-
this.ws = ws;
|
|
14
|
-
this.semaphore = config.get("maxConcurrentDownloads");
|
|
15
|
-
}
|
|
16
|
-
get activeCount() {
|
|
17
|
-
return this.activeJobs.size;
|
|
18
|
-
}
|
|
19
|
-
async handleRequest(msg) {
|
|
20
|
-
if (typeof msg.id !== "string" || !msg.id) {
|
|
21
|
-
console.error("download:request missing valid msg.id, ignoring:", msg);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
if (msg.payload == null || typeof msg.payload !== "object") {
|
|
25
|
-
console.error("download:request missing valid msg.payload, ignoring:", msg.id);
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const payload = msg.payload;
|
|
29
|
-
const requestId = msg.id;
|
|
30
|
-
if (typeof payload.magnet !== "string" || !payload.magnet) {
|
|
31
|
-
console.error("download:request missing required payload.magnet, ignoring:", requestId);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
if (typeof payload.title !== "string" || !payload.title) {
|
|
35
|
-
console.error("download:request missing required payload.title, ignoring:", requestId);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (this.activeJobs.size >= this.semaphore) {
|
|
39
|
-
this.sendMessage("download:rejected", {
|
|
40
|
-
requestId,
|
|
41
|
-
reason: "queue_full",
|
|
42
|
-
});
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const jobId = createMessageId();
|
|
46
|
-
const abortController = new AbortController();
|
|
47
|
-
const meta = {
|
|
48
|
-
tmdbId: payload.tmdbId,
|
|
49
|
-
imdbId: payload.imdbId,
|
|
50
|
-
title: payload.title,
|
|
51
|
-
year: payload.year,
|
|
52
|
-
mediaType: payload.mediaType,
|
|
53
|
-
season: payload.season,
|
|
54
|
-
episode: payload.episode,
|
|
55
|
-
episodeTitle: payload.episodeTitle,
|
|
56
|
-
magnet: payload.magnet,
|
|
57
|
-
torrentName: payload.torrentName,
|
|
58
|
-
expectedSize: payload.expectedSize,
|
|
59
|
-
};
|
|
60
|
-
const job = {
|
|
61
|
-
jobId,
|
|
62
|
-
requestId,
|
|
63
|
-
abortController,
|
|
64
|
-
phase: "adding",
|
|
65
|
-
meta,
|
|
66
|
-
};
|
|
67
|
-
this.activeJobs.set(jobId, job);
|
|
68
|
-
this.ws.setActiveJobs(this.activeJobs.size);
|
|
69
|
-
this.sendMessage("download:accepted", { jobId, requestId });
|
|
70
|
-
try {
|
|
71
|
-
await this.executeDownload(job);
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
75
|
-
const retryable = !errMsg.includes("Cancelled");
|
|
76
|
-
this.sendMessage("download:failed", {
|
|
77
|
-
jobId,
|
|
78
|
-
error: errMsg,
|
|
79
|
-
phase: job.phase,
|
|
80
|
-
retryable,
|
|
81
|
-
_meta: meta,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
finally {
|
|
85
|
-
this.activeJobs.delete(jobId);
|
|
86
|
-
this.ws.setActiveJobs(this.activeJobs.size);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
handleCancel(msg) {
|
|
90
|
-
const payload = msg.payload;
|
|
91
|
-
const jobId = payload.jobId;
|
|
92
|
-
const job = this.activeJobs.get(jobId);
|
|
93
|
-
if (job) {
|
|
94
|
-
job.abortController.abort();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
async handleCacheCheck(msg) {
|
|
98
|
-
const payload = msg.payload;
|
|
99
|
-
const requestId = payload.requestId;
|
|
100
|
-
const infoHashes = payload.infoHashes;
|
|
101
|
-
try {
|
|
102
|
-
const cached = await rdClient.checkCache(infoHashes);
|
|
103
|
-
this.sendMessage("cache:result", { requestId, cached });
|
|
104
|
-
}
|
|
105
|
-
catch (err) {
|
|
106
|
-
console.warn("Cache check failed", err);
|
|
107
|
-
this.sendMessage("cache:result", { requestId, cached: {} });
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
async executeDownload(job) {
|
|
111
|
-
const { meta, abortController } = job;
|
|
112
|
-
const signal = abortController.signal;
|
|
113
|
-
// Phase: adding
|
|
114
|
-
job.phase = "adding";
|
|
115
|
-
this.sendProgress(job.jobId, "adding", 0);
|
|
116
|
-
console.log(`[${job.jobId}] Adding magnet to RD...`);
|
|
117
|
-
const { id: torrentId } = await rdClient.addMagnet(meta.magnet);
|
|
118
|
-
if (signal.aborted)
|
|
119
|
-
throw new Error("Cancelled");
|
|
120
|
-
await rdClient.selectFiles(torrentId);
|
|
121
|
-
if (signal.aborted)
|
|
122
|
-
throw new Error("Cancelled");
|
|
123
|
-
// Phase: waiting
|
|
124
|
-
job.phase = "waiting";
|
|
125
|
-
this.sendProgress(job.jobId, "waiting", 0);
|
|
126
|
-
console.log(`[${job.jobId}] Waiting for RD to process...`);
|
|
127
|
-
const links = await rdClient.pollUntilReady(torrentId, undefined, undefined, (progress) => this.sendProgress(job.jobId, "waiting", progress), signal);
|
|
128
|
-
// Phase: unrestricting
|
|
129
|
-
job.phase = "unrestricting";
|
|
130
|
-
this.sendProgress(job.jobId, "unrestricting", 0);
|
|
131
|
-
console.log(`[${job.jobId}] Unrestricting ${links.length} links...`);
|
|
132
|
-
const unrestricted = await rdClient.unrestrictAll(links);
|
|
133
|
-
if (signal.aborted)
|
|
134
|
-
throw new Error("Cancelled");
|
|
135
|
-
// Phase: downloading
|
|
136
|
-
job.phase = "downloading";
|
|
137
|
-
console.log(`[${job.jobId}] Downloading files...`);
|
|
138
|
-
const stagingDir = config.get("directories.staging") || "/tmp/tadaima/staging";
|
|
139
|
-
const downloadedFiles = [];
|
|
140
|
-
let totalSize = 0;
|
|
141
|
-
for (const file of unrestricted) {
|
|
142
|
-
if (signal.aborted)
|
|
143
|
-
throw new Error("Cancelled");
|
|
144
|
-
const destPath = join(stagingDir, job.jobId, file.filename);
|
|
145
|
-
console.log(`[${job.jobId}] Downloading: ${file.filename}`);
|
|
146
|
-
const size = await downloadFile(file.url, destPath, (progress) => {
|
|
147
|
-
const pct = progress.totalBytes > 0
|
|
148
|
-
? Math.round((progress.downloadedBytes / progress.totalBytes) * 100)
|
|
149
|
-
: 0;
|
|
150
|
-
this.sendMessage("download:progress", {
|
|
151
|
-
jobId: job.jobId,
|
|
152
|
-
phase: "downloading",
|
|
153
|
-
progress: pct,
|
|
154
|
-
downloadedBytes: progress.downloadedBytes,
|
|
155
|
-
totalBytes: progress.totalBytes,
|
|
156
|
-
speedBps: progress.speedBps,
|
|
157
|
-
eta: progress.eta,
|
|
158
|
-
});
|
|
159
|
-
}, signal);
|
|
160
|
-
downloadedFiles.push(destPath);
|
|
161
|
-
totalSize += size;
|
|
162
|
-
}
|
|
163
|
-
// Phase: organizing
|
|
164
|
-
job.phase = "organizing";
|
|
165
|
-
this.sendProgress(job.jobId, "organizing", 0);
|
|
166
|
-
console.log(`[${job.jobId}] Organizing files...`);
|
|
167
|
-
let finalPath = "";
|
|
168
|
-
for (const filePath of downloadedFiles) {
|
|
169
|
-
finalPath = await organizeFile({
|
|
170
|
-
title: meta.title,
|
|
171
|
-
year: meta.year,
|
|
172
|
-
tmdbId: meta.tmdbId,
|
|
173
|
-
mediaType: meta.mediaType,
|
|
174
|
-
season: meta.season,
|
|
175
|
-
episode: meta.episode,
|
|
176
|
-
episodeTitle: meta.episodeTitle,
|
|
177
|
-
sourcePath: filePath,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
// Clean staging
|
|
181
|
-
await rm(join(stagingDir, job.jobId), { recursive: true, force: true }).catch(() => { });
|
|
182
|
-
// Done!
|
|
183
|
-
console.log(`[${job.jobId}] Complete: ${finalPath}`);
|
|
184
|
-
this.sendMessage("download:completed", {
|
|
185
|
-
jobId: job.jobId,
|
|
186
|
-
filePath: finalPath,
|
|
187
|
-
finalSize: totalSize,
|
|
188
|
-
_meta: meta,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
sendProgress(jobId, phase, progress) {
|
|
192
|
-
this.sendMessage("download:progress", { jobId, phase, progress });
|
|
193
|
-
}
|
|
194
|
-
sendMessage(type, payload) {
|
|
195
|
-
this.ws.send({
|
|
196
|
-
id: createMessageId(),
|
|
197
|
-
type,
|
|
198
|
-
timestamp: createTimestamp(),
|
|
199
|
-
payload,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
//# sourceMappingURL=download-handler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"download-handler.js","sourceRoot":"","sources":["../src/download-handler.ts"],"names":[],"mappings":"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"}
|
package/dist/downloader.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export interface DownloadProgress {
|
|
2
|
-
downloadedBytes: number;
|
|
3
|
-
totalBytes: number;
|
|
4
|
-
speedBps: number;
|
|
5
|
-
eta: number;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Download a file via HTTP with progress reporting.
|
|
9
|
-
*/
|
|
10
|
-
export declare function downloadFile(url: string, destPath: string, onProgress?: (progress: DownloadProgress) => void, signal?: AbortSignal, baseDir?: string): Promise<number>;
|
|
11
|
-
//# sourceMappingURL=downloader.d.ts.map
|
package/dist/downloader.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"downloader.d.ts","sourceRoot":"","sources":["../src/downloader.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,EACjD,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAqEjB"}
|