autopulse_service/settings/triggers/
sonarr.rs

1use crate::settings::rewrite::Rewrite;
2use crate::settings::timer::{EventTimers, Timer};
3use crate::settings::triggers::TriggerRequest;
4use autopulse_utils::join_path;
5use serde::{Deserialize, Serialize};
6
7#[derive(Serialize, Deserialize, Clone)]
8pub struct Sonarr {
9    /// Rewrite path
10    pub rewrite: Option<Rewrite>,
11    /// Timer settings
12    pub timer: Option<Timer>,
13    /// Targets to ignore
14    #[serde(default)]
15    pub excludes: Vec<String>,
16    /// Event-specific timers
17    pub event_timers: Option<EventTimers>,
18}
19
20#[derive(Deserialize, Clone)]
21#[serde(rename_all = "camelCase")]
22#[doc(hidden)]
23pub struct EpisodeFile {
24    pub relative_path: String,
25}
26
27#[derive(Deserialize, Clone)]
28#[serde(rename_all = "camelCase")]
29#[doc(hidden)]
30pub struct Series {
31    pub path: String,
32}
33
34#[derive(Deserialize, Clone)]
35#[serde(rename_all = "camelCase")]
36#[doc(hidden)]
37pub struct RenamedEpisodeFile {
38    pub previous_path: String,
39    pub relative_path: String,
40}
41#[derive(Deserialize, Clone)]
42#[serde(tag = "eventType")]
43#[doc(hidden)]
44pub enum SonarrRequest {
45    #[serde(rename = "Download")]
46    #[serde(rename_all = "camelCase")]
47    Download {
48        episode_file: EpisodeFile,
49        #[serde(default)]
50        deleted_files: Vec<EpisodeFile>,
51        series: Series,
52    },
53    #[serde(rename = "Rename")]
54    #[serde(rename_all = "camelCase")]
55    Rename {
56        series: Series,
57        renamed_episode_files: Vec<RenamedEpisodeFile>,
58    },
59    #[serde(rename = "SeriesDelete")]
60    #[serde(rename_all = "camelCase")]
61    SeriesDelete { series: Series },
62    #[serde(rename = "EpisodeFileDelete")]
63    #[serde(rename_all = "camelCase")]
64    EpisodeFileDelete {
65        episode_file: EpisodeFile,
66        series: Series,
67    },
68    #[serde(rename = "Test")]
69    Test,
70}
71
72impl TriggerRequest for SonarrRequest {
73    fn from_json(json: serde_json::Value) -> anyhow::Result<Self> {
74        serde_json::from_value(json).map_err(|e| anyhow::anyhow!(e))
75    }
76
77    fn paths(&self) -> Vec<(String, bool)> {
78        match self {
79            Self::EpisodeFileDelete {
80                episode_file,
81                series,
82            } => {
83                vec![(join_path(&series.path, &episode_file.relative_path), false)]
84            }
85            Self::Rename {
86                series,
87                renamed_episode_files,
88            } => {
89                let mut paths = vec![];
90
91                for file in renamed_episode_files {
92                    paths.push((file.previous_path.clone(), false));
93                    paths.push((join_path(&series.path, &file.relative_path), true));
94                }
95
96                paths
97            }
98            Self::SeriesDelete { series } => vec![(series.path.clone(), false)],
99            Self::Download {
100                episode_file,
101                series,
102                deleted_files,
103            } => {
104                let mut paths = vec![(join_path(&series.path, &episode_file.relative_path), true)];
105
106                for file in deleted_files {
107                    paths.push((join_path(&series.path, &file.relative_path), false));
108                }
109
110                paths
111            }
112            Self::Test => vec![],
113        }
114    }
115}