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