feat(network): Support for fetching all Sonarr tasks
This commit is contained in:
@@ -12,7 +12,7 @@ use tokio::sync::Mutex;
|
||||
use crate::app::App;
|
||||
|
||||
use crate::cli::CliCommandHandler;
|
||||
use crate::models::radarr_models::{ReleaseDownloadBody, TaskName};
|
||||
use crate::models::radarr_models::{RadarrTaskName, ReleaseDownloadBody};
|
||||
use crate::network::radarr_network::RadarrEvent;
|
||||
use crate::network::NetworkTrait;
|
||||
use anyhow::Result;
|
||||
@@ -107,7 +107,7 @@ pub enum RadarrCommand {
|
||||
value_enum,
|
||||
required = true
|
||||
)]
|
||||
task_name: TaskName,
|
||||
task_name: RadarrTaskName,
|
||||
},
|
||||
#[command(
|
||||
about = "Test the indexer with the given ID. Note that a successful test returns an empty JSON body; i.e. '{}'"
|
||||
|
||||
@@ -261,8 +261,8 @@ mod tests {
|
||||
},
|
||||
models::{
|
||||
radarr_models::{
|
||||
BlocklistItem, BlocklistResponse, IndexerSettings, RadarrSerdeable, ReleaseDownloadBody,
|
||||
TaskName,
|
||||
BlocklistItem, BlocklistResponse, IndexerSettings, RadarrSerdeable, RadarrTaskName,
|
||||
ReleaseDownloadBody,
|
||||
},
|
||||
Serdeable,
|
||||
},
|
||||
@@ -389,7 +389,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_start_task_command() {
|
||||
let expected_task_name = TaskName::ApplicationCheckUpdate;
|
||||
let expected_task_name = RadarrTaskName::ApplicationCheckUpdate;
|
||||
let mut mock_network = MockNetworkTrait::new();
|
||||
mock_network
|
||||
.expect_handle_network_event()
|
||||
@@ -404,7 +404,7 @@ mod tests {
|
||||
});
|
||||
let app_arc = Arc::new(Mutex::new(App::default()));
|
||||
let start_task_command = RadarrCommand::StartTask {
|
||||
task_name: TaskName::ApplicationCheckUpdate,
|
||||
task_name: RadarrTaskName::ApplicationCheckUpdate,
|
||||
};
|
||||
|
||||
let result = RadarrCliHandler::with(&app_arc, start_task_command, &mut mock_network)
|
||||
|
||||
@@ -8,7 +8,7 @@ mod tests {
|
||||
use crate::event::Key;
|
||||
use crate::handlers::radarr_handlers::system::system_details_handler::SystemDetailsHandler;
|
||||
use crate::handlers::KeyEventHandler;
|
||||
use crate::models::radarr_models::Task;
|
||||
use crate::models::radarr_models::RadarrTask;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{
|
||||
ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS,
|
||||
};
|
||||
@@ -74,7 +74,7 @@ mod tests {
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(simple_stateful_iterable_vec!(Task, String, name));
|
||||
.set_items(simple_stateful_iterable_vec!(RadarrTask, String, name));
|
||||
|
||||
SystemDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::SystemTasks, &None).handle();
|
||||
|
||||
@@ -102,7 +102,7 @@ mod tests {
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(simple_stateful_iterable_vec!(Task, String, name));
|
||||
.set_items(simple_stateful_iterable_vec!(RadarrTask, String, name));
|
||||
|
||||
SystemDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::SystemTasks, &None).handle();
|
||||
|
||||
@@ -318,7 +318,7 @@ mod tests {
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(extended_stateful_iterable_vec!(Task, String, name));
|
||||
.set_items(extended_stateful_iterable_vec!(RadarrTask, String, name));
|
||||
|
||||
SystemDetailsHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.end.key,
|
||||
@@ -357,7 +357,7 @@ mod tests {
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(extended_stateful_iterable_vec!(Task, String, name));
|
||||
.set_items(extended_stateful_iterable_vec!(RadarrTask, String, name));
|
||||
|
||||
SystemDetailsHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.end.key,
|
||||
@@ -789,7 +789,11 @@ mod tests {
|
||||
app.is_loading = is_ready;
|
||||
app.push_navigation_stack(ActiveRadarrBlock::System.into());
|
||||
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemDetailsHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::SystemTasks, &None)
|
||||
.handle();
|
||||
|
||||
@@ -9,7 +9,7 @@ mod tests {
|
||||
use crate::event::Key;
|
||||
use crate::handlers::radarr_handlers::system::SystemHandler;
|
||||
use crate::handlers::KeyEventHandler;
|
||||
use crate::models::radarr_models::Task;
|
||||
use crate::models::radarr_models::RadarrTask;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{
|
||||
ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS,
|
||||
};
|
||||
@@ -105,7 +105,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.update.key,
|
||||
@@ -135,7 +139,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.update.key,
|
||||
@@ -160,7 +168,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.events.key,
|
||||
@@ -190,7 +202,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.events.key,
|
||||
@@ -215,7 +231,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
app.push_navigation_stack(ActiveRadarrBlock::System.into());
|
||||
|
||||
SystemHandler::with(
|
||||
@@ -244,7 +264,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
app.push_navigation_stack(ActiveRadarrBlock::System.into());
|
||||
|
||||
SystemHandler::with(
|
||||
@@ -271,7 +295,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.logs.key,
|
||||
@@ -309,7 +337,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.logs.key,
|
||||
@@ -335,7 +367,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.tasks.key,
|
||||
@@ -365,7 +401,11 @@ mod tests {
|
||||
.radarr_data
|
||||
.queued_events
|
||||
.set_items(vec![QueueEvent::default()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.tasks.key,
|
||||
@@ -430,7 +470,11 @@ mod tests {
|
||||
fn test_system_handler_is_not_ready_when_logs_is_empty() {
|
||||
let mut app = App::default();
|
||||
app.is_loading = false;
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
@@ -473,7 +517,11 @@ mod tests {
|
||||
let mut app = App::default();
|
||||
app.is_loading = false;
|
||||
app.data.radarr_data.logs.set_items(vec!["test".into()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
|
||||
let system_handler = SystemHandler::with(
|
||||
&DEFAULT_KEYBINDINGS.update.key,
|
||||
@@ -490,7 +538,11 @@ mod tests {
|
||||
let mut app = App::default();
|
||||
app.is_loading = false;
|
||||
app.data.radarr_data.logs.set_items(vec!["test".into()]);
|
||||
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![RadarrTask::default()]);
|
||||
app
|
||||
.data
|
||||
.radarr_data
|
||||
|
||||
@@ -435,9 +435,9 @@ pub struct SystemStatus {
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Task {
|
||||
pub struct RadarrTask {
|
||||
pub name: String,
|
||||
pub task_name: TaskName,
|
||||
pub task_name: RadarrTaskName,
|
||||
#[serde(deserialize_with = "super::from_i64")]
|
||||
pub interval: i64,
|
||||
pub last_execution: DateTime<Utc>,
|
||||
@@ -447,7 +447,7 @@ pub struct Task {
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Copy, ValueEnum)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
pub enum TaskName {
|
||||
pub enum RadarrTaskName {
|
||||
#[default]
|
||||
ApplicationCheckUpdate,
|
||||
Backup,
|
||||
@@ -462,7 +462,7 @@ pub enum TaskName {
|
||||
RssSync,
|
||||
}
|
||||
|
||||
impl Display for TaskName {
|
||||
impl Display for RadarrTaskName {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let task_name = serde_json::to_string(&self)
|
||||
.expect("Unable to serialize task name")
|
||||
@@ -514,7 +514,7 @@ pub enum RadarrSerdeable {
|
||||
SecurityConfig(SecurityConfig),
|
||||
SystemStatus(SystemStatus),
|
||||
Tags(Vec<Tag>),
|
||||
Tasks(Vec<Task>),
|
||||
Tasks(Vec<RadarrTask>),
|
||||
Updates(Vec<Update>),
|
||||
AddMovieSearchResults(Vec<AddMovieSearchResult>),
|
||||
IndexerTestResults(Vec<IndexerTestResult>),
|
||||
@@ -555,7 +555,7 @@ serde_enum_from!(
|
||||
SecurityConfig(SecurityConfig),
|
||||
SystemStatus(SystemStatus),
|
||||
Tags(Vec<Tag>),
|
||||
Tasks(Vec<Task>),
|
||||
Tasks(Vec<RadarrTask>),
|
||||
Updates(Vec<Update>),
|
||||
AddMovieSearchResults(Vec<AddMovieSearchResult>),
|
||||
IndexerTestResults(Vec<IndexerTestResult>),
|
||||
|
||||
@@ -8,7 +8,7 @@ mod tests {
|
||||
AddMovieSearchResult, BlocklistItem, BlocklistResponse, Collection, Credit, DiskSpace,
|
||||
DownloadRecord, DownloadsResponse, Indexer, IndexerSettings, IndexerTestResult,
|
||||
MinimumAvailability, Monitor, Movie, MovieHistoryItem, QualityProfile, RadarrSerdeable,
|
||||
Release, SystemStatus, Tag, Task, TaskName, Update,
|
||||
RadarrTask, RadarrTaskName, Release, SystemStatus, Tag, Update,
|
||||
},
|
||||
servarr_models::{HostConfig, Log, LogResponse, QueueEvent, RootFolder, SecurityConfig},
|
||||
EnumDisplayStyle, Serdeable,
|
||||
@@ -17,7 +17,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_task_name_display() {
|
||||
assert_str_eq!(
|
||||
TaskName::ApplicationCheckUpdate.to_string(),
|
||||
RadarrTaskName::ApplicationCheckUpdate.to_string(),
|
||||
"ApplicationCheckUpdate"
|
||||
);
|
||||
}
|
||||
@@ -383,9 +383,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_radarr_serdeable_from_tasks() {
|
||||
let tasks = vec![Task {
|
||||
let tasks = vec![RadarrTask {
|
||||
name: "test".to_owned(),
|
||||
..Task::default()
|
||||
..RadarrTask::default()
|
||||
}];
|
||||
|
||||
let radarr_serdeable: RadarrSerdeable = tasks.clone().into();
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::app::radarr::radarr_context_clues::{
|
||||
};
|
||||
use crate::models::radarr_models::{
|
||||
AddMovieSearchResult, BlocklistItem, Collection, CollectionMovie, DownloadRecord,
|
||||
IndexerSettings, Movie, Task,
|
||||
IndexerSettings, Movie, RadarrTask,
|
||||
};
|
||||
use crate::models::servarr_data::radarr::modals::{
|
||||
AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, IndexerTestResultModalItem,
|
||||
@@ -48,7 +48,7 @@ pub struct RadarrData<'a> {
|
||||
pub collection_movies: StatefulTable<CollectionMovie>,
|
||||
pub logs: StatefulList<HorizontallyScrollableText>,
|
||||
pub log_details: StatefulList<HorizontallyScrollableText>,
|
||||
pub tasks: StatefulTable<Task>,
|
||||
pub tasks: StatefulTable<RadarrTask>,
|
||||
pub queued_events: StatefulTable<QueueEvent>,
|
||||
pub updates: ScrollableText,
|
||||
pub main_tabs: TabState,
|
||||
|
||||
@@ -5,7 +5,7 @@ use strum::EnumIter;
|
||||
use crate::models::{
|
||||
servarr_models::{DiskSpace, Indexer, QueueEvent, RootFolder},
|
||||
sonarr_models::{
|
||||
BlocklistItem, DownloadRecord, IndexerSettings, Season, Series, SonarrHistoryItem,
|
||||
BlocklistItem, DownloadRecord, IndexerSettings, Season, Series, SonarrHistoryItem, SonarrTask,
|
||||
},
|
||||
stateful_list::StatefulList,
|
||||
stateful_table::StatefulTable,
|
||||
@@ -36,6 +36,7 @@ pub struct SonarrData {
|
||||
pub series_history: Option<StatefulTable<SonarrHistoryItem>>,
|
||||
pub start_time: DateTime<Utc>,
|
||||
pub tags_map: BiMap<i64, String>,
|
||||
pub tasks: StatefulTable<SonarrTask>,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
@@ -59,6 +60,7 @@ impl Default for SonarrData {
|
||||
series_history: None,
|
||||
start_time: DateTime::default(),
|
||||
tags_map: BiMap::default(),
|
||||
tasks: StatefulTable::default(),
|
||||
version: String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ mod tests {
|
||||
assert!(sonarr_data.series_history.is_none());
|
||||
assert_eq!(sonarr_data.start_time, <DateTime<Utc>>::default());
|
||||
assert!(sonarr_data.tags_map.is_empty());
|
||||
assert!(sonarr_data.tasks.is_empty());
|
||||
assert!(sonarr_data.version.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,6 +388,44 @@ pub struct SonarrHistoryItem {
|
||||
pub data: SonarrHistoryData,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SonarrTask {
|
||||
pub name: String,
|
||||
pub task_name: SonarrTaskName,
|
||||
#[serde(deserialize_with = "super::from_i64")]
|
||||
pub interval: i64,
|
||||
pub last_execution: DateTime<Utc>,
|
||||
pub last_duration: String,
|
||||
pub next_execution: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Copy, ValueEnum)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
pub enum SonarrTaskName {
|
||||
#[default]
|
||||
ApplicationUpdateCheck,
|
||||
Backup,
|
||||
CheckHealth,
|
||||
CleanUpRecycleBin,
|
||||
Housekeeping,
|
||||
ImportListSync,
|
||||
MessagingCleanup,
|
||||
RefreshMonitoredDownloads,
|
||||
RefreshSeries,
|
||||
RssSync,
|
||||
UpdateSceneMapping,
|
||||
}
|
||||
|
||||
impl Display for SonarrTaskName {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let task_name = serde_json::to_string(&self)
|
||||
.expect("Unable to serialize task name")
|
||||
.replace('"', "");
|
||||
write!(f, "{task_name}")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||
#[serde(untagged)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
@@ -412,6 +450,7 @@ pub enum SonarrSerdeable {
|
||||
SystemStatus(SystemStatus),
|
||||
Tag(Tag),
|
||||
Tags(Vec<Tag>),
|
||||
Tasks(Vec<SonarrTask>),
|
||||
BlocklistResponse(BlocklistResponse),
|
||||
LogResponse(LogResponse),
|
||||
}
|
||||
@@ -450,6 +489,7 @@ serde_enum_from!(
|
||||
SystemStatus(SystemStatus),
|
||||
Tag(Tag),
|
||||
Tags(Vec<Tag>),
|
||||
Tasks(Vec<SonarrTask>),
|
||||
BlocklistResponse(BlocklistResponse),
|
||||
LogResponse(LogResponse),
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ mod tests {
|
||||
sonarr_models::{
|
||||
BlocklistItem, BlocklistResponse, DownloadRecord, DownloadsResponse, Episode,
|
||||
IndexerSettings, Series, SeriesStatus, SeriesType, SonarrHistoryEventType, SonarrHistoryItem,
|
||||
SonarrSerdeable, SystemStatus,
|
||||
SonarrSerdeable, SonarrTask, SonarrTaskName, SystemStatus,
|
||||
},
|
||||
EnumDisplayStyle, Serdeable,
|
||||
};
|
||||
@@ -117,6 +117,14 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_task_name_display() {
|
||||
assert_str_eq!(
|
||||
SonarrTaskName::ApplicationUpdateCheck.to_string(),
|
||||
"ApplicationUpdateCheck"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sonarr_serdeable_from() {
|
||||
let sonarr_serdeable = SonarrSerdeable::Value(json!({}));
|
||||
@@ -406,4 +414,16 @@ mod tests {
|
||||
|
||||
assert_eq!(sonarr_serdeable, SonarrSerdeable::Tags(tags));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sonarr_serdeable_from_tasks() {
|
||||
let tasks = vec![SonarrTask {
|
||||
name: "test".to_owned(),
|
||||
..SonarrTask::default()
|
||||
}];
|
||||
|
||||
let sonarr_serdeable: SonarrSerdeable = tasks.clone().into();
|
||||
|
||||
assert_eq!(sonarr_serdeable, SonarrSerdeable::Tasks(tasks));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ use crate::models::radarr_models::{
|
||||
AddMovieBody, AddMovieSearchResult, AddOptions, BlocklistResponse, Collection, CollectionMovie,
|
||||
CommandBody, Credit, CreditType, DeleteMovieParams, DownloadRecord, DownloadsResponse,
|
||||
EditCollectionParams, EditIndexerParams, EditMovieParams, IndexerSettings, IndexerTestResult,
|
||||
Movie, MovieCommandBody, MovieHistoryItem, RadarrSerdeable, ReleaseDownloadBody, SystemStatus,
|
||||
Task, TaskName, Update,
|
||||
Movie, MovieCommandBody, MovieHistoryItem, RadarrSerdeable, RadarrTask, RadarrTaskName,
|
||||
ReleaseDownloadBody, SystemStatus, Update,
|
||||
};
|
||||
use crate::models::servarr_data::radarr::modals::{
|
||||
AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, IndexerTestResultModalItem,
|
||||
@@ -73,7 +73,7 @@ pub enum RadarrEvent {
|
||||
GetUpdates,
|
||||
HealthCheck,
|
||||
SearchNewMovie(Option<String>),
|
||||
StartTask(Option<TaskName>),
|
||||
StartTask(Option<RadarrTaskName>),
|
||||
TestIndexer(Option<i64>),
|
||||
TestAllIndexers,
|
||||
TriggerAutomaticSearch(Option<i64>),
|
||||
@@ -243,7 +243,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
.map(RadarrSerdeable::from),
|
||||
RadarrEvent::GetStatus => self.get_radarr_status().await.map(RadarrSerdeable::from),
|
||||
RadarrEvent::GetTags => self.get_radarr_tags().await.map(RadarrSerdeable::from),
|
||||
RadarrEvent::GetTasks => self.get_tasks().await.map(RadarrSerdeable::from),
|
||||
RadarrEvent::GetTasks => self.get_radarr_tasks().await.map(RadarrSerdeable::from),
|
||||
RadarrEvent::GetUpdates => self.get_updates().await.map(RadarrSerdeable::from),
|
||||
RadarrEvent::HealthCheck => self
|
||||
.get_radarr_healthcheck()
|
||||
@@ -1855,7 +1855,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_tasks(&mut self) -> Result<Vec<Task>> {
|
||||
async fn get_radarr_tasks(&mut self) -> Result<Vec<RadarrTask>> {
|
||||
info!("Fetching Radarr tasks");
|
||||
let event = RadarrEvent::GetTasks;
|
||||
|
||||
@@ -1864,7 +1864,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
.await;
|
||||
|
||||
self
|
||||
.handle_request::<(), Vec<Task>>(request_props, |tasks_vec, mut app| {
|
||||
.handle_request::<(), Vec<RadarrTask>>(request_props, |tasks_vec, mut app| {
|
||||
app.data.radarr_data.tasks.set_items(tasks_vec);
|
||||
})
|
||||
.await
|
||||
@@ -2006,7 +2006,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
async fn start_task(&mut self, task: Option<TaskName>) -> Result<Value> {
|
||||
async fn start_task(&mut self, task: Option<RadarrTaskName>) -> Result<Value> {
|
||||
let event = RadarrEvent::StartTask(None);
|
||||
let task_name = if let Some(t_name) = task {
|
||||
t_name
|
||||
|
||||
@@ -733,9 +733,9 @@ mod test {
|
||||
.data
|
||||
.radarr_data
|
||||
.tasks
|
||||
.set_items(vec![Task {
|
||||
task_name: TaskName::default(),
|
||||
..Task::default()
|
||||
.set_items(vec![RadarrTask {
|
||||
task_name: RadarrTaskName::default(),
|
||||
..RadarrTask::default()
|
||||
}]);
|
||||
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
|
||||
|
||||
@@ -767,7 +767,7 @@ mod test {
|
||||
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
|
||||
|
||||
if let RadarrSerdeable::Value(value) = network
|
||||
.handle_radarr_event(RadarrEvent::StartTask(Some(TaskName::default())))
|
||||
.handle_radarr_event(RadarrEvent::StartTask(Some(RadarrTaskName::default())))
|
||||
.await
|
||||
.unwrap()
|
||||
{
|
||||
@@ -2666,7 +2666,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_get_tasks_event() {
|
||||
async fn test_handle_get_radarr_tasks_event() {
|
||||
let tasks_json = json!([{
|
||||
"name": "Application Check Update",
|
||||
"taskName": "ApplicationCheckUpdate",
|
||||
@@ -2683,20 +2683,20 @@ mod test {
|
||||
"nextExecution": "2023-05-20T21:29:16Z",
|
||||
"lastDuration": "00:00:00.5111547",
|
||||
}]);
|
||||
let response: Vec<Task> = serde_json::from_value(tasks_json.clone()).unwrap();
|
||||
let response: Vec<RadarrTask> = serde_json::from_value(tasks_json.clone()).unwrap();
|
||||
let timestamp = DateTime::from(DateTime::parse_from_rfc3339("2023-05-20T21:29:16Z").unwrap());
|
||||
let expected_tasks = vec![
|
||||
Task {
|
||||
RadarrTask {
|
||||
name: "Application Check Update".to_owned(),
|
||||
task_name: TaskName::ApplicationCheckUpdate,
|
||||
task_name: RadarrTaskName::ApplicationCheckUpdate,
|
||||
interval: 360,
|
||||
last_execution: timestamp,
|
||||
next_execution: timestamp,
|
||||
last_duration: "00:00:00.5111547".to_owned(),
|
||||
},
|
||||
Task {
|
||||
RadarrTask {
|
||||
name: "Backup".to_owned(),
|
||||
task_name: TaskName::Backup,
|
||||
task_name: RadarrTaskName::Backup,
|
||||
interval: 10080,
|
||||
last_execution: timestamp,
|
||||
next_execution: timestamp,
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::{
|
||||
},
|
||||
sonarr_models::{
|
||||
BlocklistResponse, DownloadRecord, DownloadsResponse, Episode, IndexerSettings, Series,
|
||||
SonarrHistoryItem, SonarrHistoryWrapper, SonarrSerdeable, SystemStatus,
|
||||
SonarrHistoryItem, SonarrHistoryWrapper, SonarrSerdeable, SonarrTask, SystemStatus,
|
||||
},
|
||||
stateful_table::StatefulTable,
|
||||
HorizontallyScrollableText, Route, Scrollable, ScrollableText,
|
||||
@@ -60,6 +60,7 @@ pub enum SonarrEvent {
|
||||
GetSeriesHistory(Option<i64>),
|
||||
GetStatus,
|
||||
GetTags,
|
||||
GetTasks,
|
||||
HealthCheck,
|
||||
ListSeries,
|
||||
MarkHistoryItemAsFailed(i64),
|
||||
@@ -88,6 +89,7 @@ impl NetworkResource for SonarrEvent {
|
||||
SonarrEvent::GetSeasonReleases(_) | SonarrEvent::GetEpisodeReleases(_) => "/release",
|
||||
SonarrEvent::GetSeriesHistory(_) => "/history/series",
|
||||
SonarrEvent::GetStatus => "/system/status",
|
||||
SonarrEvent::GetTasks => "/system/task",
|
||||
SonarrEvent::HealthCheck => "/health",
|
||||
SonarrEvent::ListSeries | SonarrEvent::GetSeriesDetails(_) => "/series",
|
||||
SonarrEvent::MarkHistoryItemAsFailed(_) => "/history/failed",
|
||||
@@ -202,6 +204,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
.map(SonarrSerdeable::from),
|
||||
SonarrEvent::GetStatus => self.get_sonarr_status().await.map(SonarrSerdeable::from),
|
||||
SonarrEvent::GetTags => self.get_sonarr_tags().await.map(SonarrSerdeable::from),
|
||||
SonarrEvent::GetTasks => self.get_sonarr_tasks().await.map(SonarrSerdeable::from),
|
||||
SonarrEvent::HealthCheck => self
|
||||
.get_sonarr_healthcheck()
|
||||
.await
|
||||
@@ -1156,6 +1159,21 @@ impl<'a, 'b> Network<'a, 'b> {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_sonarr_tasks(&mut self) -> Result<Vec<SonarrTask>> {
|
||||
info!("Fetching Sonarr tasks");
|
||||
let event = SonarrEvent::GetTasks;
|
||||
|
||||
let request_props = self
|
||||
.request_props_from(event, RequestMethod::Get, None::<()>, None, None)
|
||||
.await;
|
||||
|
||||
self
|
||||
.handle_request::<(), Vec<SonarrTask>>(request_props, |tasks_vec, mut app| {
|
||||
app.data.sonarr_data.tasks.set_items(tasks_vec);
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
async fn mark_sonarr_history_item_as_failed(&mut self, history_item_id: i64) -> Result<Value> {
|
||||
info!("Marking the Sonarr history item with ID: {history_item_id} as 'failed'");
|
||||
let event = SonarrEvent::MarkHistoryItemAsFailed(history_item_id);
|
||||
|
||||
@@ -20,13 +20,14 @@ mod test {
|
||||
DiskSpace, HostConfig, Indexer, IndexerField, Language, LogResponse, Quality, QualityProfile,
|
||||
QualityWrapper, QueueEvent, Release, RootFolder, SecurityConfig, Tag,
|
||||
};
|
||||
use crate::models::sonarr_models::SystemStatus;
|
||||
use crate::models::sonarr_models::{
|
||||
BlocklistItem, DownloadRecord, DownloadsResponse, Episode, EpisodeFile, MediaInfo,
|
||||
SonarrTaskName,
|
||||
};
|
||||
use crate::models::sonarr_models::{
|
||||
BlocklistResponse, SonarrHistoryData, SonarrHistoryItem, SonarrHistoryWrapper,
|
||||
};
|
||||
use crate::models::sonarr_models::{SonarrTask, SystemStatus};
|
||||
use crate::models::stateful_table::StatefulTable;
|
||||
use crate::models::HorizontallyScrollableText;
|
||||
use crate::models::{sonarr_models::SonarrSerdeable, stateful_table::SortOption};
|
||||
@@ -217,6 +218,7 @@ mod test {
|
||||
#[case(SonarrEvent::GetLogs(Some(500)), "/log")]
|
||||
#[case(SonarrEvent::GetQualityProfiles, "/qualityprofile")]
|
||||
#[case(SonarrEvent::GetStatus, "/system/status")]
|
||||
#[case(SonarrEvent::GetTasks, "/system/task")]
|
||||
#[case(SonarrEvent::MarkHistoryItemAsFailed(0), "/history/failed")]
|
||||
fn test_resource(#[case] event: SonarrEvent, #[case] expected_uri: String) {
|
||||
assert_str_eq!(event.resource(), expected_uri);
|
||||
@@ -3675,6 +3677,70 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_get_sonarr_tasks_event() {
|
||||
let tasks_json = json!([{
|
||||
"name": "Application Update Check",
|
||||
"taskName": "ApplicationUpdateCheck",
|
||||
"interval": 360,
|
||||
"lastExecution": "2023-05-20T21:29:16Z",
|
||||
"nextExecution": "2023-05-20T21:29:16Z",
|
||||
"lastDuration": "00:00:00.5111547",
|
||||
},
|
||||
{
|
||||
"name": "Backup",
|
||||
"taskName": "Backup",
|
||||
"interval": 10080,
|
||||
"lastExecution": "2023-05-20T21:29:16Z",
|
||||
"nextExecution": "2023-05-20T21:29:16Z",
|
||||
"lastDuration": "00:00:00.5111547",
|
||||
}]);
|
||||
let response: Vec<SonarrTask> = serde_json::from_value(tasks_json.clone()).unwrap();
|
||||
let timestamp = DateTime::from(DateTime::parse_from_rfc3339("2023-05-20T21:29:16Z").unwrap());
|
||||
let expected_tasks = vec![
|
||||
SonarrTask {
|
||||
name: "Application Update Check".to_owned(),
|
||||
task_name: SonarrTaskName::ApplicationUpdateCheck,
|
||||
interval: 360,
|
||||
last_execution: timestamp,
|
||||
next_execution: timestamp,
|
||||
last_duration: "00:00:00.5111547".to_owned(),
|
||||
},
|
||||
SonarrTask {
|
||||
name: "Backup".to_owned(),
|
||||
task_name: SonarrTaskName::Backup,
|
||||
interval: 10080,
|
||||
last_execution: timestamp,
|
||||
next_execution: timestamp,
|
||||
last_duration: "00:00:00.5111547".to_owned(),
|
||||
},
|
||||
];
|
||||
let (async_server, app_arc, _server) = mock_servarr_api(
|
||||
RequestMethod::Get,
|
||||
None,
|
||||
Some(tasks_json),
|
||||
None,
|
||||
SonarrEvent::GetTasks,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
|
||||
|
||||
if let SonarrSerdeable::Tasks(tasks) = network
|
||||
.handle_sonarr_event(SonarrEvent::GetTasks)
|
||||
.await
|
||||
.unwrap()
|
||||
{
|
||||
async_server.assert_async().await;
|
||||
assert_eq!(
|
||||
app_arc.lock().await.data.sonarr_data.tasks.items,
|
||||
expected_tasks
|
||||
);
|
||||
assert_eq!(tasks, response);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_mark_sonarr_history_item_as_failed_event() {
|
||||
let expected_history_item_id = 1;
|
||||
|
||||
@@ -12,7 +12,7 @@ use ratatui::{
|
||||
};
|
||||
|
||||
use crate::app::App;
|
||||
use crate::models::radarr_models::Task;
|
||||
use crate::models::radarr_models::RadarrTask;
|
||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||
use crate::models::servarr_models::QueueEvent;
|
||||
use crate::ui::radarr_ui::radarr_ui_utils::{convert_to_minutes_hours_days, style_log_list_item};
|
||||
@@ -91,7 +91,7 @@ pub(super) fn draw_system_ui_layout(f: &mut Frame<'_>, app: &mut App<'_>, area:
|
||||
}
|
||||
|
||||
fn draw_tasks(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
||||
let tasks_row_mapping = |task: &Task| {
|
||||
let tasks_row_mapping = |task: &RadarrTask| {
|
||||
let task_props = extract_task_props(task);
|
||||
|
||||
Row::new(vec![
|
||||
@@ -218,7 +218,7 @@ pub(super) struct TaskProps {
|
||||
pub(super) next_execution: String,
|
||||
}
|
||||
|
||||
pub(super) fn extract_task_props(task: &Task) -> TaskProps {
|
||||
pub(super) fn extract_task_props(task: &RadarrTask) -> TaskProps {
|
||||
let interval = convert_to_minutes_hours_days(task.interval);
|
||||
let last_duration = &task.last_duration[..8];
|
||||
let next_execution =
|
||||
|
||||
@@ -6,7 +6,7 @@ use ratatui::Frame;
|
||||
use crate::app::context_clues::{build_context_clue_string, BARE_POPUP_CONTEXT_CLUES};
|
||||
use crate::app::radarr::radarr_context_clues::SYSTEM_TASKS_CONTEXT_CLUES;
|
||||
use crate::app::App;
|
||||
use crate::models::radarr_models::Task;
|
||||
use crate::models::radarr_models::RadarrTask;
|
||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS};
|
||||
use crate::models::Route;
|
||||
use crate::ui::radarr_ui::radarr_ui_utils::style_log_list_item;
|
||||
@@ -108,7 +108,7 @@ fn draw_logs_popup(f: &mut Frame<'_>, app: &mut App<'_>) {
|
||||
|
||||
fn draw_tasks_popup(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
|
||||
let help_footer = Some(build_context_clue_string(&SYSTEM_TASKS_CONTEXT_CLUES));
|
||||
let tasks_row_mapping = |task: &Task| {
|
||||
let tasks_row_mapping = |task: &RadarrTask| {
|
||||
let task_props = extract_task_props(task);
|
||||
|
||||
Row::new(vec![
|
||||
|
||||
Reference in New Issue
Block a user