diff --git a/src/main.rs b/src/main.rs index 4bb62a3..16daa14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ mod sharry; use log::info; -use sharry::{Alias, NewShareRequest, URI}; +use sharry::{Alias, NewShareRequest, Share}; use std::time::Duration; use ureq::Agent; @@ -14,16 +14,15 @@ fn main() { .into(); let alias = Alias::new( - URI::new("sharry.yavook.de"), + "sharry.yavook.de".into(), "G7RYoWME1W7-pcgipemJcr8-39FcMd92gBu-RgufeHc51z6", ); - let share = alias.create_share(&agent, &NewShareRequest::new(Some("foo"), "", 10)); - - let share = share.unwrap(); + let share = NewShareRequest::new(Some("foo"), "", 10); + let share = Share::create(&agent, &alias, share).unwrap(); info!("share: {:?}", share); - share.create_file(&agent, "./myfile.dat").unwrap(); + // share.create_file(&agent, "./myfile.dat").unwrap(); share.notify(&agent).unwrap(); } diff --git a/src/sharry/alias.rs b/src/sharry/alias.rs index bc04e79..8ebdcb2 100644 --- a/src/sharry/alias.rs +++ b/src/sharry/alias.rs @@ -1,41 +1,38 @@ -use log::debug; -use ureq::{Agent, RequestBuilder}; +use std::fmt::{Debug, Display}; -use super::{ - api::{NewShareRequest, NewShareResponse, URI}, - share::Share, -}; +use log::debug; +use ureq::RequestBuilder; + +use super::api::URI; #[derive(Debug)] pub struct Alias { - pub(super) uri: URI, + pub(super) api_uri: String, pub(super) id: String, } -impl Alias { - pub fn new(uri: URI, id: impl Into) -> Self { - Self { uri, id: id.into() } - } +pub(super) trait SharryAlias { + fn sharry_header(self, alias: &Alias) -> Self; +} - pub(super) fn add_headers(&self, req: RequestBuilder) -> RequestBuilder { - req.header("Sharry-Alias", &self.id) - } - - pub fn create_share(&self, http: &Agent, data: &NewShareRequest) -> Result { - let endpoint = self.uri.get_endpoint("alias/upload/new"); - - let res = self - .add_headers(http.post(endpoint)) - .send_json(data)? - .body_mut() - .read_json::()?; - - debug!("response: {:?}", res); - - if !(res.success && (res.message == "Share created.")) { - return Err(ureq::Error::Other("unexpected response json".into())); - } - - Ok(Share::new(self, res.id)) +impl SharryAlias for RequestBuilder { + fn sharry_header(self, alias: &Alias) -> Self { + self.header("Sharry-Alias", &alias.id) + } +} + +impl Alias { + pub fn new(api_uri: URI, id: impl Into) -> Self { + Self { + api_uri: api_uri.into(), + id: id.into(), + } + } + + pub(super) fn get_endpoint(&self, endpoint: impl Display + Debug) -> String { + let uri = format!("{}/{}", self.api_uri, endpoint); + debug!("endpoint uri: {:?}", uri); + + uri } } diff --git a/src/sharry/api.rs b/src/sharry/api.rs index c40afc5..21bf636 100644 --- a/src/sharry/api.rs +++ b/src/sharry/api.rs @@ -1,31 +1,28 @@ -use std::fmt::Display; - -use log::debug; use serde::{Deserialize, Serialize}; -#[derive(Debug)] pub struct URI { protocol: String, base_url: String, } impl URI { - pub fn new_protocol(base_url: impl Into, protocol: impl Into) -> Self { + pub fn with_protocol(protocol: impl Into, base_url: impl Into) -> Self { Self { protocol: protocol.into(), base_url: base_url.into(), } } +} - pub fn new(base_url: impl Into) -> Self { - Self::new_protocol(base_url, "https") +impl From<&str> for URI { + fn from(value: &str) -> Self { + Self::with_protocol("https", value) } +} - pub(super) fn get_endpoint(&self, endpoint: impl Display) -> String { - let uri = format!("{}://{}/api/v2/{}", self.protocol, self.base_url, endpoint); - debug!("uri: {:?}", uri); - - uri +impl Into for URI { + fn into(self) -> String { + format!("{}://{}/api/v2", self.protocol, self.base_url) } } diff --git a/src/sharry/mod.rs b/src/sharry/mod.rs index 0285a90..fd3e969 100644 --- a/src/sharry/mod.rs +++ b/src/sharry/mod.rs @@ -4,3 +4,4 @@ mod share; pub use alias::Alias; pub use api::{NewShareRequest, URI}; +pub use share::Share; diff --git a/src/sharry/share.rs b/src/sharry/share.rs index 71be644..421f2b4 100644 --- a/src/sharry/share.rs +++ b/src/sharry/share.rs @@ -1,81 +1,47 @@ -use log::debug; -use std::{ffi::OsStr, fs, path::Path}; -use ureq::{Agent, http::StatusCode}; +use log::{debug, warn}; -use super::{alias::Alias, api}; -use api::NotifyShareResponse; +use super::{ + alias::{Alias, SharryAlias}, + api::{NewShareRequest, NewShareResponse, NotifyShareResponse}, +}; #[derive(Debug)] pub struct Share<'t> { - alias: &'t Alias, - id: String, + pub(super) alias: &'t Alias, + pub(super) id: String, } impl<'t> Share<'t> { - pub(super) fn new(alias: &'t Alias, id: String) -> Self { - Self { alias, id } - } + pub fn create( + http: &ureq::Agent, + alias: &'t Alias, + data: NewShareRequest, + ) -> Result { + let res = http + .post(alias.get_endpoint("alias/upload/new")) + .sharry_header(alias) + .send_json(data)? + .body_mut() + .read_json::()?; - pub fn create_file( - &self, - http: &Agent, - path: impl AsRef + AsRef, - ) -> Result<(), ureq::Error> { - let filename = Path::new(&path) - .file_name() - .and_then(OsStr::to_str) - .unwrap_or("file.bin"); + debug!("response: {:?}", res); - let size = fs::metadata(&path)?.len(); - - let endpoint = self - .alias - .uri - .get_endpoint(&format!("alias/upload/{}/files/tus", &self.id)); - - let res = self - .alias - .add_headers(http.post(endpoint)) - .header("Sharry-File-Name", filename) - // .header("Sharry-File-Type", "application/octet-stream") - // .header("Sharry-File-Length", size) - // .header("Tus-Resumable", "1.0.0") - .header("Upload-Length", size) - .send_empty()?; - - if res.status() != StatusCode::CREATED { - return Err(ureq::Error::Other("unexpected response status".into())); + if !(res.success && (res.message == "Share created.")) { + warn!("unexpected json response"); + return Err(ureq::Error::Other("unexpected json response".into())); } - let location = res - .headers() - .get("Location") - .ok_or_else(|| ureq::Error::Other("Location header not found".into()))? - .to_str() - .map_err(|_| ureq::Error::Other("Location header invalid".into()))?; - - debug!("location: {}", location); - - // let start = 10; - // let count = 10; - - // let mut f = File::open(path)?; - // f.seek(SeekFrom::Start(0)); - // let mut buf = vec![0; count]; - // f.read_exact(&mut buf)?; - - Ok(()) + Ok(Self { alias, id: res.id }) } pub fn notify(&self, http: &ureq::Agent) -> Result<(), ureq::Error> { let endpoint = self .alias - .uri - .get_endpoint(&format!("alias/mail/notify/{}", &self.id)); + .get_endpoint(format!("alias/mail/notify/{}", self.id)); - let res = self - .alias - .add_headers(http.post(endpoint)) + let res = http + .post(endpoint) + .sharry_header(self.alias) .send_empty()? .body_mut() .read_json::()?;