Compare commits

..
13 Commits
Author SHA1 Message Date
Quentin Robert 04252db0c4 Merge pull request #135 from Masutayunikon/release-please--branches--main
chore(main): release 3.20.2
2026-06-26 14:51:44 +02:00
Quentin Robert aeb2e938ef chore(main): release 3.20.2 2026-06-26 14:50:31 +02:00
MasutaYunikon 3799d33c62 fix(scraper): fallback on empty env for GITHUB_BASE
fix(client): add placeholder from config
fix(client): remove alldebrid
2026-06-26 14:49:53 +02:00
MasutaYunikon 98b317d493 fix(label): add season of episodes 2026-06-26 14:25:41 +02:00
Quentin Robert 4292f96645 Merge pull request #131 from Nackophilz/main
Replace favicon and add PNG logo
2026-06-09 21:44:35 +02:00
ElPouki 182c7cc807 add png logo 2026-06-09 21:42:14 +02:00
ElPouki 53be057425 replace favicon 2026-06-09 21:41:51 +02:00
github-actions[bot] ac70dba927 chore: update version.txt to v3.20.1 2026-06-08 00:23:47 +00:00
Quentin Robert f79cc244ef Merge pull request #130 from Masutayunikon/release-please--branches--main
chore(main): release 3.20.1
2026-06-08 02:23:21 +02:00
Quentin Robert 14137e1b1b chore(main): release 3.20.1 2026-06-08 02:22:48 +02:00
MasutaYunikon 43ee4597a9 Merge remote-tracking branch 'origin/main' 2026-06-08 02:16:17 +02:00
MasutaYunikon f311c8e2f3 fix(organize): import manuel ne traite que les fichiers 100% complets
L'import manuel créait un fakeTorrent sans champ files, ce qui désactivait
le filtre de complétion par fichier dans le worker. Sur Windows, tenter de
déplacer un fichier encore écrit par qBittorrent provoque EBUSY ; les fichiers
échouaient mais étaient quand même marqués importés en mémoire.

Fix :
- routes/organize.ts : appel dispatchGetFiles(hash) avant l'import pour
  récupérer la progression réelle par fichier depuis le client torrent
- organize.ts : organizeTorrent accepte un param optionnel files[] transmis
  au worker via fakeTorrent ; sans fichiers (client injoignable), le comportement
  précédent (pas de filtre) est conservé en fallback
2026-06-08 02:12:47 +02:00
github-actions[bot] 48933b4078 chore: update version.txt to v3.20.0 2026-05-29 01:12:44 +00:00
9 changed files with 67 additions and 28 deletions

No files matched your search

