diff --git a/frontend/src/I18n.ts b/frontend/src/I18n.ts index 267c067..5cd3d0d 100644 --- a/frontend/src/I18n.ts +++ b/frontend/src/I18n.ts @@ -81,6 +81,9 @@ i18n "snapshot-list-source-upload": "Upload", "snapshot-list-download": "Download", "snapshot-list-export-mldx": "Export MemoLanes Archive", + "snapshot-list-export-mldx-prompt": + "This feature will read all snapshots stored in your Fog Machine, then convert and optimize them one by one. After that, they will be merged into an archive file that can be read by MemoLanes (mldx).\nSpecifically:\n1. All snapshots will be processed in the order of snapshot time and converted into journeys in MemoLanes.\n2. Each journey's date is based on the snapshot time and your current time zone.\n3. We subtract the previous snapshot from each snapshot, so each journey will only contain the diff.\n4. Area that exists in a snapshot but not in the final snapshot will be removed. If you've used the eraser, ensure the final snapshot doesn't contain areas you don't want.\n5. Snapshots that are too small will be ignored.", + "snapshot-list-export-mldx-confirm": "Export", "snapshot-list-view": "View", "snapshot-list-note-edit": "Edit Note", "snapshot-list-note-edit-err-tolong": @@ -156,6 +159,9 @@ i18n "snapshot-list-source-upload": "上传", "snapshot-list-download": "下载", "snapshot-list-export-mldx": "导出迹忆归档", + "snapshot-list-export-mldx-prompt": + "此功能将读取你在 迷雾机器 中的所有快照并逐一转换、优化并合并成为可供 迹忆 导入的归档文件(mldx)。\n其中:\n1. 所有快照会按时间顺序逐一处理,转换成 迹忆 的旅程。\n2. 每个旅程的日期基于快照时间以及你当前的时区。\n3. 每个快照会减去上一个快照中的数据,使得每个旅程之包含差异数据。\n4. 每个快照中不存在于最后一个快照的数据将被去除。如果你使用过橡皮擦,只需要保证最后的快照中不包含你不需要的数据即可。\n5. 过小的快照将会被忽略。", + "snapshot-list-export-mldx-confirm": "导出", "snapshot-list-view": "查看", "snapshot-list-note-edit": "编辑备注", "snapshot-list-note-edit-err-tolong": "备注过长,请修改", diff --git a/frontend/src/time-machine/Api.ts b/frontend/src/time-machine/Api.ts index d08e565..209f2a0 100644 --- a/frontend/src/time-machine/Api.ts +++ b/frontend/src/time-machine/Api.ts @@ -345,8 +345,10 @@ export default class Api { public static async getMemoleanesArchiveDownloadToken(): Promise< Result > { + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const result = await this.requestApi( - "memolanes_archive/download_token", + "memolanes_archive/download_token?timezone=" + + encodeURIComponent(timezone), "get", true ); diff --git a/frontend/src/time-machine/DashboardSnapshot.css b/frontend/src/time-machine/DashboardSnapshot.css index 1d6deab..3e32296 100644 --- a/frontend/src/time-machine/DashboardSnapshot.css +++ b/frontend/src/time-machine/DashboardSnapshot.css @@ -8,3 +8,7 @@ text-align: left; height: 18px; } + +.rs-notification-content { + max-width: 600px !important; +} diff --git a/frontend/src/time-machine/DashboardSnapshot.tsx b/frontend/src/time-machine/DashboardSnapshot.tsx index 9162c9d..ce76bde 100644 --- a/frontend/src/time-machine/DashboardSnapshot.tsx +++ b/frontend/src/time-machine/DashboardSnapshot.tsx @@ -432,6 +432,50 @@ function DashboardSnapshot() { }); }; + const openMemolanesExportConfirmation = () => { + // TODO: It is a bit wierd to use `Notifaction` as a modal. Maybe we shoudln't do this, but it works okish for now. + // e.g. when `Notifaction` is open, user can still click other things on the page. + // no easy way to close the current one other than using `clear` which close all things. + // We *SHOULDN'T* allow user to open multiple confirmation, that's really confusing. + + const message = ( + +
+          {t("snapshot-list-export-mldx-prompt")}
+        
+
+ + + +
+ ); + notificationToaster.push(message, { + placement: "topCenter", + duration: 0, + }); + }; + const fileUploadUrl = Api.backendUrl + "misc/upload"; const headers = Api.tokenHeaders(); @@ -462,24 +506,15 @@ function DashboardSnapshot() { > {t("snapshot-list-upload")} - {/* TODO: This feature is not ready. */} - {/* } onClick={async () => { - const token = await Api.getMemoleanesArchiveDownloadToken(); - if (token.ok) { - window.open( - Api.backendUrl + "misc/download?token=" + token.ok, - "_blank" - ); - } else { - //TODO: error handling - } + openMemolanesExportConfirmation(); }} > {t("snapshot-list-export-mldx")} - */} + } diff --git a/server/Cargo.lock b/server/Cargo.lock index 73e3db0..393aedb 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -46,7 +46,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", "once_cell", "version_check", "zerocopy", @@ -67,11 +66,17 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "allo-isolate" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b6d794345b06592d0ebeed8e477e41b71e5a0a49df4fc0e4184d5938b99509" +checksum = "1f67642eb6773fb42a95dd3b348c305ee18dee6642274c6b412d67e985e3befc" dependencies = [ "anyhow", "atomic 0.5.3", @@ -195,10 +200,15 @@ dependencies = [ ] [[package]] -name = "arrayref" -version = "0.3.9" +name = "arg_enum_proc_macro" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] [[package]] name = "arrayvec" @@ -206,12 +216,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "assert_approx_eq" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c07dab4369547dbe5114677b33fbbf724971019f3818172d59a97a61c774ffd" - [[package]] name = "async-attributes" version = "1.1.2" @@ -350,7 +354,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -367,7 +371,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -406,6 +410,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" +dependencies = [ + "arrayvec", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -427,12 +454,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -447,13 +468,16 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bigdecimal" -version = "0.3.1" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +checksum = "8f850665a0385e070b64c38d2354e6c104c8479c59868d1e48a0c13ee2c7a1c1" dependencies = [ + "autocfg", + "libm", "num-bigint", "num-integer", "num-traits", + "serde", ] [[package]] @@ -462,6 +486,21 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -477,6 +516,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + [[package]] name = "bitvec" version = "1.0.1" @@ -531,7 +576,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "syn_derive", ] @@ -541,6 +586,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b" +[[package]] +name = "built" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" + [[package]] name = "bumpalo" version = "3.16.0" @@ -592,6 +643,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.7.2" @@ -630,6 +687,16 @@ dependencies = [ "shlex", ] +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -657,6 +724,27 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "chrono-tz" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6dd8046d00723a59a2f8c5f295c515b9bb9a331ee4f8f3d4dd49e428acd3b6" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94fea34d77a245229e7746bd2beb786cd2a896f306ff491fb8cecb3074b10a7" +dependencies = [ + "parse-zoneinfo", + "phf_codegen", +] + [[package]] name = "cipher" version = "0.4.4" @@ -698,7 +786,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -707,6 +795,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colorchoice" version = "1.0.2" @@ -738,12 +832,6 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "constant_time_eq" version = "0.3.1" @@ -866,6 +954,12 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -896,7 +990,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -907,7 +1001,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -943,7 +1037,7 @@ checksum = "51aac4c99b2e6775164b412ea33ae8441b2fde2dbf05a20bc0052a63d08c475b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -975,7 +1069,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -1041,7 +1135,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics 0.10.1", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -1064,7 +1158,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -1079,18 +1173,6 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" -[[package]] -name = "educe" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bd92664bf78c4d3dba9b7cdafce6fa15b13ed3ed16175218196942e99168a8" -dependencies = [ - "enum-ordinalize", - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "either" version = "1.13.0" @@ -1140,26 +1222,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "enum-ordinalize" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" -dependencies = [ - "enum-ordinalize-derive", -] - -[[package]] -name = "enum-ordinalize-derive" -version = "4.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "env_logger" version = "0.10.2" @@ -1187,7 +1249,7 @@ checksum = "d4291f0c7220b67ad15e9d5300ba2f215cee504f0924d60e77c9d1c77e7a69b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -1206,16 +1268,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "error-chain" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" -dependencies = [ - "backtrace", - "version_check", -] - [[package]] name = "etcetera" version = "0.8.0" @@ -1254,11 +1306,26 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fallible-iterator" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fallible-streaming-iterator" @@ -1304,6 +1371,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "file-rotate" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3ed82142801f5b1363f7d463963d114db80f467e860b1cd82228eaebc627a0" +dependencies = [ + "chrono", + "flate2", +] + [[package]] name = "flate2" version = "1.0.34" @@ -1327,9 +1404,9 @@ dependencies = [ [[package]] name = "flutter_rust_bridge" -version = "2.0.0-dev.24" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610e046fae4b0b21210e67b212f3a97ccfd454976e8ef74634d641a2ce9a7075" +checksum = "93b95a1b4f20b8c037535bcda990abf0ae2bd94c93e27ebbbe00633322bc1561" dependencies = [ "allo-isolate", "android_logger", @@ -1345,7 +1422,9 @@ dependencies = [ "futures", "js-sys", "lazy_static", + "log", "oslog", + "portable-atomic", "threadpool", "tokio", "wasm-bindgen", @@ -1355,9 +1434,16 @@ dependencies = [ [[package]] name = "flutter_rust_bridge_macros" -version = "2.0.0-dev.24" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa90b2229a73f1aac282856e7870d11c8d1117285c8f6d7142de581497277825" +checksum = "fafd532ccfcce8ef23e858fe07303ff572e8b302be6ec0b0f38ca6eb319206dc" +dependencies = [ + "hex", + "md-5", + "proc-macro2", + "quote", + "syn 2.0.89", +] [[package]] name = "fnv" @@ -1374,6 +1460,7 @@ dependencies = [ "base64 0.22.1", "byte-unit", "chrono", + "chrono-tz", "dotenv", "email_address", "endorphin", @@ -1510,7 +1597,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -1588,6 +1675,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.31.1" @@ -1614,12 +1711,9 @@ dependencies = [ [[package]] name = "gpx" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b436c838dada2b577d1b80ac62b5569584990fb10fc6554a95cfd67c6e5db9e" +version = "0.10.0" +source = "git+https://github.com/MemoLanes/gpx.git?branch=relax-parsing#42f8d9d5a083df1e5f2e88dc7a7fb098cd0b1998" dependencies = [ - "assert_approx_eq", - "error-chain", "geo-types", "thiserror", "time", @@ -1664,6 +1758,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -1700,9 +1804,9 @@ checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "hashlink" -version = "0.8.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ "hashbrown 0.14.5", ] @@ -1712,9 +1816,6 @@ name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] [[package]] name = "heck" @@ -1970,6 +2071,45 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.25.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" + [[package]] name = "indexmap" version = "2.6.0" @@ -1989,7 +2129,7 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2022,6 +2162,17 @@ version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d762194228a2f1c11063e46e32e5acb96e66e906382b9eb5441f2e0504bbd5a" +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "ipnet" version = "2.10.1" @@ -2047,9 +2198,18 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -2069,6 +2229,23 @@ dependencies = [ "libc", ] +[[package]] +name = "journey_kernel" +version = "0.1.0" +source = "git+https://github.com/MemoLanes/MemoLanes.git?rev=ebf359c#ebf359cb49d77c0a907f8499c0e94c06a1919da1" +dependencies = [ + "bincode", + "image", + "serde", + "serde_json", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.72" @@ -2124,12 +2301,28 @@ dependencies = [ "spin", ] +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +[[package]] +name = "libfuzzer-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" +dependencies = [ + "arbitrary", + "cc", +] + [[package]] name = "libm" version = "0.2.8" @@ -2138,9 +2331,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libsqlite3-sys" -version = "0.26.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", @@ -2193,6 +2386,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "lzma-rs" version = "0.3.0" @@ -2212,6 +2414,16 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "md-5" version = "0.10.6" @@ -2237,16 +2449,20 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memolanes_core" version = "0.1.0" -source = "git+https://github.com/MemoLanes/MemoLanes.git?rev=cee5400#cee5400d54b2ae5bb3f105fac6734de12a6f50a4" +source = "git+https://github.com/MemoLanes/MemoLanes.git?rev=ebf359c#ebf359cb49d77c0a907f8499c0e94c06a1919da1" dependencies = [ "anyhow", "chrono", + "file-rotate", "flate2", "flutter_rust_bridge", + "geo-types", "gpx", "hex", + "image", "integer-encoding", - "itertools", + "itertools 0.13.0", + "journey_kernel", "kml", "lazy_static", "log", @@ -2257,12 +2473,11 @@ dependencies = [ "sha1", "simplelog", "sql_split", - "strum 0.25.0", + "strum", "strum_macros", - "tiny-skia", "uuid", - "zip 0.6.6", - "zstd 0.12.4", + "zip 2.2.0", + "zstd 0.13.2", ] [[package]] @@ -2344,6 +2559,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nom" version = "7.1.3" @@ -2354,6 +2575,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2397,6 +2624,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -2410,9 +2648,20 @@ dependencies = [ name = "num-iter" version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", + "num-bigint", "num-integer", "num-traits", ] @@ -2484,7 +2733,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2537,9 +2786,9 @@ dependencies = [ [[package]] name = "ouroboros" -version = "0.17.2" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" +checksum = "944fa20996a25aded6b4795c6d63f10014a7a83f8be9828a11860b08c5fc4a67" dependencies = [ "aliasable", "ouroboros_macro", @@ -2548,15 +2797,16 @@ dependencies = [ [[package]] name = "ouroboros_macro" -version = "0.17.2" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" +checksum = "39b0deead1528fd0e5947a8546a9642a9777c25f6e1e26f34c97b204bbb465bd" dependencies = [ "heck 0.4.1", - "proc-macro-error", + "itertools 0.12.1", "proc-macro2", + "proc-macro2-diagnostics 0.10.1", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2620,14 +2870,12 @@ dependencies = [ ] [[package]] -name = "password-hash" -version = "0.4.2" +name = "parse-zoneinfo" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" dependencies = [ - "base64ct", - "rand_core", - "subtle", + "regex", ] [[package]] @@ -2636,18 +2884,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest", - "hmac", - "password-hash", - "sha2", -] - [[package]] name = "pbkdf2" version = "0.12.2" @@ -2678,7 +2914,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics 0.10.1", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -2696,6 +2932,44 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -2774,6 +3048,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "portable-atomic" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2807,7 +3087,6 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.109", "version_check", ] @@ -2841,14 +3120,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -2874,11 +3153,30 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "version_check", "yansi 1.0.1", ] +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn 2.0.89", +] + [[package]] name = "protobuf" version = "3.7.1" @@ -2950,6 +3248,21 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.31.0" @@ -3013,6 +3326,76 @@ dependencies = [ "fastrand 1.9.0", ] +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.12.1", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -3048,7 +3431,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -3147,6 +3530,12 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" + [[package]] name = "ring" version = "0.17.8" @@ -3241,7 +3630,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.79", + "syn 2.0.89", "unicode-xid", "version_check", ] @@ -3312,9 +3701,9 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.29.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ "bitflags 2.6.0", "fallible-iterator", @@ -3441,14 +3830,14 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] name = "sea-orm" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1fee0cf8528dbe6eda29d5798afc522a63b75e44c5b15721e6e64af9c7cc4b" +checksum = "d5680a8b686985116607ef5f5af2b1f9e1cc2c228330e93101816a0baa279afa" dependencies = [ "async-stream", "async-trait", @@ -3464,7 +3853,7 @@ dependencies = [ "serde", "serde_json", "sqlx", - "strum 0.26.3", + "strum", "thiserror", "time", "tracing", @@ -3474,9 +3863,9 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0b8869c75cf3fbb1bd860abb025033cd2e514c5f4fa43e792697cb1fe6c882" +checksum = "70a157f42d291ccbd6e913b9d9b12dbe2ccbcf0472efc60c8715dd1254083aec" dependencies = [ "chrono", "clap", @@ -3491,23 +3880,23 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8737b566799ed0444f278d13c300c4c6f1a91782f60ff5825a591852d5502030" +checksum = "3a239e3bb1b566ad4ec2654d0d193d6ceddfd733487edc9c21a64d214c773910" dependencies = [ "heck 0.4.1", "proc-macro2", "quote", "sea-bae", - "syn 2.0.79", + "syn 2.0.89", "unicode-ident", ] [[package]] name = "sea-orm-migration" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216643749e26ce27ab6c51d3475f2692981d4a902d34455bcd322f412900df5c" +checksum = "63ba07e9f2479cc671758fcb1edee42ff2e32c34b3e67ab41d0af1e41f73c74e" dependencies = [ "async-trait", "clap", @@ -3542,13 +3931,12 @@ dependencies = [ [[package]] name = "sea-query" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4fd043b8117af233e221f73e3ea8dfbc8e8c3c928017c474296db45c649105c" +checksum = "ff504d13b5e4b52fffcf2fb203d0352a5722fa5151696db768933e41e1e591bb" dependencies = [ "bigdecimal", "chrono", - "educe", "inherent", "ordered-float", "rust_decimal", @@ -3560,9 +3948,9 @@ dependencies = [ [[package]] name = "sea-query-binder" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754965d4aee6145bec25d0898e5c931e6c22859789ce62fd85a42a15ed5a8ce3" +checksum = "b0019f47430f7995af63deda77e238c17323359af241233ec768aba1faea7608" dependencies = [ "bigdecimal", "chrono", @@ -3584,15 +3972,15 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "thiserror", ] [[package]] name = "sea-schema" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad52149fc81836ea7424c3425d8f6ed8ad448dd16d2e4f6a3907ba46f3f2fd78" +checksum = "aab1592d17860a9a8584d9b549aebcd06f7bdc3ff615f71752486ba0b05b1e6e" dependencies = [ "futures", "sea-query", @@ -3608,7 +3996,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -3642,29 +4030,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] name = "serde_json" -version = "1.0.131" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67d42a0bd4ac281beff598909bb56a86acaf979b84483e1c79c10dcaf98f8cf3" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -3755,6 +4143,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "simdutf8" version = "0.1.5" @@ -3772,6 +4169,12 @@ dependencies = [ "time", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -3795,6 +4198,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -3843,9 +4249,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33" +checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e" dependencies = [ "sqlx-core", "sqlx-macros", @@ -3856,11 +4262,10 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" +checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e" dependencies = [ - "ahash 0.8.11", "atoi", "bigdecimal", "byteorder", @@ -3868,14 +4273,14 @@ dependencies = [ "chrono", "crc", "crossbeam-queue", - "dotenvy", "either", - "event-listener 2.5.3", + "event-listener 5.3.1", "futures-channel", "futures-core", "futures-intrusive", "futures-io", "futures-util", + "hashbrown 0.14.5", "hashlink", "hex", "indexmap", @@ -3902,26 +4307,26 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec" +checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn 1.0.109", + "syn 2.0.89", ] [[package]] name = "sqlx-macros-core" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc" +checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5" dependencies = [ "dotenvy", "either", - "heck 0.4.1", + "heck 0.5.0", "hex", "once_cell", "proc-macro2", @@ -3933,7 +4338,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 1.0.109", + "syn 2.0.89", "tempfile", "tokio", "url", @@ -3941,12 +4346,12 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" +checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a" dependencies = [ "atoi", - "base64 0.21.7", + "base64 0.22.1", "bigdecimal", "bitflags 2.6.0", "byteorder", @@ -3988,12 +4393,12 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" +checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8" dependencies = [ "atoi", - "base64 0.21.7", + "base64 0.22.1", "bigdecimal", "bitflags 2.6.0", "byteorder", @@ -4019,7 +4424,6 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "sha1", "sha2", "smallvec", "sqlx-core", @@ -4033,9 +4437,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f" +checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680" dependencies = [ "atoi", "chrono", @@ -4049,6 +4453,7 @@ dependencies = [ "log", "percent-encoding", "serde", + "serde_urlencoded", "sqlx-core", "time", "tracing", @@ -4080,12 +4485,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strict-num" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" - [[package]] name = "stringprep" version = "0.1.5" @@ -4103,12 +4502,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" - [[package]] name = "strum" version = "0.26.3" @@ -4117,15 +4510,15 @@ checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum_macros" -version = "0.25.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -4147,9 +4540,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -4165,7 +4558,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -4198,12 +4591,31 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml", + "version-compare", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "tempfile" version = "3.13.0" @@ -4243,7 +4655,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -4265,6 +4677,17 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.36" @@ -4298,32 +4721,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-skia" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" -dependencies = [ - "arrayref", - "arrayvec", - "bytemuck", - "cfg-if", - "log", - "png", - "tiny-skia-path", -] - -[[package]] -name = "tiny-skia-path" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" -dependencies = [ - "arrayref", - "bytemuck", - "strict-num", -] - [[package]] name = "tinyvec" version = "1.8.0" @@ -4365,7 +4762,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -4473,7 +4870,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -4589,12 +4986,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "unicode-xid" version = "0.2.6" @@ -4656,7 +5047,18 @@ checksum = "6b91f57fe13a38d0ce9e28a03463d8d3c2468ed03d75375110ec71d93b449a08" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", +] + +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", ] [[package]] @@ -4677,6 +5079,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" @@ -4726,7 +5134,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "wasm-bindgen-shared", ] @@ -4760,7 +5168,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4781,6 +5189,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "which" version = "4.4.2" @@ -5087,7 +5501,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -5107,7 +5521,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.89", ] [[package]] @@ -5116,16 +5530,11 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ - "aes", "byteorder", "bzip2", - "constant_time_eq 0.1.5", "crc32fast", "crossbeam-utils", "flate2", - "hmac", - "pbkdf2 0.11.0", - "sha1", "time", "zstd 0.11.2+zstd.1.5.2", ] @@ -5139,7 +5548,7 @@ dependencies = [ "aes", "arbitrary", "bzip2", - "constant_time_eq 0.3.1", + "constant_time_eq", "crc32fast", "crossbeam-utils", "deflate64", @@ -5149,7 +5558,7 @@ dependencies = [ "indexmap", "lzma-rs", "memchr", - "pbkdf2 0.12.2", + "pbkdf2", "rand", "sha1", "thiserror", @@ -5182,15 +5591,6 @@ dependencies = [ "zstd-safe 5.0.2+zstd.1.5.2", ] -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe 6.0.6", -] - [[package]] name = "zstd" version = "0.13.2" @@ -5210,16 +5610,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", -] - [[package]] name = "zstd-safe" version = "7.2.1" @@ -5238,3 +5628,27 @@ dependencies = [ "cc", "pkg-config", ] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768" +dependencies = [ + "zune-core", +] diff --git a/server/Cargo.toml b/server/Cargo.toml index db3ccfd..360b286 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -26,7 +26,7 @@ sha2 = "0.10" jwt = "0.16" rand = "0.8.5" email_address = "0.2.9" -memolanes_core = { git = "https://github.com/MemoLanes/MemoLanes.git", rev = "cee5400" } +memolanes_core = { git = "https://github.com/MemoLanes/MemoLanes.git", rev = "ebf359c" } rocket_cors = "0.6.0" base64 = "0.22.1" byte-unit = "5.1.4" @@ -38,3 +38,4 @@ endorphin = "0.1.9" log = "0.4" sea-orm-rocket = "0.5.4" openssl = { version = "0.10.66", features = ["vendored"] } +chrono-tz = "0.10.0" diff --git a/server/entity/Cargo.toml b/server/entity/Cargo.toml index 7608341..7a03346 100644 --- a/server/entity/Cargo.toml +++ b/server/entity/Cargo.toml @@ -11,4 +11,4 @@ path = "src/lib.rs" [dependencies] serde = "1.0" serde_json = "1.0" -sea-orm = { version = "^1.0.1", features = [ "sqlx-postgres", "runtime-tokio-native-tls", "macros" ] } +sea-orm = { version = "^1.1", features = [ "sqlx-postgres", "runtime-tokio-native-tls", "macros" ] } diff --git a/server/src/memolanes_archive_handler.rs b/server/src/memolanes_archive_handler.rs index 81594c4..a50279d 100644 --- a/server/src/memolanes_archive_handler.rs +++ b/server/src/memolanes_archive_handler.rs @@ -4,9 +4,17 @@ use crate::{APIResponse, ServerState}; use rocket::http::Status; use serde_json::json; -#[get("/download_token")] -async fn get_download_token(server_state: &rocket::State, user: User) -> APIResponse { - let download_item = misc_handler::DownloadItem::MemolanesArchive { uid: user.uid }; +#[get("/download_token?")] +async fn get_download_token( + server_state: &rocket::State, + user: User, + timezone: String, +) -> APIResponse { + let timezone: chrono_tz::Tz = timezone.parse()?; + let download_item = misc_handler::DownloadItem::MemolanesArchive { + uid: user.uid, + timezone, + }; Ok(( Status::Ok, json!({ diff --git a/server/src/misc_handler.rs b/server/src/misc_handler.rs index dd0c383..63de131 100644 --- a/server/src/misc_handler.rs +++ b/server/src/misc_handler.rs @@ -4,10 +4,11 @@ use crate::user_handler::User; use crate::utils; use crate::{APIResponse, InternalError, ServerState}; use anyhow::Result; -use chrono::NaiveDate; +use chrono::Duration; use entity::sea_orm; -use entity::snapshot; +use entity::snapshot::{self, SyncFiles}; use memolanes_core::journey_header::JourneyKind; +use memolanes_core::journey_kernel::JourneyBitmap; use rocket::data::{Data, ToByteUnit}; use rocket::http::ContentType; use rocket::http::Status; @@ -18,13 +19,13 @@ use sea_orm_rocket::Connection; use serde_json::json; use std::fs; use std::io::{Cursor, Seek, Write}; -use std::time::Duration; use tempfile::TempDir; +use tokio::time::Instant; #[derive(Clone)] pub enum DownloadItem { Snapshot { snapshot_id: i64 }, - MemolanesArchive { uid: i64 }, + MemolanesArchive { uid: i64, timezone: chrono_tz::Tz }, } pub fn generate_download_token(server_state: &ServerState, download_item: DownloadItem) -> String { @@ -33,7 +34,7 @@ pub fn generate_download_token(server_state: &ServerState, download_item: Downlo download_items.insert( download_token.clone(), download_item, - Duration::from_secs(10 * 60), + std::time::Duration::from_secs(10 * 60), ); download_token } @@ -75,10 +76,10 @@ fn get_download_item( download_times.get(token).cloned() } -async fn generate_sync_zip_from_snapshot( +async fn internal_generate_sync_zip_from_sync_files( server_state: &rocket::State, writer: &mut W, - snapshot: entity::snapshot::Model, + sync_files: &entity::snapshot::SyncFiles, user: &User, ) -> Result<(), InternalError> { let mut zip = zip::ZipWriter::new(writer); @@ -86,8 +87,7 @@ async fn generate_sync_zip_from_snapshot( zip::write::SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored); zip.add_directory("Sync/", options)?; - let entity::snapshot::SyncFiles(sync_files) = snapshot.sync_files; - for (file_id, sha256) in &sync_files { + for (file_id, sha256) in &sync_files.0 { let sync_file = data_fetcher::SyncFile::create_from_id(*file_id, sha256)?; zip.start_file(format!("Sync/{}", sync_file.filename()), options)?; let mut file = server_state.file_storage.open_file(user, sha256)?; @@ -98,6 +98,16 @@ async fn generate_sync_zip_from_snapshot( Ok(()) } +async fn generate_sync_zip_from_snapshot( + server_state: &rocket::State, + writer: &mut W, + snapshot: &entity::snapshot::Model, + user: &User, +) -> Result<(), InternalError> { + internal_generate_sync_zip_from_sync_files(server_state, writer, &snapshot.sync_files, user) + .await +} + async fn download_snapshot( conn: Connection<'_, Db>, server_state: &rocket::State, @@ -118,7 +128,7 @@ async fn download_snapshot( generate_sync_zip_from_snapshot( server_state, &mut std::io::Cursor::new(&mut buf), - snapshot, + &snapshot, &user, ) .await?; @@ -130,53 +140,179 @@ async fn download_snapshot( } } +struct InternalProcessSnapshotOutput { + bitmap_diff: JourneyBitmap, + state: (SyncFiles, JourneyBitmap), +} + +fn internal_count_bitmap_blocks(bitmap: &JourneyBitmap) -> u64 { + let mut blocks: u64 = 0; + bitmap.tiles.iter().for_each(|(_, tiles)| { + blocks += tiles.blocks.len() as u64; + }); + blocks +} + +async fn internal_memolanes_archive_process_snapshot( + server_state: &rocket::State, + temp_dir: &TempDir, + user: &User, + final_bitmap: &Option, + snapshot: &entity::snapshot::Model, + prev_state: &Option<(SyncFiles, JourneyBitmap)>, +) -> Result, InternalError> { + let mut sync_files = snapshot.sync_files.clone(); + match prev_state { + None => (), + Some((prev_sync_files, _)) => { + // an optimization, we only care about files that are new + sync_files + .0 + .retain(|file_id, hash| prev_sync_files.0.get(file_id) != Some(hash)); + } + } + + if sync_files.0.is_empty() { + return Ok(None); + } + + let zip_file_path = temp_dir.path().join("temp_sync.zip"); + let mut zip_file = fs::File::create(&zip_file_path)?; + internal_generate_sync_zip_from_sync_files(server_state, &mut zip_file, &sync_files, user) + .await?; + drop(zip_file); + + let full_journey_bitmap = + memolanes_core::import_data::load_fow_sync_data(zip_file_path.to_str().unwrap())?.0; + + fs::remove_file(&zip_file_path)?; + + let mut journey_bitmap = full_journey_bitmap.clone(); + + // compute a better diff + // the current one minus the previous one + match prev_state { + None => (), + Some((_, prev_full_bitmap)) => { + journey_bitmap.difference(prev_full_bitmap); + journey_bitmap.intersection(&full_journey_bitmap); + } + } + + // only keep things that are in the final bitmap + match final_bitmap { + None => (), + Some(final_bitmap) => { + journey_bitmap.intersection(final_bitmap); + } + } + + if journey_bitmap.tiles.is_empty() { + return Ok(None); + } + + // skipping super small snapshots + if internal_count_bitmap_blocks(&journey_bitmap) <= 4 { + return Ok(None); + } + + // we are keeping this bitmap + Ok(Some(InternalProcessSnapshotOutput { + bitmap_diff: journey_bitmap, + // we need original value + state: (snapshot.sync_files.clone(), full_journey_bitmap), + })) +} + async fn download_memolanes_archive( conn: Connection<'_, Db>, server_state: &rocket::State, uid: i64, + timezone: chrono_tz::Tz, ) -> Result { + let start_time = Instant::now(); + let db = conn.into_inner(); let snapshots = snapshot::Entity::find() .filter(snapshot::Column::UserId.eq(uid)) - .order_by_desc(snapshot::Column::Timestamp) + .order_by_asc(snapshot::Column::Timestamp) .all(db) .await?; let user = User { uid }; let temp_dir = TempDir::new()?; let mut main_db = memolanes_core::main_db::MainDb::open(temp_dir.path().to_str().unwrap()); - for snapshot in snapshots { - let zip_file_path = temp_dir.path().join("temp_sync.zip"); - let mut zip_file = fs::File::create(&zip_file_path)?; - generate_sync_zip_from_snapshot(server_state, &mut zip_file, snapshot, &user).await?; - drop(zip_file); - - let journey_bitmap = - memolanes_core::import_data::load_fow_sync_data(zip_file_path.to_str().unwrap())?; - - fs::remove_file(&zip_file_path)?; - - let journey_data = memolanes_core::journey_data::JourneyData::Bitmap(journey_bitmap.0); - - // TODO: postprocess bitmap (e.g. compute delta) - - // TODO: generate these details - main_db.with_txn(|txn| { - txn.create_and_insert_journey( - NaiveDate::default(), - None, - None, - None, - JourneyKind::DefaultKind, - None, - journey_data, + + let final_bitmap = match snapshots.last() { + None => None, + Some(snapshot) => { + let zip_file_path = temp_dir.path().join("temp_sync.zip"); + let mut zip_file = fs::File::create(&zip_file_path)?; + generate_sync_zip_from_snapshot(server_state, &mut zip_file, snapshot, &user).await?; + drop(zip_file); + Some( + memolanes_core::import_data::load_fow_sync_data(zip_file_path.to_str().unwrap())?.0, ) - })?; + } + }; + + let mut prev_state = None; + + for snapshot in snapshots { + let result = internal_memolanes_archive_process_snapshot( + server_state, + &temp_dir, + &user, + &final_bitmap, + &snapshot, + &prev_state, + ) + .await?; + + match result { + None => (), // skipping this snapshot + Some(InternalProcessSnapshotOutput { bitmap_diff, state }) => { + prev_state = Some(state); + + let journey_data = memolanes_core::journey_data::JourneyData::Bitmap(bitmap_diff); + + // Compute the date based on user's timezone. The 6 hours diff is to account for the sync delay. + // This is a best effort thing. + let journey_date = (snapshot.timestamp - Duration::hours(6)) + .with_timezone(&timezone) + .date_naive(); + + // TODO: generate these details + main_db.with_txn(|txn| { + txn.create_and_insert_journey( + journey_date, + None, + Some(snapshot.timestamp), + None, + JourneyKind::DefaultKind, + snapshot.note, + journey_data, + ) + })?; + } + } } let mut buf = Vec::new(); let mut writer = Cursor::new(&mut buf); - memolanes_core::archive::archive_all_as_zip(&mut main_db, &mut writer)?; + main_db.with_txn(|txn| { + memolanes_core::archive::export_as_mldx( + &memolanes_core::archive::WhatToExport::All, + txn, + &mut writer, + ) + })?; + + println!( + "Finsih generating memolanes archive, user = {}, time_used = {:?}", + user.uid, + start_time.elapsed() + ); Ok(FileResponse::Ok { filename: String::from("export.mldx"), @@ -195,8 +331,8 @@ async fn download<'r>( Some(DownloadItem::Snapshot { snapshot_id }) => { download_snapshot(conn, server_state, snapshot_id).await } - Some(DownloadItem::MemolanesArchive { uid }) => { - download_memolanes_archive(conn, server_state, uid).await + Some(DownloadItem::MemolanesArchive { uid, timezone }) => { + download_memolanes_archive(conn, server_state, uid, timezone).await } } } @@ -224,7 +360,11 @@ async fn upload<'r>( let mut uploaded_items = server_state.uploaded_items.lock().unwrap(); let upload_token = utils::random_token(|token| !uploaded_items.contains_key(token)); - uploaded_items.insert(upload_token.clone(), bytes, Duration::from_secs(60)); + uploaded_items.insert( + upload_token.clone(), + bytes, + std::time::Duration::from_secs(60), + ); Ok((Status::Ok, json!({ "upload_token": upload_token }))) }