瀏覽代碼

Add upload file rename support

timvisee 7 年之前
父節點
當前提交
649190b17a
共有 3 個文件被更改,包括 49 次插入5 次删除
  1. 17 2
      api/src/action/upload.rs
  2. 6 2
      cli/src/action/upload.rs
  3. 26 1
      cli/src/cmd/cmd_upload.rs

+ 17 - 2
api/src/action/upload.rs

@@ -51,16 +51,27 @@ pub struct Upload {
     /// The file to upload.
     path: PathBuf,
 
+    /// The name of the file being uploaded.
+    /// This has no relation to the file path, and will become the name of the
+    /// shared file if set.
+    name: Option<String>,
+
     /// An optional password to protect the file with.
     password: Option<String>,
 }
 
 impl Upload {
     /// Construct a new upload action.
-    pub fn new(host: Url, path: PathBuf, password: Option<String>) -> Self {
+    pub fn new(
+        host: Url,
+        path: PathBuf,
+        name: Option<String>,
+        password: Option<String>,
+    ) -> Self {
         Self {
             host,
             path,
+            name,
             password,
         }
     }
@@ -118,10 +129,14 @@ impl Upload {
     fn create_metadata(&self, key: &KeySet, file: &FileData)
         -> Result<Vec<u8>, MetaError>
     {
+        // Determine what filename to use
+        let name = self.name.clone()
+            .unwrap_or(file.name().to_owned());
+
         // Construct the metadata
         let metadata = Metadata::from(
             key.iv(),
-            file.name().to_owned(),
+            name,
             file.mime().clone(),
         ).to_json().into_bytes();
 

+ 6 - 2
cli/src/action/upload.rs

@@ -39,8 +39,12 @@ impl<'a> Upload<'a> {
         let bar = Arc::new(Mutex::new(ProgressBar::new_upload()));
 
         // Execute an upload action
-        let file = ApiUpload::new(host, path, self.cmd.password())
-            .invoke(&client, bar)?;
+        let file = ApiUpload::new(
+            host,
+            path,
+            self.cmd.name().map(|name| name.to_owned()),
+            self.cmd.password(),
+        ).invoke(&client, bar)?;
 
         // Get the download URL, and report it in the console
         let url = file.download_url(true);

+ 26 - 1
cli/src/cmd/cmd_upload.rs

@@ -24,6 +24,13 @@ impl<'a: 'b, 'b> CmdUpload<'a> {
                 .help("The file to upload")
                 .required(true)
                 .multiple(false))
+            .arg(Arg::with_name("name")
+                .long("name")
+                .short("n")
+                .alias("file")
+                .alias("f")
+                .value_name("NAME")
+                .help("Rename the file being uploaded"))
             .arg(Arg::with_name("password")
                 .long("password")
                 .short("p")
@@ -31,7 +38,7 @@ impl<'a: 'b, 'b> CmdUpload<'a> {
                 .value_name("PASSWORD")
                 .min_values(0)
                 .max_values(1)
-                .help("Protect file with a password"))
+                .help("Protect the file with a password"))
             .arg(Arg::with_name("host")
                 .long("host")
                 .short("h")
@@ -61,7 +68,25 @@ impl<'a: 'b, 'b> CmdUpload<'a> {
             .map(|matches| CmdUpload { matches })
     }
 
+    /// The the name to use for the uploaded file.
+    /// If no custom name is given, none is returned.
+    // TODO: validate custom names, no path separators
+    // TODO: only allow extension renaming with force flag
+    pub fn name(&'a self) -> Option<&'a str> {
+        // Get the chosen file name
+        let name = self.matches.value_of("name")?;
+
+        // The file name must not be empty
+        if name.trim().is_empty() {
+            // TODO: return an error here
+            panic!("the new name must not be empty");
+        }
+
+        Some(name)
+    }
+
     /// Get the selected file to upload.
+    // TODO: maybe return a file or path instance here
     pub fn file(&'a self) -> &'a str {
         self.matches.value_of("FILE")
             .expect("no file specified to upload")