ani-auto 1.3.0 → 1.3.1
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 +10 -33
- package/package.json +2 -3
- package/src/cli.js +331 -183
- package/src/config.js +5 -3
- package/src/daemon.js +90 -30
- package/src/db.js +39 -7
- package/src/engine.js +44 -23
- package/src/network.js +88 -0
- package/src/notify.js +70 -47
package/src/notify.js
CHANGED
|
@@ -3,83 +3,106 @@
|
|
|
3
3
|
const { execSync } = require('child_process');
|
|
4
4
|
const { loadConfig } = require('./config');
|
|
5
5
|
|
|
6
|
-
// Bot token is shared — each user only needs their own chat ID
|
|
7
|
-
// Users get their chat ID by messaging @anime_auto_downloader_bot on Telegram
|
|
8
6
|
const BOT_TOKEN = '8695132702:AAEFDoSL6nkdwDOoz5wmoVkmuhaYa4tNw0o';
|
|
9
7
|
|
|
10
|
-
// ── Telegram
|
|
8
|
+
// ── Telegram helpers ───────────────────────────────────────────────────────
|
|
11
9
|
|
|
12
|
-
async function sendTelegram(
|
|
10
|
+
async function sendTelegram(payload) {
|
|
13
11
|
const config = loadConfig();
|
|
14
12
|
const chatId = config.telegramChatId;
|
|
15
|
-
if (!chatId) return;
|
|
16
|
-
if (config.telegramNotify === false) return;
|
|
13
|
+
if (!chatId || config.telegramNotify === false) return;
|
|
17
14
|
try {
|
|
18
15
|
const fetch = require('node-fetch');
|
|
19
|
-
|
|
16
|
+
const isPhoto = !!payload.photo;
|
|
17
|
+
const endpoint = isPhoto ? 'sendPhoto' : 'sendMessage';
|
|
18
|
+
await fetch(`https://api.telegram.org/bot${BOT_TOKEN}/${endpoint}`, {
|
|
20
19
|
method: 'POST',
|
|
21
20
|
headers: { 'Content-Type': 'application/json' },
|
|
22
|
-
body: JSON.stringify({
|
|
23
|
-
chat_id: String(chatId),
|
|
24
|
-
text,
|
|
25
|
-
parse_mode: 'HTML',
|
|
26
|
-
}),
|
|
21
|
+
body: JSON.stringify({ chat_id: String(chatId), parse_mode: 'HTML', ...payload }),
|
|
27
22
|
});
|
|
28
23
|
} catch (e) {
|
|
29
|
-
// silently fail
|
|
24
|
+
// silently fail
|
|
30
25
|
}
|
|
31
26
|
}
|
|
32
27
|
|
|
33
|
-
// ── KDE
|
|
28
|
+
// ── KDE desktop ────────────────────────────────────────────────────────────
|
|
34
29
|
|
|
35
|
-
function sendDesktop(title, body, urgency = 'normal') {
|
|
30
|
+
async function sendDesktop(title, body, urgency = 'normal', posterUrl = null) {
|
|
36
31
|
try {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
let icon = '';
|
|
33
|
+
if (posterUrl) {
|
|
34
|
+
const os = require('os');
|
|
35
|
+
const path = require('path');
|
|
36
|
+
const fs = require('fs');
|
|
37
|
+
const fetch = require('node-fetch');
|
|
38
|
+
const tmp = path.join(os.tmpdir(), 'ani-auto-poster.jpg');
|
|
39
|
+
try {
|
|
40
|
+
const res = await fetch(posterUrl);
|
|
41
|
+
fs.writeFileSync(tmp, await res.buffer());
|
|
42
|
+
icon = `-i "${tmp}"`;
|
|
43
|
+
} catch (e) {}
|
|
44
|
+
}
|
|
45
|
+
execSync(`notify-send -u ${urgency} ${icon} -a "ani-auto" "${title}" "${body}"`, { stdio: 'ignore' });
|
|
46
|
+
} catch (e) {}
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
// ── Public notification functions
|
|
49
|
+
// ── Public notification functions ──────────────────────────────────────────
|
|
45
50
|
|
|
46
|
-
async function notifyEpisode(animeTitle, episode) {
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
async function notifyEpisode(animeTitle, episode, quality, posterUrl) {
|
|
52
|
+
const caption =
|
|
53
|
+
`<b>${animeTitle}</b>\n` +
|
|
54
|
+
`<code>━━━━━━━━━━━━━━━</code>\n` +
|
|
55
|
+
`✅ Episode ${episode} downloaded\n` +
|
|
56
|
+
`🎞 Quality: ${quality || 'default'}`;
|
|
57
|
+
|
|
58
|
+
if (posterUrl) {
|
|
59
|
+
await sendTelegram({ photo: posterUrl, caption });
|
|
60
|
+
} else {
|
|
61
|
+
await sendTelegram({ text: `🎬 ${caption}` });
|
|
62
|
+
}
|
|
63
|
+
await sendDesktop(animeTitle, `Episode ${episode} downloaded`, 'normal', posterUrl);
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
async function notifyFailed(animeTitle, episode, error) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
67
|
+
const text =
|
|
68
|
+
`❌ <b>${animeTitle}</b>\n` +
|
|
69
|
+
`<code>━━━━━━━━━━━━━━━</code>\n` +
|
|
70
|
+
`Episode ${episode} failed\n` +
|
|
71
|
+
`<i>${error}</i>`;
|
|
72
|
+
await sendTelegram({ text });
|
|
73
|
+
await sendDesktop(animeTitle, `Episode ${episode} failed`, 'critical');
|
|
58
74
|
}
|
|
59
75
|
|
|
60
76
|
async function notifySummary(totals) {
|
|
61
|
-
if (totals.downloaded === 0 && totals.failed === 0) return;
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
await sendTelegram(
|
|
69
|
-
sendDesktop('ani-auto run complete',
|
|
77
|
+
if (totals.downloaded === 0 && totals.failed === 0) return;
|
|
78
|
+
const text =
|
|
79
|
+
`📊 <b>ani-auto run complete</b>\n` +
|
|
80
|
+
`<code>━━━━━━━━━━━━━━━</code>\n` +
|
|
81
|
+
`✅ Downloaded: ${totals.downloaded}\n` +
|
|
82
|
+
`⏭ Skipped: ${totals.skipped}\n` +
|
|
83
|
+
`❌ Failed: ${totals.failed}`;
|
|
84
|
+
await sendTelegram({ text });
|
|
85
|
+
await sendDesktop('ani-auto run complete', `Downloaded: ${totals.downloaded} Failed: ${totals.failed}`);
|
|
70
86
|
}
|
|
71
87
|
|
|
72
|
-
async function notifyDaemonStart(intervalMinutes) {
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
async function notifyDaemonStart(intervalMinutes, downloadingCount) {
|
|
89
|
+
const { version } = require('../package.json');
|
|
90
|
+
const text =
|
|
91
|
+
`🚀 <b>ani-auto daemon started</b>\n` +
|
|
92
|
+
`<code>━━━━━━━━━━━━━━━</code>\n` +
|
|
93
|
+
`📦 Version: v${version}\n` +
|
|
94
|
+
`📺 Downloading: ${downloadingCount} anime\n` +
|
|
95
|
+
`⏱ Fallback check every ${intervalMinutes} minutes`;
|
|
96
|
+
await sendTelegram({ text });
|
|
97
|
+
await sendDesktop(
|
|
98
|
+
`ani-auto v${version} started`,
|
|
99
|
+
`Downloading ${downloadingCount} anime · every ${intervalMinutes} min`
|
|
100
|
+
);
|
|
77
101
|
}
|
|
78
102
|
|
|
79
103
|
async function notifyDaemonStop() {
|
|
80
|
-
|
|
81
|
-
await
|
|
82
|
-
sendDesktop('ani-auto daemon stopped', '');
|
|
104
|
+
await sendTelegram({ text: '🛑 <b>ani-auto daemon stopped</b>' });
|
|
105
|
+
await sendDesktop('ani-auto daemon stopped', '');
|
|
83
106
|
}
|
|
84
107
|
|
|
85
108
|
module.exports = {
|