diff --git a/Cargo.lock b/Cargo.lock index e8022d4..81ed7a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,34 +1,77 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 4 + [[package]] -name = "adler32" -version = "1.2.0" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] [[package]] name = "ahash" -version = "0.4.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "arbitrary" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775a8770d29db3dadcb858482cc240af7b2ffde4ac4de67d1d4955728103f0e2" +dependencies = [ + "derive_arbitrary", +] [[package]] name = "bitflags" -version = "1.2.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bzip2" -version = "0.3.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" dependencies = [ "bzip2-sys", "libc", @@ -36,9 +79,9 @@ dependencies = [ [[package]] name = "bzip2-sys" -version = "0.1.10+1.0.8" +version = "0.1.11+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17fa3d1ac1ca21c5c4e36a97f3c3eb25084576f6fc47bf0139c1123434216c6c" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" dependencies = [ "cc", "libc", @@ -47,15 +90,14 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.67" +version = "1.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" +dependencies = [ + "jobserver", + "libc", + "shlex", +] [[package]] name = "cfg-if" @@ -64,19 +106,129 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "crc32fast" -version = "1.2.1" +name = "cipher" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "cfg-if 1.0.0", + "crypto-common", + "inout", ] [[package]] -name = "fallible-iterator" -version = "0.2.0" +name = "constant_time_eq" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deflate64" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d475dfebcb4854d596b17b09f477616f80f17a550517f2b3615d8c205d5c802b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fallible-streaming-iterator" @@ -86,45 +238,107 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "flate2" -version = "1.0.14" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ - "cfg-if 0.1.10", "crc32fast", - "libc", "miniz_oxide", ] [[package]] -name = "hashbrown" -version = "0.9.1" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", ] [[package]] -name = "hashlink" -version = "0.6.0" +name = "hashbrown" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d99cf782f0dc4372d26846bec3de7804ceb5df083c2d4462c0b8d2330e894fa8" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.1", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", ] [[package]] name = "libc" -version = "0.2.87" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "265d751d31d6780a3f956bb5b8022feba2d94eeee5a84ba64f4212eedca42213" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libsqlite3-sys" -version = "0.20.1" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d31059f22935e6c31830db5249ba2b7ecd54fd73a9909286f0a67aa55c2fbd" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", @@ -132,23 +346,57 @@ dependencies = [ ] [[package]] -name = "memchr" -version = "2.3.4" +name = "lockfree-object-pool" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" [[package]] -name = "miniz_oxide" -version = "0.3.7" +name = "log" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" dependencies = [ - "adler32", + "byteorder", + "crc", ] [[package]] -name = "pbdbfixer" +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "pbdbfixer" +version = "1.0.0" dependencies = [ "quick-xml", "rusqlite", @@ -156,84 +404,187 @@ dependencies = [ ] [[package]] -name = "pkg-config" -version = "0.3.19" +name = "pbkdf2" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quick-xml" -version = "0.22.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" +checksum = "ffbfb3ddf5364c9cfcd65549a1e7b801d0e8d1b14c1a1590a6408aa93cfbfa84" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] -name = "rusqlite" -version = "0.24.2" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38ee71cbab2c827ec0ac24e76f82eca723cee92c509a65f67dee393c25112" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rusqlite" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ "bitflags", "fallible-iterator", "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", - "memchr", "smallvec", ] [[package]] -name = "smallvec" -version = "1.6.1" +name = "serde" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +dependencies = [ + "serde_derive", +] [[package]] -name = "syn" -version = "1.0.60" +name = "serde_derive" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "syn", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] name = "thiserror" -version = "1.0.24" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.24" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", @@ -242,65 +593,161 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ - "libc", - "wasi", - "winapi", + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", ] [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "time-core" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "vcpkg" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "winapi" -version = "0.3.9" +name = "zerocopy" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "byteorder", + "zerocopy-derive", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "zerocopy-derive" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "zeroize" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "zip" -version = "0.5.11" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8264fcea9b7a036a4a5103d7153e988dbc2ebbafb34f68a3c2d404b6b82d74b6" +checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" dependencies = [ - "byteorder", + "aes", + "arbitrary", "bzip2", + "constant_time_eq", "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", "flate2", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "rand", + "sha1", "thiserror", "time", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index 57db8d2..7ec5c0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,18 @@ [package] name = "pbdbfixer" -version = "0.8.0" +version = "1.0.0" authors = ["Martin Brodbeck "] -edition = "2018" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -zip = "0.5" -quick-xml = "0.22" +zip = "2.2.0" +quick-xml = "0.37" [dependencies.rusqlite] -version = "0.24" +version = "0.32.1" features = ["bundled"] + +[profile.release] +strip = true diff --git a/README.md b/README.md index c21e920..564b3dc 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,10 @@ # PbDbFixer ## Motivation -Since Pocketbook has some problems with extracting metadata correctly from -EPUB files, this program tries fix these issues. It tries to identify -wrong database entries and fix it by reading the corresponding epub -metadata. +Since Pocketbook has some problems with extracting metadata correctly from EPUB files, this program tries fix these issues. It tries to identify wrong database entries and fix it by reading the corresponding epub metadata. ## Features -The app tries to fix the following issues in the database +PbDbFixer tries to fix the following issues in the database - Correction of wrong firstauthor entries (books_impl table) - Correction of wrong first_author_letter entries (books_impl table) - Correction of wrong author entries (books_impl table) @@ -18,11 +15,13 @@ The app tries to fix the following issues in the database The best results are achieved when metadata has been carefully maintained with **Calibre**. ## Compatibility -This program is tested on a PocketBook -- *Touch HD 3* (software version 6.1) -- *Inkpad 3 Pro* (software version 6.0 and 6.3 beta) - - Known minor issue: dialog orientation is wrong -- *Touch Lux 4* (software version 6.0) +This program has been tested on a PocketBook +- *Touch Lux 4* (software version 6.5) +- *Touch HD 3* (software version 6.7) +- *Era* (software version 6.8) [^1] +- *InkPad 3 Pro* (software version 6.8) [^1] +- *InkPad 4* (software version 6.8) +- *Verse Pro* (software version 6.8) [^1] It might work with other PocketBook devices/software versions. Please tell me if it works for you (and do make a backup of the explorer-3.db file before trying!). @@ -40,15 +39,21 @@ If you don't see any changes: There might be an explorer (which shows your library) process already running. Then you should just stop/kill it with the task manager. Putting the device to sleep and then wake it up might also work. Afterwards, the changes should be visible to the explorer. ## Feedback -Feedback is highly appreciated. You can reach me via Matrix [@beedaddy:matrix.rustysoft.de](https://matrix.to/#/@beedaddy:matrix.rustysoft.de) or ask questions in the [PbDbFixer-Thread](https://www.e-reader-forum.de/t/pbdbfixer-noch-ein-tool-zum-korrigieren-von-metadaten.156702/) of the German *E-Reader Forum*. +Feedback is highly appreciated. You can reach me via +- Matrix Chat [@beedaddy:matrix.rustysoft.de](https://matrix.to/#/@beedaddy:matrix.rustysoft.de) +- [PbDbFixer-Thread](https://www.e-reader-forum.de/t/pbdbfixer-noch-ein-tool-zum-korrigieren-von-metadaten.156702/) of the German *E-Reader Forum*. +- E-Mail: info@rustysoft.de ## Build -If you want to build PbDbFixer yourself, make sure that you have Rust's toolchain target `arm-unknown-linux-gnueabi` as well as the GCC cross compiler for ARM CPUs installed. On Arch Linux, the AUR package `arm-linux-gnueabi-gcc75-linaro-bin` does the job. Don't forget to tell `cargo` which compiler/linker it has to invoke. In my case, I had to edit `~/.cargo/config`: +If you want to build PbDbFixer yourself, make sure that you have Rust's toolchain target `armv7-unknown-linux-gnueabi` installed. Additionaly, you should use [PocketBook's SDK](https://github.com/pocketbook/SDK_6.3.0/tree/6.5) for being able to cross-compile specific for these devices. Don't forget to tell `cargo` which compiler/linker it has to invoke. In my case, I had to edit `~/.cargo/config.toml`: ``` -[target.arm-unknown-linux-gnueabi] -linker = "arm-linux-gnueabi-gcc" +[target.armv7-unknown-linux-gnueabi] +linker = "SDKs/PB/SDK_6.3.0/SDK-B288/usr/bin/arm-obreey-linux-gnueabi-gcc" ``` -Now you can easily compile the stuff by invoking + +Now you can easily compile the stuff. Note that you have to tell where the libraries are located (`LD_LIBRARY_PATH`): ``` -cargo build --release --target=arm-unknown-linux-gnueabi +LD_LIBRARY_PATH="$HOME/SDKs/PB/SDK_6.3.0/SDK-B288/usr/lib" cargo build --release --target=armv7-unknown-linux-gnueabi ``` + +[^1]: User feedback diff --git a/src/database.rs b/src/database.rs index 1ce6aea..e640771 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,4 +1,4 @@ -use rusqlite::{named_params, Connection, Transaction, NO_PARAMS}; +use rusqlite::{named_params, Connection, Transaction}; use crate::epub; @@ -17,12 +17,20 @@ pub struct BookEntry { fn get_epubs_from_database(tx: &Transaction) -> Vec { let mut book_entries = Vec::new(); - let mut stmt = tx - .prepare( - r#" + let version: i32 = tx + .query_row(r#"SELECT id FROM version"#, [], |r| r.get(0)) + .unwrap(); + + let books_or_files = match version { + x if x >= 38 => "files", + _ => "books", + }; + + let stmt_str = format!( + r#" SELECT books.id, folders.name, files.filename, books.firstauthor, books.author, genres.name, first_author_letter, series - FROM books_impl books JOIN files + FROM books_impl books JOIN files, storages ON books.id = files.book_id JOIN folders ON folders.id = files.folder_id @@ -30,12 +38,14 @@ fn get_epubs_from_database(tx: &Transaction) -> Vec { ON books.id = btg.bookid LEFT OUTER JOIN genres ON genres.id = btg.genreid - WHERE files.storageid = 1 AND books.ext = 'epub' + WHERE files.storageid IN (SELECT storages.id WHERE storages.type = 1) AND {}.ext = 'epub' ORDER BY books.id"#, - ) - .unwrap(); + &books_or_files + ); - let mut rows = stmt.query(NO_PARAMS).unwrap(); + let mut stmt = tx.prepare(&stmt_str).unwrap(); + + let mut rows = stmt.query([]).unwrap(); while let Some(row) = rows.next().unwrap() { let book_id: i32 = row.get(0).unwrap(); @@ -79,44 +89,44 @@ fn remove_ghost_books_from_db(tx: &Transaction) -> usize { ) .unwrap(); - let num = stmt.execute(NO_PARAMS).unwrap(); + let num = stmt.execute([]).unwrap(); tx.execute( r#"DELETE FROM books_settings WHERE bookid NOT IN ( SELECT id FROM books_impl )"#, - NO_PARAMS, + [], ) .unwrap(); let version: i32 = tx - .query_row(r#"SELECT id FROM version"#, NO_PARAMS, |r| r.get(0)) + .query_row(r#"SELECT id FROM version"#, [], |r| r.get(0)) .unwrap(); if version >= 37 { tx.execute( r#"DELETE FROM books_fast_hashes WHERE book_id NOT IN ( SELECT id FROM books_impl )"#, - NO_PARAMS, + [], ) .unwrap(); } else { tx.execute( r#"DELETE FROM books_uids WHERE book_id NOT IN ( SELECT id FROM books_impl )"#, - NO_PARAMS, + [], ) .unwrap(); } tx.execute( r#"DELETE FROM bookshelfs_books WHERE bookid NOT IN ( SELECT id FROM books_impl )"#, - NO_PARAMS, + [], ) .unwrap(); tx.execute( r#"DELETE FROM booktogenre WHERE bookid NOT IN ( SELECT id FROM books_impl )"#, - NO_PARAMS, + [], ) .unwrap(); tx.execute( r#"DELETE FROM social WHERE bookid NOT IN ( SELECT id FROM books_impl )"#, - NO_PARAMS, + [], ) .unwrap(); @@ -170,7 +180,7 @@ pub fn fix_db_entries() -> Statistics { let mut stmt = tx .prepare("UPDATE books_impl SET firstauthor = :file_as WHERE id = :book_id") .unwrap(); - stmt.execute_named( + stmt.execute( named_params![":file_as": firstauthors.join(" & "), ":book_id": entry.id], ) .unwrap(); @@ -190,7 +200,7 @@ pub fn fix_db_entries() -> Statistics { let mut stmt = tx .prepare("UPDATE books_impl SET first_author_letter = :first_letter WHERE id = :book_id") .unwrap(); - stmt.execute_named( + stmt.execute( named_params![":first_letter": first_author_letter,":book_id": entry.id], ) .unwrap(); @@ -209,7 +219,7 @@ pub fn fix_db_entries() -> Statistics { let mut stmt = tx .prepare("UPDATE books_impl SET author = :authors WHERE id = :book_id") .unwrap(); - stmt.execute_named( + stmt.execute( named_params![":authors": authornames.join(", "), ":book_id": entry.id], ) .unwrap(); @@ -221,7 +231,7 @@ pub fn fix_db_entries() -> Statistics { let mut stmt = tx .prepare(r#"INSERT INTO genres (name) SELECT :genre ON CONFLICT DO NOTHING"#) .unwrap(); - stmt.execute_named(named_params![":genre": &epub_metadata.genre]) + stmt.execute(named_params![":genre": &epub_metadata.genre]) .unwrap(); let mut stmt = tx .prepare( @@ -233,10 +243,8 @@ pub fn fix_db_entries() -> Statistics { ON CONFLICT DO NOTHING"#, ) .unwrap(); - stmt.execute_named( - named_params![":bookid": &entry.id, ":genre": &epub_metadata.genre], - ) - .unwrap(); + stmt.execute(named_params![":bookid": &entry.id, ":genre": &epub_metadata.genre]) + .unwrap(); stat.genres_fixed = stat.genres_fixed + 1; } @@ -245,7 +253,7 @@ pub fn fix_db_entries() -> Statistics { let mut stmt = tx .prepare("UPDATE books_impl SET series = :series, numinseries = :series_index WHERE id = :book_id") .unwrap(); - stmt.execute_named( + stmt.execute( named_params![":series": &epub_metadata.series.name, ":series_index": &epub_metadata.series.index, ":book_id": entry.id], ) .unwrap(); diff --git a/src/epub.rs b/src/epub.rs index a5916d4..3ee7e28 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -52,24 +52,25 @@ fn get_rootfile(archive: &mut ZipArchive) -> String { container.read_to_string(&mut xml_str_buffer).unwrap(); let mut reader = Reader::from_str(&xml_str_buffer); - reader.trim_text(true); + reader.config_mut().trim_text(true); let mut buf = Vec::new(); let mut opf_filename = String::new(); loop { - match reader.read_event(&mut buf) { - Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) if e.local_name() == b"rootfile" => { - opf_filename = String::from_utf8( - e.attributes() - .filter(|attr| attr.as_ref().unwrap().key == b"full-path") - .next() - .unwrap() - .unwrap() - .value - .to_vec(), - ) - .unwrap(); + match reader.read_event_into(&mut buf) { + Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) + if e.name().as_ref() == b"rootfile" => + { + opf_filename = e + .attributes() + .filter(|attr| attr.as_ref().unwrap().key.as_ref() == b"full-path") + .next() + .unwrap() + .unwrap() + .unescape_value() + .unwrap() + .to_string(); break; } Ok(Event::Eof) => break, @@ -128,22 +129,22 @@ pub fn get_epub_metadata(filename: &str) -> Option { let mut xml_authors = HashMap::new(); loop { - match reader.read_event(&mut buf) { + match reader.read_event_into(&mut buf) { // See if we have EPUB3 or EPUB2 - Ok(Event::Start(ref e)) if e.local_name() == b"package" => { + Ok(Event::Start(ref e)) if e.name().as_ref() == b"package" => { if e.attributes().any(|attr| { - attr.as_ref().unwrap().key == b"version" + attr.as_ref().unwrap().key.as_ref() == b"version" && attr.as_ref().unwrap().value.starts_with(b"3") }) { is_epub3 = true; } } - Ok(Event::Start(ref e)) if e.local_name() == b"creator" => { + Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"creator" => { creator_found = true; if is_epub3 { if let Some(idval) = e .attributes() - .filter(|attr| attr.as_ref().unwrap().key == b"id") + .filter(|attr| attr.as_ref().unwrap().key.as_ref() == b"id") .next() { curr_id = "#".to_string() @@ -159,19 +160,26 @@ pub fn get_epub_metadata(filename: &str) -> Option { } else { if let Some(file_as_val) = e .attributes() - .filter(|attr| attr.as_ref().unwrap().key.ends_with(b"file-as")) + .filter(|attr| { + attr.as_ref() + .unwrap() + .key + .as_ref() + .ends_with(b"file-as") + }) .next() { curr_id = "none".to_string() + xml_authors.len().to_string().as_str(); let entry = xml_authors.entry(curr_id.clone()).or_insert(XmlAut::new()); entry.sort = file_as_val .unwrap() - .unescape_and_decode_value(&reader) - .unwrap_or_default(); + .unescape_value() + .unwrap_or_default() + .to_string(); entry.role = "aut".to_string(); } else if let Some(_role_val) = e .attributes() - .filter(|attr| attr.as_ref().unwrap().key.ends_with(b"role")) + .filter(|attr| attr.as_ref().unwrap().key.as_ref().ends_with(b"role")) .next() { curr_id = "none".to_string() + xml_authors.len().to_string().as_str(); @@ -190,33 +198,33 @@ pub fn get_epub_metadata(filename: &str) -> Option { creator_found = false; } - Ok(Event::Start(ref e)) if e.local_name() == b"meta" && is_epub3 => { + Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"meta" && is_epub3 => { if let Some(refines) = e .attributes() - .filter(|attr| attr.as_ref().unwrap().key == b"refines") + .filter(|attr| attr.as_ref().unwrap().key.as_ref() == b"refines") .next() { if e.attributes().any(|attr| { - attr.as_ref().unwrap().key == b"property" + attr.as_ref().unwrap().key.as_ref() == b"property" && attr.as_ref().unwrap().value.ends_with(b"file-as") }) { curr_id = String::from_utf8(refines.unwrap().value.to_vec()).unwrap(); file_as_found = true; } else if e.attributes().any(|attr| { - attr.as_ref().unwrap().key == b"property" + attr.as_ref().unwrap().key.as_ref() == b"property" && attr.as_ref().unwrap().value.ends_with(b"role") }) { curr_id = String::from_utf8(refines.unwrap().value.to_vec()).unwrap(); role_found = true; } else if e.attributes().any(|attr| { - attr.as_ref().unwrap().key == b"property" + attr.as_ref().unwrap().key.as_ref() == b"property" && attr.as_ref().unwrap().value.ends_with(b"group-position") }) { series_index_found = true; } } if e.attributes().any(|attr| { - attr.as_ref().unwrap().key == b"property" + attr.as_ref().unwrap().key.as_ref() == b"property" && attr .as_ref() .unwrap() @@ -226,40 +234,41 @@ pub fn get_epub_metadata(filename: &str) -> Option { series_found = true; } } - Ok(Event::Empty(ref e)) if e.local_name() == b"meta" && !is_epub3 => { + Ok(Event::Empty(ref e)) if e.local_name().as_ref() == b"meta" && !is_epub3 => { if e.attributes().any(|attr| { - attr.as_ref().unwrap().key == b"name" + attr.as_ref().unwrap().key.as_ref() == b"name" && attr .as_ref() .unwrap() - .unescaped_value() + .unescape_value() .unwrap() - .ends_with(b"series") + .ends_with("series") }) { epub_meta.series.name = e .attributes() - .filter(|attr| attr.as_ref().unwrap().key == b"content") + .filter(|attr| attr.as_ref().unwrap().key.as_ref() == b"content") .next() .unwrap() .unwrap() - .unescape_and_decode_value(&reader) - .unwrap_or_default(); + .unescape_value() + .unwrap_or_default() + .to_string(); } else if e.attributes().any(|attr| { - attr.as_ref().unwrap().key == b"name" + attr.as_ref().unwrap().key.as_ref() == b"name" && attr .as_ref() .unwrap() - .unescaped_value() + .unescape_value() .unwrap() - .ends_with(b"series_index") + .ends_with("series_index") }) { let index_float = e .attributes() - .filter(|attr| attr.as_ref().unwrap().key == b"content") + .filter(|attr| attr.as_ref().unwrap().key.as_ref() == b"content") .next() .unwrap() .unwrap() - .unescape_and_decode_value(&reader) + .unescape_value() .unwrap_or_default() .parse::() .unwrap_or_default(); @@ -291,11 +300,11 @@ pub fn get_epub_metadata(filename: &str) -> Option { series_index_found = false; } - Ok(Event::Start(ref e)) if e.local_name() == b"subject" => { + Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"subject" => { genre_found = true; } Ok(Event::Text(ref e)) if genre_found => { - epub_meta.genre = e.unescape_and_decode(&reader).unwrap(); + epub_meta.genre = e.unescape().unwrap().to_string(); genre_found = false; } Ok(Event::Eof) => break,