autopulse_service/settings/triggers/
sonarr.rs1use crate::settings::path_filter::PathFilter;
2use crate::settings::rewrite::Rewrite;
3use crate::settings::timer::{EventTimers, Timer};
4use crate::settings::triggers::{TriggerConfig, TriggerRequest};
5use autopulse_utils::join_path;
6use serde::{Deserialize, Serialize};
7
8#[derive(Serialize, Deserialize, Clone)]
9pub struct Sonarr {
10 pub rewrite: Option<Rewrite>,
12 pub timer: Option<Timer>,
14 #[serde(default)]
16 pub excludes: Vec<String>,
17 #[serde(default)]
19 pub filter: PathFilter,
20 pub event_timers: Option<EventTimers>,
22}
23
24impl TriggerConfig for Sonarr {
25 fn rewrite(&self) -> Option<&Rewrite> {
26 self.rewrite.as_ref()
27 }
28
29 fn timer(&self) -> Option<&Timer> {
30 self.timer.as_ref()
31 }
32
33 fn excludes(&self) -> &Vec<String> {
34 &self.excludes
35 }
36
37 fn filter(&self) -> &PathFilter {
38 &self.filter
39 }
40
41 fn event_timers(&self) -> Option<&EventTimers> {
42 self.event_timers.as_ref()
43 }
44}
45
46#[derive(Deserialize, Clone)]
47#[serde(rename_all = "camelCase")]
48#[doc(hidden)]
49pub struct EpisodeFile {
50 pub relative_path: String,
51}
52
53#[derive(Deserialize, Clone)]
54#[serde(rename_all = "camelCase")]
55#[doc(hidden)]
56pub struct Series {
57 pub path: String,
58}
59
60#[derive(Deserialize, Clone)]
61#[serde(rename_all = "camelCase")]
62#[doc(hidden)]
63pub struct RenamedEpisodeFile {
64 pub previous_path: String,
65 pub relative_path: String,
66}
67#[derive(Deserialize, Clone)]
68#[serde(tag = "eventType")]
69#[doc(hidden)]
70pub enum SonarrRequest {
71 #[serde(rename = "Download")]
72 #[serde(rename_all = "camelCase")]
73 Download {
74 episode_file: Option<EpisodeFile>,
76 #[serde(default)]
78 episode_files: Vec<EpisodeFile>,
79 #[serde(default)]
80 deleted_files: Vec<EpisodeFile>,
81 series: Series,
82 },
83 #[serde(rename = "Rename")]
84 #[serde(rename_all = "camelCase")]
85 Rename {
86 series: Series,
87 renamed_episode_files: Vec<RenamedEpisodeFile>,
88 },
89 #[serde(rename = "SeriesDelete")]
90 #[serde(rename_all = "camelCase")]
91 SeriesDelete { series: Series },
92 #[serde(rename = "EpisodeFileDelete")]
93 #[serde(rename_all = "camelCase")]
94 EpisodeFileDelete {
95 episode_file: EpisodeFile,
96 series: Series,
97 },
98 #[serde(rename = "Test")]
99 Test,
100 #[serde(other)]
101 Other,
102}
103
104impl TriggerRequest for SonarrRequest {
105 fn from_json(json: serde_json::Value) -> anyhow::Result<Self> {
106 serde_json::from_value(json).map_err(|e| anyhow::anyhow!(e))
107 }
108
109 fn paths(&self) -> Vec<(String, bool)> {
110 match self {
111 Self::EpisodeFileDelete {
112 episode_file,
113 series,
114 } => {
115 vec![(join_path(&series.path, &episode_file.relative_path), false)]
116 }
117 Self::Rename {
118 series,
119 renamed_episode_files,
120 } => {
121 let mut paths = vec![];
122
123 for file in renamed_episode_files {
124 paths.push((file.previous_path.clone(), false));
125 paths.push((join_path(&series.path, &file.relative_path), true));
126 }
127
128 paths
129 }
130 Self::SeriesDelete { series } => vec![(series.path.clone(), false)],
131 Self::Download {
132 episode_file,
133 episode_files,
134 series,
135 deleted_files,
136 } => {
137 let mut paths: Vec<(String, bool)> = vec![];
138
139 if let Some(ef) = episode_file {
140 paths.push((join_path(&series.path, &ef.relative_path), true));
141 }
142
143 for ef in episode_files {
144 paths.push((join_path(&series.path, &ef.relative_path), true));
145 }
146
147 for file in deleted_files {
148 paths.push((join_path(&series.path, &file.relative_path), false));
149 }
150
151 paths
152 }
153 Self::Test | Self::Other => vec![],
154 }
155 }
156}