use crate::{FilesClient, PaginationInfo, Result};
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AutomationType {
CreateFolder,
DeleteFile,
CopyFile,
MoveFile,
As2Send,
RunSync,
ImportFile,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AutomationTrigger {
Daily,
Custom,
Webhook,
Email,
Action,
Interval,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AutomationEntity {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub always_serialize_jobs: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub always_overwrite_size_matching_files: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub automation: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deleted: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub destination_replace_from: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub destination_replace_to: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub destinations: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub disabled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exclude_pattern: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub flatten_destination_structure: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub group_ids: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub holiday_region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub human_readable_schedule: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ignore_locked_folders: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub import_urls: Option<Vec<serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub interval: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_modified_at: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub legacy_folder_matching: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub legacy_sync_ids: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub overwrite_files: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub path_time_zone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub recurring_day: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub retry_on_failure_interval_in_minutes: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub retry_on_failure_number_of_attempts: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule_days_of_week: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule_time_zone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule_times_of_day: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sync_ids: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_actions: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_ids: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub value: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub webhook_url: Option<String>,
}
pub struct AutomationHandler {
client: FilesClient,
}
impl AutomationHandler {
pub fn new(client: FilesClient) -> Self {
Self { client }
}
pub async fn list(
&self,
cursor: Option<&str>,
per_page: Option<i64>,
automation: Option<&str>,
) -> Result<(Vec<AutomationEntity>, PaginationInfo)> {
let mut params = vec![];
if let Some(c) = cursor {
params.push(("cursor", c.to_string()));
}
if let Some(pp) = per_page {
params.push(("per_page", pp.to_string()));
}
if let Some(a) = automation {
params.push(("automation", a.to_string()));
}
let query = if params.is_empty() {
String::new()
} else {
format!(
"?{}",
params
.iter()
.map(|(k, v)| format!("{}={}", k, v))
.collect::<Vec<_>>()
.join("&")
)
};
let response = self
.client
.get_raw(&format!("/automations{}", query))
.await?;
let automations: Vec<AutomationEntity> = serde_json::from_value(response)?;
let pagination = PaginationInfo {
cursor_next: None,
cursor_prev: None,
};
Ok((automations, pagination))
}
pub async fn get(&self, id: i64) -> Result<AutomationEntity> {
let response = self.client.get_raw(&format!("/automations/{}", id)).await?;
Ok(serde_json::from_value(response)?)
}
#[allow(clippy::too_many_arguments)]
pub async fn create(
&self,
automation: &str,
source: Option<&str>,
destination: Option<&str>,
destinations: Option<Vec<String>>,
interval: Option<&str>,
path: Option<&str>,
trigger: Option<&str>,
) -> Result<AutomationEntity> {
let mut request_body = json!({
"automation": automation,
});
if let Some(s) = source {
request_body["source"] = json!(s);
}
if let Some(d) = destination {
request_body["destination"] = json!(d);
}
if let Some(dests) = destinations {
request_body["destinations"] = json!(dests);
}
if let Some(i) = interval {
request_body["interval"] = json!(i);
}
if let Some(p) = path {
request_body["path"] = json!(p);
}
if let Some(t) = trigger {
request_body["trigger"] = json!(t);
}
let response = self.client.post_raw("/automations", request_body).await?;
Ok(serde_json::from_value(response)?)
}
#[allow(clippy::too_many_arguments)]
pub async fn update(
&self,
id: i64,
source: Option<&str>,
destination: Option<&str>,
interval: Option<&str>,
disabled: Option<bool>,
) -> Result<AutomationEntity> {
let mut request_body = json!({});
if let Some(s) = source {
request_body["source"] = json!(s);
}
if let Some(d) = destination {
request_body["destination"] = json!(d);
}
if let Some(i) = interval {
request_body["interval"] = json!(i);
}
if let Some(dis) = disabled {
request_body["disabled"] = json!(dis);
}
let response = self
.client
.patch_raw(&format!("/automations/{}", id), request_body)
.await?;
Ok(serde_json::from_value(response)?)
}
pub async fn delete(&self, id: i64) -> Result<()> {
self.client
.delete_raw(&format!("/automations/{}", id))
.await?;
Ok(())
}
pub async fn manual_run(&self, id: i64) -> Result<serde_json::Value> {
let response = self
.client
.post_raw(&format!("/automations/{}/manual_run", id), json!({}))
.await?;
Ok(response)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_handler_creation() {
let client = FilesClient::builder().api_key("test-key").build().unwrap();
let _handler = AutomationHandler::new(client);
}
}