+17
View File
@@ -1,5 +1,22 @@
# Changelog
## [3.20.2](https://github.com/Masutayunikon/FanKarr/compare/v3.20.1...v3.20.2) (2026-06-26)
### Bug Fixes
* **client:** add placeholder from config ([3799d33](https://github.com/Masutayunikon/FanKarr/commit/3799d33c625fe28eab4b46917ff32b1266cda1e3))
* **client:** remove alldebrid ([3799d33](https://github.com/Masutayunikon/FanKarr/commit/3799d33c625fe28eab4b46917ff32b1266cda1e3))
* **label:** add season of episodes ([98b317d](https://github.com/Masutayunikon/FanKarr/commit/98b317d493b7742c330d49ca816c0fecd983e82a))
* **scraper:** fallback on empty env for GITHUB_BASE ([3799d33](https://github.com/Masutayunikon/FanKarr/commit/3799d33c625fe28eab4b46917ff32b1266cda1e3))
## [3.20.1](https://github.com/Masutayunikon/FanKarr/compare/v3.20.0...v3.20.1) (2026-06-08)
### Bug Fixes
* **organize:** import manuel ne traite que les fichiers 100% complets ([f311c8e](https://github.com/Masutayunikon/FanKarr/commit/f311c8e2f3b9f53b6d03a327cf1b5bfd69cc6424))
## [3.20.0](https://github.com/Masutayunikon/FanKarr/compare/v3.19.1...v3.20.0) (2026-05-29)
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 231 KiB

+3 -2
View File
@@ -2,8 +2,9 @@ import { DATA_DIR } from '../config.js'
import path from 'path'
import fs from 'fs'
const GITHUB_BASE = process.env.GITHUB_BASE
?? 'https://raw.githubusercontent.com/masutayunikon/fankarr-scraper/main'
const GITHUB_BASE =
process.env.GITHUB_BASE?.trim() ||
'https://raw.githubusercontent.com/masutayunikon/fankarr-scraper/main'
const CACHE_TTL_MS = 1 * 60 * 60 * 1000
+6 -2
View File
@@ -520,13 +520,17 @@ export async function organizeTorrent(
hash : string,
name : string,
savePath : string,
seriesData: any[]
seriesData: any[],
files? : { name?: string; progress: number; priority?: number }[],
): Promise<OrganizeResult> {
logger.info('organize', `Import manuel lancé pour "${name}" (${hash})`)
return new Promise((resolve, reject) => {
const worker = new Worker(resolveWorkerPath())
const fakeTorrent = { hash, name, save_path: savePath, state: 'seeding' }
// files : progression par fichier récupérée depuis le client torrent.
// Permet au worker de ne traiter que les fichiers à 100% et d'éviter
// les EBUSY sur Windows quand qBit est encore en train d'écrire les autres.
const fakeTorrent = { hash, name, save_path: savePath, state: 'seeding', files: files ?? [] }
const result: OrganizeResult = { total: 0, skipped: 0, done: 0, errors: [] }
worker.on('message', (msg: any) => {
+8 -1
View File
@@ -4,6 +4,7 @@ import { logger } from '../logger.js'
import { organizeTorrent, migrateOrganizedEpisodeIds } from '../organize.js'
import { loadEnrichedSeriesData } from '../lib/github-cache.js'
import { recentOrganized, pushNotif } from '../lib/notifs.js'
import { dispatchGetFiles } from '../torrent-clients/index.js'
import { DATA_DIR } from '../config.js'
import path from 'path'
@@ -36,7 +37,13 @@ router.post('/organize', requireAuth, async (req, res) => {
if (!hash || !name || !save_path) { res.status(400).json({ error: 'hash, name et save_path requis' }); return }
try {
const seriesData = await loadEnrichedSeriesData()
const result = await organizeTorrent(hash, name, save_path, seriesData)
// Récupère la progression par fichier depuis le client torrent.
// Permet au worker de sauter les fichiers encore en téléchargement (EBUSY sur Windows).
// En cas d'échec (client injoignable, hash non trouvé), on continue sans filtre.
const files = await dispatchGetFiles(hash).catch(() => [])
const result = await organizeTorrent(hash, name, save_path, seriesData, files)
if (result.done > 0 || result.errors.length > 0) {
pushNotif({ hash, name, done: result.done, skipped: result.skipped, errors: result.errors.length, errorFiles: result.errors, at: new Date().toISOString() })
}
+30 -16
View File
@@ -606,33 +606,47 @@ const _epChapCache = new Map<string | null | undefined, ReturnType<typeof _parse
*/
function _parseEpChap(plot: string | null | undefined): {
episodes: string | null
chapters: string | null
season: number | null
chapters: string |null
cleanPlot: string
} {
const text = plot ?? ''
const epMatch = text.match(/[éeÉE]pisodes?\s+(\d+)(?:\s+[àa]\s+(\d+))?/i)
const chapMatch = text.match(/chapitres?\s+(\d+)(?:\s+[àa]\s+(\d+))?/i)
const epMatch = text.match(
/[éeÉE]pisodes?\s+(\d+)(?:\s+[àa]\s+(\d+))?(?:\s+de\s+la\s+saison\s+(\d+))?/i
)
const seasonMatch = text.match(/saison\s+(\d+)/i)
const chapMatch = text.match(
/chapitres?\s+(\d+)(?:\s+[àa]\s+(\d+))?/i
)
const episodes = epMatch
? (epMatch[2] ? `Ép. ${epMatch[1]}–${epMatch[2]}` : `Ép. ${epMatch[1]}`)
: null
const chapters = chapMatch
? (chapMatch[2] ? `Ch. ${chapMatch[1]}–${chapMatch[2]}` : `Ch. ${chapMatch[1]}`)
: null
? (epMatch[2] ? `Ép. ${epMatch[1]}–${epMatch[2]}` : `Ép. ${epMatch[1]}`)
: null
const season = epMatch?.[3]
? Number(epMatch[3])
: seasonMatch
? Number(seasonMatch[1])
: null
const chapters = chapMatch
? (chapMatch[2] ? `Ch. ${chapMatch[1]}–${chapMatch[2]}` : `Ch. ${chapMatch[1]}`)
: null
// Retirer les lignes contenant les références d'épisodes ou chapitres
let cleanPlot = text
if (episodes || chapters) {
if (episodes || chapters || season) {
cleanPlot = text
.split(/\r?\n/)
.filter(line => !/[éeÉE]pisodes?\s+\d+|chapitres?\s+\d+/i.test(line))
.join('\n')
.replace(/\n{3,}/g, '\n\n')
.trim()
.split(/\r?\n/)
.filter(line => !/(?:[éeÉE]pisodes?\s+\d+|chapitres?\s+\d+|saison\s+\d+)/i.test(line))
.join('\n')
.replace(/\n{3,}/g, '\n\n')
.trim()
}
return { episodes, chapters, cleanPlot }
return { episodes, season, chapters, cleanPlot }
}
function parseEpChap(plot: string | null | undefined) {
if (_epChapCache.has(plot)) return _epChapCache.get(plot)!
+2 -6
View File
@@ -182,7 +182,7 @@
<input
v-model="modal.config[field.key]"
:type="field.type === 'password' ? 'password' : 'text'"
placeholder=""
:placeholder="field.placeholder ?? ''"
class="settings-input"
/>
</div>
@@ -254,11 +254,7 @@ const clientMatrix = [
{
id: 'real-debrid', label: 'Real-Debrid', version: 'API v1',
auth: 'Clé API', fileSelect: true, fileProgress: true, torrentUpload: 'proxy', categories: false, deleteFiles: true,
},
{
id: 'alldebrid', label: 'AllDebrid', version: 'API v4',
auth: 'Clé API', fileSelect: false, fileProgress: true, torrentUpload: 'proxy', categories: false, deleteFiles: true,
},
}
]
const modal = ref({
+1 -1
View File
@@ -1 +1 @@
3.20.0
3.20.2