ani-auto 1.0.4 → 1.1.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/engine.js +26 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ani-auto",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Automatic anime episode downloader",
5
5
  "bin": {
6
6
  "ani-auto": "./src/cli.js"
package/src/engine.js CHANGED
@@ -10,6 +10,7 @@ const { loadConfig } = require('./config');
10
10
  const db = require('./db');
11
11
  const { getUserList, pickTitle } = require('./anilist');
12
12
  const scraper = require('./scraper');
13
+ const { version } = require('../package.json');
13
14
 
14
15
  // ── Logging ────────────────────────────────────────────────────────────────
15
16
 
@@ -137,25 +138,27 @@ async function processAnime(workItem, config, multiBar, auto = false, runQuality
137
138
  const existingRow = db.getAnimeBySiteTitle(workItem.title);
138
139
  let siteAnime;
139
140
 
140
- if (existingRow?.confirmed_site_id) {
141
- siteAnime = { session: existingRow.confirmed_site_id, title: existingRow.confirmed_site_title };
141
+ // Always do a fresh search — session IDs expire on AnimePahe
142
+ const siteResults = await scraper.searchAll(workItem.title);
143
+ if (!siteResults.length) {
144
+ warn(`[${workItem.title}] Not found on site — skipping.`);
145
+ return { downloaded: 0, skipped: 0, failed: 0 };
146
+ }
147
+
148
+ if (existingRow?.confirmed_site_title) {
149
+ // We have a saved title preference — find it in fresh results
150
+ const savedMatch = siteResults.find(r =>
151
+ r.title?.toLowerCase() === existingRow.confirmed_site_title.toLowerCase()
152
+ ) || siteResults[0];
153
+ siteAnime = savedMatch;
142
154
  info(`[${workItem.title}] Using saved site match: ${chalk.bold(siteAnime.title)}`);
155
+ // Update session ID in DB
156
+ db.saveConfirmedSiteMatch(workItem.title, siteAnime.session, siteAnime.title);
143
157
  } else if (auto) {
144
- const siteResults = await scraper.searchAll(workItem.title);
145
- if (!siteResults.length) {
146
- warn(`[${workItem.title}] Not found on site — skipping.`);
147
- return { downloaded: 0, skipped: 0, failed: 0 };
148
- }
149
158
  siteAnime = siteResults[0];
150
159
  db.saveConfirmedSiteMatch(workItem.title, siteAnime.session, siteAnime.title);
151
160
  info(`[${workItem.title}] Auto-matched to: ${chalk.bold(siteAnime.title)}`);
152
161
  } else {
153
- const siteResults = await scraper.searchAll(workItem.title);
154
- if (!siteResults.length) {
155
- warn(`[${workItem.title}] Not found on site — skipping.`);
156
- return { downloaded: 0, skipped: 0, failed: 0 };
157
- }
158
-
159
162
  const topResults = siteResults.slice(0, 5);
160
163
  const { pick } = await inquirer.prompt([{
161
164
  type: 'list',
@@ -221,12 +224,13 @@ async function processAnime(workItem, config, multiBar, auto = false, runQuality
221
224
 
222
225
  info(`[${workItem.title}] ${toDownload.length} unwatched episode(s) to download (Q:${q} L:${l}, skipping first ${watched}).`);
223
226
 
224
- // Use AniList title for folder — consistent with what user sees on AniList
225
- const cleanTitle = buildFolderName(workItem.title);
226
- const season = detectSeason(workItem.title);
227
- // Strip "Season X" from the display title used in filename to avoid duplication
228
- const displayTitle = cleanTitle.replace(/\s*season\s*\d+\s*/gi, '').trim();
229
- const outputDir = path.join(config.outputDir, cleanTitle);
227
+ // Folder uses AniList title — consistent with what user sees on AniList
228
+ const cleanTitle = buildFolderName(workItem.title);
229
+ const season = detectSeason(workItem.title);
230
+ // Filename uses site title (better casing) with Season X stripped to avoid duplication
231
+ const siteClean = buildFolderName(siteAnime.title || workItem.title);
232
+ const displayTitle = siteClean.replace(/[:\s]*season\s*\d+[:\s]*/gi, ' ').replace(/\s+/g, ' ').trim();
233
+ const outputDir = path.join(config.outputDir, cleanTitle);
230
234
  if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
231
235
 
232
236
  const queue = [...toDownload];
@@ -285,9 +289,9 @@ async function runCycle({ auto = false, quality = null, language = null } = {})
285
289
  await db.initDb();
286
290
  const config = loadConfig();
287
291
 
288
- console.log(chalk.bold.red('\n ╔══════════════════════════════╗'));
289
- console.log(chalk.bold.red(' ANI-AUTO — CHECK RUN ║'));
290
- console.log(chalk.bold.red(' ╚══════════════════════════════╝\n'));
292
+ console.log(chalk.bold.red('\n ╔════════════════════════════════╗'));
293
+ console.log(chalk.bold.red(` ANI-AUTO v${version} — CHECK RUN ║`));
294
+ console.log(chalk.bold.red(' ╚════════════════════════════════╝\n'));
291
295
 
292
296
  const watchList = await resolveWatchList(config);
293
297