Add support for compressing to .tgz, add gio network mount example

This commit is contained in:
Jeremy Soller 2024-09-10 11:50:14 -06:00
parent c4c92be708
commit 4374132e2f
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
6 changed files with 219 additions and 135 deletions

137
Cargo.lock generated
View file

@ -91,9 +91,9 @@ dependencies = [
[[package]]
name = "addr2line"
version = "0.22.0"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
dependencies = [
"gimli",
]
@ -254,9 +254,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.86"
version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8"
[[package]]
name = "apply"
@ -396,9 +396,9 @@ dependencies = [
[[package]]
name = "async-executor"
version = "1.13.0"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7"
checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
dependencies = [
"async-task",
"concurrent-queue",
@ -655,17 +655,17 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "backtrace"
version = "0.3.73"
version = "0.3.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide 0.7.4",
"miniz_oxide 0.8.0",
"object",
"rustc-demangle",
"windows-targets 0.52.6",
]
[[package]]
@ -914,9 +914,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.1.16"
version = "1.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b"
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
dependencies = [
"jobserver",
"libc",
@ -942,9 +942,9 @@ dependencies = [
[[package]]
name = "cfg-expr"
version = "0.15.8"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
checksum = "345c78335be0624ed29012dc10c49102196c6882c12dde65d9f35b02da2aada8"
dependencies = [
"smallvec",
"target-lexicon",
@ -1213,7 +1213,7 @@ dependencies = [
[[package]]
name = "cosmic-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"atomicwrites",
"cosmic-config-derive",
@ -1232,7 +1232,7 @@ dependencies = [
[[package]]
name = "cosmic-config-derive"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"quote",
"syn 1.0.109",
@ -1246,10 +1246,12 @@ dependencies = [
"dirs 5.0.1",
"env_logger",
"fastrand 2.1.1",
"flate2",
"fork",
"freedesktop_entry_parser",
"fs_extra",
"gio",
"glib",
"glob",
"i18n-embed",
"i18n-embed-fl",
@ -1306,7 +1308,7 @@ dependencies = [
[[package]]
name = "cosmic-text"
version = "0.12.1"
source = "git+https://github.com/pop-os/cosmic-text.git#9d132f8ebdb350d3db22c1502f72484a8f8c4b8a"
source = "git+https://github.com/pop-os/cosmic-text.git#e8f567cf5b456dfab749a575c257acaa36f622d9"
dependencies = [
"bitflags 2.6.0",
"fontdb",
@ -1329,7 +1331,7 @@ dependencies = [
[[package]]
name = "cosmic-theme"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"almost",
"cosmic-config",
@ -1817,9 +1819,9 @@ dependencies = [
[[package]]
name = "error-code"
version = "3.2.0"
version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b"
checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
[[package]]
name = "etagere"
@ -2365,15 +2367,15 @@ dependencies = [
[[package]]
name = "gimli"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
[[package]]
name = "gio"
version = "0.19.8"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c49f117d373ffcc98a35d114db5478bc223341cff53e39a5d6feced9e2ddffe"
checksum = "dcacaa37401cad0a95aadd266bc39c72a131d454fc012f6dfd217f891d76cc52"
dependencies = [
"futures-channel",
"futures-core",
@ -2384,14 +2386,13 @@ dependencies = [
"libc",
"pin-project-lite",
"smallvec",
"thiserror",
]
[[package]]
name = "gio-sys"
version = "0.19.8"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cd743ba4714d671ad6b6234e8ab2a13b42304d0e13ab7eba1dcdd78a7d6d4ef"
checksum = "5237611e97e9b86ab5768adc3eef853ae713ea797aa3835404acdfacffc9fb38"
dependencies = [
"glib-sys",
"gobject-sys",
@ -2419,9 +2420,9 @@ checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945"
[[package]]
name = "glib"
version = "0.19.9"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39650279f135469465018daae0ba53357942a5212137515777d5fdca74984a44"
checksum = "95648aac01b75503000bb3bcaa5ec7a7a2dd61e43636b8b1814854de94dd80e4"
dependencies = [
"bitflags 2.6.0",
"futures-channel",
@ -2436,14 +2437,13 @@ dependencies = [
"libc",
"memchr",
"smallvec",
"thiserror",
]
[[package]]
name = "glib-macros"
version = "0.19.9"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4429b0277a14ae9751350ad9b658b1be0abb5b54faa5bcdf6e74a3372582fad7"
checksum = "302f1d633c9cdef4350330e7b68fd8016e2834bb106c93fdf9789fcde753c1ab"
dependencies = [
"heck 0.5.0",
"proc-macro-crate 3.2.0",
@ -2454,9 +2454,9 @@ dependencies = [
[[package]]
name = "glib-sys"
version = "0.19.8"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c2dc18d3a82b0006d470b13304fbbb3e0a9bd4884cf985a60a7ed733ac2c4a5"
checksum = "92eee4531c1c9abba945d19378b205031b5890e1f99c319ba0503b6e0c06a163"
dependencies = [
"libc",
"system-deps",
@ -2470,9 +2470,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "globset"
version = "0.4.14"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19"
dependencies = [
"aho-corasick",
"bstr",
@ -2515,9 +2515,9 @@ dependencies = [
[[package]]
name = "gobject-sys"
version = "0.19.8"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e697e252d6e0416fd1d9e169bda51c0f1c926026c39ca21fbe8b1bb5c3b8b9e"
checksum = "fa3d1dcd8a1eb2e7c22be3d5e792b14b186f3524f79b25631730f9a8c169d49a"
dependencies = [
"glib-sys",
"libc",
@ -2774,7 +2774,7 @@ dependencies = [
[[package]]
name = "iced"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"dnd",
"iced_accessibility",
@ -2793,7 +2793,7 @@ dependencies = [
[[package]]
name = "iced_accessibility"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"accesskit",
"accesskit_unix",
@ -2803,7 +2803,7 @@ dependencies = [
[[package]]
name = "iced_core"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"bitflags 2.6.0",
"dnd",
@ -2825,7 +2825,7 @@ dependencies = [
[[package]]
name = "iced_futures"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"futures",
"iced_core",
@ -2838,7 +2838,7 @@ dependencies = [
[[package]]
name = "iced_graphics"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"bitflags 2.6.0",
"bytemuck",
@ -2862,7 +2862,7 @@ dependencies = [
[[package]]
name = "iced_renderer"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@ -2874,7 +2874,7 @@ dependencies = [
[[package]]
name = "iced_runtime"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"dnd",
"iced_accessibility",
@ -2888,7 +2888,7 @@ dependencies = [
[[package]]
name = "iced_sctk"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"enum-repr",
"float-cmp",
@ -2915,7 +2915,7 @@ dependencies = [
[[package]]
name = "iced_style"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"iced_core",
"once_cell",
@ -2925,7 +2925,7 @@ dependencies = [
[[package]]
name = "iced_tiny_skia"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"bytemuck",
"cosmic-text",
@ -2942,7 +2942,7 @@ dependencies = [
[[package]]
name = "iced_wgpu"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"as-raw-xcb-connection",
"bitflags 2.6.0",
@ -2971,7 +2971,7 @@ dependencies = [
[[package]]
name = "iced_widget"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"dnd",
"iced_accessibility",
@ -2989,7 +2989,7 @@ dependencies = [
[[package]]
name = "iced_winit"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"dnd",
"iced_accessibility",
@ -3187,9 +3187,9 @@ dependencies = [
[[package]]
name = "ignore"
version = "0.4.22"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1"
checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b"
dependencies = [
"crossbeam-deque",
"globset",
@ -3505,7 +3505,7 @@ checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]]
name = "libcosmic"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#b66f8986d1b897e53471f05fdc27b851cb4fa958"
source = "git+https://github.com/pop-os/libcosmic.git#05da0a83b25e857a85f8ac4e02097d21d367d63d"
dependencies = [
"apply",
"ashpd 0.9.1",
@ -4381,9 +4381,9 @@ dependencies = [
[[package]]
name = "parking"
version = "2.2.0"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "parking_lot"
@ -4691,15 +4691,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "quick-xml"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96a05e2e8efddfa51a84ca47cec303fac86c8541b686d37cac5efc0e094417bc"
dependencies = [
"memchr",
]
[[package]]
name = "quick-xml"
version = "0.36.1"
@ -5168,18 +5159,18 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
[[package]]
name = "serde"
version = "1.0.209"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.209"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
@ -5571,9 +5562,9 @@ dependencies = [
[[package]]
name = "system-deps"
version = "6.2.2"
version = "7.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
checksum = "070a0a5e7da2d24be457809c4b3baa57a835fd2829ad8b86f9a049052fe71031"
dependencies = [
"cfg-expr",
"heck 0.5.0",
@ -7248,9 +7239,9 @@ dependencies = [
[[package]]
name = "xml-rs"
version = "0.8.21"
version = "0.8.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601"
checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26"
[[package]]
name = "xmlwriter"

View file

@ -14,8 +14,10 @@ chrono = { version = "0.4", features = ["unstable-locales"] }
dirs = "5.0.1"
env_logger = "0.11"
freedesktop_entry_parser = { version = "1.3", optional = true }
flate2 = "1.0"
fs_extra = { git = "https://github.com/pop-os/fs_extra.git" }
gio = { version = "0.19", optional = true }
gio = { version = "0.20", optional = true }
glib = { version = "0.20", optional = true }
glob = "0.3"
icu_collator = "1.5"
icu_provider = { version = "1.5", features = ["sync"] }
@ -65,7 +67,7 @@ features = ["serde"]
[features]
default = ["desktop", "gvfs", "notify", "winit", "wgpu"]
desktop = ["libcosmic/desktop", "dep:freedesktop_entry_parser", "dep:xdg"]
gvfs = ["dep:gio"]
gvfs = ["dep:gio", "dep:glib"]
notify = ["dep:notify-rust"]
wayland = ["libcosmic/wayland"]
winit = ["libcosmic/winit"]

23
examples/mount.rs Normal file
View file

@ -0,0 +1,23 @@
use gio::prelude::*;
use std::env;
fn main() {
let uri = env::args().nth(1).expect("no uri provided");
let context = glib::MainContext::new();
context.block_on(async {
let mount_op = gio::MountOperation::new();
mount_op.connect_ask_password(|mount_op, message, default_user, default_domain, flags| {
println!(
"{}, {}, {}, {:?}",
message, default_user, default_domain, flags
);
mount_op.set_anonymous(true);
mount_op.reply(gio::MountOperationResult::Handled);
});
let file = gio::File::for_uri(&uri);
let res = file
.mount_enclosing_volume_future(gio::MountMountFlags::empty(), Some(&mount_op))
.await;
println!("{:?}", res);
});
}

View file

@ -303,19 +303,32 @@ impl ContextPage {
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub enum ArchiveType {
Tgz,
#[default]
Zip,
}
impl ArchiveType {
pub fn extension(&self) -> String {
pub fn all() -> &'static [Self] {
&[Self::Tgz, Self::Zip]
}
pub fn extension(&self) -> &str {
match self {
ArchiveType::Zip => ".zip".to_string(),
ArchiveType::Tgz => ".tgz",
ArchiveType::Zip => ".zip",
}
}
}
impl AsRef<str> for ArchiveType {
fn as_ref(&self) -> &str {
self.extension()
}
}
#[derive(Clone, Debug)]
pub enum DialogPage {
Compress {
@ -1299,7 +1312,7 @@ impl Application for App {
if let Some(destination) = current_path.parent().zip(current_path.file_stem()) {
let to = destination.0.to_path_buf();
let name = destination.1.to_str().unwrap_or_default().to_string();
let archive_type = ArchiveType::Zip;
let archive_type = ArchiveType::default();
self.dialog_pages.push_back(DialogPage::Compress {
paths,
to,
@ -2436,6 +2449,8 @@ impl Application for App {
}
};
let archive_types = ArchiveType::all();
let selected = archive_types.iter().position(|&x| x == *archive_type);
dialog
.primary_action(
widget::button::suggested(fl!("create"))
@ -2455,12 +2470,20 @@ impl Application for App {
paths: paths.clone(),
to: to.clone(),
name: name.clone(),
archive_type: archive_type.clone(),
archive_type: *archive_type,
})
})
.on_submit_maybe(complete_maybe)
.into(),
widget::text::body(".zip").into(),
widget::dropdown(archive_types, selected, move |index| {
Message::DialogUpdate(DialogPage::Compress {
paths: paths.clone(),
to: to.clone(),
name: name.clone(),
archive_type: archive_types[index],
})
})
.into(),
])
.align_items(Alignment::Center)
.spacing(space_xxs)

View file

@ -126,10 +126,14 @@ pub fn context_menu<'a>(
children.push(menu_item(fl!("copy"), Action::Copy).into());
children.push(container(horizontal_rule(1)).padding([0, 8]).into());
let supported_archive_types = ["application/x-tar", "application/zip"]
.iter()
.filter_map(|mime_type| mime_type.parse::<Mime>().ok())
.collect::<Vec<_>>();
let supported_archive_types = [
"application/x-compressed-tar",
"application/x-tar",
"application/zip",
]
.iter()
.filter_map(|mime_type| mime_type.parse::<Mime>().ok())
.collect::<Vec<_>>();
selected_types.retain(|t| !supported_archive_types.contains(t));
if selected_types.is_empty() {
children.push(menu_item(fl!("extract-here"), Action::ExtractHere).into());

View file

@ -15,7 +15,9 @@ use walkdir::WalkDir;
use crate::{
app::{ArchiveType, DialogPage, Message},
config::IconSizes,
fl, tab,
fl,
mime_icon::mime_for_path,
tab,
};
fn err_str<T: ToString>(err: T) -> String {
@ -374,26 +376,31 @@ impl Operation {
} => {
let msg_tx = msg_tx.clone();
tokio::task::spawn_blocking(move || -> Result<(), String> {
let Some(relative_root) = to.parent() else {
return Err(format!("path {:?} has no parent directory", to));
};
let mut paths = paths;
for path in paths.clone().iter() {
if path.is_dir() {
let new_paths_it = WalkDir::new(path).into_iter();
for entry in new_paths_it.skip(1) {
let entry = entry.map_err(err_str)?;
paths.push(entry.path().to_path_buf());
}
}
}
match archive_type {
ArchiveType::Zip => {
ArchiveType::Tgz => {
let mut archive = fs::File::create(&to)
.map(io::BufWriter::new)
.map(zip::ZipWriter::new)
.map(|w| {
flate2::write::GzEncoder::new(w, flate2::Compression::default())
})
.map(tar::Builder::new)
.map_err(err_str)?;
let zip_options = zip::write::SimpleFileOptions::default();
let mut paths = paths;
for path in paths.clone().iter() {
if path.is_dir() {
let new_paths_it = WalkDir::new(path).into_iter();
for entry in new_paths_it.skip(1) {
let entry = entry.map_err(err_str)?;
paths.push(entry.path().to_path_buf());
}
}
}
let total_paths = paths.len();
for (i, path) in paths.iter().enumerate() {
executor::block_on(async {
@ -405,27 +412,56 @@ impl Operation {
.await;
});
if let Some(relative_root) = to.parent() {
if let Some(relative_path) =
path.strip_prefix(relative_root).map_err(err_str)?.to_str()
{
if path.is_file() {
archive
.start_file(relative_path, zip_options)
.map_err(err_str)?;
if let Some(relative_path) =
path.strip_prefix(relative_root).map_err(err_str)?.to_str()
{
archive
.append_path_with_name(path, relative_path)
.map_err(err_str)?;
}
}
let mut buffer = Vec::new();
let mut file = fs::File::open(&path)
.map(io::BufReader::new)
.map_err(err_str)?;
archive.finish().map_err(err_str)?;
}
ArchiveType::Zip => {
let mut archive = fs::File::create(&to)
.map(io::BufWriter::new)
.map(zip::ZipWriter::new)
.map_err(err_str)?;
file.read_to_end(&mut buffer).map_err(err_str)?;
archive.write_all(&buffer).map_err(err_str)?;
} else {
archive
.add_directory(relative_path, zip_options)
.map_err(err_str)?;
}
//TODO: set unix_permissions per file?
let zip_options = zip::write::SimpleFileOptions::default();
let total_paths = paths.len();
for (i, path) in paths.iter().enumerate() {
executor::block_on(async {
let total_progress = (i as f32) / total_paths as f32;
let _ = msg_tx
.lock()
.await
.send(Message::PendingProgress(id, 100.0 * total_progress))
.await;
});
if let Some(relative_path) =
path.strip_prefix(relative_root).map_err(err_str)?.to_str()
{
if path.is_file() {
archive
.start_file(relative_path, zip_options)
.map_err(err_str)?;
let mut buffer = Vec::new();
let mut file = fs::File::open(&path)
.map(io::BufReader::new)
.map_err(err_str)?;
file.read_to_end(&mut buffer).map_err(err_str)?;
archive.write_all(&buffer).map_err(err_str)?;
} else {
archive
.add_directory(relative_path, zip_options)
.map_err(err_str)?;
}
}
}
@ -611,21 +647,26 @@ impl Operation {
}
}
if let Some(mime) = mime_guess::from_path(&path).first() {
match mime.essence_str() {
"application/x-tar" => fs::File::open(path)
.map(io::BufReader::new)
.map(tar::Archive::new)
.and_then(|mut archive| archive.unpack(new_dir))
.map_err(err_str)?,
"application/zip" => fs::File::open(path)
.map(io::BufReader::new)
.map(zip::ZipArchive::new)
.map_err(err_str)?
.and_then(|mut archive| archive.extract(new_dir))
.map_err(err_str)?,
_ => Err(format!("unsupported mime type {:?}", mime))?,
}
let mime = mime_for_path(&path);
match mime.essence_str() {
"application/x-compressed-tar" => fs::File::open(path)
.map(io::BufReader::new)
.map(flate2::read::GzDecoder::new)
.map(tar::Archive::new)
.and_then(|mut archive| archive.unpack(new_dir))
.map_err(err_str)?,
"application/x-tar" => fs::File::open(path)
.map(io::BufReader::new)
.map(tar::Archive::new)
.and_then(|mut archive| archive.unpack(new_dir))
.map_err(err_str)?,
"application/zip" => fs::File::open(path)
.map(io::BufReader::new)
.map(zip::ZipArchive::new)
.map_err(err_str)?
.and_then(|mut archive| archive.extract(new_dir))
.map_err(err_str)?,
_ => Err(format!("unsupported mime type {:?}", mime))?,
}
}
}