Browse Source

Add download limit parameter to CLI upload command

timvisee 7 years ago
parent
commit
3fb9536777

+ 1 - 1
api/src/action/params.rs

@@ -17,7 +17,7 @@ use file::remote_file::RemoteFile;
 const HEADER_AUTH_NONCE: &'static str = "WWW-Authenticate";
 
 /// The default download count.
-const PARAMS_DEFAULT_DOWNLOAD: u8 = 1;
+pub const PARAMS_DEFAULT_DOWNLOAD: u8 = 1;
 
 /// The minimum allowed number of downloads, enforced by the server.
 pub const PARAMS_DOWNLOAD_MIN: u8 = 1;

+ 30 - 1
api/src/action/upload.rs

@@ -33,6 +33,11 @@ use reader::{
     ProgressReader,
     ProgressReporter,
 };
+use super::params::{
+    Error as ParamsError,
+    Params,
+    ParamsData,
+};
 use super::password::{
     Error as PasswordError,
     Password,
@@ -58,6 +63,9 @@ pub struct Upload {
 
     /// An optional password to protect the file with.
     password: Option<String>,
+
+    /// An optional download limit.
+    downloads: Option<u8>,
 }
 
 impl Upload {
@@ -67,12 +75,14 @@ impl Upload {
         path: PathBuf,
         name: Option<String>,
         password: Option<String>,
+        downloads: Option<u8>,
     ) -> Self {
         Self {
             host,
             path,
             name,
             password,
+            downloads,
         }
     }
 
@@ -118,7 +128,16 @@ impl Upload {
             Password::new(
                 &result,
                 &password,
-                nonce,
+                nonce.clone(),
+            ).invoke(client)?;
+        }
+
+        // Change parameters if set
+        if self.downloads.is_some() {
+            Params::new(
+                &result,
+                ParamsData::from(self.downloads),
+                nonce.clone(),
             ).invoke(client)?;
         }
 
@@ -373,6 +392,10 @@ pub enum Error {
     #[fail(display = "Failed to upload the file")]
     Upload(#[cause] UploadError),
 
+    /// An error occurred while chaining file parameters.
+    #[fail(display = "Failed to change file parameters")]
+    Params(#[cause] ParamsError),
+
     /// An error occurred while setting the password.
     #[fail(display = "Failed to set the password")]
     Password(#[cause] PasswordError),
@@ -402,6 +425,12 @@ impl From<UploadError> for Error {
     }
 }
 
+impl From<ParamsError> for Error {
+    fn from(err: ParamsError) -> Error {
+        Error::Params(err)
+    }
+}
+
 impl From<PasswordError> for Error {
     fn from(err: PasswordError) -> Error {
         Error::Password(err)

+ 1 - 0
cli/src/action/upload.rs

@@ -44,6 +44,7 @@ impl<'a> Upload<'a> {
             path,
             self.cmd.name().map(|name| name.to_owned()),
             self.cmd.password(),
+            self.cmd.downloads(),
         ).invoke(&client, bar)?;
 
         // Get the download URL, and report it in the console

+ 0 - 1
cli/src/cmd/cmd_params.rs

@@ -1,5 +1,4 @@
 use ffsend_api::action::params::{
-    // TODO: test min/max
     PARAMS_DOWNLOAD_MIN as DOWNLOAD_MIN,
     PARAMS_DOWNLOAD_MAX as DOWNLOAD_MAX,
 };

+ 36 - 0
cli/src/cmd/cmd_upload.rs

@@ -1,3 +1,8 @@
+use ffsend_api::action::params::{
+    PARAMS_DEFAULT_DOWNLOAD as DOWNLOAD_DEFAULT,
+    PARAMS_DOWNLOAD_MIN as DOWNLOAD_MIN,
+    PARAMS_DOWNLOAD_MAX as DOWNLOAD_MAX,
+};
 use ffsend_api::url::{ParseError, Url};
 
 use rpassword::prompt_password_stderr;
@@ -39,6 +44,15 @@ impl<'a: 'b, 'b> CmdUpload<'a> {
                 .min_values(0)
                 .max_values(1)
                 .help("Protect the file with a password"))
+            .arg(Arg::with_name("downloads")
+                .long("downloads")
+                .short("d")
+                .alias("download")
+                .alias("down")
+                .alias("dlimit")
+                .value_name("COUNT")
+                .default_value("1")
+                .help("Set the download limit"))
             .arg(Arg::with_name("host")
                 .long("host")
                 .short("h")
@@ -153,4 +167,26 @@ impl<'a: 'b, 'b> CmdUpload<'a> {
                 .expect("failed to read password from stdin")
         )
     }
+
+    /// Get the download limit if set.
+    pub fn downloads(&'a self) -> Option<u8> {
+        // Get the number of downloads, or none if not set or default
+        // TODO: do not unwrap, report an error
+        self.matches.value_of("downloads")
+            .map(|d| d.parse::<u8>().expect("invalid number of downloads"))
+            .and_then(|d| if d == DOWNLOAD_DEFAULT { None } else { Some(d) })
+            .and_then(|d| {
+                // Check the download count bounds
+                if d < DOWNLOAD_MIN || d > DOWNLOAD_MAX {
+                    panic!(
+                        "invalid number of downloads, must be between {} and {}",
+                        DOWNLOAD_MIN,
+                        DOWNLOAD_MAX,
+                    );
+                }
+
+                // Return the value
+                Some(d)
+            })
+    }
 }