fix: résolution du hash qBittorrent par catégorie unique
L'ancienne stratégie diff avant/après échouait quand plusieurs
torrents étaient ajoutés en parallèle (le diff voyait N nouveaux
torrents et ne pouvait pas les distinguer). Les tags et savepath
ne sont pas appliqués sur qBittorrent 4.x en url-encoded.
Nouvelle approche : chaque download managé crée une catégorie
`sl-{uuid}` dans qBittorrent, puis résout le hash en filtrant
par catégorie. Le poller retente aussi la résolution par catégorie
pour les torrents avec qb_hash NULL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ use std::time::Duration;
|
||||
use tracing::{info, trace, warn};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{error::ApiError, metadata_refresh, prowlarr::extract_volumes_from_title_pub, qbittorrent::{load_qbittorrent_config, qbittorrent_login}, state::AppState};
|
||||
use crate::{error::ApiError, metadata_refresh, prowlarr::extract_volumes_from_title_pub, qbittorrent::{load_qbittorrent_config, qbittorrent_login, resolve_hash_by_category}, state::AppState};
|
||||
|
||||
// ─── Types ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -256,6 +256,33 @@ async fn poll_qbittorrent_downloads(pool: &PgPool) -> anyhow::Result<bool> {
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("qBittorrent login: {}", e.message))?;
|
||||
|
||||
// Try to resolve hash for rows that are missing it (category-based retry)
|
||||
for row in &rows {
|
||||
let qb_hash: Option<String> = row.get("qb_hash");
|
||||
if qb_hash.is_some() {
|
||||
continue;
|
||||
}
|
||||
let tid: Uuid = row.get("id");
|
||||
let category = format!("sl-{tid}");
|
||||
if let Some(hash) = resolve_hash_by_category(&client, &base_url, &sid, &category).await {
|
||||
info!("[TORRENT_POLLER] Late-resolved hash {hash} for torrent {tid} via category {category}");
|
||||
let _ = sqlx::query(
|
||||
"UPDATE torrent_downloads SET qb_hash = $1, updated_at = NOW() WHERE id = $2",
|
||||
)
|
||||
.bind(&hash)
|
||||
.bind(tid)
|
||||
.execute(pool)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-fetch rows to include newly resolved hashes
|
||||
let rows = sqlx::query(
|
||||
"SELECT id, qb_hash FROM torrent_downloads WHERE status = 'downloading'",
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
// Filter to rows that have a resolved hash
|
||||
let rows: Vec<_> = rows.into_iter().filter(|r| {
|
||||
let qb_hash: Option<String> = r.get("qb_hash");
|
||||
|
||||
Reference in New Issue
Block a user