fix: Implemented a handful of fixes that are breaking changes between Sonarr v3 and v4

This commit is contained in:
2024-12-13 19:44:10 -07:00
parent f03120e5a1
commit 682bc91855
14 changed files with 137 additions and 91 deletions
+1 -1
View File
@@ -313,7 +313,7 @@ with all items tagged `Beta`.
## Servarr Requirements ## Servarr Requirements
* [Radarr >= 5.3.6.8612](https://radarr.video/docs/api/) * [Radarr >= 5.3.6.8612](https://radarr.video/docs/api/)
* [Sonarr >= v3](https://sonarr.tv/docs/api/) * [Sonarr >= v4](https://sonarr.tv/docs/api/)
* [Readarr v1](https://readarr.com/docs/api/) * [Readarr v1](https://readarr.com/docs/api/)
* [Lidarr v1](https://lidarr.audio/docs/api/) * [Lidarr v1](https://lidarr.audio/docs/api/)
* [Whisparr >= v3](https://whisparr.com/docs/api/) * [Whisparr >= v3](https://whisparr.com/docs/api/)
@@ -240,10 +240,14 @@ mod tests {
#[test] #[test]
fn test_history_sorting_options_language() { fn test_history_sorting_options_language() {
let expected_cmp_fn: fn(&SonarrHistoryItem, &SonarrHistoryItem) -> Ordering = |a, b| { let expected_cmp_fn: fn(&SonarrHistoryItem, &SonarrHistoryItem) -> Ordering = |a, b| {
a.language let default_language = Language {
.name id: 1,
.to_lowercase() name: "_".to_owned(),
.cmp(&b.language.name.to_lowercase()) };
let language_a = &a.languages.first().unwrap_or(&default_language);
let language_b = &b.languages.first().unwrap_or(&default_language);
language_a.cmp(language_b)
}; };
let mut expected_history_vec = history_vec(); let mut expected_history_vec = history_vec();
expected_history_vec.sort_by(expected_cmp_fn); expected_history_vec.sort_by(expected_cmp_fn);
@@ -361,10 +365,10 @@ mod tests {
id: 3, id: 3,
source_title: "test 1".into(), source_title: "test 1".into(),
event_type: SonarrHistoryEventType::Grabbed, event_type: SonarrHistoryEventType::Grabbed,
language: Language { languages: vec![Language {
id: 1, id: 1,
name: "telgu".to_owned(), name: "telgu".to_owned(),
}, }],
quality: QualityWrapper { quality: QualityWrapper {
quality: Quality { quality: Quality {
name: "HD - 1080p".to_owned(), name: "HD - 1080p".to_owned(),
@@ -377,10 +381,10 @@ mod tests {
id: 2, id: 2,
source_title: "test 2".into(), source_title: "test 2".into(),
event_type: SonarrHistoryEventType::DownloadFolderImported, event_type: SonarrHistoryEventType::DownloadFolderImported,
language: Language { languages: vec![Language {
id: 3, id: 3,
name: "chinese".to_owned(), name: "chinese".to_owned(),
}, }],
quality: QualityWrapper { quality: QualityWrapper {
quality: Quality { quality: Quality {
name: "SD - 720p".to_owned(), name: "SD - 720p".to_owned(),
@@ -393,10 +397,10 @@ mod tests {
id: 1, id: 1,
source_title: "test 3".into(), source_title: "test 3".into(),
event_type: SonarrHistoryEventType::EpisodeFileDeleted, event_type: SonarrHistoryEventType::EpisodeFileDeleted,
language: Language { languages: vec![Language {
id: 1, id: 1,
name: "english".to_owned(), name: "english".to_owned(),
}, }],
quality: QualityWrapper { quality: QualityWrapper {
quality: Quality { quality: Quality {
name: "HD - 1080p".to_owned(), name: "HD - 1080p".to_owned(),
+9 -4
View File
@@ -6,6 +6,7 @@ use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::{handle_clear_errors, KeyEventHandler}; use crate::handlers::{handle_clear_errors, KeyEventHandler};
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS};
use crate::models::servarr_models::Language;
use crate::models::sonarr_models::SonarrHistoryItem; use crate::models::sonarr_models::SonarrHistoryItem;
use crate::models::stateful_table::SortOption; use crate::models::stateful_table::SortOption;
@@ -142,10 +143,14 @@ pub(in crate::handlers::sonarr_handlers) fn history_sorting_options(
SortOption { SortOption {
name: "Language", name: "Language",
cmp_fn: Some(|a, b| { cmp_fn: Some(|a, b| {
a.language let default_language = Language {
.name id: 1,
.to_lowercase() name: "_".to_owned(),
.cmp(&b.language.name.to_lowercase()) };
let language_a = &a.languages.first().unwrap_or(&default_language);
let language_b = &b.languages.first().unwrap_or(&default_language);
language_a.cmp(language_b)
}), }),
}, },
SortOption { SortOption {
+4 -3
View File
@@ -119,7 +119,7 @@ pub struct DownloadRecord {
pub output_path: Option<HorizontallyScrollableText>, pub output_path: Option<HorizontallyScrollableText>,
#[serde(default)] #[serde(default)]
pub indexer: String, pub indexer: String,
pub download_client: String, pub download_client: Option<String>,
} }
impl Eq for DownloadRecord {} impl Eq for DownloadRecord {}
@@ -233,7 +233,7 @@ pub struct EpisodeFile {
pub path: String, pub path: String,
#[serde(deserialize_with = "super::from_i64")] #[serde(deserialize_with = "super::from_i64")]
pub size: i64, pub size: i64,
pub language: Language, pub languages: Vec<Language>,
pub quality: QualityWrapper, pub quality: QualityWrapper,
pub date_added: DateTime<Utc>, pub date_added: DateTime<Utc>,
pub media_info: Option<MediaInfo>, pub media_info: Option<MediaInfo>,
@@ -300,6 +300,7 @@ impl Eq for Rating {}
#[derive(Derivative, Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] #[derive(Derivative, Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Season { pub struct Season {
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>, pub title: Option<String>,
#[serde(deserialize_with = "super::from_i64")] #[serde(deserialize_with = "super::from_i64")]
pub season_number: i64, pub season_number: i64,
@@ -587,7 +588,7 @@ pub struct SonarrHistoryItem {
#[serde(deserialize_with = "super::from_i64")] #[serde(deserialize_with = "super::from_i64")]
pub episode_id: i64, pub episode_id: i64,
pub quality: QualityWrapper, pub quality: QualityWrapper,
pub language: Language, pub languages: Vec<Language>,
pub date: DateTime<Utc>, pub date: DateTime<Utc>,
pub event_type: SonarrHistoryEventType, pub event_type: SonarrHistoryEventType,
pub data: SonarrHistoryData, pub data: SonarrHistoryData,
+4 -6
View File
@@ -2103,12 +2103,10 @@ impl<'a, 'b> Network<'a, 'b> {
.handle_request::<Value, Value>(request_props, |test_results, mut app| { .handle_request::<Value, Value>(request_props, |test_results, mut app| {
if test_results.as_object().is_none() { if test_results.as_object().is_none() {
app.data.radarr_data.indexer_test_errors = Some( app.data.radarr_data.indexer_test_errors = Some(
test_results test_results.as_array().unwrap()[0]
.as_array()
.unwrap()[0]
.get("errorMessage") .get("errorMessage")
.unwrap() .unwrap()
.to_string() .to_string(),
); );
} else { } else {
app.data.radarr_data.indexer_test_errors = Some(String::new()); app.data.radarr_data.indexer_test_errors = Some(String::new());
@@ -2254,7 +2252,7 @@ impl<'a, 'b> Network<'a, 'b> {
let tags = edit_tags.clone(); let tags = edit_tags.clone();
let missing_tags_vec = edit_tags let missing_tags_vec = edit_tags
.split(',') .split(',')
.filter(|&tag| !tag.is_empty() && tags_map.get_by_right(tag.trim()).is_none()) .filter(|&tag| !tag.is_empty() && tags_map.get_by_right(tag.to_lowercase().trim()).is_none())
.collect::<Vec<&str>>(); .collect::<Vec<&str>>();
for tag in missing_tags_vec { for tag in missing_tags_vec {
@@ -2273,7 +2271,7 @@ impl<'a, 'b> Network<'a, 'b> {
.data .data
.radarr_data .radarr_data
.tags_map .tags_map
.get_by_right(tag.trim()) .get_by_right(tag.to_lowercase().trim())
.unwrap() .unwrap()
}) })
.collect() .collect()
+3 -3
View File
@@ -4882,7 +4882,7 @@ mod test {
#[tokio::test] #[tokio::test]
async fn test_extract_and_add_radarr_tag_ids_vec() { async fn test_extract_and_add_radarr_tag_ids_vec() {
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
let tags = " test,hi ,, usenet ".to_owned(); let tags = " test,HI ,, usenet ".to_owned();
{ {
let mut app = app_arc.lock().await; let mut app = app_arc.lock().await;
app.data.radarr_data.tags_map = BiMap::from_iter([ app.data.radarr_data.tags_map = BiMap::from_iter([
@@ -4903,7 +4903,7 @@ mod test {
async fn test_extract_and_add_radarr_tag_ids_vec_add_missing_tags_first() { async fn test_extract_and_add_radarr_tag_ids_vec_add_missing_tags_first() {
let (async_server, app_arc, _server) = mock_servarr_api( let (async_server, app_arc, _server) = mock_servarr_api(
RequestMethod::Post, RequestMethod::Post,
Some(json!({ "label": "testing" })), Some(json!({ "label": "TESTING" })),
Some(json!({ "id": 3, "label": "testing" })), Some(json!({ "id": 3, "label": "testing" })),
None, None,
RadarrEvent::GetTags, RadarrEvent::GetTags,
@@ -4911,7 +4911,7 @@ mod test {
None, None,
) )
.await; .await;
let tags = "usenet, test, testing".to_owned(); let tags = "usenet, test, TESTING".to_owned();
{ {
let mut app = app_arc.lock().await; let mut app = app_arc.lock().await;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
+4 -4
View File
@@ -116,7 +116,7 @@ impl NetworkResource for SonarrEvent {
SonarrEvent::GetIndexers | SonarrEvent::DeleteIndexer(_) | SonarrEvent::EditIndexer(_) => { SonarrEvent::GetIndexers | SonarrEvent::DeleteIndexer(_) | SonarrEvent::EditIndexer(_) => {
"/indexer" "/indexer"
} }
SonarrEvent::GetLanguageProfiles => "/languageprofile", SonarrEvent::GetLanguageProfiles => "/language",
SonarrEvent::GetLogs(_) => "/log", SonarrEvent::GetLogs(_) => "/log",
SonarrEvent::GetDiskSpace => "/diskspace", SonarrEvent::GetDiskSpace => "/diskspace",
SonarrEvent::GetQualityProfiles => "/qualityprofile", SonarrEvent::GetQualityProfiles => "/qualityprofile",
@@ -1709,7 +1709,7 @@ impl<'a, 'b> Network<'a, 'b> {
Date Added: {}", Date Added: {}",
file.relative_path, file.relative_path,
file.path, file.path,
file.language.name, file.languages.first().unwrap_or(&Language::default()).name,
file.date_added, file.date_added,
); );
@@ -2730,7 +2730,7 @@ impl<'a, 'b> Network<'a, 'b> {
let tags = edit_tags.clone(); let tags = edit_tags.clone();
let missing_tags_vec = edit_tags let missing_tags_vec = edit_tags
.split(',') .split(',')
.filter(|&tag| !tag.is_empty() && tags_map.get_by_right(tag.trim()).is_none()) .filter(|&tag| !tag.is_empty() && tags_map.get_by_right(tag.to_lowercase().trim()).is_none())
.collect::<Vec<&str>>(); .collect::<Vec<&str>>();
for tag in missing_tags_vec { for tag in missing_tags_vec {
@@ -2749,7 +2749,7 @@ impl<'a, 'b> Network<'a, 'b> {
.data .data
.sonarr_data .sonarr_data
.tags_map .tags_map
.get_by_right(tag.trim()) .get_by_right(tag.to_lowercase().trim())
.unwrap() .unwrap()
}) })
.collect() .collect()
+36 -36
View File
@@ -114,7 +114,7 @@ mod test {
"path": "/nfs/tv/series/season 1/episode 1.mkv", "path": "/nfs/tv/series/season 1/episode 1.mkv",
"size": 3543348019, "size": 3543348019,
"dateAdded": "2024-02-10T07:28:45Z", "dateAdded": "2024-02-10T07:28:45Z",
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"mediaInfo": { "mediaInfo": {
"audioBitrate": 0, "audioBitrate": 0,
@@ -285,7 +285,7 @@ mod test {
#[case(SonarrEvent::HealthCheck, "/health")] #[case(SonarrEvent::HealthCheck, "/health")]
#[case(SonarrEvent::GetBlocklist, "/blocklist?page=1&pageSize=10000")] #[case(SonarrEvent::GetBlocklist, "/blocklist?page=1&pageSize=10000")]
#[case(SonarrEvent::GetDiskSpace, "/diskspace")] #[case(SonarrEvent::GetDiskSpace, "/diskspace")]
#[case(SonarrEvent::GetLanguageProfiles, "/languageprofile")] #[case(SonarrEvent::GetLanguageProfiles, "/language")]
#[case(SonarrEvent::GetLogs(Some(500)), "/log")] #[case(SonarrEvent::GetLogs(Some(500)), "/log")]
#[case(SonarrEvent::GetQualityProfiles, "/qualityprofile")] #[case(SonarrEvent::GetQualityProfiles, "/qualityprofile")]
#[case(SonarrEvent::GetStatus, "/system/status")] #[case(SonarrEvent::GetStatus, "/system/status")]
@@ -2791,7 +2791,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -2804,7 +2804,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -2883,7 +2883,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -2896,7 +2896,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -2954,7 +2954,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -2967,7 +2967,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -3396,7 +3396,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -3409,7 +3409,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -3526,7 +3526,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -3539,7 +3539,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -3656,7 +3656,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -3669,7 +3669,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -3764,7 +3764,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -3777,7 +3777,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -4447,7 +4447,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -4460,7 +4460,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -4563,7 +4563,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -4576,7 +4576,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -4679,7 +4679,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -4692,7 +4692,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -5329,7 +5329,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -5342,7 +5342,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -5451,7 +5451,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -5464,7 +5464,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -5557,7 +5557,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -5570,7 +5570,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -5659,7 +5659,7 @@ mod test {
"sourceTitle": "z episode", "sourceTitle": "z episode",
"episodeId": 1007, "episodeId": 1007,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -5672,7 +5672,7 @@ mod test {
"sourceTitle": "A Episode", "sourceTitle": "A Episode",
"episodeId": 2001, "episodeId": 2001,
"quality": { "quality": { "name": "Bluray-1080p" } }, "quality": { "quality": { "name": "Bluray-1080p" } },
"language": { "id": 1, "name": "English" }, "languages": [{ "id": 1, "name": "English" }],
"date": "2024-02-10T07:28:45Z", "date": "2024-02-10T07:28:45Z",
"eventType": "grabbed", "eventType": "grabbed",
"data": { "data": {
@@ -7216,7 +7216,7 @@ mod test {
#[tokio::test] #[tokio::test]
async fn test_extract_and_add_sonarr_tag_ids_vec() { async fn test_extract_and_add_sonarr_tag_ids_vec() {
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
let tags = " test,hi ,, usenet ".to_owned(); let tags = " test,HI ,, usenet ".to_owned();
{ {
let mut app = app_arc.lock().await; let mut app = app_arc.lock().await;
app.data.sonarr_data.tags_map = BiMap::from_iter([ app.data.sonarr_data.tags_map = BiMap::from_iter([
@@ -7237,7 +7237,7 @@ mod test {
async fn test_extract_and_add_sonarr_tag_ids_vec_add_missing_tags_first() { async fn test_extract_and_add_sonarr_tag_ids_vec_add_missing_tags_first() {
let (async_server, app_arc, _server) = mock_servarr_api( let (async_server, app_arc, _server) = mock_servarr_api(
RequestMethod::Post, RequestMethod::Post,
Some(json!({ "label": "testing" })), Some(json!({ "label": "TESTING" })),
Some(json!({ "id": 3, "label": "testing" })), Some(json!({ "id": 3, "label": "testing" })),
None, None,
SonarrEvent::GetTags, SonarrEvent::GetTags,
@@ -7245,7 +7245,7 @@ mod test {
None, None,
) )
.await; .await;
let tags = "usenet, test, testing".to_owned(); let tags = "usenet, test, TESTING".to_owned();
{ {
let mut app = app_arc.lock().await; let mut app = app_arc.lock().await;
app.data.sonarr_data.add_series_modal = Some(AddSeriesModal { app.data.sonarr_data.add_series_modal = Some(AddSeriesModal {
@@ -7562,7 +7562,7 @@ mod test {
"/nfs/tv/Test show/season 1/", "/nfs/tv/Test show/season 1/",
)), )),
indexer: "kickass torrents".to_owned(), indexer: "kickass torrents".to_owned(),
download_client: "transmission".to_owned(), download_client: Some("transmission".to_owned()),
} }
} }
@@ -7598,7 +7598,7 @@ mod test {
path: "/nfs/tv/series/season 1/episode 1.mkv".to_owned(), path: "/nfs/tv/series/season 1/episode 1.mkv".to_owned(),
size: 3543348019, size: 3543348019,
quality: quality_wrapper(), quality: quality_wrapper(),
language: language(), languages: vec![language()],
date_added: DateTime::from(DateTime::parse_from_rfc3339("2024-02-10T07:28:45Z").unwrap()), date_added: DateTime::from(DateTime::parse_from_rfc3339("2024-02-10T07:28:45Z").unwrap()),
media_info: Some(media_info()), media_info: Some(media_info()),
} }
@@ -7624,7 +7624,7 @@ mod test {
source_title: "Test source".into(), source_title: "Test source".into(),
episode_id: 1, episode_id: 1,
quality: quality_wrapper(), quality: quality_wrapper(),
language: language(), languages: vec![language()],
date: DateTime::from(DateTime::parse_from_rfc3339("2024-02-10T07:28:45Z").unwrap()), date: DateTime::from(DateTime::parse_from_rfc3339("2024-02-10T07:28:45Z").unwrap()),
event_type: SonarrHistoryEventType::Grabbed, event_type: SonarrHistoryEventType::Grabbed,
data: history_data(), data: history_data(),
-2
View File
@@ -44,9 +44,7 @@ impl DrawUi for LibraryUi {
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let route = app.get_current_route(); let route = app.get_current_route();
if !matches!(route, Route::Radarr(_, Some(_))) {
draw_library(f, app, area); draw_library(f, app, area);
}
match route { match route {
_ if MovieDetailsUi::accepts(route) => MovieDetailsUi::draw(f, app, area), _ if MovieDetailsUi::accepts(route) => MovieDetailsUi::draw(f, app, area),
+6 -1
View File
@@ -115,7 +115,12 @@ fn draw_downloads(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
.to_string(), .to_string(),
), ),
Cell::from(indexer.to_owned()), Cell::from(indexer.to_owned()),
Cell::from(download_client.to_owned()), Cell::from(
download_client
.as_ref()
.unwrap_or(&String::new())
.to_owned(),
),
]) ])
.primary() .primary()
}; };
+8 -2
View File
@@ -64,7 +64,7 @@ fn draw_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let history_row_mapping = |history_item: &SonarrHistoryItem| { let history_row_mapping = |history_item: &SonarrHistoryItem| {
let SonarrHistoryItem { let SonarrHistoryItem {
source_title, source_title,
language, languages,
quality, quality,
event_type, event_type,
date, date,
@@ -80,7 +80,13 @@ fn draw_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
Row::new(vec![ Row::new(vec![
Cell::from(source_title.to_string()), Cell::from(source_title.to_string()),
Cell::from(event_type.to_string()), Cell::from(event_type.to_string()),
Cell::from(language.name.to_owned()), Cell::from(
languages
.iter()
.map(|language| language.name.to_owned())
.collect::<Vec<String>>()
.join(","),
),
Cell::from(quality.quality.name.to_owned()), Cell::from(quality.quality.name.to_owned()),
Cell::from(date.to_string()), Cell::from(date.to_string()),
]) ])
@@ -254,7 +254,7 @@ fn draw_episode_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect)
let history_row_mapping = |history_item: &SonarrHistoryItem| { let history_row_mapping = |history_item: &SonarrHistoryItem| {
let SonarrHistoryItem { let SonarrHistoryItem {
source_title, source_title,
language, languages,
quality, quality,
event_type, event_type,
date, date,
@@ -270,7 +270,13 @@ fn draw_episode_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect)
Row::new(vec![ Row::new(vec![
Cell::from(source_title.to_string()), Cell::from(source_title.to_string()),
Cell::from(event_type.to_string()), Cell::from(event_type.to_string()),
Cell::from(language.name.to_owned()), Cell::from(
languages
.iter()
.map(|language| language.name.to_owned())
.collect::<Vec<String>>()
.join(","),
),
Cell::from(quality.quality.name.to_owned()), Cell::from(quality.quality.name.to_owned()),
Cell::from(date.to_string()), Cell::from(date.to_string()),
]) ])
+24 -7
View File
@@ -4,6 +4,7 @@ use crate::models::sonarr_models::{
DownloadRecord, DownloadStatus, Episode, SonarrHistoryEventType, SonarrHistoryItem, SonarrRelease, DownloadRecord, DownloadStatus, Episode, SonarrHistoryEventType, SonarrHistoryItem, SonarrRelease,
}; };
use crate::models::Route; use crate::models::Route;
use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi;
use crate::ui::sonarr_ui::sonarr_ui_utils::{ use crate::ui::sonarr_ui::sonarr_ui_utils::{
create_download_failed_history_event_details, create_download_failed_history_event_details,
create_download_folder_imported_history_event_details, create_download_folder_imported_history_event_details,
@@ -27,7 +28,6 @@ use ratatui::layout::{Alignment, Constraint, Rect};
use ratatui::prelude::{Line, Style, Stylize, Text}; use ratatui::prelude::{Line, Style, Stylize, Text};
use ratatui::widgets::{Cell, Paragraph, Row, Wrap}; use ratatui::widgets::{Cell, Paragraph, Row, Wrap};
use ratatui::Frame; use ratatui::Frame;
use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi;
#[cfg(test)] #[cfg(test)]
#[path = "season_details_ui_tests.rs"] #[path = "season_details_ui_tests.rs"]
@@ -38,7 +38,8 @@ pub(super) struct SeasonDetailsUi;
impl DrawUi for SeasonDetailsUi { impl DrawUi for SeasonDetailsUi {
fn accepts(route: Route) -> bool { fn accepts(route: Route) -> bool {
if let Route::Sonarr(active_sonarr_block, _) = route { if let Route::Sonarr(active_sonarr_block, _) = route {
return EpisodeDetailsUi::accepts(route) || SEASON_DETAILS_BLOCKS.contains(&active_sonarr_block); return EpisodeDetailsUi::accepts(route)
|| SEASON_DETAILS_BLOCKS.contains(&active_sonarr_block);
} }
false false
@@ -52,7 +53,15 @@ impl DrawUi for SeasonDetailsUi {
let content_area = draw_tabs( let content_area = draw_tabs(
f, f,
popup_area, popup_area,
&format!("Season {} Details", app.data.sonarr_data.seasons.current_selection().season_number), &format!(
"Season {} Details",
app
.data
.sonarr_data
.seasons
.current_selection()
.season_number
),
&app &app
.data .data
.sonarr_data .sonarr_data
@@ -259,7 +268,7 @@ fn draw_season_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let history_row_mapping = |history_item: &SonarrHistoryItem| { let history_row_mapping = |history_item: &SonarrHistoryItem| {
let SonarrHistoryItem { let SonarrHistoryItem {
source_title, source_title,
language, languages,
quality, quality,
event_type, event_type,
date, date,
@@ -275,7 +284,13 @@ fn draw_season_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
Row::new(vec![ Row::new(vec![
Cell::from(source_title.to_string()), Cell::from(source_title.to_string()),
Cell::from(event_type.to_string()), Cell::from(event_type.to_string()),
Cell::from(language.name.to_owned()), Cell::from(
languages
.iter()
.map(|language| language.name.to_owned())
.collect::<Vec<String>>()
.join(","),
),
Cell::from(quality.quality.name.to_owned()), Cell::from(quality.quality.name.to_owned()),
Cell::from(date.to_string()), Cell::from(date.to_string()),
]) ])
@@ -339,11 +354,13 @@ fn draw_season_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let (current_selection, is_empty) = if season_details_modal.season_releases.is_empty() { let (current_selection, is_empty) = if season_details_modal.season_releases.is_empty() {
(SonarrRelease::default(), true) (SonarrRelease::default(), true)
} else { } else {
(season_details_modal (
season_details_modal
.season_releases .season_releases
.current_selection() .current_selection()
.clone(), .clone(),
season_details_modal.season_releases.is_empty()) season_details_modal.season_releases.is_empty(),
)
}; };
let season_release_table_footer = season_details_modal let season_release_table_footer = season_details_modal
.season_details_tabs .season_details_tabs
@@ -312,7 +312,7 @@ fn draw_series_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let history_row_mapping = |history_item: &SonarrHistoryItem| { let history_row_mapping = |history_item: &SonarrHistoryItem| {
let SonarrHistoryItem { let SonarrHistoryItem {
source_title, source_title,
language, languages,
quality, quality,
event_type, event_type,
date, date,
@@ -328,7 +328,13 @@ fn draw_series_history_table(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
Row::new(vec![ Row::new(vec![
Cell::from(source_title.to_string()), Cell::from(source_title.to_string()),
Cell::from(event_type.to_string()), Cell::from(event_type.to_string()),
Cell::from(language.name.to_owned()), Cell::from(
languages
.iter()
.map(|language| language.name.to_owned())
.collect::<Vec<String>>()
.join(","),
),
Cell::from(quality.quality.name.to_owned()), Cell::from(quality.quality.name.to_owned()),
Cell::from(date.to_string()), Cell::from(date.to_string()),
]) ])