From e7471a767d2876e8d7a0c99af4d364cdbd7ba934 Mon Sep 17 00:00:00 2001 From: Jerry Wong Date: Fri, 24 Jun 2022 14:04:11 +0800 Subject: [PATCH] Refactor score logic --- Cargo.lock | 805 +++++++++++++++++++++++++++++++++++++--- app/package.json | 12 +- app/src/App.tsx | 122 +++--- core/Cargo.toml | 5 + core/src/base/mod.rs | 60 ++- core/src/command/mod.rs | 120 ++++-- core/src/main.rs | 153 ++++++++ 7 files changed, 1132 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3453aae..c33bfab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cipher", "cpufeatures", "opaque-debug", @@ -56,7 +56,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -70,8 +70,12 @@ name = "ark-shelf-desktop" version = "0.1.0" dependencies = [ "anyhow", + "arklib", "clap", + "crossbeam-channel", "home", + "lazy_static", + "notify", "reqwest", "scraper", "serde", @@ -79,11 +83,34 @@ dependencies = [ "tauri", "tauri-build", "tauri-macros", + "tokio", "url", "walkdir", "zip", ] +[[package]] +name = "arklib" +version = "0.1.0" +source = "git+https://github.com/ARK-Builders/arklib#e32c78112ad8b2e045755aea8b6e5a5087bee9eb" +dependencies = [ + "anyhow", + "canonical-path", + "crc32fast", + "env_logger", + "flate2", + "fs_extra", + "image", + "lazy_static", + "libloading", + "log", + "pdfium-render", + "tar", + "target-lexicon", + "ureq", + "walkdir", +] + [[package]] name = "atk" version = "0.15.1" @@ -134,7 +161,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -155,6 +182,35 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" +[[package]] +name = "bindgen" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + [[package]] name = "bitflags" version = "1.3.2" @@ -275,6 +331,12 @@ dependencies = [ "system-deps 6.0.2", ] +[[package]] +name = "canonical-path" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" + [[package]] name = "cargo_toml" version = "0.11.5" @@ -301,6 +363,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfb" version = "0.6.1" @@ -329,12 +400,24 @@ dependencies = [ "smallvec", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chunked_transfer" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" + [[package]] name = "cipher" version = "0.3.0" @@ -344,6 +427,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "clang-sys" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "3.1.18" @@ -430,6 +524,26 @@ dependencies = [ "memchr", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494" +dependencies = [ + "log", + "web-sys", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -498,17 +612,42 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", "crossbeam-utils", + "memoffset", + "once_cell", + "scopeguard", ] [[package]] @@ -517,7 +656,7 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "lazy_static", ] @@ -617,7 +756,7 @@ checksum = "de0a745c25b32caa56b82a3950f5fec7893a960f4c10ca3b02060b0c38d8c2ce" dependencies = [ "libc", "libdbus-sys", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -669,7 +808,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "dirs-sys-next", ] @@ -681,7 +820,7 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -711,6 +850,12 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "embed-resource" version = "1.7.2" @@ -736,7 +881,36 @@ version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", +] + +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "exr" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14cc0e06fb5f67e5d6beadf3a382fec9baca1aa751c6d5368fdeee7e5932c215" +dependencies = [ + "bit_field", + "deflate 1.0.0", + "flume", + "half", + "inflate 0.4.5", + "lebe", + "smallvec", + "threadpool", ] [[package]] @@ -764,10 +938,10 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -780,6 +954,19 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.10.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ceeb589a3157cac0ab8cc585feb749bd2cea5cb55a6ee802ad72d9fd38303da" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin 0.9.3", +] + [[package]] name = "fnv" version = "1.0.7" @@ -811,6 +998,47 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" + +[[package]] +name = "fsevent" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +dependencies = [ + "bitflags", + "fsevent-sys", +] + +[[package]] +name = "fsevent-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" +dependencies = [ + "libc", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + [[package]] name = "futf" version = "0.1.5" @@ -1016,7 +1244,7 @@ dependencies = [ "libc", "log", "rustversion", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1044,7 +1272,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] @@ -1055,9 +1283,21 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", + "js-sys", "libc", "wasi 0.10.2+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" +dependencies = [ + "color_quant", + "weezl", ] [[package]] @@ -1087,7 +1327,7 @@ dependencies = [ "gobject-sys", "libc", "system-deps 6.0.2", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1239,6 +1479,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hashbrown" version = "0.11.2" @@ -1284,7 +1530,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1355,6 +1601,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.19" @@ -1446,9 +1698,15 @@ dependencies = [ "bytemuck", "byteorder", "color_quant", + "exr", + "gif", + "jpeg-decoder", "num-iter", "num-rational", "num-traits", + "png 0.17.5", + "scoped_threadpool", + "tiff", ] [[package]] @@ -1479,13 +1737,51 @@ dependencies = [ "adler32", ] +[[package]] +name = "inflate" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" +dependencies = [ + "adler32", +] + +[[package]] +name = "inotify" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "instant" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", ] [[package]] @@ -1572,6 +1868,15 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.57" @@ -1592,6 +1897,16 @@ dependencies = [ "treediff", ] +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "kuchiki" version = "0.8.1" @@ -1610,6 +1925,18 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lebe" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff" + [[package]] name = "libc" version = "0.2.126" @@ -1625,6 +1952,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if 1.0.0", + "winapi 0.3.9", +] + [[package]] name = "lock_api" version = "0.4.7" @@ -1641,7 +1978,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -1650,7 +1987,7 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "generator", "scoped-tls", "serde", @@ -1751,6 +2088,12 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.5.3" @@ -1760,6 +2103,25 @@ dependencies = [ "adler", ] +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + [[package]] name = "mio" version = "0.8.3" @@ -1772,6 +2134,39 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio 0.6.23", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.6", +] + [[package]] name = "native-tls" version = "0.2.10" @@ -1818,6 +2213,17 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + [[package]] name = "new_debug_unreachable" version = "1.0.4" @@ -1830,6 +2236,34 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "notify" +version = "4.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" +dependencies = [ + "bitflags", + "filetime", + "fsevent", + "fsevent-sys", + "inotify", + "libc", + "mio 0.6.23", + "mio-extras", + "walkdir", + "winapi 0.3.9", +] + [[package]] name = "notify-rust" version = "4.5.8" @@ -1990,7 +2424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 1.0.0", "foreign-types", "libc", "once_cell", @@ -2036,7 +2470,7 @@ checksum = "0eca3ecae1481e12c3d9379ec541b238a16f0b75c9a409942daa8ec20dbfdb62" dependencies = [ "log", "serde", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2046,7 +2480,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c92f2b54f081d635c77e7120862d48db8e91f7f21cef23ab1b4fe9971c59f55" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2113,12 +2547,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2127,7 +2561,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec", @@ -2169,6 +2603,34 @@ dependencies = [ "sha2", ] +[[package]] +name = "pdfium-render" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54152d97c4972b2d05970e085d90ac0400723a1c4d67867775b0bcc6846a9223" +dependencies = [ + "bindgen", + "bitflags", + "bytes", + "console_error_panic_hook", + "console_log", + "image", + "js-sys", + "lazy_static", + "libloading", + "log", + "utf16string", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" version = "2.1.0" @@ -2292,6 +2754,26 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -2318,7 +2800,7 @@ checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" dependencies = [ "bitflags", "deflate 0.7.20", - "inflate", + "inflate 0.3.4", "num-iter", ] @@ -2494,6 +2976,30 @@ dependencies = [ "cty", ] +[[package]] +name = "rayon" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.13" @@ -2546,7 +3052,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2611,6 +3117,27 @@ dependencies = [ "windows 0.37.0", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi 0.3.9", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.3.3" @@ -2629,6 +3156,18 @@ dependencies = [ "semver 1.0.9", ] +[[package]] +name = "rustls" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +dependencies = [ + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "rustversion" version = "1.0.6" @@ -2666,6 +3205,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + [[package]] name = "scopeguard" version = "1.1.0" @@ -2688,6 +3233,16 @@ dependencies = [ "tendril", ] +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" version = "2.6.1" @@ -2872,7 +3427,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c77f4e7f65455545c2153c1253d25056825e77ee2533f0e41deb65a93a34852f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", ] @@ -2883,7 +3438,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", ] @@ -2904,7 +3459,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", ] [[package]] @@ -2932,7 +3502,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2963,6 +3533,21 @@ dependencies = [ "system-deps 5.0.0", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +dependencies = [ + "lock_api", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -3127,7 +3712,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271450eb289cb4d8d0720c6ce70c72c8c858c93dd61fc625881616752e6b98f6" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "core-foundation-sys", "libc", "objc", @@ -3144,6 +3729,12 @@ dependencies = [ "xattr", ] +[[package]] +name = "target-lexicon" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" + [[package]] name = "tauri" version = "1.0.0" @@ -3319,12 +3910,12 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand", "libc", "redox_syscall", "remove_dir_all", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -3388,6 +3979,26 @@ dependencies = [ "once_cell", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cfada0986f446a770eca461e8c6566cb879682f7d687c8348aa0c857bd52286" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.9" @@ -3430,12 +4041,26 @@ dependencies = [ "bytes", "libc", "memchr", - "mio", + "mio 0.8.3", "num_cpus", "once_cell", + "parking_lot 0.12.1", "pin-project-lite", + "signal-hook-registry", "socket2", - "winapi", + "tokio-macros", + "winapi 0.3.9", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -3483,7 +4108,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3599,6 +4224,29 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "ureq" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9399fa2f927a3d327187cbd201480cee55bee6ac5d3c77dd27f0c6814cff16d5" +dependencies = [ + "base64", + "chunked_transfer", + "flate2", + "log", + "once_cell", + "rustls", + "url", + "webpki", + "webpki-roots", +] + [[package]] name = "url" version = "2.2.2" @@ -3618,6 +4266,15 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16string" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b62a1e85e12d5d712bf47a85f426b73d303e2d00a90de5f3004df3596e9d216" +dependencies = [ + "byteorder", +] + [[package]] name = "uuid" version = "0.8.2" @@ -3699,7 +4356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", - "winapi", + "winapi 0.3.9", "winapi-util", ] @@ -3737,7 +4394,7 @@ version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -3762,7 +4419,7 @@ version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "js-sys", "wasm-bindgen", "web-sys", @@ -3854,6 +4511,25 @@ dependencies = [ "system-deps 6.0.2", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" +dependencies = [ + "webpki", +] + [[package]] name = "webview2-com" version = "0.16.0" @@ -3891,12 +4567,35 @@ dependencies = [ "windows-bindgen", ] +[[package]] +name = "weezl" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4" + +[[package]] +name = "which" +version = "4.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +dependencies = [ + "either", + "lazy_static", + "libc", +] + [[package]] name = "wildmatch" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -3907,6 +4606,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -3919,7 +4624,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -4089,7 +4794,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -4144,6 +4849,16 @@ dependencies = [ "windows-implement", ] +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "x11" version = "2.19.1" diff --git a/app/package.json b/app/package.json index 72f40b2..5756415 100644 --- a/app/package.json +++ b/app/package.json @@ -11,13 +11,8 @@ "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^13.0.0", "@testing-library/user-event": "^13.2.1", - "@types/jest": "^27.0.1", - "@types/node": "^16.7.13", - "@types/react": "^18.0.0", - "@types/react-dom": "^18.0.0", "axios": "^0.27.2", "dayjs": "^1.11.3", - "lodash": "^4.17.21", "react": "^18.1.0", "react-dom": "^18.1.0", "react-hook-form": "^7.31.3", @@ -53,7 +48,10 @@ }, "devDependencies": { "@craco/craco": "^6.4.3", - "@types/lodash": "^4.14.182", - "craco-swc": "^0.5.1" + "craco-swc": "^0.5.1", + "@types/jest": "^27.0.1", + "@types/node": "^16.7.13", + "@types/react": "^18.0.0", + "@types/react-dom": "^18.0.0" } } diff --git a/app/src/App.tsx b/app/src/App.tsx index 787d7eb..344ccbf 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -30,7 +30,6 @@ import { FormatListBulleted, SortByAlpha, } from '@mui/icons-material'; -import { intersection } from 'lodash'; interface LinkInfo { title: string; @@ -60,9 +59,9 @@ interface OpenGraph { /// Represents the "og:locale" OpenGraph meta tag locale: string; } -interface Config { - mode: SortMode; - score: string[]; +interface LinkScoreMap { + name: string; + value: number; } interface LinkListItemProps { link: LinkInfo; @@ -73,11 +72,13 @@ const Home = () => { const [mode, setMode] = useState('normal'); const [linkInfos, setLinkInfos] = useState([]); + const [scores, setScores] = useState([]); + const { register, handleSubmit, reset } = useForm(); const [page, setPage] = useState(0); const itemPerPage = 5; const pageCount = Math.ceil(linkInfos.length / itemPerPage); - + console.log(linkInfos); const createLink: SubmitHandler = (data) => { invoke('create_link', { ...data, @@ -106,43 +107,11 @@ const Home = () => { console.error(e); throw e; }); - - const defaultConfig: Config = { - mode: 'score', - score: links.map((val) => val.name), - }; - // Get config or initialize one. - const initialConfig = await invoke('get_config').catch((e) => { - console.log('failed to get config', e); - // Fallback to create the default config - return invoke('set_config', { - config: defaultConfig, - }); + const scores = await invoke('get_scores').catch((e) => { + console.error(e); + return [] as LinkScoreMap[]; }); - - console.log('initialConfig:', initialConfig); - // Merge List item into config score when mode is set to score. - if (mode === 'score') { - // merge config score with current linkList - // - // if a item is added/deleted from disk, it will disappeared on the list. - let mergedScore = intersection( - initialConfig.score, - links.map((val) => val.name) - ); - console.log('merged:', mergedScore); - console.log('links', links); - let mergedLinkInfos = mergedScore.map((val) => { - const link = links.find((link) => { - return link.name === val; - }); - return link; - }) as LinkInfo[]; - - console.log('mergedLinkInfos:', mergedLinkInfos); - setLinkInfos(mergedLinkInfos); - return; - } + setScores(scores); // Sort and push link infos setLinkInfos( (links as LinkInfo[]) @@ -156,10 +125,15 @@ const Home = () => { b.created_time.secs_since_epoch - a.created_time.secs_since_epoch ); - // Default to score + case 'score': + const item_a = + scores.find((val) => val.name === a.name)?.value ?? 0; + const item_b = + scores.find((val) => val.name === b.name)?.value ?? 0; + + return item_b - item_a; } }) - // TODO ); }, [mode]); @@ -167,22 +141,6 @@ const Home = () => { refreshInfo(); }, [refreshInfo]); - const updateScore = (arr: LinkInfo[]) => { - const updatedConfig: Config = { - mode: 'score', - score: arr.map((val) => val.name), - }; - console.log('updatedConfig:', updatedConfig); - invoke('set_config', { - config: updatedConfig, - }) - .then((_) => { - console.log('successfully set config'); - }) - .catch((e) => { - throw e; - }); - }; const LinkList = () => { const LinkListItem = ({ link, index }: LinkListItemProps) => { const [previewInfo, setPreviewInfo] = useState(); @@ -259,28 +217,54 @@ const Home = () => { { - let arr = Array.from(linkInfos); - [arr[index - 1], arr[index]] = [arr[index], arr[index - 1]]; + let arr = Array.from(scores); + arr = arr.map((val) => { + if (val.name === link.name) { + val.value += 1; + } + return val; + }); console.log(arr); - setLinkInfos(arr); - updateScore(arr); + invoke('set_scores', { + linkScoreMaps: arr, + }); + // setScores(arr); + refreshInfo(); }}> { - let arr = Array.from(linkInfos); - [arr[index], arr[index + 1]] = [arr[index + 1], arr[index]]; + let arr = Array.from(scores); + arr = arr.map((val) => { + if (val.name === link.name) { + val.value -= 1; + } + return val; + }); console.log(arr); - setLinkInfos(arr); - updateScore(arr); + setScores(arr); + invoke('set_scores', { + linkScoreMaps: arr, + }).then(() => { + refreshInfo(); + }); }}> + + Score: + {scores.find((val) => val.name === link.name)?.value} + diff --git a/core/Cargo.toml b/core/Cargo.toml index dec5f66..ec88d0e 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -26,6 +26,11 @@ tauri-macros = "1.0.0" walkdir = "2.3.2" anyhow = "1.0.57" reqwest = "0.11.11" +arklib = { git = "https://github.com/ARK-Builders/arklib" } +notify = "4.0.17" +tokio = { version = "1.19.2", features = ["full"] } +crossbeam-channel = "0.5.5" +lazy_static = "1.4.0" [features] # by default Tauri runs in production mode # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL diff --git a/core/src/base/mod.rs b/core/src/base/mod.rs index f4a1974..569d3a8 100644 --- a/core/src/base/mod.rs +++ b/core/src/base/mod.rs @@ -1,13 +1,20 @@ mod link; +use std::{fs::File, path::Path}; + pub use link::{Link, OpenGraph}; use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct LinkScoreMap { + pub name: String, + pub value: i64, +} + /// ARK Config #[derive(Debug, Serialize, Deserialize)] pub struct Config { /// Sorting mode. pub mode: Mode, - /// The score content, repensented to a score. - pub score: Option>, } #[derive(Debug, Serialize, Deserialize)] @@ -20,3 +27,52 @@ pub enum Mode { /// Sorting by score Score, } +pub type Scores = Vec; +#[derive(Debug, Deserialize, Serialize, PartialEq, PartialOrd, Clone)] +pub struct Score { + pub hash: String, + // Score could take a negative value. + pub value: i64, +} + +impl Score { + pub fn calc_hash(path: impl AsRef) -> String { + format!( + "{:x}", + arklib::id::ResourceId::compute( + File::open(&path).unwrap().metadata().unwrap().len(), + path, + ) + .crc32 + ) + } + pub fn parse(content: String) -> Scores { + let splited = content + .split("\n") + .map(|val| { + let mapped = val.split(": ").collect::>(); + Score { + hash: mapped[0].to_string(), + value: i64::from_str_radix(mapped[1], 10).unwrap(), + } + }) + .collect::>(); + splited + } + + pub fn format(hash: String, value: i64) -> String { + String::from(format!("{hash}: {value}")) + } + pub fn into_lines(arr: Scores) -> String { + arr.iter() + .map(|s| Score::format(s.hash.clone(), s.value)) + .collect::>() + .join("\n") + } +} + +impl ToString for Score { + fn to_string(&self) -> String { + Score::format(self.hash.clone(), self.value) + } +} diff --git a/core/src/command/mod.rs b/core/src/command/mod.rs index c7d3c22..aefe64a 100644 --- a/core/src/command/mod.rs +++ b/core/src/command/mod.rs @@ -1,20 +1,21 @@ use std::{ + ffi::OsString, fs::{self, File}, - io::Write, + io::{Read, Write}, path::PathBuf, }; use crate::{ - base::{Config, Link, OpenGraph}, - Cli, + base::{Link, LinkScoreMap, OpenGraph, Score}, + Cli, SCORES_PATH, }; use tauri::{Builder, Runtime}; use url::Url; -use walkdir::WalkDir; +use walkdir::{DirEntry, WalkDir}; #[tauri::command] -/// Create a `.link` +/// Create a `.lin&mut k` fn create_link( title: String, desc: String, @@ -38,15 +39,30 @@ fn delete_link(name: String, state: tauri::State) { fs::remove_file(format!("{}/{}", &state.path, name)).expect("cannot remove the link"); } +fn get_fs_links(state: tauri::State) -> Vec { + WalkDir::new(state.path.clone()) + .max_depth(1) + .into_iter() + .filter(|file| { + file.as_ref() + .unwrap() + .file_name() + .to_str() + .unwrap() + .to_string() + .ends_with(".link") + }) + .map(|e| e.unwrap()) + .collect::>() +} + #[tauri::command(async)] /// Read names of `.link` in user specific directory fn read_link_list(state: tauri::State) -> Vec { let mut path_list = vec![]; - for item in WalkDir::new(state.path.clone()).max_depth(1).into_iter() { - let file_name = item.unwrap().file_name().to_str().unwrap().to_string(); - if file_name.ends_with(".link") { - path_list.push(file_name); - } + for item in get_fs_links(state.clone()) { + let file_name = item.file_name().to_str().unwrap().to_string(); + path_list.push(file_name); } path_list } @@ -56,19 +72,79 @@ async fn generate_link_preview(url: String) -> Result { Link::get_preview(url).await.map_err(|e| e.to_string()) } +/// Get the score list #[tauri::command(async)] -fn get_config(state: tauri::State) -> Result { - let config_path = PathBuf::from(&state.path).join("ark_config"); - let file = File::open(config_path).map_err(|e| e.to_string())?; - let j = serde_json::from_reader(file).map_err(|e| e.to_string())?; - Ok(j) +fn get_scores(state: tauri::State) -> Result, String> { + let mut file = File::open(SCORES_PATH.as_path()).map_err(|e| e.to_string())?; + let mut string_buf = String::new(); + file.read_to_string(&mut string_buf) + .map_err(|e| e.to_string())?; + let scores = Score::parse(string_buf); + let fs_links = get_fs_links(state); + + let link_score_maps = fs_links + .iter() + .map(|entry| { + let item = scores + .iter() + .find(|s| Score::calc_hash(entry.path()) == s.hash) + .unwrap(); + LinkScoreMap { + name: entry.file_name().to_str().unwrap().to_string(), + value: item.value, + } + }) + .collect::>(); + Ok(link_score_maps) } +/// Set scores +/// +/// Only affected scores file. #[tauri::command(async)] -fn set_config(config: Config, state: tauri::State) -> Result<(), String> { - let config_path = PathBuf::from(&state.path).join("ark_config"); - let mut file = File::create(config_path).map_err(|e| e.to_string())?; - file.write_all(serde_json::to_vec(&config).unwrap().as_slice()) +fn set_scores(link_score_maps: Vec, state: tauri::State) -> Result<(), String> { + let mut buf = String::new(); + let mut scores_file = File::options() + .read(true) + .open(SCORES_PATH.as_path()) + .unwrap(); + scores_file + .read_to_string(&mut buf) + .map_err(|e| e.to_string())?; + + let scores = Score::parse(buf); + let fs_links = get_fs_links(state); + + let transformed = link_score_maps + .iter() + .map(|s| { + let item = fs_links + .iter() + .find(|e| e.file_name().to_os_string() == OsString::from(s.name.clone())) + .unwrap(); + + Score { + hash: Score::calc_hash(item.path()), + value: s.value, + } + }) + .collect::>(); + + let merged = scores + .iter() + .map(|s| match transformed.iter().find(|&ms| ms.hash == s.hash) { + Some(item) => item.clone(), + None => s.clone(), + }) + .collect::>(); + + let mut scores_file = File::options() + .write(true) + .truncate(true) + .open(SCORES_PATH.as_path()) + .unwrap(); + scores_file + .write_all(Score::into_lines(merged).as_bytes()) .map_err(|e| e.to_string())?; Ok(()) } @@ -77,7 +153,7 @@ fn set_config(config: Config, state: tauri::State) -> Result<(), String> { /// Read data from `.link` file fn read_link(name: String, state: tauri::State) -> Link { let link = Link::from(PathBuf::from(format!("{}/{}", &state.path, name))); - dbg!(&link); + // dbg!(&link); return link; } @@ -88,7 +164,7 @@ pub fn set_command(builder: Builder) -> Builder { delete_link, generate_link_preview, read_link, - get_config, - set_config + get_scores, + set_scores ]) } diff --git a/core/src/main.rs b/core/src/main.rs index 076b42b..0da655f 100644 --- a/core/src/main.rs +++ b/core/src/main.rs @@ -5,9 +5,31 @@ pub mod base; mod command; +use base::{Score, Scores}; use clap::Parser; use command::*; use home::home_dir; +use lazy_static::lazy_static; +use notify::{watcher, DebouncedEvent, Watcher}; +use std::{ + fs::File, + io::{Read, Write}, + path::{Path, PathBuf}, + sync::mpsc::channel, + thread, + time::Duration, +}; +use walkdir::{DirEntry, WalkDir}; + +lazy_static! { + pub static ref ARK_SHELF_DATA_PATH: PathBuf = + PathBuf::from(Cli::parse().path).join(".ark").join("shelf"); + pub static ref SCORES_PATH: PathBuf = PathBuf::from(Cli::parse().path) + .join(".ark") + .join("shelf") + .join("scores"); +} + #[derive(Parser, Default, Debug)] #[clap( name = "ARK Shelf Desktop", @@ -23,9 +45,140 @@ struct Cli { path: String, } +// Initialize file watcher. +fn init_score_watcher(path: String) { + thread::spawn(|| { + let (tx, rx) = channel(); + let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); + watcher + .watch(path, notify::RecursiveMode::NonRecursive) + .unwrap(); + loop { + match rx.recv() { + Ok(event) => match event { + // Append new link into score file + DebouncedEvent::Create(path) => { + let score = Score { + hash: Score::calc_hash(path), + value: 0, + }; + let mut score_file = File::options() + .append(true) + .open(SCORES_PATH.as_path()) + .unwrap(); + score_file + .write_all(format!("\n{}", score.to_string()).as_bytes()) + .unwrap(); + } + // Remove from score file + DebouncedEvent::NoticeRemove(_) => { + // let score = Score { + // hash: Score::calc_hash(path), + // value: 0, + // }; + let mut buf = String::new(); + let mut scores_file = File::options() + .read(true) + .open(SCORES_PATH.as_path()) + .unwrap(); + scores_file.read_to_string(&mut buf).unwrap(); + + let scores = Score::parse(buf); + let merged = merge_scores(Cli::parse().path, scores); + let mut merged_scores_file = File::options() + .write(true) + .truncate(true) + .open(SCORES_PATH.as_path()) + .unwrap(); + merged_scores_file + .write_all(Score::into_lines(merged).as_bytes()) + .unwrap(); + } + _ => {} + }, + Err(e) => { + panic!("{e}") + } + } + } + }); +} + +// Merge scores with provided score list. +fn merge_scores(path: impl AsRef, merge_scores: Scores) -> Scores { + let entrys = WalkDir::new(path) + .max_depth(1) + .into_iter() + .filter(|entry| { + entry + .as_ref() + .unwrap() + .file_name() + .to_str() + .unwrap() + .to_string() + .ends_with(".link") + }) + .map(|e| e.unwrap()) + .collect::>(); + + let init_scores = entrys + .iter() + .map(|entry| Score { + hash: Score::calc_hash(entry.path()), + // Default to 0 + value: 0, + }) + .collect::(); + + init_scores + .iter() + .map(|score| + // Merge score item if the item already existed in to-be-merged scores + // Item not found in init_scores will be ignored. (Remove from the list) + match merge_scores.iter().find(|&s| s.hash == score.hash) { + Some(item) => item.clone(), + None => score.clone(), + }) + .collect::() + // Score::into_lines(merged) +} + fn main() { let cli = Cli::parse(); + lazy_static::initialize(&SCORES_PATH); + lazy_static::initialize(&ARK_SHELF_DATA_PATH); std::fs::create_dir_all(&cli.path).unwrap(); + std::fs::create_dir_all(ARK_SHELF_DATA_PATH.as_path()).unwrap(); + // Check if the scores file is existed, otherwise create one. + let mut scores_file = File::options() + .read(true) + .open(SCORES_PATH.as_path()) + .unwrap_or_else(|_| File::create(SCORES_PATH.as_path()).unwrap()); + + let mut scores_string = String::new(); + + scores_file.read_to_string(&mut scores_string).unwrap_or(0); + let mut prepare_merge = vec![]; + // Skip if there's no content in the file. + if !scores_string.is_empty() { + prepare_merge = Score::parse(scores_string); + } + dbg!(&prepare_merge); + let merged = merge_scores(&cli.path, prepare_merge); + + let mut scores_file = File::options() + .write(true) + .truncate(true) + .open(SCORES_PATH.as_path()) + .unwrap(); + // Merge scores item and write to score file. + scores_file + .write_all(Score::into_lines(merged).as_bytes()) + .unwrap(); + + init_score_watcher(cli.path.clone()); + let builder = tauri::Builder::default(); let builder = set_command(builder); builder