diff --git a/Cargo.lock b/Cargo.lock index edab192..3385026 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,10 +135,10 @@ name = "chrono" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -152,7 +152,7 @@ dependencies = [ "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -366,8 +366,10 @@ dependencies = [ "pbr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "prettytable-rs 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "version-compare 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -388,15 +390,25 @@ dependencies = [ "openssl 0.10.7 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "filetime" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "foreign-types" version = "0.3.2" @@ -496,7 +508,7 @@ dependencies = [ "net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -720,15 +732,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num-integer" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -813,7 +825,7 @@ dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -979,7 +991,7 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1055,12 +1067,12 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1075,7 +1087,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1085,7 +1097,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1167,6 +1179,17 @@ name = "take" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "tar" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "xattr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -1176,6 +1199,18 @@ dependencies = [ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tempfile" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "term" version = "0.4.6" @@ -1214,7 +1249,7 @@ dependencies = [ [[package]] name = "time" -version = "0.1.39" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1387,7 +1422,7 @@ name = "toml" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1467,7 +1502,7 @@ name = "url_serde" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1491,7 +1526,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "vec_map" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1556,6 +1591,14 @@ dependencies = [ "xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "xattr" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "xcb" version = "0.8.2" @@ -1610,6 +1653,7 @@ dependencies = [ "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" @@ -1648,8 +1692,8 @@ dependencies = [ "checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" "checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" -"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" +"checksum num-integer 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "2fef16815bb502c6a3be7fd842b7fd6e3371d5fbd33acc8ada7cc6c616cb4798" +"checksum num-traits 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c22f20a157cb4af265c71e47db525852368feeb4a0013f0f8c68a7f4ef0d0fc1" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "877f30f37acef6749b1841cceab289707f211aecfc756553cd63976190e6cc2e" "checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" @@ -1687,8 +1731,8 @@ dependencies = [ "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" -"checksum serde 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "1921d0c6997bf121f5a85e3fed9ffd2cdfa87254f84e92f9b72e4cd84fbcf79f" -"checksum serde_derive 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "3e45b261b57a9da43b0a9a41bb99b73d22ff1dd98b289de1381241e8542bd1d4" +"checksum serde 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)" = "de4dee3b122edad92d80c66cac8d967ec7f8bf16a3b452247d6eb1dbf83c8f22" +"checksum serde_derive 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)" = "7149ef7af607b09e0e7df38b1fd74264f08a29a67f604d5cb09d3fbdb1e256bc" "checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" @@ -1702,12 +1746,14 @@ dependencies = [ "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" +"checksum tar 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6af6b94659f9a571bf769a5b71f54079393585ee0bfdd71b691be22d7d6b1d18" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +"checksum tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47776f63b85777d984a50ce49d6b9e58826b6a3766a449fc95bc66cd5663c15b" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" +"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" "checksum tokio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d00555353b013e170ed8bc4e13f648a317d1fd12157dbcae13f7013f6cf29f5" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" "checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" @@ -1737,7 +1783,7 @@ dependencies = [ "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" "checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380" -"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version-compare 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "78068add8bf1e4d37d13fa5867182fe4c03f8e525c831053733f83aaba942d37" "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" @@ -1748,4 +1794,5 @@ dependencies = [ "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x11-clipboard 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2e7374c7699210cca7084ca61d57e09640fc744d1391808cb9ae2fe4ca9bd1df" +"checksum xattr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "abb373b92de38a4301d66bec009929b4fb83120ea1c4a401be89dbe0b9777443" "checksum xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" diff --git a/ROADMAP.md b/ROADMAP.md index 59e3fb4..00acad1 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,11 +3,14 @@ The first release used for gathering feedback on the application by selected people. Features: +- A `defaults` command to list defaults such as the host URL and history file +- Make use of stdout and stderr consistent - Allow file/directory archiving on upload - Allow unarchiving on download - Use clipboard through `xclip` on Linux if available for persistence - Allow environment variable settings using `Arg.env(NAME)` - Write complete README +- Polish command outputs, make it consistent (format, color) - Automated releases through CI - Release binaries on GitHub - Ubuntu PPA package diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 7d0f57e..a13b3be 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -39,5 +39,7 @@ prettytable-rs = "0.6" rpassword = "2.0" serde = "1.0" serde_derive = "1.0" +tar = "0.4" +tempfile = "3" toml = "0.4" version-compare = "0.0.6" diff --git a/cli/src/action/upload.rs b/cli/src/action/upload.rs index 1ffeba5..68469b8 100644 --- a/cli/src/action/upload.rs +++ b/cli/src/action/upload.rs @@ -1,3 +1,7 @@ +// TODO: remove all expect unwraps, replace them with proper errors + +extern crate tempfile; + use std::fs::File; use std::path::Path; use std::sync::{Arc, Mutex}; @@ -8,7 +12,9 @@ use ffsend_api::action::params::ParamsDataBuilder; use ffsend_api::action::upload::Upload as ApiUpload; use ffsend_api::config::{UPLOAD_SIZE_MAX, UPLOAD_SIZE_MAX_RECOMMENDED}; use ffsend_api::reqwest::Client; +use self::tempfile::NamedTempFile; +use archive::archiver::Archiver; use cmd::matcher::{Matcher, MainMatcher, UploadMatcher}; use error::ActionError; #[cfg(feature = "history")] @@ -48,7 +54,7 @@ impl<'a> Upload<'a> { let matcher_upload = UploadMatcher::with(self.cmd_matches).unwrap(); // Get API parameters - let path = Path::new(matcher_upload.file()).to_path_buf(); + let mut path = Path::new(matcher_upload.file()).to_path_buf(); let host = matcher_upload.host(); // TODO: ensure the file exists and is accessible @@ -112,11 +118,59 @@ impl<'a> Upload<'a> { } }; + // The file name to use + let mut file_name = matcher_upload.name().map(|s| s.to_owned()); + + // A temporary archive file, only used when archiving + // The temporary file is stored here, to ensure it's lifetime exceeds the upload process + let mut tmp_archive: Option = None; + + // Archive the file if specified + if matcher_upload.archive() { + println!("Archiving file..."); + + // Create a new temporary file to write the archive to + tmp_archive = Some( + NamedTempFile::new().expect("failed to create temporary archive file"), + ); + if let Some(tmp_archive) = &tmp_archive { + // Get the path, and the actual file + let archive_path = tmp_archive.path().clone().to_path_buf(); + let archive_file = tmp_archive.as_file().try_clone() + .expect("failed to clone archive file"); + + // Select the file name to use if not set + if file_name.is_none() { + file_name = Some( + path.file_name() + .expect("failed to determine file name") + .to_str() + .map(|s| s.to_owned()) + .expect("failed to create string from file name") + ); + } + + // Build an archiver and append the file + let mut archiver = Archiver::new(archive_file); + archiver.append_path(file_name.as_ref().unwrap(), &path) + .expect("failed to append file to archive"); + + // Finish the archival process, writes the archive file + archiver.finish().expect("failed to write archive file"); + + // Append archive extention to name, set to upload archived file + if let Some(ref mut file_name) = file_name { + file_name.push_str(".tar"); + } + path = archive_path; + } + } + // Execute an upload action let file = ApiUpload::new( host, - path, - matcher_upload.name().map(|name| name.to_owned()), + path.clone(), + file_name, matcher_upload.password(), params, ).invoke(&client, bar)?; @@ -149,6 +203,11 @@ impl<'a> Upload<'a> { } } + // Close the temporary zip file, to ensure it's removed + if let Some(tmp_archive) = tmp_archive.take() { + tmp_archive.close(); + } + Ok(()) } } diff --git a/cli/src/archive/archiver.rs b/cli/src/archive/archiver.rs new file mode 100644 index 0000000..efaf351 --- /dev/null +++ b/cli/src/archive/archiver.rs @@ -0,0 +1,74 @@ +extern crate tar; + +use std::fs::File; +use std::io::{ + Error as IoError, + Write, +}; +use std::path::Path; + +use self::tar::Builder as TarBuilder; + +pub type Result = ::std::result::Result; + +pub struct Archiver { + /// The tar builder. + inner: TarBuilder, +} + +impl Archiver { + /// Construct a new archive builder. + pub fn new(writer: W) -> Archiver { + Archiver { + inner: TarBuilder::new(writer), + } + } + + /// Add the entry at the given `src` path, to the given relative `path` in the archive. + /// + /// If a directory path is given, the whole directory including it's contents is added to the + /// archive. + /// + /// If no entry exists at the given `src_path`, an error is returned. + pub fn append_path(&mut self, path: P, src_path: Q) + -> Result<()> + where + P: AsRef, + Q: AsRef, + { + // Append the path as file or directory + if src_path.as_ref().is_file() { + self.append_file(path, &mut File::open(src_path)?) + } else if src_path.as_ref().is_dir() { + self.append_dir(path, src_path) + } else { + // TODO: return a IO NotFound error here! + panic!("Unable to append path to archive, not a file or directory"); + } + } + + /// Append a file to the archive builder. + pub fn append_file

(&mut self, path: P, file: &mut File) + -> Result<()> + where + P: AsRef, + { + self.inner.append_file(path, file) + } + + /// Append a directory to the archive builder. + // TODO: Define a flag to add recursively or not + pub fn append_dir(&mut self, path: P, src_path: Q) + -> Result<()> + where + P: AsRef, + Q: AsRef, + { + self.inner.append_dir_all(path, src_path) + } + + // TODO: some description + pub fn finish(mut self) -> Result<()> { + self.inner.finish() + } +} diff --git a/cli/src/archive/mod.rs b/cli/src/archive/mod.rs new file mode 100644 index 0000000..4bf42aa --- /dev/null +++ b/cli/src/archive/mod.rs @@ -0,0 +1 @@ +pub mod archiver; diff --git a/cli/src/cmd/cmd/upload.rs b/cli/src/cmd/cmd/upload.rs index 9b1e4ae..a3e2a6f 100644 --- a/cli/src/cmd/cmd/upload.rs +++ b/cli/src/cmd/cmd/upload.rs @@ -32,6 +32,11 @@ impl CmdUpload { .alias("f") .value_name("NAME") .help("Rename the file being uploaded")) + .arg(Arg::with_name("archive") + .long("archive") + .short("a") + .alias("arch") + .help("Package the file as an archive")) .arg(Arg::with_name("open") .long("open") .short("o") diff --git a/cli/src/cmd/handler.rs b/cli/src/cmd/handler.rs index 9af5b7d..8676b2f 100644 --- a/cli/src/cmd/handler.rs +++ b/cli/src/cmd/handler.rs @@ -48,7 +48,10 @@ impl<'a: 'b, 'b> Handler<'a> { .version(crate_version!()) .author(crate_authors!()) .about(crate_description!()) - .after_help("This application is not affiliated with Mozilla, Firefox or Firefox Send.") + .after_help("\ + The public Send service that is used as default host is provided by Mozilla.\n\ + This application is not affiliated with Mozilla, Firefox or Firefox Send.\ + ") .global_setting(AppSettings::GlobalVersion) .global_setting(AppSettings::VersionlessSubcommands) // TODO: enable below command when it doesn't break `p` anymore. diff --git a/cli/src/cmd/matcher/upload.rs b/cli/src/cmd/matcher/upload.rs index 130c96a..438d989 100644 --- a/cli/src/cmd/matcher/upload.rs +++ b/cli/src/cmd/matcher/upload.rs @@ -71,6 +71,12 @@ impl<'a: 'b, 'b> UploadMatcher<'a> { }) } + /// Check whether to archive the file to upload. + /// TODO: infer to use this flag if a directory is selected + pub fn archive(&self) -> bool { + self.matches.is_present("archive") + } + /// Check whether to open the file URL in the user's browser. pub fn open(&self) -> bool { self.matches.is_present("open") diff --git a/cli/src/main.rs b/cli/src/main.rs index 061fb84..e29441b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -17,6 +17,7 @@ extern crate serde; extern crate serde_derive; mod action; +mod archive; mod cmd; mod error; #[cfg(feature = "history")]