feat: implement local-files feature with various enhancements and cleanup

This commit is contained in:
2026-03-17 03:00:39 +01:00
parent c4d2e48f73
commit d8dd047020
18 changed files with 160 additions and 131 deletions

View File

@@ -179,11 +179,7 @@ impl JwtValidator {
/// Get the user ID (subject) from a token without full validation
/// Useful for logging/debugging, but should not be trusted for auth
pub fn decode_unverified(&self, token: &str) -> Result<JwtClaims, JwtError> {
let mut validation = Validation::new(Algorithm::HS256);
validation.insecure_disable_signature_validation();
validation.validate_exp = false;
let token_data = decode::<JwtClaims>(token, &self.decoding_key, &validation)
let token_data = jsonwebtoken::dangerous::insecure_decode::<JwtClaims>(token)
.map_err(|_| JwtError::InvalidFormat)?;
Ok(token_data.claims)

View File

@@ -376,12 +376,11 @@ impl IMediaProvider for JellyfinMediaProvider {
if resp.status().is_success() {
let info: JellyfinPlaybackInfoResponse = resp.json().await
.map_err(|e| DomainError::InfrastructureError(format!("PlaybackInfo parse failed: {e}")))?;
if let Some(src) = info.media_sources.first() {
if src.supports_direct_stream {
if let Some(rel_url) = &src.direct_stream_url {
return Ok(format!("{}{}&api_key={}", self.config.base_url, rel_url, self.config.api_key));
}
}
if let Some(src) = info.media_sources.first()
&& src.supports_direct_stream
&& let Some(rel_url) = &src.direct_stream_url
{
return Ok(format!("{}{}&api_key={}", self.config.base_url, rel_url, self.config.api_key));
}
}
// Fallback: HLS at 8 Mbps

View File

@@ -86,10 +86,8 @@ impl IMediaProvider for LocalFilesProvider {
} else {
ContentType::Movie
};
if let Some(ref ct) = filter.content_type {
if &content_type != ct {
return None;
}
if let Some(ref ct) = filter.content_type && &content_type != ct {
return None;
}
// collections: match against top_dir
@@ -117,22 +115,16 @@ impl IMediaProvider for LocalFilesProvider {
}
// duration bounds
if let Some(min) = filter.min_duration_secs {
if item.duration_secs < min {
return None;
}
if let Some(min) = filter.min_duration_secs && item.duration_secs < min {
return None;
}
if let Some(max) = filter.max_duration_secs {
if item.duration_secs > max {
return None;
}
if let Some(max) = filter.max_duration_secs && item.duration_secs > max {
return None;
}
// search_term: case-insensitive substring in title
if let Some(ref q) = filter.search_term {
if !item.title.to_lowercase().contains(&q.to_lowercase()) {
return None;
}
if let Some(ref q) = filter.search_term && !item.title.to_lowercase().contains(&q.to_lowercase()) {
return None;
}
Some(to_media_item(id, &item))

View File

@@ -171,15 +171,13 @@ impl TranscodeManager {
continue;
}
let playlist = path.join("playlist.m3u8");
if let Ok(meta) = tokio::fs::metadata(&playlist).await {
if let Ok(modified) = meta.modified() {
if let Ok(age) = now.duration_since(modified) {
if age > ttl {
warn!("cleanup: removing stale transcode {:?}", path);
let _ = tokio::fs::remove_dir_all(&path).await;
}
}
}
if let Ok(meta) = tokio::fs::metadata(&playlist).await
&& let Ok(modified) = meta.modified()
&& let Ok(age) = now.duration_since(modified)
&& age > ttl
{
warn!("cleanup: removing stale transcode {:?}", path);
let _ = tokio::fs::remove_dir_all(&path).await;
}
}
}