fix: ajout des boutons pour les episodes sans torrent

This commit is contained in:
MasutaYunikon committed 2026-04-21 10:27:48 +02:00
1 parent 247694ab3e
commit 1b2036b57b
2 files changed
+72

No files matched your search

+20
View File
@@ -65,6 +65,14 @@ router.get('/series/:id', requireAuth, async (req, res) => {
}
}
if (serieData) {
// Lookup rapide hash → torrent pack (intégrale ou saison)
const torrentByHash = new Map<string, { torrent_url: string; magnet: string; type: string; raw: string; fankai: boolean }>()
for (const t of (serieData.torrents ?? []))
if (t.infohash) torrentByHash.set(t.infohash.toLowerCase(), { torrent_url: t.torrent_url, magnet: t.magnet, type: 'pack_integrale', raw: t.title ?? '', fankai: t.fankai ?? true })
for (const sd_s of (serieData.seasons ?? []))
for (const t of (sd_s.torrents ?? []))
if (t.infohash) torrentByHash.set(t.infohash.toLowerCase(), { torrent_url: t.torrent_url, magnet: t.magnet, type: 'pack_saison', raw: t.title ?? '', fankai: t.fankai ?? true })
for (const t of (serieData.torrents ?? [])) {
integraleTorrents.push({ ...t, raw: t.title })
const resolved = buildResolvedEpisodes(serieData, t.infohash)
@@ -101,6 +109,18 @@ router.get('/series/:id', requireAuth, async (req, res) => {
organizedEpisodeIds.add(ep.id)
}
}
// Fallback : si l'épisode n'a pas de torrent individuel,
// on crée un torrent synthétique depuis ep.paths (fichier dans un pack)
if (!episodeTorrentMap[ep.id]) {
for (const pathEntry of (ep.paths ?? [])) {
if (typeof pathEntry !== 'object' || !pathEntry.infohash) continue
const pack = torrentByHash.get(pathEntry.infohash.toLowerCase())
if (!pack) continue
episodeTorrentMap[ep.id] = { torrent_url: pack.torrent_url, magnet: pack.magnet, type: pack.type, raw: pack.raw, manual: false, fankai: pack.fankai, file_index: pathEntry.file_index ?? null, file_path: pathEntry.path ?? null }
availableEpisodeIds.add(ep.id)
break
}
}
}
}
}
+52
View File
@@ -40,6 +40,50 @@
</div>
</div>
<!-- Tableau comparatif -->
<div>
<h3 class="text-sm font-semibold text-primary mb-1">Comparatif des clients</h3>
<p class="text-xs text-muted mb-3">Fonctionnalités supportées par chaque client.</p>
<div class="overflow-x-auto rounded-xl border border-border">
<table class="w-full text-xs">
<thead>
<tr class="border-b border-border bg-shell">
<th class="text-left px-4 py-2.5 text-muted font-medium">Client</th>
<th class="text-center px-3 py-2.5 text-muted font-medium">Sélection fichier</th>
<th class="text-center px-3 py-2.5 text-muted font-medium">Catégories</th>
<th class="text-center px-3 py-2.5 text-muted font-medium">Dossier cible</th>
<th class="text-center px-3 py-2.5 text-muted font-medium">Remap. chemin</th>
</tr>
</thead>
<tbody class="divide-y divide-border/60">
<tr v-for="row in clientMatrix" :key="row.id" class="hover:bg-hover/40 transition-colors">
<td class="px-4 py-2.5">
<div class="flex items-center gap-2">
<span class="w-1.5 h-1.5 rounded-full shrink-0"
:class="healthStatus[clients.find(c => c.type === row.id)?.uuid ?? ''] === true ? 'bg-green-500' :
healthStatus[clients.find(c => c.type === row.id)?.uuid ?? ''] === false ? 'bg-red-500' : 'bg-transparent'" />
<span class="text-primary font-medium">{{ row.label }}</span>
</div>
</td>
<td class="text-center px-3 py-2.5">
<span :class="row.fileSelect === '✗' ? 'text-muted' : row.fileSelect.startsWith('Async') ? 'text-yellow-500' : 'text-green-400'">
{{ row.fileSelect }}
</span>
</td>
<td class="text-center px-3 py-2.5" :class="row.categories ? 'text-green-400' : 'text-muted'">{{ row.categories ? '✓' : '✗' }}</td>
<td class="text-center px-3 py-2.5 text-green-400">✓</td>
<td class="text-center px-3 py-2.5 text-green-400">✓</td>
</tr>
</tbody>
</table>
</div>
<p class="text-[11px] text-muted mt-2">
<span class="text-green-400">✓ Natif</span> — appliqué à l'ajout ·
<span class="text-yellow-500">Async</span> — appliqué après récupération des métadonnées ·
<span class="text-muted">✗</span> — non supporté, torrent complet téléchargé
</p>
</div>
<!-- Modal ajout -->
<Teleport to="body">
<div
@@ -118,6 +162,14 @@ const clients = ref<any[]>([])
const availableClients = ref<any[]>([])
const healthStatus = ref<Record<string, boolean | null>>({})
const clientMatrix = [
{ id: 'qbittorrent', label: 'qBittorrent', fileSelect: 'Async', categories: true },
{ id: 'transmission', label: 'Transmission', fileSelect: '✓ Natif', categories: true },
{ id: 'rtorrent', label: 'rTorrent / ruTorrent', fileSelect: 'Async', categories: true },
{ id: 'utorrent', label: 'uTorrent', fileSelect: '✗', categories: true },
{ id: 'synology-ds', label: 'Synology Download Station', fileSelect: '✗', categories: false },
]
const modal = ref({
open : false,
uuid : null as string | null,