autopulse_service/settings/triggers/
sportarr.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 Sportarr {
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 Sportarr {
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)]
56#[serde(rename_all = "camelCase")]
57#[doc(hidden)]
58pub struct Series {
59 pub path: Option<String>,
60}
61
62#[derive(Deserialize, Clone)]
63#[serde(tag = "eventType")]
64#[doc(hidden)]
65pub enum SportarrRequest {
66 #[serde(rename = "Download")]
67 #[serde(rename_all = "camelCase")]
68 Download {
69 episode_file: Option<EpisodeFile>,
70 #[serde(default)]
71 episode_files: Vec<EpisodeFile>,
72 #[serde(default)]
73 deleted_files: Vec<EpisodeFile>,
74 series: Series,
75 },
76 #[serde(rename = "Rename")]
78 #[serde(rename_all = "camelCase")]
79 Rename { series: Series },
80 #[serde(rename = "SeriesDelete")]
81 #[serde(rename_all = "camelCase")]
82 SeriesDelete { series: Series },
83 #[serde(rename = "EpisodeFileDelete")]
85 #[serde(rename_all = "camelCase")]
86 EpisodeFileDelete {
87 #[serde(default)]
88 deleted_files: Vec<EpisodeFile>,
89 series: Series,
90 },
91 #[serde(rename = "Test")]
92 Test,
93 #[serde(other)]
94 Other,
95}
96
97impl TriggerRequest for SportarrRequest {
98 fn from_json(json: serde_json::Value) -> anyhow::Result<Self> {
99 serde_json::from_value(json).map_err(|e| anyhow::anyhow!(e))
100 }
101
102 fn paths(&self) -> Vec<(String, bool)> {
103 match self {
104 Self::EpisodeFileDelete {
105 deleted_files,
106 series,
107 } => {
108 let Some(series_path) = series.path.as_ref() else {
109 return vec![];
110 };
111
112 deleted_files
113 .iter()
114 .map(|f| (join_path(series_path, &f.relative_path), false))
115 .collect()
116 }
117 Self::Rename { series } => series
118 .path
119 .clone()
120 .map(|path| vec![(path, true)])
121 .unwrap_or_default(),
122 Self::SeriesDelete { series } => series
123 .path
124 .clone()
125 .map(|path| vec![(path, false)])
126 .unwrap_or_default(),
127 Self::Download {
128 episode_file,
129 episode_files,
130 series,
131 deleted_files,
132 } => {
133 let mut paths: Vec<(String, bool)> = vec![];
134
135 let Some(series_path) = series.path.as_ref() else {
136 return paths;
137 };
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}