feat(network): Support for adding a new series to Sonarr
This commit is contained in:
@@ -1,9 +1,68 @@
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::models::{
|
||||
sonarr_models::{Episode, SonarrHistoryItem, SonarrRelease},
|
||||
servarr_models::RootFolder,
|
||||
sonarr_models::{Episode, SeriesMonitor, SeriesType, SonarrHistoryItem, SonarrRelease},
|
||||
stateful_list::StatefulList,
|
||||
stateful_table::StatefulTable,
|
||||
ScrollableText,
|
||||
HorizontallyScrollableText, ScrollableText,
|
||||
};
|
||||
|
||||
use super::sonarr_data::SonarrData;
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "modals_tests.rs"]
|
||||
mod modals_tests;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct AddSeriesModal {
|
||||
pub root_folder_list: StatefulList<RootFolder>,
|
||||
pub monitor_list: StatefulList<SeriesMonitor>,
|
||||
pub quality_profile_list: StatefulList<String>,
|
||||
pub language_profile_list: StatefulList<String>,
|
||||
pub series_type_list: StatefulList<SeriesType>,
|
||||
pub use_season_folder: bool,
|
||||
pub tags: HorizontallyScrollableText,
|
||||
}
|
||||
|
||||
impl From<&SonarrData> for AddSeriesModal {
|
||||
fn from(sonarr_data: &SonarrData) -> AddSeriesModal {
|
||||
let mut add_series_modal = AddSeriesModal {
|
||||
use_season_folder: true,
|
||||
..AddSeriesModal::default()
|
||||
};
|
||||
add_series_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(SeriesMonitor::iter()));
|
||||
add_series_modal
|
||||
.series_type_list
|
||||
.set_items(Vec::from_iter(SeriesType::iter()));
|
||||
let mut quality_profile_names: Vec<String> = sonarr_data
|
||||
.quality_profile_map
|
||||
.right_values()
|
||||
.cloned()
|
||||
.collect();
|
||||
quality_profile_names.sort();
|
||||
add_series_modal
|
||||
.quality_profile_list
|
||||
.set_items(quality_profile_names);
|
||||
let mut language_profile_names: Vec<String> = sonarr_data
|
||||
.language_profiles_map
|
||||
.right_values()
|
||||
.cloned()
|
||||
.collect();
|
||||
language_profile_names.sort();
|
||||
add_series_modal
|
||||
.language_profile_list
|
||||
.set_items(language_profile_names);
|
||||
add_series_modal
|
||||
.root_folder_list
|
||||
.set_items(sonarr_data.root_folders.items.to_vec());
|
||||
|
||||
add_series_modal
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct EpisodeDetailsModal {
|
||||
pub episode_details: ScrollableText,
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use bimap::BiMap;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::models::{
|
||||
servarr_data::sonarr::{modals::AddSeriesModal, sonarr_data::SonarrData},
|
||||
servarr_models::RootFolder,
|
||||
sonarr_models::{SeriesMonitor, SeriesType},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_add_series_modal_from_sonarr_data() {
|
||||
let root_folder = RootFolder {
|
||||
id: 1,
|
||||
path: "/nfs".to_owned(),
|
||||
accessible: true,
|
||||
free_space: 219902325555200,
|
||||
unmapped_folders: None,
|
||||
};
|
||||
let mut sonarr_data = SonarrData {
|
||||
quality_profile_map: BiMap::from_iter([
|
||||
(2222, "HD - 1080p".to_owned()),
|
||||
(1111, "Any".to_owned()),
|
||||
]),
|
||||
language_profiles_map: BiMap::from_iter([
|
||||
(2222, "English".to_owned()),
|
||||
(1111, "Any".to_owned()),
|
||||
]),
|
||||
..SonarrData::default()
|
||||
};
|
||||
sonarr_data
|
||||
.root_folders
|
||||
.set_items(vec![root_folder.clone()]);
|
||||
|
||||
let add_series_modal = AddSeriesModal::from(&sonarr_data);
|
||||
|
||||
assert_eq!(
|
||||
add_series_modal.monitor_list.items,
|
||||
Vec::from_iter(SeriesMonitor::iter())
|
||||
);
|
||||
assert_eq!(
|
||||
add_series_modal.series_type_list.items,
|
||||
Vec::from_iter(SeriesType::iter())
|
||||
);
|
||||
assert_eq!(
|
||||
add_series_modal.quality_profile_list.items,
|
||||
vec!["Any".to_owned(), "HD - 1080p".to_owned()]
|
||||
);
|
||||
assert_eq!(
|
||||
add_series_modal.language_profile_list.items,
|
||||
vec!["Any".to_owned(), "English".to_owned()]
|
||||
);
|
||||
assert_eq!(add_series_modal.root_folder_list.items, vec![root_folder]);
|
||||
assert!(add_series_modal.tags.text.is_empty());
|
||||
assert!(add_series_modal.use_season_folder);
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,15 @@ use crate::models::{
|
||||
servarr_data::modals::IndexerTestResultModalItem,
|
||||
servarr_models::{DiskSpace, Indexer, QueueEvent, RootFolder},
|
||||
sonarr_models::{
|
||||
BlocklistItem, DownloadRecord, IndexerSettings, Season, Series, SonarrHistoryItem, SonarrTask,
|
||||
AddSeriesSearchResult, BlocklistItem, DownloadRecord, IndexerSettings, Season, Series,
|
||||
SonarrHistoryItem, SonarrTask,
|
||||
},
|
||||
stateful_list::StatefulList,
|
||||
stateful_table::StatefulTable,
|
||||
HorizontallyScrollableText, Route, ScrollableText,
|
||||
};
|
||||
|
||||
use super::modals::SeasonDetailsModal;
|
||||
use super::modals::{AddSeriesModal, SeasonDetailsModal};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "sonarr_data_tests.rs"]
|
||||
@@ -21,6 +22,9 @@ mod sonarr_data_tests;
|
||||
|
||||
pub struct SonarrData {
|
||||
pub add_list_exclusion: bool,
|
||||
pub add_searched_series: Option<StatefulTable<AddSeriesSearchResult>>,
|
||||
pub add_series_modal: Option<AddSeriesModal>,
|
||||
pub add_series_search: Option<HorizontallyScrollableText>,
|
||||
pub blocklist: StatefulTable<BlocklistItem>,
|
||||
pub delete_series_files: bool,
|
||||
pub downloads: StatefulTable<DownloadRecord>,
|
||||
@@ -58,6 +62,9 @@ impl Default for SonarrData {
|
||||
fn default() -> SonarrData {
|
||||
SonarrData {
|
||||
add_list_exclusion: false,
|
||||
add_searched_series: None,
|
||||
add_series_search: None,
|
||||
add_series_modal: None,
|
||||
blocklist: StatefulTable::default(),
|
||||
downloads: StatefulTable::default(),
|
||||
delete_series_files: false,
|
||||
|
||||
@@ -49,6 +49,9 @@ mod tests {
|
||||
let sonarr_data = SonarrData::default();
|
||||
|
||||
assert!(!sonarr_data.add_list_exclusion);
|
||||
assert!(sonarr_data.add_searched_series.is_none());
|
||||
assert!(sonarr_data.add_series_search.is_none());
|
||||
assert!(sonarr_data.add_series_modal.is_none());
|
||||
assert!(sonarr_data.blocklist.is_empty());
|
||||
assert!(!sonarr_data.delete_series_files);
|
||||
assert!(sonarr_data.downloads.is_empty());
|
||||
|
||||
@@ -27,19 +27,46 @@ mod sonarr_models_tests;
|
||||
pub struct AddSeriesBody {
|
||||
pub tvdb_id: i64,
|
||||
pub title: String,
|
||||
pub monitored: bool,
|
||||
pub root_folder_path: String,
|
||||
pub quality_profile_id: i64,
|
||||
pub series_type: SeriesType,
|
||||
pub season_folder: bool,
|
||||
pub language_profile_id: i64,
|
||||
pub series_type: String,
|
||||
pub season_folder: bool,
|
||||
pub tags: Vec<i64>,
|
||||
pub add_options: AddSeriesOptions,
|
||||
}
|
||||
|
||||
#[derive(Derivative, Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddSeriesSearchResult {
|
||||
#[serde(deserialize_with = "super::from_i64")]
|
||||
pub tvdb_id: i64,
|
||||
pub title: HorizontallyScrollableText,
|
||||
pub status: Option<String>,
|
||||
pub ended: bool,
|
||||
pub overview: Option<String>,
|
||||
pub genres: Vec<String>,
|
||||
#[serde(deserialize_with = "super::from_i64")]
|
||||
pub year: i64,
|
||||
pub network: Option<String>,
|
||||
#[serde(deserialize_with = "super::from_i64")]
|
||||
pub runtime: i64,
|
||||
pub ratings: Option<Rating>,
|
||||
pub statistics: Option<AddSeriesSearchResultStatistics>,
|
||||
}
|
||||
|
||||
#[derive(Derivative, Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddSeriesSearchResultStatistics {
|
||||
#[serde(deserialize_with = "super::from_i64")]
|
||||
pub season_count: i64,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Serialize, Debug, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AddSeriesOptions {
|
||||
pub monitor: SeriesMonitor,
|
||||
pub monitor: String,
|
||||
pub search_for_cutoff_unmet_episodes: bool,
|
||||
pub search_for_missing_episodes: bool,
|
||||
}
|
||||
@@ -258,9 +285,9 @@ pub struct Series {
|
||||
)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum SeriesMonitor {
|
||||
Unknown,
|
||||
#[default]
|
||||
All,
|
||||
Unknown,
|
||||
Future,
|
||||
Missing,
|
||||
Existing,
|
||||
|
||||
Reference in New Issue
Block a user