Skip to content

Commit 3a7835f

Browse files
committed
lookups
1 parent 65af1a5 commit 3a7835f

2 files changed

Lines changed: 204 additions & 12 deletions

File tree

src/model/episodes.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ pub struct EpisodeForUpdate {
105105
pub trakt_votes: Option<u64>,
106106
}
107107

108+
fn should_retry_episode_lookup_with_enriched_ids(
109+
original_ids: &RsIds,
110+
enriched_ids: &RsIds,
111+
) -> bool {
112+
enriched_ids.as_all_external_ids() != original_ids.as_all_external_ids()
113+
}
114+
108115
impl ModelController {
109116
async fn lookup_episodes_metadata(
110117
&self,
@@ -214,9 +221,27 @@ impl ModelController {
214221
query.serie_ref = Some(serie.item.id);
215222
store.get_episodes(query).await?
216223
} else {
217-
let episodes = self
224+
let mut episodes = self
218225
.lookup_episodes_metadata(library_id, &serie_id, &id, requesting_user)
219226
.await?;
227+
if episodes.is_empty() {
228+
if let Some(serie) = self
229+
.get_serie(library_id, serie_id.clone(), requesting_user)
230+
.await?
231+
{
232+
let enriched_ids: RsIds = serie.item.into();
233+
if should_retry_episode_lookup_with_enriched_ids(&id, &enriched_ids) {
234+
episodes = self
235+
.lookup_episodes_metadata(
236+
library_id,
237+
&serie_id,
238+
&enriched_ids,
239+
requesting_user,
240+
)
241+
.await?;
242+
}
243+
}
244+
}
220245
if episodes.is_empty() {
221246
return Err(SourcesError::NotFound(Some(format!(
222247
"get_episodes_by_id - Unable to find episodes for {:?}",
@@ -702,3 +727,32 @@ impl ModelController {
702727
.await
703728
}
704729
}
730+
731+
#[cfg(test)]
732+
mod tests {
733+
use super::should_retry_episode_lookup_with_enriched_ids;
734+
use rs_plugin_common_interfaces::domain::rs_ids::RsIds;
735+
736+
#[test]
737+
fn enriched_episode_lookup_retries_when_new_external_ids_are_added() {
738+
let original = RsIds::from_tmdb(203744);
739+
let mut enriched = RsIds::from_tmdb(203744);
740+
enriched.set("tvdb", 421070u64);
741+
742+
assert!(should_retry_episode_lookup_with_enriched_ids(
743+
&original,
744+
&enriched
745+
));
746+
}
747+
748+
#[test]
749+
fn enriched_episode_lookup_does_not_retry_when_external_ids_are_unchanged() {
750+
let original = RsIds::from_tmdb(203744);
751+
let enriched = RsIds::from_tmdb(203744);
752+
753+
assert!(!should_retry_episode_lookup_with_enriched_ids(
754+
&original,
755+
&enriched
756+
));
757+
}
758+
}

src/model/series.rs

Lines changed: 149 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,33 @@ pub struct SerieForUpdate {
106106
pub max_created: Option<i64>,
107107
}
108108

109+
enum ExternalSerieImageFallback {
110+
ReturnRawError,
111+
RetryWithResolvedLocalId(String),
112+
RetryWithEnrichedLookup { name: String, ids: RsIds },
113+
}
114+
115+
fn external_serie_image_fallback(
116+
requested_id: &str,
117+
requested_ids: RsIds,
118+
resolved_serie: Option<ItemWithRelations<Serie>>,
119+
) -> ExternalSerieImageFallback {
120+
let Some(serie) = resolved_serie else {
121+
return ExternalSerieImageFallback::ReturnRawError;
122+
};
123+
124+
if serie.item.id != requested_id && !RsIds::is_id(&serie.item.id) {
125+
return ExternalSerieImageFallback::RetryWithResolvedLocalId(serie.item.id);
126+
}
127+
128+
let name = serie.item.name.clone();
129+
130+
ExternalSerieImageFallback::RetryWithEnrichedLookup {
131+
name,
132+
ids: RsIds::from(serie.item),
133+
}
134+
}
135+
109136
impl SerieForUpdate {
110137
pub fn has_update(&self) -> bool {
111138
self != &SerieForUpdate::default()
@@ -800,20 +827,57 @@ impl ModelController {
800827
)
801828
.await;
802829
}
803-
let lookup_query = RsLookupQuery::Serie(RsLookupSerie {
830+
let raw_lookup_query = RsLookupQuery::Serie(RsLookupSerie {
804831
name: None,
805-
ids: Some(serie_ids),
832+
ids: Some(serie_ids.clone()),
806833
page_key: None,
807834
});
808-
self.serve_cached_entity_image(
809-
library_id,
810-
serie_id,
811-
lookup_query,
812-
&kind,
813-
&config,
814-
requesting_user,
815-
)
816-
.await
835+
let raw_result = self
836+
.serve_cached_entity_image(
837+
library_id,
838+
serie_id,
839+
raw_lookup_query,
840+
&kind,
841+
&config,
842+
requesting_user,
843+
)
844+
.await;
845+
if raw_result.is_ok() {
846+
return raw_result;
847+
}
848+
849+
let resolved_serie = self
850+
.get_serie(library_id, serie_id.to_string(), requesting_user)
851+
.await?;
852+
match external_serie_image_fallback(serie_id, serie_ids, resolved_serie) {
853+
ExternalSerieImageFallback::ReturnRawError => raw_result,
854+
ExternalSerieImageFallback::RetryWithResolvedLocalId(local_id) => {
855+
self.serie_image(
856+
library_id,
857+
&local_id,
858+
Some(kind),
859+
size,
860+
requesting_user,
861+
)
862+
.await
863+
}
864+
ExternalSerieImageFallback::RetryWithEnrichedLookup { name, ids } => {
865+
let lookup_query = RsLookupQuery::Serie(RsLookupSerie {
866+
name: Some(name),
867+
ids: Some(ids),
868+
page_key: None,
869+
});
870+
self.serve_cached_entity_image(
871+
library_id,
872+
serie_id,
873+
lookup_query,
874+
&kind,
875+
&config,
876+
requesting_user,
877+
)
878+
.await
879+
}
880+
}
817881
} else {
818882
self.serve_local_entity_image(
819883
library_id,
@@ -969,3 +1033,77 @@ impl ModelController {
9691033
Ok(())
9701034
}
9711035
}
1036+
1037+
#[cfg(test)]
1038+
mod tests {
1039+
use super::{external_serie_image_fallback, ExternalSerieImageFallback};
1040+
use crate::domain::serie::Serie;
1041+
use rs_plugin_common_interfaces::domain::{rs_ids::RsIds, ItemWithRelations};
1042+
1043+
#[test]
1044+
fn external_serie_image_fallback_returns_raw_error_when_resolution_fails() {
1045+
let fallback =
1046+
external_serie_image_fallback("tmdb:203744", RsIds::from_tmdb(203744), None);
1047+
1048+
assert!(matches!(
1049+
fallback,
1050+
ExternalSerieImageFallback::ReturnRawError
1051+
));
1052+
}
1053+
1054+
#[test]
1055+
fn external_serie_image_fallback_retries_with_local_id_when_entity_exists_locally() {
1056+
let resolved = ItemWithRelations {
1057+
item: Serie {
1058+
id: "local-serie-id".to_string(),
1059+
name: "Sugar".to_string(),
1060+
tmdb: Some(203744),
1061+
tvdb: Some(421070),
1062+
..Default::default()
1063+
},
1064+
relations: None,
1065+
};
1066+
1067+
let fallback = external_serie_image_fallback(
1068+
"tmdb:203744",
1069+
RsIds::from_tmdb(203744),
1070+
Some(resolved),
1071+
);
1072+
1073+
match fallback {
1074+
ExternalSerieImageFallback::RetryWithResolvedLocalId(local_id) => {
1075+
assert_eq!(local_id, "local-serie-id");
1076+
}
1077+
_ => panic!("expected local-id retry"),
1078+
}
1079+
}
1080+
1081+
#[test]
1082+
fn external_serie_image_fallback_retries_with_enriched_ids_for_external_results() {
1083+
let resolved = ItemWithRelations {
1084+
item: Serie {
1085+
id: "tmdb:203744".to_string(),
1086+
name: "Sugar".to_string(),
1087+
tmdb: Some(203744),
1088+
tvdb: Some(421070),
1089+
..Default::default()
1090+
},
1091+
relations: None,
1092+
};
1093+
1094+
let fallback = external_serie_image_fallback(
1095+
"tmdb:203744",
1096+
RsIds::from_tmdb(203744),
1097+
Some(resolved),
1098+
);
1099+
1100+
match fallback {
1101+
ExternalSerieImageFallback::RetryWithEnrichedLookup { name, ids } => {
1102+
assert_eq!(name, "Sugar");
1103+
assert_eq!(ids.tmdb(), Some(203744));
1104+
assert_eq!(ids.tvdb(), Some(421070));
1105+
}
1106+
_ => panic!("expected enriched lookup retry"),
1107+
}
1108+
}
1109+
}

0 commit comments

Comments
 (0)