From 60f3eaf239a39fcf3dbcee53c6b946c5fa7f80c1 Mon Sep 17 00:00:00 2001 From: rustmailer Date: Sun, 14 Sep 2025 17:11:09 +0800 Subject: [PATCH] feat(gmail api): handle label change events in history callback --- Cargo.lock | 269 +++++++++--------- Cargo.toml | 16 +- src/modules/cache/imap/manager.rs | 3 +- .../cache/vendor/gmail/sync/history.rs | 76 ++++- src/modules/hook/events/mod.rs | 3 +- src/modules/hook/events/payload.rs | 4 +- 6 files changed, 226 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 177ce61..959f3c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,12 +158,6 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -409,7 +403,7 @@ dependencies = [ "serde_nanos", "serde_repr", "thiserror 1.0.68", - "time 0.3.41", + "time 0.3.43", "tokio", "tokio-rustls", "tokio-util", @@ -654,7 +648,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cexpr", "clang-sys", "itertools 0.12.1", @@ -692,12 +686,6 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.6.0" @@ -1003,17 +991,16 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.0", ] [[package]] @@ -1103,9 +1090,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.46" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" dependencies = [ "clap_builder", "clap_derive", @@ -1113,9 +1100,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.46" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" dependencies = [ "anstream", "anstyle", @@ -1125,9 +1112,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1590,9 +1577,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", "serde", @@ -1744,7 +1731,7 @@ dependencies = [ "rand 0.8.5", "serde", "smallvec", - "time 0.3.41", + "time 0.3.43", "tokio", "tracing", ] @@ -1947,8 +1934,8 @@ checksum = "d6215aee357f8c7c989ebb4b8466ca4d7dc93b3957039f2fc3ea2ade8ea5f279" dependencies = [ "bit-set", "derivative", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1958,8 +1945,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf04c5ec15464ace8355a7b440a33aece288993475556d461154d7a62ad9947c" dependencies = [ "bit-set", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1977,6 +1964,26 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "fax" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" +dependencies = [ + "fax_derive", +] + +[[package]] +name = "fax_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "fdeflate" version = "0.3.7" @@ -2536,7 +2543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" dependencies = [ "async-trait", - "bitflags 2.6.0", + "bitflags", "bytes 1.7.2", "cfg-if", "data-encoding", @@ -2552,7 +2559,7 @@ dependencies = [ "rustls", "rustls-pki-types", "thiserror 2.0.12", - "time 0.3.41", + "time 0.3.43", "tinyvec", "tokio", "tokio-rustls", @@ -3016,9 +3023,9 @@ dependencies = [ [[package]] name = "image" -version = "0.25.6" +version = "0.25.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" dependencies = [ "bytemuck", "byteorder-lite", @@ -3026,6 +3033,7 @@ dependencies = [ "exr", "gif", "image-webp", + "moxcms", "num-traits", "png", "qoi", @@ -3133,7 +3141,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "libc", ] @@ -3246,12 +3254,6 @@ dependencies = [ "libc", ] -[[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.77" @@ -3282,7 +3284,7 @@ dependencies = [ "percent-encoding", "referencing", "regex", - "regex-syntax 0.8.5", + "regex-syntax", "serde", "serde_json", "uuid-simd", @@ -3319,7 +3321,7 @@ dependencies = [ "lalrpop-util", "petgraph 0.7.1", "regex", - "regex-syntax 0.8.5", + "regex-syntax", "sha3", "string_cache", "term", @@ -3333,7 +3335,7 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8d05b3fe34b8bd562c338db725dfa9beb9451a48f65f129ccb9538b48d2c93b" dependencies = [ - "regex-automata 0.4.8", + "regex-automata", "rustversion", ] @@ -3495,9 +3497,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ea4e65087ff52f3862caff188d489f1fab49a0cb09e01b2e3f1a617b10aaed" +checksum = "bfe949189f46fabb938b3a9a0be30fdd93fd8a09260da863399a8cf3db756ec8" dependencies = [ "hashbrown 0.15.2", ] @@ -3626,11 +3628,11 @@ dependencies = [ [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -3790,6 +3792,16 @@ dependencies = [ "uuid", ] +[[package]] +name = "moxcms" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08" +dependencies = [ + "num-traits", + "pxfm", +] + [[package]] name = "multer" version = "3.1.0" @@ -3902,7 +3914,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -3980,12 +3992,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4164,7 +4175,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -4222,7 +4233,7 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", "once_cell", "onig_sys", @@ -4250,7 +4261,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -4313,12 +4324,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "parking" version = "2.2.1" @@ -4578,11 +4583,11 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" -version = "0.17.16" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" dependencies = [ - "bitflags 1.3.2", + "bitflags", "crc32fast", "fdeflate", "flate2", @@ -4993,7 +4998,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.6.0", + "bitflags", "memchr", "unicase", ] @@ -5004,7 +5009,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" dependencies = [ - "bitflags 2.6.0", + "bitflags", "getopts", "memchr", "pulldown-cmark-escape", @@ -5017,6 +5022,15 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" +[[package]] +name = "pxfm" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55f4fedc84ed39cb7a489322318976425e42a147e2be79d8f878e2884f94e84" +dependencies = [ + "num-traits", +] + [[package]] name = "qoi" version = "0.4.1" @@ -5304,7 +5318,7 @@ version = "11.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -5351,7 +5365,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62871f2d65009c0256aed1b9cfeeb8ac272833c404e13d53d400cd0dad7a2ac0" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -5407,17 +5421,8 @@ checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -5428,7 +5433,7 @@ checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] @@ -5442,15 +5447,9 @@ dependencies = [ "itertools 0.13.0", "nohash", "regex", - "regex-syntax 0.8.5", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.5" @@ -5633,7 +5632,7 @@ version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys 0.4.14", @@ -5646,7 +5645,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys 0.9.3", @@ -5783,10 +5782,10 @@ dependencies = [ "semver 1.0.26", "serde", "serde_json", - "snafu 0.8.7", + "snafu 0.8.9", "sysinfo", "tempfile", - "time 0.3.41", + "time 0.3.43", "time-tz", "timeago", "tokio", @@ -5881,7 +5880,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -5904,7 +5903,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5685b6ae43bfcf7d2e7dfcfb5d8e8f61b46442c902531e41a32a9a8bf0ee0fb6" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cssparser", "derive_more", "fxhash", @@ -6290,11 +6289,11 @@ dependencies = [ [[package]] name = "snafu" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0062a372b26c4a6e9155d099a3416d732514fd47ae2f235b3695b820afcee74a" +checksum = "6e84b3f4eacbf3a1ce05eac6763b4d629d60cbc94d632e4092c54ade71f1e1a2" dependencies = [ - "snafu-derive 0.8.7", + "snafu-derive 0.8.9", ] [[package]] @@ -6311,9 +6310,9 @@ dependencies = [ [[package]] name = "snafu-derive" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e5fd9e3263fc19d73abd5107dbd4d43e37949212d2b15d4d334ee5db53022b8" +checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -6636,9 +6635,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.21.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" dependencies = [ "fastrand 2.1.1", "getrandom 0.3.1", @@ -6729,13 +6728,16 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" dependencies = [ + "fax", "flate2", - "jpeg-decoder", + "half", + "quick-error 2.0.1", "weezl", + "zune-jpeg", ] [[package]] @@ -6755,12 +6757,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" dependencies = [ "deranged", - "itoa", "js-sys", "libc", "num-conv", @@ -6768,14 +6769,14 @@ dependencies = [ "powerfmt", "serde", "time-core", - "time-macros 0.2.22", + "time-macros 0.2.24", ] [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" @@ -6789,9 +6790,9 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -6822,7 +6823,7 @@ dependencies = [ "phf_codegen", "serde", "serde-xml-rs 0.5.1", - "time 0.3.41", + "time 0.3.43", "wasm-bindgen", ] @@ -7046,7 +7047,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.6.0", + "bitflags", "bytes 1.7.2", "futures-util", "http 1.3.1", @@ -7090,7 +7091,7 @@ checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", "thiserror 1.0.68", - "time 0.3.41", + "time 0.3.43", "tracing-subscriber", ] @@ -7148,14 +7149,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "serde", "serde_json", "sharded-slab", @@ -7553,7 +7554,7 @@ dependencies = [ "sha2 0.10.9", "sha3", "simdutf8", - "snafu 0.8.7", + "snafu 0.8.9", "snap", "strip-ansi-escapes", "syslog_loose", @@ -7854,7 +7855,7 @@ dependencies = [ "windows-collections", "windows-core 0.60.1", "windows-future", - "windows-link", + "windows-link 0.1.0", "windows-numerics", ] @@ -7897,7 +7898,7 @@ checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247" dependencies = [ "windows-implement 0.59.0", "windows-interface 0.59.1", - "windows-link", + "windows-link 0.1.0", "windows-result 0.3.1", "windows-strings 0.3.1", ] @@ -7909,7 +7910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a787db4595e7eb80239b74ce8babfb1363d8e343ab072f2ffe901400c03349f0" dependencies = [ "windows-core 0.60.1", - "windows-link", + "windows-link 0.1.0", ] [[package]] @@ -7962,6 +7963,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-numerics" version = "0.1.1" @@ -7969,7 +7976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "005dea54e2f6499f2cee279b8f703b3cf3b5734a2d8d21867c8f44003182eeed" dependencies = [ "windows-core 0.60.1", - "windows-link", + "windows-link 0.1.0", ] [[package]] @@ -7987,7 +7994,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" dependencies = [ - "windows-link", + "windows-link 0.1.0", ] [[package]] @@ -8006,7 +8013,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-link", + "windows-link 0.1.0", ] [[package]] @@ -8191,7 +8198,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -8379,7 +8386,7 @@ dependencies = [ "rand 0.8.5", "sha1 0.10.6", "thiserror 1.0.68", - "time 0.3.41", + "time 0.3.43", "zeroize", "zopfli", "zstd", @@ -8450,9 +8457,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.16" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4a518c0ea2576f4da876349d7f67a7be489297cd77c2cf9e04c2e05fcd3974" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" dependencies = [ "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index 58c4718..e9a1b15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,8 +19,8 @@ opt-level = 3 codegen-units = 1 [dependencies] -chrono = "0.4.41" -clap = { version = "4.5.46", features = ["derive", "env"] } +chrono = "0.4.42" +clap = { version = "4.5.47", features = ["derive", "env"] } mimalloc = "0.1.48" native_db = "0.8.2" redb = "2.6.2" @@ -49,9 +49,9 @@ serde_json = "1.0.143" tokio = { version = "1.47.1", features = ["full"] } tracing = "0.1.41" tracing-appender = "0.2.3" -tracing-subscriber = { version = "0.3.19", features = ["env-filter", "json"] } +tracing-subscriber = { version = "0.3.20", features = ["env-filter", "json"] } base64 = "0.22.1" -snafu = "0.8.7" +snafu = "0.8.9" reqwest = { version = "0.12.23", default-features = false, features = [ "json", "stream", @@ -102,13 +102,13 @@ prost-types = "0.13.5" semver = "1.0.26" governor = "0.10.1" async-nats = { version = "0.42.0" } -lru = "0.16.0" +lru = "0.16.1" mime_guess = "2.0.5" pulldown-cmark = "0.13.0" html-escape = "0.2.13" hex = "0.4.3" scraper = "0.24.0" -time = { version = "0.3.41", features = [ +time = { version = "0.3.43", features = [ "formatting", "parsing", "local-offset", @@ -123,7 +123,7 @@ dashmap = "6.1.0" prometheus = "0.14.0" # Statically links OpenSSL by compiling from source, avoiding system library dependencies openssl-sys = { version = "0.9.109", optional = true, features = ["vendored"] } -image = "0.25.6" +image = "0.25.8" gethostname = "1.0.2" glob = "0.3.3" [build-dependencies] @@ -132,4 +132,4 @@ poem-grpc-build = "0.5.7" [dev-dependencies] #bincode = "1.3.3" #secret-lib = "1.0.0" -tempfile = "3.21.0" +tempfile = "3.22.0" diff --git a/src/modules/cache/imap/manager.rs b/src/modules/cache/imap/manager.rs index 21dc90f..a66f922 100644 --- a/src/modules/cache/imap/manager.rs +++ b/src/modules/cache/imap/manager.rs @@ -153,7 +153,7 @@ impl EnvelopeFlagsManager { account_id: account.id, account_email: account.email.clone(), mailbox_name: current.mailbox_name, - uid, + uid: Some(uid), from: current.from, to: current.to, message_id: current.message_id, @@ -162,6 +162,7 @@ impl EnvelopeFlagsManager { date: current.date, flags_added: added, flags_removed: removed, + mid: None, }), ), )) diff --git a/src/modules/cache/vendor/gmail/sync/history.rs b/src/modules/cache/vendor/gmail/sync/history.rs index 96bc708..56e9990 100644 --- a/src/modules/cache/vendor/gmail/sync/history.rs +++ b/src/modules/cache/vendor/gmail/sync/history.rs @@ -2,7 +2,7 @@ // Licensed under RustMailer License Agreement v1.0 // Unauthorized copying, modification, or distribution is prohibited. -use ahash::{AHashSet, HashSet}; +use ahash::{AHashMap, AHashSet, HashSet}; use tokio::task::JoinHandle; use tracing::{info, warn}; @@ -24,7 +24,7 @@ use crate::{ hook::{ channel::{Event, EVENT_CHANNEL}, events::{ - payload::{Attachment, EmailAddedToFolder}, + payload::{Attachment, EmailAddedToFolder, EmailFlagsChanged}, EventPayload, EventType, RustMailerEvent, }, task::EventHookTask, @@ -112,12 +112,19 @@ pub fn find_existing_remote_labels( .collect() } +#[derive(Debug, Default)] +struct LabelChange { + pub added: Vec, + pub removed: Vec, +} + pub async fn apply_history( account: &AccountV2, label: &GmailLabels, history_list: Vec, ) -> RustMailerResult<()> { for history in history_list { + let mut label_changes: AHashMap = AHashMap::new(); // -- labels_added for item in history.labels_added { let current = @@ -125,9 +132,21 @@ pub async fn apply_history( match current { Some(mut current) => { let mut merged: HashSet = current.label_ids.into_iter().collect(); + let mut actually_added = Vec::new(); if let Some(to_add) = &item.label_ids { + for l in to_add { + if !merged.contains(l) { + actually_added.push(l.clone()); + } + } merged.extend(to_add.iter().cloned()); } + if !actually_added.is_empty() { + let entry = label_changes + .entry(item.message.id.clone()) + .or_insert_with(|| LabelChange::default()); + entry.added.extend(actually_added); + } current.label_ids = merged.into_iter().collect(); GmailEnvelope::upsert(current).await?; } @@ -146,12 +165,25 @@ pub async fn apply_history( match current { Some(mut current) => { if let Some(to_remove) = &item.label_ids { + let mut actually_removed = Vec::new(); if to_remove.contains(&label.id.to_string()) { GmailEnvelope::delete(account.id, label.id, ¤t.id).await?; } else { - current.label_ids.retain(|id| !to_remove.contains(id)); + current.label_ids.retain(|id| { + let keep = !to_remove.contains(id); + if !keep { + actually_removed.push(id.clone()); + } + keep + }); GmailEnvelope::upsert(current).await?; } + if !actually_removed.is_empty() { + let entry = label_changes + .entry(item.message.id.clone()) + .or_insert_with(|| LabelChange::default()); + entry.removed.extend(actually_removed); + } } } None => { @@ -162,6 +194,44 @@ pub async fn apply_history( } } } + + if !label_changes.is_empty() { + if !account.minimal_sync() + && EventHookTask::is_watching_email_flags_changed(account.id).await? + { + for entry in label_changes { + if let Some(current) = + GmailEnvelope::find(account.id, label.id, entry.0.as_str()).await? + { + EVENT_CHANNEL + .queue(Event::new( + account.id, + &account.email, + RustMailerEvent::new( + EventType::EmailFlagsChanged, + EventPayload::EmailFlagsChanged(EmailFlagsChanged { + account_id: account.id, + account_email: account.email.clone(), + mailbox_name: current.label_name, + uid: None, + from: current.from, + to: current.to, + message_id: current.message_id, + subject: current.subject, + internal_date: Some(current.internal_date), + date: current.date, + flags_added: entry.1.added, + flags_removed: entry.1.removed, + mid: Some(entry.0), + }), + ), + )) + .await; + } + } + } + } + let len = history.messages_added.len(); let mut handles: Vec>> = Vec::with_capacity(len); // -- messages_added diff --git a/src/modules/hook/events/mod.rs b/src/modules/hook/events/mod.rs index 57f13ae..50f62be 100644 --- a/src/modules/hook/events/mod.rs +++ b/src/modules/hook/events/mod.rs @@ -206,7 +206,7 @@ impl RustMailerEvent { account_id: id!(64), account_email: account_email.clone(), mailbox_name: "INBOX".into(), - uid: 1003, + uid: Some(1003), from: Some(addr("sender@example.com")), to: Some(vec![addr("recipient@example.com")]), message_id: Some("".into()), @@ -215,6 +215,7 @@ impl RustMailerEvent { date: Some(timestamp), flags_added: vec![EnvelopeFlag::new(EmailFlag::Seen, None).to_string()], flags_removed: vec![EnvelopeFlag::new(EmailFlag::Flagged, None).to_string()], + mid: None } ); diff --git a/src/modules/hook/events/payload.rs b/src/modules/hook/events/payload.rs index 0e7e00f..b1f13b8 100644 --- a/src/modules/hook/events/payload.rs +++ b/src/modules/hook/events/payload.rs @@ -103,7 +103,9 @@ pub struct EmailFlagsChanged { /// Name of the mailbox (folder) containing the email. pub mailbox_name: String, /// Unique identifier (UID) of the email within the mailbox. - pub uid: u32, + pub uid: Option, + /// Unique identifier (UID) of the email within the mailbox. + pub mid: Option, /// Optional sender address of the email. pub from: Option, /// Optional list of recipient addresses (To field) for the email.