Skip to main content

autopulse_service/settings/triggers/
sonarr.rs

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