feat: match RSS results by IMDb id (#99)
ci / web (push) Successful in 28s
e2e / e2e (push) Successful in 53s
ci / rust (push) Successful in 2m15s

This commit was merged in pull request #99.
This commit is contained in:
2026-08-23 02:44:42 +01:00
parent 3082568171
commit 02d99ae558
11 changed files with 312 additions and 70 deletions
+8 -1
View File
@@ -180,28 +180,35 @@ impl GrabAction {
let original_language =
(!metadata.original_language.is_empty()).then_some(metadata.original_language.clone());
let digital_release = metadata.digital_release.map(|date| date.to_string());
// §6.2: the id RSS matching prefers, and the one Torznab movie
// searches take. TMDB does not know one for every title.
let imdb_id = metadata.imdb_id.clone();
let title_ref = title.as_str();
let original_language_ref = original_language.as_deref();
let digital_release_ref = digital_release.as_deref();
let imdb_id_ref = imdb_id.as_deref();
let changed = sqlx::query!(
r#"UPDATE movies
SET title = ?, year = ?, original_language = ?, digital_release = ?,
imdb_id = ?,
metadata_refreshed_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
search_attempts = 0, last_searched_at = NULL,
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
WHERE id = ? AND (
title IS NOT ? OR year IS NOT ? OR original_language IS NOT ?
OR digital_release IS NOT ?
OR digital_release IS NOT ? OR imdb_id IS NOT ?
)"#,
title_ref,
year,
original_language_ref,
digital_release_ref,
imdb_id_ref,
movie.id,
title_ref,
year,
original_language_ref,
digital_release_ref,
imdb_id_ref,
)
.execute(database.pool())
.await?
+9 -2
View File
@@ -14,7 +14,7 @@ use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::path::PathBuf;
use arr_core::matching::{match_movie, MatchKind, WantedMovie};
use arr_core::matching::{match_movie, MatchKind, ReleaseIds, WantedMovie};
use arr_core::{Language, MovieId};
use arr_db::{Blacklist, Db, MoviePolicy};
use arr_dl::TransmissionClient;
@@ -124,7 +124,11 @@ impl RssAction {
for release in releases {
let claims = arr_parse::parse(&release.name);
let Some(matched) = match_movie(wanted, release.tmdb_id, &claims) else {
let ids = ReleaseIds {
tmdb_id: release.tmdb_id,
imdb_id: release.imdb_id.clone(),
};
let Some(matched) = match_movie(wanted, &ids, &claims) else {
continue;
};
let movie_id = matched.movie.0;
@@ -142,6 +146,7 @@ impl RssAction {
release = release.name,
by = match matched.kind {
MatchKind::TmdbId => "tmdb id",
MatchKind::ImdbId => "imdb id",
MatchKind::TitleAndYear => "title and year",
},
"RSS result matched a wanted title"
@@ -218,6 +223,7 @@ async fn wanted_movies(database: &Db) -> Result<Vec<WantedMovie>, GrabError> {
r#"
SELECT m.id AS "id!: i64",
m.tmdb_id AS "tmdb_id!: i64",
m.imdb_id AS "imdb_id: String",
m.title AS "title!: String",
m.year
FROM movies m
@@ -242,6 +248,7 @@ async fn wanted_movies(database: &Db) -> Result<Vec<WantedMovie>, GrabError> {
.map(|row| WantedMovie {
id: MovieId(row.id),
tmdb_id: u32::try_from(row.tmdb_id).ok(),
imdb_id: row.imdb_id,
title: row.title,
year: row.year.and_then(|year| u16::try_from(year).ok()),
})