From 485c2cf21c377e64094c9b0c42bbef4166dcd7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn-Michael=20Miehe?= <40151420+ldericher@users.noreply.github.com> Date: Fri, 23 May 2025 01:11:11 +0000 Subject: [PATCH] file creation works --- src/main.rs | 7 +++--- src/sharry/api.rs | 28 ++++++++++++++--------- src/sharry/mod.rs | 57 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/src/main.rs b/src/main.rs index 006bb38..4bb62a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,7 @@ mod sharry; use log::info; -use sharry::{ - Alias, - api::{NewShareRequest, URI}, -}; +use sharry::{Alias, NewShareRequest, URI}; use std::time::Duration; use ureq::Agent; @@ -26,5 +23,7 @@ fn main() { let share = share.unwrap(); info!("share: {:?}", share); + share.create_file(&agent, "./myfile.dat").unwrap(); + share.notify(&agent).unwrap(); } diff --git a/src/sharry/api.rs b/src/sharry/api.rs index 1a66779..44d3027 100644 --- a/src/sharry/api.rs +++ b/src/sharry/api.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use log::debug; use serde::{Deserialize, Serialize}; @@ -8,18 +10,18 @@ pub struct URI { } impl URI { - pub fn new_protocol(base_url: &str, protocol: &str) -> Self { + pub fn new_protocol(base_url: impl Into, protocol: impl Into) -> Self { Self { protocol: protocol.into(), base_url: base_url.into(), } } - pub fn new(base_url: &str) -> Self { + pub fn new(base_url: impl Into) -> Self { Self::new_protocol(base_url, "https") } - pub fn get_endpoint(&self, endpoint: &str) -> String { + pub fn get_endpoint(&self, endpoint: impl Display) -> String { let uri = format!("{}://{}/api/v2/{}", self.protocol, self.base_url, endpoint); debug!("uri: {:?}", uri); @@ -29,20 +31,24 @@ impl URI { #[derive(Serialize)] #[allow(non_snake_case)] -pub struct NewShareRequest<'t> { - name: Option<&'t str>, +pub struct NewShareRequest { + name: Option, validity: u32, - description: &'t str, + description: String, maxViews: u32, - password: Option<&'t str>, + password: Option, } -impl<'t> NewShareRequest<'t> { - pub fn new(name: Option<&'t str>, description: &'t str, max_views: u32) -> Self { +impl NewShareRequest { + pub fn new( + name: Option>, + description: impl Into, + max_views: u32, + ) -> Self { Self { - name: name, + name: name.map(Into::into), validity: 0, - description: description, + description: description.into(), maxViews: max_views, password: None, } diff --git a/src/sharry/mod.rs b/src/sharry/mod.rs index a0ebc4c..89ace00 100644 --- a/src/sharry/mod.rs +++ b/src/sharry/mod.rs @@ -1,7 +1,9 @@ -pub mod api; +mod api; -use api::{NewShareRequest, NewShareResponse, NotifyShareResponse, URI}; +pub use api::{NewShareRequest, URI}; +use api::{NewShareResponse, NotifyShareResponse}; use log::debug; +use std::{ffi::OsStr, fs, path::Path}; use ureq::{self, RequestBuilder}; #[derive(Debug)] @@ -11,7 +13,7 @@ pub struct Alias { } impl Alias { - pub fn new(uri: URI, id: &str) -> Self { + pub fn new(uri: URI, id: impl Into) -> Self { Self { uri, id: id.into() } } @@ -50,7 +52,54 @@ pub struct Share<'t> { } impl<'t> Share<'t> { - pub fn add_file(&self) {} + pub fn create_file( + &self, + http: &ureq::Agent, + path: impl AsRef + AsRef, + ) -> Result<(), ureq::Error> { + let filename = Path::new(&path) + .file_name() + .and_then(OsStr::to_str) + .unwrap_or("file.bin"); + + 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()?; + + assert_eq!(res.status(), ureq::http::StatusCode::CREATED); + + 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(()) + } pub fn notify(&self, http: &ureq::Agent) -> Result<(), ureq::Error> { let endpoint = self