refactor: 用更 idiomatic 的方式改写一些代码 (#54)

* refactor: Config 采用 arc_swap 而非锁

* refactor: 改进 config 的检查,及其他一些细微优化

* refactor: 不再拆分 lib.rs 和 main.rs
This commit is contained in:
idlercloud
2024-04-04 18:39:41 +08:00
committed by GitHub
parent 2521fe932b
commit 4ba23ce8fc
12 changed files with 279 additions and 255 deletions

259
Cargo.lock generated
View File

@@ -130,6 +130,18 @@ name = "anyhow"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
dependencies = [
"backtrace",
]
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
dependencies = [
"serde",
]
[[package]]
name = "arrayvec"
@@ -166,16 +178,16 @@ checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3"
dependencies = [
"concurrent-queue",
"event-listener 5.2.0",
"event-listener-strategy 0.5.0",
"event-listener-strategy 0.5.1",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-compression"
version = "0.4.6"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c"
checksum = "86a9249d1447a85f95810c620abea82e001fe58a31713fcce614caf52499f905"
dependencies = [
"flate2",
"futures-core",
@@ -186,14 +198,14 @@ dependencies = [
[[package]]
name = "async-executor"
version = "1.8.0"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c"
checksum = "10b3e585719c2358d2660232671ca8ca4ddb4be4ce8a1842d6c2dc8685303316"
dependencies = [
"async-lock 3.3.0",
"async-task",
"concurrent-queue",
"fastrand 2.0.1",
"fastrand 2.0.2",
"futures-lite 2.3.0",
"slab",
]
@@ -246,8 +258,8 @@ dependencies = [
"futures-io",
"futures-lite 2.3.0",
"parking",
"polling 3.5.0",
"rustix 0.38.31",
"polling 3.6.0",
"rustix 0.38.32",
"slab",
"tracing",
"windows-sys 0.52.0",
@@ -319,7 +331,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -330,13 +342,13 @@ checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799"
[[package]]
name = "async-trait"
version = "0.1.78"
version = "0.1.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85"
checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -356,15 +368,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "backtrace"
version = "0.3.69"
version = "0.3.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
dependencies = [
"addr2line",
"cc",
@@ -403,9 +415,10 @@ name = "bili-sync"
version = "2.0.0"
dependencies = [
"anyhow",
"arc-swap",
"async-stream",
"chrono",
"cookie 0.18.0",
"cookie 0.18.1",
"dirs",
"entity",
"env_logger",
@@ -438,9 +451,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.2"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
dependencies = [
"serde",
]
@@ -475,7 +488,7 @@ dependencies = [
"async-channel 2.2.0",
"async-lock 3.3.0",
"async-task",
"fastrand 2.0.1",
"fastrand 2.0.2",
"futures-io",
"futures-lite 2.3.0",
"piper",
@@ -484,9 +497,9 @@ dependencies = [
[[package]]
name = "borsh"
version = "1.3.1"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667"
checksum = "0901fc8eb0aca4c83be0106d6f2db17d86a08dfc2c25f0e84464bf381158add6"
dependencies = [
"borsh-derive",
"cfg_aliases",
@@ -494,15 +507,15 @@ dependencies = [
[[package]]
name = "borsh-derive"
version = "1.3.1"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd"
checksum = "51670c3aa053938b0ee3bd67c3817e471e626151131b934038e83c5bf8de48f5"
dependencies = [
"once_cell",
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
"syn_derive",
]
@@ -542,9 +555,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
version = "1.5.0"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
[[package]]
name = "cc"
@@ -566,9 +579,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "chrono"
version = "0.4.35"
version = "0.4.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e"
dependencies = [
"android-tzdata",
"iana-time-zone",
@@ -581,9 +594,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.3"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
dependencies = [
"clap_builder",
"clap_derive",
@@ -603,14 +616,14 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.3"
version = "4.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f"
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -653,9 +666,9 @@ dependencies = [
[[package]]
name = "cookie"
version = "0.18.0"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8"
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
dependencies = [
"time",
"version_check",
@@ -754,9 +767,9 @@ dependencies = [
[[package]]
name = "der"
version = "0.7.8"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
dependencies = [
"const-oid",
"pem-rfc7468",
@@ -940,9 +953,9 @@ dependencies = [
[[package]]
name = "event-listener-strategy"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291"
checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3"
dependencies = [
"event-listener 5.2.0",
"pin-project-lite",
@@ -959,9 +972,9 @@ dependencies = [
[[package]]
name = "fastrand"
version = "2.0.1"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
[[package]]
name = "filenamify"
@@ -1115,7 +1128,7 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5"
dependencies = [
"fastrand 2.0.1",
"fastrand 2.0.2",
"futures-core",
"futures-io",
"parking",
@@ -1130,7 +1143,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -1210,9 +1223,9 @@ dependencies = [
[[package]]
name = "h2"
version = "0.4.3"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4"
checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069"
dependencies = [
"bytes",
"fnv",
@@ -1470,9 +1483,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.2.5"
version = "2.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
"equivalent",
"hashbrown 0.14.3",
@@ -1486,7 +1499,7 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -1526,9 +1539,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.10"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "js-sys"
@@ -1571,13 +1584,12 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]]
name = "libredox"
version = "0.0.1"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.4.2",
"bitflags 2.5.0",
"libc",
"redox_syscall",
]
[[package]]
@@ -1643,9 +1655,9 @@ dependencies = [
[[package]]
name = "memchr"
version = "2.7.1"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "migration"
@@ -1810,7 +1822,7 @@ version = "0.10.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
dependencies = [
"bitflags 2.4.2",
"bitflags 2.5.0",
"cfg-if",
"foreign-types",
"libc",
@@ -1827,7 +1839,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -1838,9 +1850,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.101"
version = "0.9.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff"
checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2"
dependencies = [
"cc",
"libc",
@@ -1884,7 +1896,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -1939,9 +1951,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.7.8"
version = "2.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8"
checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95"
dependencies = [
"memchr",
"thiserror",
@@ -1950,9 +1962,9 @@ dependencies = [
[[package]]
name = "pest_derive"
version = "2.7.8"
version = "2.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026"
checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c"
dependencies = [
"pest",
"pest_generator",
@@ -1960,22 +1972,22 @@ dependencies = [
[[package]]
name = "pest_generator"
version = "2.7.8"
version = "2.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80"
checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
name = "pest_meta"
version = "2.7.8"
version = "2.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293"
checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca"
dependencies = [
"once_cell",
"pest",
@@ -1999,14 +2011,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
name = "pin-project-lite"
version = "0.2.13"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "pin-utils"
@@ -2021,7 +2033,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4"
dependencies = [
"atomic-waker",
"fastrand 2.0.1",
"fastrand 2.0.2",
"futures-io",
]
@@ -2070,14 +2082,15 @@ dependencies = [
[[package]]
name = "polling"
version = "3.5.0"
version = "3.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9"
checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi",
"pin-project-lite",
"rustix 0.38.31",
"rustix 0.38.32",
"tracing",
"windows-sys 0.52.0",
]
@@ -2238,9 +2251,9 @@ dependencies = [
[[package]]
name = "redox_users"
version = "0.4.4"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891"
dependencies = [
"getrandom",
"libredox",
@@ -2249,14 +2262,14 @@ dependencies = [
[[package]]
name = "regex"
version = "1.10.3"
version = "1.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.6",
"regex-syntax 0.8.2",
"regex-syntax 0.8.3",
]
[[package]]
@@ -2276,7 +2289,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.2",
"regex-syntax 0.8.3",
]
[[package]]
@@ -2287,9 +2300,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "rend"
@@ -2302,9 +2315,9 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.12.0"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58b48d98d932f4ee75e541614d32a7f44c889b72bd9c2e04d95edd135989df88"
checksum = "2d66674f2b6fb864665eea7a3c1ac4e3dfacd2fda83cf6f935a612e01b0e3338"
dependencies = [
"async-compression",
"base64",
@@ -2399,9 +2412,9 @@ dependencies = [
[[package]]
name = "rust_decimal"
version = "1.34.3"
version = "1.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39449a79f45e8da28c57c341891b69a183044b29518bb8f86dbac9df60bb7df"
checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a"
dependencies = [
"arrayvec",
"borsh",
@@ -2435,11 +2448,11 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.31"
version = "0.38.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
dependencies = [
"bitflags 2.4.2",
"bitflags 2.5.0",
"errno",
"libc",
"linux-raw-sys 0.4.13",
@@ -2492,7 +2505,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -2550,7 +2563,7 @@ dependencies = [
"proc-macro2",
"quote",
"sea-bae",
"syn 2.0.52",
"syn 2.0.58",
"unicode-ident",
]
@@ -2614,7 +2627,7 @@ dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
"thiserror",
]
@@ -2649,9 +2662,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "security-framework"
version = "2.9.2"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
@@ -2662,9 +2675,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
version = "2.9.1"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
dependencies = [
"core-foundation-sys",
"libc",
@@ -2687,14 +2700,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
name = "serde_json"
version = "1.0.114"
version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
dependencies = [
"itoa",
"ryu",
@@ -2789,9 +2802,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.13.1"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
@@ -2955,7 +2968,7 @@ dependencies = [
"atoi",
"base64",
"bigdecimal",
"bitflags 2.4.2",
"bitflags 2.5.0",
"byteorder",
"bytes",
"chrono",
@@ -3002,7 +3015,7 @@ dependencies = [
"atoi",
"base64",
"bigdecimal",
"bitflags 2.4.2",
"bitflags 2.5.0",
"byteorder",
"chrono",
"crc",
@@ -3082,9 +3095,9 @@ dependencies = [
[[package]]
name = "strsim"
version = "0.11.0"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
@@ -3111,7 +3124,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -3133,9 +3146,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.52"
version = "2.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
dependencies = [
"proc-macro2",
"quote",
@@ -3151,7 +3164,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -3194,8 +3207,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if",
"fastrand 2.0.1",
"rustix 0.38.31",
"fastrand 2.0.2",
"rustix 0.38.32",
"windows-sys 0.52.0",
]
@@ -3216,7 +3229,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -3277,9 +3290,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.36.0"
version = "1.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
dependencies = [
"backtrace",
"bytes",
@@ -3302,7 +3315,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -3433,7 +3446,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]
@@ -3609,7 +3622,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
"wasm-bindgen-shared",
]
@@ -3643,7 +3656,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -3904,7 +3917,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.52",
"syn 2.0.58",
]
[[package]]

View File

@@ -4,7 +4,8 @@ version = "2.0.0"
edition = "2021"
[dependencies]
anyhow = "1.0.81"
anyhow = { version = "1.0.81", features = ["backtrace"] }
arc-swap = { version = "1.7", features = ["serde"] }
async-stream = "0.3.5"
chrono = { version = "0.4.35", features = ["serde"] }
cookie = "0.18.0"

View File

@@ -8,7 +8,6 @@
> [!CAUTION]
> 当前新版本尚不稳定,可能会有未告知的不兼容更改,请优先使用 Python 版本。
为 NAS 用户编写的 BILIBILI 收藏夹同步工具,可使用 EMBY 等媒体库工具浏览。
支持展示视频封面、名称、加入日期、标签、分页等。
@@ -34,14 +33,18 @@ video_name 支持设置 bvid视频编号、title视频标题、upper
page_name 除支持 video 的全部参数外,还支持 ptitle分 P 标题、pid分 P 页号)。
对于每个 favorite_list 的下载路径,程序会在其下建立如下的文件夹:
1. 单页视频:
```bash
├── {video_name}
│   ├── {page_name}.mp4
│   ├── {page_name}.nfo
│   └── {page_name}-poster.jpg
```
2. 多页视频:
```bash
├── {video_name}
│   ├── poster.jpg
@@ -54,6 +57,7 @@ page_name 除支持 video 的全部参数外,还支持 ptitle分 P 标题
│   │   └── {page_name} - S01E02-thumb.jpg
│   └── tvshow.nfo
```
对于 filter_option 的可选值,请前往 [analyzer.rs](https://github.com/amtoaer/bili-sync/blob/main/src/bilibili/analyzer.rs) 查看。
## 配置文件示例与说明
@@ -102,4 +106,4 @@ no_hires = false
- [ ] 提供简单易用的打包(如 docker
- [ ] 更好的错误处理
- [ ] 更好的日志
- [ ] 请求过快出现风控的 workaround
- [ ] 请求过快出现风控的 workaround

View File

@@ -1,3 +1,5 @@
use std::sync::Arc;
use anyhow::Result;
use reqwest::{header, Method};
@@ -54,31 +56,30 @@ impl Default for Client {
}
pub struct BiliClient {
credential: Option<Credential>,
client: Client,
}
impl BiliClient {
pub fn new(credential: Option<Credential>) -> Self {
pub fn new() -> Self {
let client = Client::new();
Self { credential, client }
Self { client }
}
pub fn request(&self, method: Method, url: &str) -> reqwest::RequestBuilder {
self.client.request(method, url, self.credential.as_ref())
let credential = CONFIG.credential.load();
self.client.request(method, url, credential.as_deref())
}
pub async fn check_refresh(&mut self) -> Result<()> {
let Some(credential) = self.credential.as_mut() else {
pub async fn check_refresh(&self) -> Result<()> {
let credential = CONFIG.credential.load();
let Some(credential) = credential.as_deref() else {
return Ok(());
};
if !credential.need_refresh(&self.client).await? {
return Ok(());
}
credential.refresh(&self.client).await?;
let mut config = CONFIG.lock().unwrap();
config.credential = Some(credential.clone());
config.save()
let new_credential = credential.refresh(&self.client).await?;
CONFIG.credential.store(Some(Arc::new(new_credential)));
CONFIG.save()
}
}

View File

@@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
use super::error::BiliError;
use crate::bilibili::Client;
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Credential {
pub sessdata: String,
pub bili_jct: String,
@@ -32,6 +32,16 @@ impl Credential {
}
}
const fn empty() -> Self {
Self {
sessdata: String::new(),
bili_jct: String::new(),
buvid3: String::new(),
dedeuserid: String::new(),
ac_time_value: String::new(),
}
}
/// 检查凭据是否有效
pub async fn need_refresh(&self, client: &Client) -> Result<bool> {
let res = client
@@ -55,13 +65,12 @@ impl Credential {
res["data"]["refresh"].as_bool().ok_or(anyhow!("check refresh failed"))
}
pub async fn refresh(&mut self, client: &Client) -> Result<()> {
pub async fn refresh(&self, client: &Client) -> Result<Self> {
let correspond_path = Self::get_correspond_path();
let csrf = self.get_refresh_csrf(client, correspond_path).await?;
let new_credential = self.get_new_credential(client, &csrf).await?;
self.confirm_refresh(client, &new_credential).await?;
*self = new_credential;
Ok(())
Ok(new_credential)
}
fn get_correspond_path() -> String {
@@ -125,9 +134,9 @@ JNrRuoEUXpabUzGB8QIDAQAB
bail!(BiliError::RequestFailed(code, msg.to_owned()));
}
let set_cookies = headers.get_all(header::SET_COOKIE);
let mut credential = Credential {
let mut credential = Self {
buvid3: self.buvid3.clone(),
..Default::default()
..Self::empty()
};
let required_cookies = HashSet::from(["SESSDATA", "bili_jct", "DedeUserID"]);
let cookies: Vec<Cookie> = set_cookies

View File

@@ -3,7 +3,6 @@ use async_stream::stream;
use chrono::serde::ts_seconds;
use chrono::{DateTime, Utc};
use futures::Stream;
use log::error;
use serde_json::Value;
use crate::bilibili::error::BiliError;

View File

@@ -1,107 +1,114 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::path::Path;
use std::sync::Mutex;
use std::path::PathBuf;
use anyhow::{anyhow, Result};
use log::warn;
use anyhow::Result;
use arc_swap::ArcSwapOption;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use crate::bilibili::{Credential, FilterOption};
pub static CONFIG: Lazy<Mutex<Config>> = Lazy::new(|| {
let config = Config::new();
// 保存一次,确保配置文件存在
config.save().unwrap();
pub static CONFIG: Lazy<Config> = Lazy::new(|| {
let config = Config::load().unwrap_or_else(|err| {
warn!("Failed loading config: {err}");
let new_config = Config::new();
// 保存一次,确保配置文件存在
new_config.save().unwrap();
new_config
});
// 检查配置文件内容
config.check();
Mutex::new(Config::new())
config
});
pub static CONFIG_DIR: Lazy<PathBuf> =
Lazy::new(|| dirs::config_dir().expect("No config path found").join("bili-sync"));
#[derive(Serialize, Deserialize)]
pub struct Config {
pub credential: Option<Credential>,
pub credential: ArcSwapOption<Credential>,
pub filter_option: FilterOption,
pub favorite_list: HashMap<String, String>,
pub video_name: String,
pub page_name: String,
pub favorite_list: HashMap<String, PathBuf>,
pub video_name: Cow<'static, str>,
pub page_name: Cow<'static, str>,
pub interval: u64,
pub upper_path: String,
pub upper_path: PathBuf,
}
impl Default for Config {
fn default() -> Self {
Self {
credential: Some(Credential::default()),
filter_option: FilterOption::default(),
favorite_list: HashMap::new(),
video_name: "{{bvid}}".to_string(),
page_name: "{{bvid}}".to_string(),
interval: 1200,
upper_path: dirs::config_dir()
.unwrap()
.join("bili-sync")
.join("upper_face")
.to_str()
.unwrap()
.to_string(),
}
Self::new()
}
}
impl Config {
fn new() -> Self {
Config::load().unwrap_or_default()
Self {
credential: ArcSwapOption::empty(),
filter_option: FilterOption::default(),
favorite_list: HashMap::new(),
video_name: Cow::Borrowed("{{bvid}}"),
page_name: Cow::Borrowed("{{bvid}}"),
interval: 1200,
upper_path: CONFIG_DIR.join("upper_face"),
}
}
/// 简单的预检查
pub fn check(&self) {
assert!(
!self.favorite_list.is_empty(),
"No favorite list found, program won't do anything"
);
for path in self.favorite_list.values() {
assert!(Path::new(path).is_absolute(), "Path in favorite list must be absolute");
let mut ok = true;
if self.favorite_list.is_empty() {
ok = false;
error!("No favorite list found, program won't do anything");
}
assert!(
Path::new(&self.upper_path).is_absolute(),
"Upper face path must be absolute"
);
assert!(!self.video_name.is_empty(), "No video name template found");
assert!(!self.page_name.is_empty(), "No page name template found");
match self.credential {
Some(ref credential) => {
assert!(
!(credential.sessdata.is_empty()
|| credential.bili_jct.is_empty()
|| credential.buvid3.is_empty()
|| credential.dedeuserid.is_empty()
|| credential.ac_time_value.is_empty()),
"Credential is incomplete"
)
for path in self.favorite_list.values() {
if !path.is_absolute() {
ok = false;
error!("Path in favorite list must be absolute: {}", path.display());
}
None => {
warn!("No credential found, can't access high quality video");
}
if !self.upper_path.is_absolute() {
ok = false;
error!("Upper face path must be absolute");
}
if self.video_name.is_empty() {
ok = false;
error!("No video name template found");
}
if self.page_name.is_empty() {
ok = false;
error!("No page name template found");
}
let credential = self.credential.load();
if let Some(credential) = credential.as_deref() {
if credential.sessdata.is_empty()
|| credential.bili_jct.is_empty()
|| credential.buvid3.is_empty()
|| credential.dedeuserid.is_empty()
|| credential.ac_time_value.is_empty()
{
ok = false;
error!("Credential is incomplete");
}
} else {
warn!("No credential found, can't access high quality video");
}
if !ok {
panic!("Config in {} is invalid", CONFIG_DIR.join("config.toml").display());
}
}
fn load() -> Result<Self> {
let config_path = dirs::config_dir()
.ok_or(anyhow!("No config path found"))?
.join("bili-sync")
.join("config.toml");
let config_path = CONFIG_DIR.join("config.toml");
let config_content = std::fs::read_to_string(config_path)?;
Ok(toml::from_str(&config_content)?)
}
pub fn save(&self) -> Result<()> {
let config_path = dirs::config_dir()
.ok_or(anyhow!("No config path found"))?
.join("bili-sync")
.join("config.toml");
if let Some(parent) = config_path.parent() {
std::fs::create_dir_all(parent)?;
}
let config_path = CONFIG_DIR.join("config.toml");
std::fs::create_dir_all(&*CONFIG_DIR)?;
std::fs::write(config_path, toml::to_string_pretty(self)?)?;
Ok(())
}

View File

@@ -7,7 +7,6 @@ use entity::{favorite, page, video};
use filenamify::filenamify;
use futures::stream::{FuturesOrdered, FuturesUnordered};
use futures::{pin_mut, Future, StreamExt};
use log::{error, info, warn};
use sea_orm::entity::prelude::*;
use sea_orm::ActiveValue::Set;
use sea_orm::TransactionTrait;
@@ -31,7 +30,7 @@ use crate::error::DownloadAbortError;
pub async fn process_favorite_list(
bili_client: &BiliClient,
fid: &str,
path: &str,
path: &Path,
connection: &DatabaseConnection,
) -> Result<()> {
let favorite_model = refresh_favorite_list(bili_client, fid, path, connection).await?;
@@ -43,7 +42,7 @@ pub async fn process_favorite_list(
pub async fn refresh_favorite_list(
bili_client: &BiliClient,
fid: &str,
path: &str,
path: &Path,
connection: &DatabaseConnection,
) -> Result<favorite::Model> {
let bili_favorite_list = FavoriteList::new(bili_client, fid.to_owned());
@@ -141,11 +140,6 @@ pub async fn download_unprocessed_videos(
for (video_model, _) in &unhandled_videos_pages {
uppers_mutex.insert(video_model.upper_id, (Mutex::new(()), Mutex::new(())));
}
let upper_path = {
let config = CONFIG.lock().unwrap();
config.upper_path.clone()
};
let upper_path = Path::new(&upper_path);
let mut tasks = unhandled_videos_pages
.into_iter()
.map(|(video_model, pages_model)| {
@@ -157,7 +151,7 @@ pub async fn download_unprocessed_videos(
connection,
&semaphore,
&downloader,
upper_path,
&CONFIG.upper_path,
upper_mutex,
)
})

View File

@@ -21,13 +21,10 @@ use crate::config::CONFIG;
pub static TEMPLATE: Lazy<handlebars::Handlebars> = Lazy::new(|| {
let mut handlebars = handlebars::Handlebars::new();
let config = CONFIG.lock().unwrap();
handlebars
.register_template_string("video", config.video_name.clone())
.unwrap();
handlebars
.register_template_string("page", config.page_name.clone())
.register_template_string("video", &CONFIG.video_name)
.unwrap();
handlebars.register_template_string("page", &CONFIG.page_name).unwrap();
handlebars
});
@@ -48,13 +45,13 @@ pub struct NFOSerializer<'a>(pub ModelWrapper<'a>, pub NFOMode);
/// 根据获得的收藏夹信息,插入或更新数据库中的收藏夹,并返回收藏夹对象
pub async fn handle_favorite_info(
info: &FavoriteListInfo,
path: &str,
path: &Path,
connection: &DatabaseConnection,
) -> Result<favorite::Model> {
favorite::Entity::insert(favorite::ActiveModel {
f_id: Set(info.id),
name: Set(info.title.to_string()),
path: Set(path.to_owned()),
name: Set(info.title.clone()),
path: Set(path.to_string_lossy().to_string()),
..Default::default()
})
.on_conflict(

View File

@@ -1,18 +1,13 @@
use anyhow::{anyhow, Result};
use anyhow::Result;
use migration::{Migrator, MigratorTrait};
use sea_orm::{Database, DatabaseConnection};
use tokio::fs;
use crate::config::CONFIG_DIR;
pub async fn database_connection() -> Result<DatabaseConnection> {
let config_dir = dirs::config_dir().ok_or(anyhow!("No config path found"))?;
let target = config_dir.join("bili-sync").join("data.sqlite");
if let Some(parent) = target.parent() {
fs::create_dir_all(parent).await?;
}
Ok(Database::connect(format!(
"sqlite://{}?mode=rwc",
config_dir.join("bili-sync").join("data.sqlite").to_str().unwrap()
))
.await?)
let target = CONFIG_DIR.join("data.sqlite");
fs::create_dir_all(&*CONFIG_DIR).await?;
Ok(Database::connect(format!("sqlite://{}?mode=rwc", target.to_str().unwrap())).await?)
}
pub async fn migrate_database(connection: &DatabaseConnection) -> Result<()> {

View File

@@ -1,6 +0,0 @@
pub mod bilibili;
pub mod config;
pub mod core;
pub mod database;
pub mod downloader;
pub mod error;

View File

@@ -1,34 +1,44 @@
use bili_sync::bilibili::BiliClient;
use bili_sync::core::command::process_favorite_list;
use bili_sync::database::{database_connection, migrate_database};
use log::error;
#[macro_use]
extern crate log;
mod bilibili;
mod config;
mod core;
mod database;
mod downloader;
mod error;
use once_cell::sync::Lazy;
use self::bilibili::BiliClient;
use self::config::CONFIG;
use self::core::command::process_favorite_list;
use self::database::{database_connection, migrate_database};
#[tokio::main]
async fn main() -> ! {
env_logger::init();
Lazy::force(&CONFIG);
let mut anchor = chrono::Local::now().date_naive();
let (credential, interval, favorites) = {
let config = bili_sync::config::CONFIG.lock().unwrap();
(config.credential.clone(), config.interval, config.favorite_list.clone())
};
let mut bili_client = BiliClient::new(credential);
let bili_client = BiliClient::new();
let connection = database_connection().await.unwrap();
migrate_database(&connection).await.unwrap();
loop {
if anchor != chrono::Local::now().date_naive() {
if let Err(e) = bili_client.check_refresh().await {
error!("Error: {e}");
tokio::time::sleep(std::time::Duration::from_secs(interval)).await;
tokio::time::sleep(std::time::Duration::from_secs(CONFIG.interval)).await;
continue;
}
anchor = chrono::Local::now().date_naive();
}
for (fid, path) in &favorites {
for (fid, path) in &CONFIG.favorite_list {
let res = process_favorite_list(&bili_client, fid, path, &connection).await;
if let Err(e) = res {
error!("Error: {e}");
}
}
tokio::time::sleep(std::time::Duration::from_secs(interval)).await;
tokio::time::sleep(std::time::Duration::from_secs(CONFIG.interval)).await;
}
}