mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-21 15:22:20 +02:00
TMDB retry fixed and added cooldown. (#613)
New Features Background probing for Live streams with configurable interval; new input options to trigger probing and toggle background resolution. Configuration Changes metadata_update reorganized into grouped sections: log, resolve, probe, ffprobe, tmdb. FFprobe controls moved under ffprobe.* and now require explicit time/size units; new live ffprobe settings. Added metadata_update.tmdb.cooldown (default 7d) and grouped TMDB settings. Bug Fixes TMDB no-match cooldown to prevent endless requeues. Documentation README and UI help updated to reflect grouped metadata_update fields and explanations.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::api::model::UpdateTask;
|
||||
use crate::api::model::{ActiveProviderManager, ProviderHandle, ProviderIdType, ResolveReason, ResolveReasonSet};
|
||||
use crate::library::MetadataResolver;
|
||||
use crate::library::{MetadataResolver, MetadataStorage};
|
||||
use crate::model::FetchedPlaylist;
|
||||
use crate::model::{AppConfig, ConfigTarget, MetadataUpdateConfig};
|
||||
use crate::model::{ConfigInput, ConfigInputFlags, InputSource};
|
||||
@@ -18,6 +18,7 @@ use crate::repository::{
|
||||
get_input_storage_path, persist_input_series_info_batch, MemoryPlaylistSource, PlaylistSource,
|
||||
};
|
||||
use crate::repository::{xtream_get_file_path, BPlusTreeQuery};
|
||||
use crate::utils::ffmpeg::{ProbeFailureKind, ProbeUrlOutcome};
|
||||
use crate::utils::{debug_if_enabled, xtream};
|
||||
use log::{debug, error, info, log_enabled, trace, warn, Level};
|
||||
use parking_lot::Mutex;
|
||||
@@ -45,11 +46,11 @@ impl SeriesProbeSettings {
|
||||
pub fn from_metadata_update(metadata_update: Option<&MetadataUpdateConfig>) -> Self {
|
||||
let defaults = MetadataUpdateConfig::default();
|
||||
Self {
|
||||
timeout_secs: metadata_update.and_then(|cfg| cfg.ffprobe_timeout).unwrap_or(60),
|
||||
timeout_secs: metadata_update.and_then(|cfg| cfg.ffprobe.timeout).unwrap_or(60),
|
||||
analyze_duration_micros: metadata_update
|
||||
.map_or(defaults.ffprobe_analyze_duration_micros, |cfg| cfg.ffprobe_analyze_duration_micros),
|
||||
.map_or(defaults.ffprobe.analyze_duration_micros, |cfg| cfg.ffprobe.analyze_duration_micros),
|
||||
probe_size_bytes: metadata_update
|
||||
.map_or(defaults.ffprobe_probe_size_bytes, |cfg| cfg.ffprobe_probe_size_bytes),
|
||||
.map_or(defaults.ffprobe.probe_size_bytes, |cfg| cfg.ffprobe.probe_size_bytes),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -695,6 +696,7 @@ pub async fn update_series_metadata(
|
||||
|
||||
let mut fetched_new = false;
|
||||
let mut properties_updated = false;
|
||||
let mut probe_failure: Option<ProbeFailureKind> = None;
|
||||
|
||||
let display_id = series_id_opt.map_or_else(|| "StringID".to_string(), |v| v.to_string());
|
||||
|
||||
@@ -759,7 +761,12 @@ pub async fn update_series_metadata(
|
||||
{
|
||||
let config = app_config.config.load();
|
||||
let library_config = config.library.as_ref();
|
||||
let meta_resolver = MetadataResolver::new(library_config, client.clone());
|
||||
let metadata_update_config = config.metadata_update.as_ref();
|
||||
let tmdb_storage = metadata_update_config
|
||||
.filter(|cfg| cfg.tmdb.enabled)
|
||||
.map(|_| MetadataStorage::new(storage_path.clone()));
|
||||
let meta_resolver =
|
||||
MetadataResolver::from_config(library_config, metadata_update_config, client.clone(), tmdb_storage);
|
||||
|
||||
let mut meta = None;
|
||||
let mut tried_title = false;
|
||||
@@ -856,7 +863,7 @@ pub async fn update_series_metadata(
|
||||
ep.title, ep.season, ep.episode_num, missing_reason
|
||||
);
|
||||
|
||||
if let Some((_quality, raw_video, raw_audio)) = crate::utils::ffmpeg::probe_url(
|
||||
match crate::utils::ffmpeg::probe_url(
|
||||
&episode_url,
|
||||
user_agent.as_deref(),
|
||||
probe_settings.analyze_duration_micros,
|
||||
@@ -865,15 +872,25 @@ pub async fn update_series_metadata(
|
||||
)
|
||||
.await
|
||||
{
|
||||
if let Some(v) = raw_video {
|
||||
ep.video = Some(v.to_string().into());
|
||||
properties_updated = true;
|
||||
ProbeUrlOutcome::Success(_quality, raw_video, raw_audio) => {
|
||||
if let Some(v) = raw_video {
|
||||
ep.video = Some(v.to_string().into());
|
||||
properties_updated = true;
|
||||
}
|
||||
if let Some(a) = raw_audio {
|
||||
ep.audio = Some(a.to_string().into());
|
||||
properties_updated = true;
|
||||
}
|
||||
probed_count += 1;
|
||||
}
|
||||
if let Some(a) = raw_audio {
|
||||
ep.audio = Some(a.to_string().into());
|
||||
properties_updated = true;
|
||||
ProbeUrlOutcome::Failed(ProbeFailureKind::NotFound) => {
|
||||
probe_failure = Some(ProbeFailureKind::NotFound);
|
||||
}
|
||||
ProbeUrlOutcome::Failed(ProbeFailureKind::Other) => {
|
||||
if probe_failure.is_none() {
|
||||
probe_failure = Some(ProbeFailureKind::Other);
|
||||
}
|
||||
}
|
||||
probed_count += 1;
|
||||
}
|
||||
|
||||
if let Some(h) = temp_handle {
|
||||
@@ -897,6 +914,19 @@ pub async fn update_series_metadata(
|
||||
}
|
||||
}
|
||||
|
||||
let probe_only_unresolved = do_probe && !fetch_info && !resolve_tmdb && !properties_updated && !fetched_new;
|
||||
if probe_only_unresolved {
|
||||
if let Some(kind) = probe_failure {
|
||||
let err = match kind {
|
||||
ProbeFailureKind::NotFound => {
|
||||
shared::error::info_err!("Probe failed with 404 Not Found for Series {display_id}")
|
||||
}
|
||||
ProbeFailureKind::Other => shared::error::info_err!("Probe failed for Series {display_id}"),
|
||||
};
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Persist
|
||||
if properties_updated || fetched_new {
|
||||
if save {
|
||||
|
||||
Reference in New Issue
Block a user