@@ -15,10 +15,12 @@ use super::{
1515
1616const HISTORY_MIGRATION : & str = "canonical_history_ids_v4" ;
1717
18+ fn non_empty_id ( id : Option < & str > ) -> Option < & str > {
19+ id. map ( str:: trim) . filter ( |id| !id. is_empty ( ) )
20+ }
21+
1822fn series_history_key ( serie : & Serie ) -> String {
19- serie
20- . imdb
21- . as_ref ( )
23+ non_empty_id ( serie. imdb . as_deref ( ) )
2224 . map ( |imdb| format ! ( "imdb/{imdb}" ) )
2325 . unwrap_or_else ( || format ! ( "redseat/{}" , serie. id) )
2426}
@@ -28,9 +30,7 @@ pub fn series_history_id(serie: &Serie) -> String {
2830}
2931
3032pub fn movie_history_id ( movie : & Movie ) -> String {
31- movie
32- . imdb
33- . as_ref ( )
33+ non_empty_id ( movie. imdb . as_deref ( ) )
3434 . map ( |imdb| format ! ( "movie:imdb/{imdb}" ) )
3535 . unwrap_or_else ( || format ! ( "movie:redseat/{}" , movie. id) )
3636}
@@ -121,7 +121,7 @@ fn episode_legacy_ids(serie: &Serie, episode: &Episode) -> HashSet<String> {
121121 . collect ( ) ;
122122
123123 for key in [
124- serie. imdb . as_ref ( ) . map ( |id| format ! ( "imdb/{id}" ) ) ,
124+ non_empty_id ( serie. imdb . as_deref ( ) ) . map ( |id| format ! ( "imdb/{id}" ) ) ,
125125 serie. tmdb . map ( |id| format ! ( "tmdb/{id}" ) ) ,
126126 serie. tvdb . map ( |id| format ! ( "tvdb/{id}" ) ) ,
127127 Some ( format ! ( "redseat/{}" , serie. id) ) ,
@@ -160,8 +160,22 @@ fn unique_candidates<T>(candidates: HashMap<String, HashSet<T>>) -> HashMap<Stri
160160
161161fn is_current_history_id ( kind : & MediaType , id : & str ) -> bool {
162162 match kind {
163- MediaType :: Movie => id. starts_with ( "movie:imdb/" ) || id. starts_with ( "movie:redseat/" ) ,
164- MediaType :: Episode => id. starts_with ( "episode:imdb/" ) ,
163+ MediaType :: Movie => [ "movie:imdb/" , "movie:redseat/" ]
164+ . into_iter ( )
165+ . any ( |prefix| non_empty_id ( id. strip_prefix ( prefix) ) . is_some ( ) ) ,
166+ MediaType :: Episode => {
167+ let Some ( path) = id. strip_prefix ( "episode:imdb/" ) else {
168+ return false ;
169+ } ;
170+ let mut parts = path. split ( '/' ) ;
171+ matches ! (
172+ ( parts. next( ) , parts. next( ) , parts. next( ) , parts. next( ) ) ,
173+ ( Some ( imdb) , Some ( season) , Some ( number) , None )
174+ if non_empty_id( Some ( imdb) ) . is_some( )
175+ && season. parse:: <u32 >( ) . is_ok( )
176+ && number. parse:: <u32 >( ) . is_ok( )
177+ )
178+ }
165179 _ => true ,
166180 }
167181}
@@ -354,38 +368,25 @@ impl ModelController {
354368
355369 pub async fn migrate_series_history_ids (
356370 & self ,
357- library_id : & str ,
358371 old_serie : & Serie ,
359372 new_serie : & Serie ,
360373 ) -> crate :: Result < ( ) > {
361- if series_history_id ( old_serie) == series_history_id ( new_serie) {
374+ let old_prefix = format ! ( "episode:{}/" , series_history_key( old_serie) ) ;
375+ let new_prefix = format ! ( "episode:{}/" , series_history_key( new_serie) ) ;
376+ if old_prefix == new_prefix {
362377 return Ok ( ( ) ) ;
363378 }
364379
365- let store = self . store . get_library_store ( library_id) ?;
366- let episode_targets: HashMap < String , String > = store
367- . get_episodes ( EpisodeQuery {
368- serie_ref : Some ( new_serie. id . clone ( ) ) ,
369- ..Default :: default ( )
370- } )
371- . await ?
372- . into_iter ( )
373- . map ( |episode| {
374- (
375- episode_history_id ( old_serie, & episode) ,
376- episode_history_id ( new_serie, & episode) ,
377- )
378- } )
379- . collect ( ) ;
380380 let watched_rewrites = self
381381 . store
382382 . get_all_watched ( )
383383 . await ?
384384 . into_iter ( )
385385 . filter ( |row| row. kind == MediaType :: Episode )
386386 . filter_map ( |row| {
387+ let suffix = row. id . strip_prefix ( & old_prefix) ?;
387388 Some ( HistoryIdRewrite {
388- new_id : episode_targets . get ( & row . id ) ? . clone ( ) ,
389+ new_id : format ! ( "{new_prefix}{suffix}" ) ,
389390 kind : row. kind ,
390391 old_id : row. id ,
391392 user_ref : row. user_ref ?,
@@ -399,8 +400,9 @@ impl ModelController {
399400 . into_iter ( )
400401 . filter ( |row| row. kind == MediaType :: Episode )
401402 . filter_map ( |row| {
403+ let suffix = row. id . strip_prefix ( & old_prefix) ?;
402404 Some ( ProgressIdRewrite {
403- new_id : episode_targets . get ( & row . id ) ? . clone ( ) ,
405+ new_id : format ! ( "{new_prefix}{suffix}" ) ,
404406 new_parent : Some ( series_history_id ( new_serie) ) ,
405407 kind : row. kind ,
406408 old_id : row. id ,
0 commit comments