rs_plugin_common_interfaces/
lib.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use strum_macros::EnumString;
4
5pub use domain::{element_type::ElementType, external_images::{ExternalImage, ImageType}};
6pub use request::{RsRequest, RsCookie, RsCookies, RsRequestFiles, RsRequestPluginRequest, RsRequestStatus};
7pub use url::{RsLink, RsLinkType};
8pub use lookup::{RsLookupEpisode, RsLookupBook, RsLookupMovie, RsLookupMedia, RsLookupPerson, RsLookupSerie, RsLookupSerieSeason, RsLookupSong, RsLookupQuery, RsLookupSourceResult, RsLookupWrapper};
9
10pub use video::{RsAudio, RsResolution, RsVideoCodec, RsVideoFormat};
11
12#[cfg(feature = "rusqlite")]
13pub mod rusqlite;
14
15pub mod request;
16pub mod url;
17pub mod lookup;
18pub mod provider;
19
20pub mod video;
21
22pub mod domain;
23
24pub const INTERFACE_VERSION: u16 = 1;
25
26#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
27#[serde(rename_all = "camelCase")]
28pub struct CustomParam {
29 pub name: String,
30 pub param: CustomParamTypes,
31 pub description: Option<String>,
32 #[serde(default)]
33 pub required: bool
34}
35
36
37
38#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
39#[serde(rename_all = "camelCase")]
40pub struct PluginInformation {
41 pub name: String,
42 pub capabilities: Vec<PluginType>,
43 pub publisher: String,
44 pub description: String,
45 pub credential_kind: Option<CredentialType>,
46 pub oauth_url: Option<String>,
47 pub version: u16,
48
49 #[serde(default)]
50 pub settings: Vec<CustomParam>,
51
52 pub interface_version: u16,
53}
54
55impl PluginInformation {
56 pub fn capabilities_tostring(&self) -> String {
57 self.capabilities.iter()
58 .map(|plugin| plugin.to_string())
59 .collect::<Vec<_>>()
60 .join(", ")
61 }
62}
63
64
65
66
67#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, strum_macros::Display,EnumString, Default)]
68#[serde(rename_all = "camelCase")]
69#[strum(serialize_all = "camelCase")]
70pub enum PluginType {
71 ImageClassification,
72 UrlParser,
73 Request,
74 Lookup,
75 Provider,
76 #[default]
77 Other,
78}
79
80#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, strum_macros::Display,EnumString, Default)]
81#[serde(rename_all = "camelCase", tag = "type")]
82#[strum(serialize_all = "camelCase")]
83pub enum CredentialType {
84 Url,
85 Password,
86 Oauth {
87 url: String
89 },
90 #[default]
91 Token,
92}
93
94#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, strum_macros::Display,EnumString)]
95#[serde(rename_all = "camelCase")]
96#[strum(serialize_all = "camelCase")]
97pub enum CustomParamTypes {
98 Text(Option<String>),
99 Url(Option<String>),
100 Integer(Option<i64>),
101 UInteger(Option<u64>),
102 Float(Option<f64>),
103}
104
105#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
106#[serde(rename_all = "camelCase")]
107pub struct PluginCredential {
108 pub kind: CredentialType,
109 pub login: Option<String>,
110 pub password: Option<String>,
111 pub settings: Value,
112 pub user_ref: Option<String>,
113 pub refresh_token: Option<String>,
114 pub expires: Option<i64>,
115}
116
117#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, strum_macros::Display,EnumString, Default)]
118#[strum(serialize_all = "camelCase")]
119#[serde(rename_all = "camelCase")]
120pub enum RsFileType {
121 Directory,
122 Photo,
123 Video,
124 Archive,
125 Album,
126 #[default]
127 Other
128}
129
130#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, strum_macros::Display, EnumString, Default)]
131#[serde(rename_all = "camelCase")]
132#[strum(serialize_all = "camelCase")]
133pub enum MediaType {
134 Movie,
135 Episode,
136 Book,
137 Song,
138 #[strum(default)]
139 Custom(String),
140 #[default]
141 Unknown,
142}
143
144#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, strum_macros::Display, EnumString, Default)]
145#[serde(rename_all = "camelCase")]
146#[strum(serialize_all = "camelCase")]
147pub enum Gender {
148 Male,
149 Female,
150 Animal,
151 Other,
152 #[strum(default)]
153 Custom(String),
154 #[default]
155 Unknown,
156}
157
158
159
160#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
161#[serde(rename_all = "camelCase")]
162pub struct RsPluginRequest<T> {
163 pub request: T,
164 pub plugin_settings: Value,
165 pub credential: Option<PluginCredential>
166}
167
168
169
170
171#[cfg(test)]
172mod tests {
173 use std::str::FromStr;
174
175 use super::*;
176
177 #[test]
178 fn resolution_parsing() {
179 assert_eq!(RsResolution::from_filename("Test.2024.S01E01.1080p.VOSTFR.DSNP.WEB-DL.DDP5.1.H.264"), RsResolution::FullHD);
180 assert_eq!(RsResolution::from_filename("Test.2024.S01E01_720p VOSTFR.DSNP.WEB-DL.DDP5.1.H.264"), RsResolution::HD);
181 assert_eq!(RsResolution::from_filename("TestIn4k.2024.S01E01_VOSTFR.DSNP.WEB-DL.DDP5.1.H.264"), RsResolution::Unknown);
182 assert_eq!(RsResolution::from_filename("TestIn4k.2024.S01E01_4K_VOSTFR.DSNP.WEB-DL.DDP5.Atmos.1.H.264"), RsResolution::UHD);
183 }
184
185
186 #[test]
187 fn resolution_string() {
188 assert_eq!("4K", RsResolution::UHD.to_string());
189 assert_eq!(RsResolution::from_str("1080p").unwrap(), RsResolution::FullHD);
190 assert_eq!(RsResolution::from_str("erzr").unwrap(), RsResolution::Custom("erzr".to_owned()));
191 }
192 #[test]
193 fn audio_parsing() {
194 assert_eq!(RsAudio::from_filename("Test.2024.S01E01.1080p.VOSTFR.DSNP.WEB-DL.DDP5.1.H.264"), RsAudio::DDP51);
195 assert_eq!(RsAudio::from_filename("Test.2024.S01E01_720p VOSTFR.DSNP.WEB-DL.DDP5.1._atmos_H.264"), RsAudio::Atmos);
196 let list = RsAudio::list_from_filename("TestIn4k.2024.S01E01_4K_VOSTFR.DSNP.WEB-DL.DDP5.1.Atmos.H.264");
197 assert_eq!(list.len(), 2);
198 assert!(list.contains(&RsAudio::Atmos));
199 assert!(list.contains(&RsAudio::DDP51));
200 }
201
202 #[test]
203 fn videocodec_parsing() {
204 assert_eq!(RsVideoCodec::from_filename("Test.2024.S01E01.1080p.VOSTFR.DSNP.WEB-DL.DDP5.1.H.264"), RsVideoCodec::H264);
205 assert_eq!(RsVideoCodec::from_filename("Test.2024.S01E01_720p VOSTFR.DSNP.WEB-DL.DDP5.1.HEVC"), RsVideoCodec::H265);
206 assert_eq!(RsVideoCodec::from_filename("TestIn4k.2024.S01E01_VOSTFR.DSNP.WEB-DL.DDP5.1.X.265"), RsVideoCodec::H265);
207
208 }
209
210 #[test]
211 fn video_format_parsing() {
212 assert_eq!(RsVideoFormat::from_filename("Test.2024.S01E01.1080p.VOSTFR.DSNP.WEB-DL.DDP5.1.H.264.mp4"), RsVideoFormat::Mp4);
213 assert_eq!(RsVideoFormat::from_filename("Test.2024.S01E01_720p VOSTFR.DSNP.WEB-DL.DDP5.1._atmos_H.264"), RsVideoFormat::Other);
214 assert_eq!(RsVideoFormat::from_filename("Test.2024.S01E01.1080p.VOSTFR.DSNP.WEB-DL.DDP5.1.H.264.WMV"), RsVideoFormat::Wmv);
215
216 assert_eq!(RsVideoFormat::Mp4.to_string(), "mp4");
217 assert_eq!(RsVideoFormat::from_str("mkv").unwrap(), RsVideoFormat::Mkv);
218 }
219}