1#![allow(unused)]
2use crate::serde_types::*;
4use anyhow::{Context, Result};
5use serde::{Deserialize, Serialize};
7use std::env;
9use std::fs;
11
12const SERVER_URL: &str = "https://storage.bunnycdn.com";
13
14#[derive(Debug)]
15pub enum ResponseData {
16 StorageInfo(Vec<Option<StorageObject>>),
17 BunnyStatus(BunnyResponse),
18 HttpStatus(reqwest::StatusCode),
19}
20
21impl ResponseData {
22 pub fn print(&self) {
23 match self {
24 ResponseData::StorageInfo(storage) => {
25 let json = serde_json::to_string_pretty(&storage).unwrap();
26 println!("{}", json);
27 }
28 ResponseData::HttpStatus(status) => {
29 if !status.is_success() {
30 error!("{}", status);
31 } else {
32 println!("{}", status);
33 }
34 }
35 ResponseData::BunnyStatus(status) => {
36 println!("{:?}", status);
37 }
38 }
39 }
40}
41
42#[derive(Debug, Serialize, Deserialize)]
43pub struct StorageZone {
44 api_endpoint: String,
45 name: String,
46 api_key: String,
47}
48
49impl StorageZone {
50 pub fn new(name: String, api_key: String) -> Self {
51 StorageZone {
52 name,
53 api_key,
54 api_endpoint: SERVER_URL.to_string(),
55 }
56 }
57
58 pub fn set_api_endpoint(&mut self, api_endpoint: &str) -> &Self {
59 self.api_endpoint = api_endpoint.to_string();
60 self
61 }
62
63 pub fn name(&self) -> String {
64 self.name.clone()
65 }
66
67 pub async fn download_file(&self, file_path: &str, object_url: &str) -> Result<ResponseData> {
68 let request_url = format!("{}/{}/{}", self.api_endpoint, self.name, object_url);
69 trace!("{}", request_url);
70 let response = reqwest::Client::new()
72 .get(&request_url)
73 .header("AccessKey", &self.api_key)
74 .header("Accept", "application/json")
75 .header("Accept-Encoding", "gzip, br")
76 .send()
77 .await?;
78
79 let http_status = response.status();
80 let response_data = ResponseData::HttpStatus(http_status);
81 if http_status.as_u16() == 200 {
82 let data = response.text().await?;
83 fs::write(file_path, data)?;
84 }
85 Ok(response_data)
92 }
93
94 pub async fn upload_file(&self, file_path: &str, object_url: &str) -> Result<ResponseData> {
95 let request_url = format!("{}/{}/{}", self.api_endpoint, self.name, object_url);
96 let pwd = env::current_dir().unwrap();
97 trace!("request_url:{}, file_path:{}/{}", request_url, pwd.display(), file_path);
98 let file_contents = fs::read(file_path)?;
99 let response = reqwest::Client::new()
101 .put(&request_url)
102 .header("AccessKey", &self.api_key)
103 .header("Accept-Encoding", "gzip, br")
104 .body(file_contents)
105 .send()
106 .await?;
107
108 let http_status = response.status();
109 let response_data = ResponseData::HttpStatus(http_status);
110 if http_status.as_u16() == 201 {
111 info!("{:?}", "upload successful");
112 }
113 Ok(response_data)
114 }
115
116 pub async fn delete(&self, object_url: &str) -> Result<ResponseData> {
117 let request_url = format!("{}/{}/{}", self.api_endpoint, self.name, object_url);
118 trace!("{}", request_url);
119
120 let response = reqwest::Client::new()
121 .delete(&request_url)
122 .header("AccessKey", &self.api_key)
123 .header("Accept-Encoding", "gzip, br")
124 .send()
125 .await?;
126
127 let response_data = ResponseData::HttpStatus(response.status());
128 Ok(response_data)
133 }
134
135 pub async fn get_objects(&self, directory_url: &str) -> Result<ResponseData> {
136 let request_url = format!("{}/{}/{}", self.api_endpoint, self.name, directory_url);
137 trace!("{:?}", request_url);
138
139 let response = reqwest::Client::new()
140 .get(&request_url)
141 .header("AccessKey", &self.api_key)
142 .header("Accept", "application/json")
143 .header("Accept-Encoding", "gzip, br")
144 .send()
145 .await?;
146
147 let http_status = response.status();
148 trace!("{}", http_status);
149 let mut response_data = ResponseData::HttpStatus(http_status);
153 if http_status.as_u16() == 200 {
155 let data = response.text().await?;
158 trace!("{:?}", data);
159 let data = serde_json::from_str::<Vec<Option<StorageObject>>>(&data)
161 .context("Can't parse JSON! Make sure to select a directory not a file")?;
162 trace!("{:?}", data);
163 response_data = ResponseData::StorageInfo(data);
165 trace!("{:?}", response_data);
166 } else if http_status.as_u16() == 404 {
167 response_data = match response.json().await {
168 Ok(data) => ResponseData::BunnyStatus(data), Err(_) => response_data, };
171 trace!("{:?}", response_data);
172 } else {
173 let data = response.text().await?;
174 trace!("{} - {:?}", http_status, data);
175 }
176 Ok(response_data)
177 }
178}