Get cross seed doing what it's actually meant to do: cross seed!
This commit is contained in:
parent
9a7d08cb81
commit
5327c578cd
|
@ -0,0 +1,3 @@
|
|||
[submodule "abstracttorrent"]
|
||||
path = abstracttorrent
|
||||
url = https://github.com/SeanOMik/abstracttorrent.git
|
|
@ -2,6 +2,14 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "abstracttorrent"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"qbittorrent",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
|
@ -56,6 +64,17 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atom_syndication"
|
||||
version = "0.11.0"
|
||||
|
@ -179,6 +198,49 @@ dependencies = [
|
|||
"custom_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"time",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie_store"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e4b6aa369f41f5faa04bb80c9b1f4216ea81646ed6124d76ba5c49a7aafd9cd"
|
||||
dependencies = [
|
||||
"cookie",
|
||||
"idna",
|
||||
"log",
|
||||
"publicsuffix",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"time",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.2"
|
||||
|
@ -201,6 +263,7 @@ dependencies = [
|
|||
name = "cross-seed"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"abstracttorrent",
|
||||
"argmap",
|
||||
"async-recursion",
|
||||
"bytes 1.1.0",
|
||||
|
@ -213,6 +276,7 @@ dependencies = [
|
|||
"rss",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"stopwatch",
|
||||
"tokio 1.19.2",
|
||||
"toml",
|
||||
"torznab",
|
||||
|
@ -421,6 +485,15 @@ dependencies = [
|
|||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "figment"
|
||||
version = "0.10.6"
|
||||
|
@ -451,6 +524,21 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
|
@ -461,6 +549,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
|
@ -603,7 +697,7 @@ dependencies = [
|
|||
"indexmap",
|
||||
"slab",
|
||||
"tokio 1.19.2",
|
||||
"tokio-util 0.7.3",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -613,6 +707,12 @@ version = "0.11.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
|
@ -693,6 +793,19 @@ dependencies = [
|
|||
"tokio-rustls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes 1.1.0",
|
||||
"hyper",
|
||||
"native-tls",
|
||||
"tokio 1.19.2",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
|
@ -712,12 +825,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.8.2"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"hashbrown 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -726,6 +839,15 @@ version = "0.1.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.4"
|
||||
|
@ -758,9 +880,9 @@ checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
|||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.57"
|
||||
version = "0.3.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397"
|
||||
checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
@ -871,6 +993,16 @@ version = "0.3.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.3"
|
||||
|
@ -901,9 +1033,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
|
||||
checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
|
@ -934,6 +1066,24 @@ dependencies = [
|
|||
"ws2_32-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.37"
|
||||
|
@ -951,6 +1101,42 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"rand",
|
||||
"rustc-serialize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rustc-serialize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
|
@ -961,6 +1147,29 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"rustc-serialize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
|
@ -980,12 +1189,66 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.9.0"
|
||||
|
@ -1097,10 +1360,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.39"
|
||||
name = "pkg-config"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
|
||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -1118,6 +1393,35 @@ dependencies = [
|
|||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psl-types"
|
||||
version = "2.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8eda7c62d9ecaafdf8b62374c006de0adf61666ae96a96ba74a37134aa4e470"
|
||||
|
||||
[[package]]
|
||||
name = "publicsuffix"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "292972edad6bbecc137ab84c5e36421a4a6c979ea31d3cc73540dd04315b33e1"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"hashbrown 0.11.2",
|
||||
"idna",
|
||||
"psl-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qbittorrent"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"serde_with",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.22.0"
|
||||
|
@ -1140,13 +1444,50 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.18"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
dependencies = [
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.3.1",
|
||||
"rdrand",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
|
@ -1180,14 +1521,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.10"
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"base64",
|
||||
"bytes 1.1.0",
|
||||
"cookie",
|
||||
"cookie_store",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
|
@ -1196,21 +1548,27 @@ dependencies = [
|
|||
"http-body",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"native-tls",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"proc-macro-hack",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio 1.19.2",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tokio-util 0.6.10",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
|
@ -1246,6 +1604,12 @@ dependencies = [
|
|||
"quick-xml 0.22.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
|
@ -1269,9 +1633,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "0.3.0"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360"
|
||||
checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9"
|
||||
dependencies = [
|
||||
"base64",
|
||||
]
|
||||
|
@ -1282,6 +1646,16 @@ version = "1.0.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
@ -1298,6 +1672,29 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
|
@ -1344,6 +1741,17 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
|
@ -1468,6 +1876,15 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "stopwatch"
|
||||
version = "0.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d04b5ebc78da44d3a456319d8bc2783e7d8cc7ccbb5cb4dc3f54afbd93bf728"
|
||||
dependencies = [
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
|
@ -1476,15 +1893,29 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.96"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
|
||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"libc",
|
||||
"redox_syscall 0.2.13",
|
||||
"remove_dir_all",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.31"
|
||||
|
@ -1514,6 +1945,24 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82501a4c1c0330d640a6e176a3d6a204f5ec5237aca029029d21864a902e27b0"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"libc",
|
||||
"num_threads",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
|
@ -1562,7 +2011,7 @@ dependencies = [
|
|||
"bytes 1.1.0",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio 0.8.3",
|
||||
"mio 0.8.4",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.1",
|
||||
|
@ -1637,6 +2086,16 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio 1.19.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-reactor"
|
||||
version = "0.1.12"
|
||||
|
@ -1753,20 +2212,6 @@ dependencies = [
|
|||
"tokio-reactor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507"
|
||||
dependencies = [
|
||||
"bytes 1.1.0",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tokio 1.19.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.3"
|
||||
|
@ -1818,9 +2263,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
||||
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
|
@ -1912,6 +2357,15 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.8"
|
||||
|
@ -1920,9 +2374,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
||||
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
|
@ -1969,6 +2423,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
@ -1993,9 +2453,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.80"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad"
|
||||
checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
|
@ -2003,9 +2463,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.80"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4"
|
||||
checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
|
@ -2018,9 +2478,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.30"
|
||||
version = "0.4.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2"
|
||||
checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
|
@ -2030,9 +2490,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.80"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5"
|
||||
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
@ -2040,9 +2500,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.80"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b"
|
||||
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2053,15 +2513,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.80"
|
||||
version = "0.2.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744"
|
||||
checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.57"
|
||||
version = "0.3.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283"
|
||||
checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
|
|
@ -9,11 +9,18 @@ edition = "2021"
|
|||
tokio = { version = "1.19.2", features = ["full"] }
|
||||
tracing = "0.1.35"
|
||||
tracing-subscriber = "0.3.11"
|
||||
futures = "0.3.21"
|
||||
futures = { version = "0.3.21", features= ["executor"] }
|
||||
toml = "0.5.9"
|
||||
lava_torrent = "0.7.0" # https://docs.rs/lava_torrent/0.7.0/lava_torrent/
|
||||
torznab = "0.7.2" # https://docs.rs/torznab/0.7.2/torznab/
|
||||
|
||||
stopwatch = "0.0.7"
|
||||
|
||||
magnet-url = { git = "https://github.com/SeanOMik/magnet-url-rs.git", branch = "main" }
|
||||
abstracttorrent = { path = "abstracttorrent" }
|
||||
#abstracttorrent = { git = "https://github.com/SeanOMik/abstracttorrent.git", branch = "main" }
|
||||
#qbittorrent = { git = "https://github.com/SeanOMik/qbittorrent-rs.git", branch = "main"}
|
||||
|
||||
serde_with = "1.14.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
figment = { version = "0.10", features = ["toml", "env"] }
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 2b4cd84d7faf49d37492c6ff5708454beea7857a
|
|
@ -0,0 +1 @@
|
|||
pub mod qbittorrent;
|
|
@ -0,0 +1,8 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct QBittorrentConfig {
|
||||
pub url: String,
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
|
@ -9,7 +9,11 @@ use crate::torznab::TorznabClient;
|
|||
|
||||
use super::CliProvider;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
fn default_bool_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
/// The path of the torrents to search.
|
||||
torrents_path: String,
|
||||
|
@ -29,13 +33,12 @@ pub struct Config {
|
|||
#[serde(default)]
|
||||
pub use_cache: bool,
|
||||
|
||||
/// Whether to keep the original torrent file and create a new one for cross-seed or delete original and upload cross-seed
|
||||
#[serde(default)]
|
||||
pub replace_torrents: bool,
|
||||
|
||||
/// Whether or not to strip public trackers from cross-seed torrents.
|
||||
#[serde(default)]
|
||||
pub strip_public: bool,
|
||||
pub strip_public_trackers: bool,
|
||||
|
||||
/// The category of added cross-seed torrents.
|
||||
torrent_category: Option<String>,
|
||||
|
||||
/// Used for deserializing the indexers into a Vec<Indexer>.
|
||||
#[serde(rename = "indexers")]
|
||||
|
@ -44,11 +47,16 @@ pub struct Config {
|
|||
/// The indexers to search.
|
||||
#[serde(skip)]
|
||||
pub indexers: Vec<Indexer>,
|
||||
|
||||
/// Config section for qbittorrent client
|
||||
pub qbittorrent: Option<super::client::qbittorrent::QBittorrentConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub enum RunMode {
|
||||
#[serde(alias = "script")]
|
||||
Script,
|
||||
#[serde(alias = "daemon")]
|
||||
Daemon,
|
||||
}
|
||||
|
||||
|
@ -60,13 +68,25 @@ impl Default for RunMode {
|
|||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub enum TorrentMode {
|
||||
Inject,
|
||||
Search,
|
||||
/// Inject a found torrent's trackers into the torrent being downloaded
|
||||
/// by the client.
|
||||
#[serde(alias = "inject_trackers", alias = "injecttrackers")]
|
||||
InjectTrackers,
|
||||
|
||||
/// Upload the torrent file to the torrent client. This will cause there
|
||||
/// to be two uploading torrents on the client. One which is found by cross-seed
|
||||
/// and the other which was imported by the user or another application.
|
||||
#[serde(alias = "inject_file", alias = "injectfile")]
|
||||
InjectFile,
|
||||
|
||||
/// Cross-seeded torrents will be stored in the filesystem.
|
||||
#[serde(alias = "search")]
|
||||
Filesystem,
|
||||
}
|
||||
|
||||
impl Default for TorrentMode {
|
||||
fn default() -> Self {
|
||||
TorrentMode::Inject
|
||||
TorrentMode::InjectTrackers
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,4 +165,10 @@ impl Config {
|
|||
pub fn output_path_str(&self) -> Option<&String> {
|
||||
self.output_path.as_ref()
|
||||
}
|
||||
|
||||
pub fn torrent_category(&self) -> String {
|
||||
self.torrent_category.as_ref()
|
||||
.unwrap_or(&String::from("cross-seed-rs"))
|
||||
.clone()
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
pub mod config;
|
||||
pub use config::Config;
|
||||
pub use config::*;
|
||||
|
||||
pub mod argument_tree;
|
||||
pub use argument_tree::*;
|
||||
|
||||
pub mod cli_provider;
|
||||
pub use cli_provider::*;
|
||||
|
||||
pub mod client;
|
230
src/main.rs
230
src/main.rs
|
@ -1,12 +1,18 @@
|
|||
mod config;
|
||||
mod torznab;
|
||||
mod torrent_client;
|
||||
|
||||
use config::Config;
|
||||
use config::{Config, TorrentMode};
|
||||
|
||||
use abstracttorrent::common::GetTorrentListParams;
|
||||
use abstracttorrent::torrent::{TorrentUpload, TorrentState, TorrentInfo};
|
||||
use lava_torrent::bencode::BencodeElem;
|
||||
use tracing::{info, Level, debug};
|
||||
use tracing::{info, Level, debug, warn, error};
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::error::Error;
|
||||
use std::vec;
|
||||
|
||||
use lava_torrent::torrent::v1::{Torrent, AnnounceList};
|
||||
|
||||
|
@ -39,15 +45,22 @@ fn read_torrents(path: &Path) -> Result<Vec<PathBuf>, Box<dyn Error>> {
|
|||
#[tokio::main]
|
||||
async fn main() {
|
||||
let subscriber = tracing_subscriber::fmt()
|
||||
.with_max_level(Level::INFO)
|
||||
.with_max_level(Level::DEBUG)
|
||||
.finish();
|
||||
|
||||
tracing::subscriber::set_global_default(subscriber).expect("Failed to set global default log subscriber");
|
||||
|
||||
// Get config and debug the torrents
|
||||
let config = Config::new();
|
||||
let config = Arc::new(Config::new());
|
||||
info!("Searching for torrents in: {}", config.torrents_path_str());
|
||||
|
||||
// Get a torrent client from the config.
|
||||
let mut torrent_client = torrent_client::TorrentClient::from_config(&config);
|
||||
torrent_client.login(&config).await.unwrap();
|
||||
|
||||
// Torrent client no longer needs to mut, so we can just create an `Arc` without a mutex.
|
||||
let torrent_client = Arc::new(torrent_client);
|
||||
|
||||
let mut indexers = config.indexers.clone();
|
||||
|
||||
// Create torznab clients for each indexer.
|
||||
|
@ -64,24 +77,59 @@ async fn main() {
|
|||
|
||||
// Log the amount of torrents.
|
||||
let torrent_files = read_torrents(config.torrents_path()).unwrap();
|
||||
info!("Found {} torrents", torrent_files.len());
|
||||
info!("Found {} torrent files...", torrent_files.len());
|
||||
|
||||
// Convert the indexers to be async friendly.
|
||||
let mut indexers = indexers.iter()
|
||||
.map(|indexer| Arc::new(RwLock::new(indexer.clone())))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Store async tasks to wait for them to finish
|
||||
let mut indexer_handles = vec![];
|
||||
|
||||
for torrent_path in torrent_files.iter() {
|
||||
let torrent = Torrent::read_from_file(torrent_path).unwrap();
|
||||
info!("Parsing all torrent files...");
|
||||
|
||||
let mut stop = stopwatch::Stopwatch::start_new();
|
||||
// Get the torrents and from the paths
|
||||
let mut torrents: Vec<Result<Torrent, lava_torrent::LavaTorrentError>> = torrent_files.iter()
|
||||
.map(|path| Torrent::read_from_file(path))
|
||||
.collect();
|
||||
stop.stop();
|
||||
info!("Took {} seconds to parse all torrents", stop.elapsed().as_secs());
|
||||
drop(stop);
|
||||
|
||||
// Remove the torrents that failed to be read from the file, and
|
||||
// are not in the download client.
|
||||
|
||||
// NOTE: It might be better to get all torrents on the client and check that the torrents are on the
|
||||
// client locally.
|
||||
torrents.retain(|torrent| {
|
||||
if let Ok(torrent) = torrent {
|
||||
let info = futures::executor::block_on(torrent_client.get_torrent_info(&torrent)).unwrap();
|
||||
info.is_some()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
});
|
||||
// Unwrap the results, all errored ones were removed from the `.retain`
|
||||
let torrents: Vec<Torrent> = torrents.iter()
|
||||
.map(|res| res.as_ref().unwrap().clone())
|
||||
.collect();
|
||||
|
||||
info!("Found {} torrents that are in the client and on the filesystem", torrents.len());
|
||||
|
||||
for torrent in torrents {
|
||||
let torrent = Arc::new(torrent);
|
||||
|
||||
for indexer in indexers.iter() {
|
||||
info!("Checking for \"{}\"", torrent.name);
|
||||
|
||||
// Clone some `Arc`s for the new async task.
|
||||
let mut indexer = Arc::clone(indexer);
|
||||
let torrent = Arc::clone(&torrent);
|
||||
let torrent_client = Arc::clone(&torrent_client);
|
||||
let config = Arc::clone(&config);
|
||||
|
||||
indexer_handles.push(tokio::spawn(async move {
|
||||
let lock = indexer.read().await;
|
||||
match &lock.client {
|
||||
|
@ -95,39 +143,159 @@ async fn main() {
|
|||
if let Some(result) = results.first() {
|
||||
let found_torrent = result.download_torrent().await.unwrap();
|
||||
|
||||
// Check if we found the same torrent in its own indexer
|
||||
if found_torrent.info_hash() == torrent.info_hash() {
|
||||
debug!("Found same torrent in its own indexer, skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(found_announces) = &found_torrent.announce_list {
|
||||
// Some urls can be encoded so we need to decode to compare them.
|
||||
let found_announces: Vec<Vec<String>> = found_announces.iter()
|
||||
.map(|a_list| a_list.iter().map(|a| urlencoding::decode(a).unwrap().to_string()).collect::<Vec<String>>())
|
||||
.map(|a_list|
|
||||
a_list.iter().map(|a| urlencoding::decode(a)
|
||||
.unwrap().to_string())
|
||||
.collect::<Vec<String>>())
|
||||
.collect();
|
||||
|
||||
if let Some(torrent_announces) = &torrent.announce_list {
|
||||
let mut found_announces_flat: Vec<&String> = Vec::new();
|
||||
for i in found_announces.iter() {
|
||||
for j in i.iter() {
|
||||
found_announces_flat.push(j);
|
||||
}
|
||||
}
|
||||
// Get the trackers of the torrent from the download client.
|
||||
let request_info = TorrentInfo::from_hash(torrent.info_hash());
|
||||
let torrent_announces = torrent_client.get_torrent_trackers(&request_info).await.unwrap();
|
||||
let torrent_announces: Vec<&String> = torrent_announces.iter().map(|t| &t.url).collect();
|
||||
|
||||
let mut flat_announces: Vec<&String> = Vec::new();
|
||||
for i in torrent_announces.iter() {
|
||||
for j in i.iter() {
|
||||
flat_announces.push(j);
|
||||
}
|
||||
}
|
||||
// Flatten the announce list to make them easier to search.
|
||||
let found_announces: Vec<&String> = found_announces.iter()
|
||||
.flat_map(|array| array.iter())
|
||||
.collect();
|
||||
|
||||
// Check if the announce urls from the found torrent are in the one
|
||||
// that is on the file system.
|
||||
let mut in_tracker = true;
|
||||
for found_url in found_announces_flat.iter() {
|
||||
in_tracker = in_tracker && flat_announces.contains(found_url);
|
||||
}
|
||||
// Check if the client has the trackers of the torrent already.
|
||||
let mut client_has_trackers = found_announces.iter()
|
||||
.all(|tracker| torrent_announces.contains(tracker));
|
||||
|
||||
if !in_tracker {
|
||||
info!("Found a cross-seedable torrent for {}", found_torrent.name);
|
||||
} else {
|
||||
debug!("Found the torrent in its original indexer, skipping...");
|
||||
if !client_has_trackers {
|
||||
info!("Found a cross-seedable torrent for {}", found_torrent.name);
|
||||
|
||||
match torrent_client.get_torrent_info(&torrent).await.unwrap() {
|
||||
Some(info) => {
|
||||
info!("Got info: {:?}", info);
|
||||
|
||||
match info.state {
|
||||
TorrentState::Uploading | TorrentState::QueuedUploading => {
|
||||
debug!("The torrent is being uploaded on the client");
|
||||
|
||||
//if config.add_trackers {
|
||||
match config.torrent_mode {
|
||||
TorrentMode::InjectTrackers => {
|
||||
debug!("Can add trackers to the torrent");
|
||||
|
||||
if found_torrent.is_private() {
|
||||
debug!("The found torrent is private, so we must remove the torrent and re-add it with the new trackers...");
|
||||
|
||||
match torrent_client.remove_torrent(&info, false).await {
|
||||
Ok(()) => {
|
||||
debug!("Re-uploading torrent to client...");
|
||||
|
||||
info!("Found announces: {:?}", found_announces);
|
||||
|
||||
// Combine both announces and deref the Strings by cloning them.
|
||||
let mut torrent_announces: Vec<String> = torrent_announces.into_iter()
|
||||
.chain(found_announces)
|
||||
.cloned()
|
||||
.collect();
|
||||
// Remove the [DHT], [PeX] and [LSD] announces from the list.
|
||||
// The client should handle those.
|
||||
torrent_announces.retain(|announce| !(announce.starts_with("** [") && announce.ends_with("] **")));
|
||||
|
||||
info!("Old torrent: {:?}", torrent.announce_list);
|
||||
|
||||
let mut torrent = (*torrent).clone();
|
||||
torrent.announce_list = Some(vec![torrent_announces]);
|
||||
if let Some(extra) = torrent.extra_info_fields.as_mut() {
|
||||
extra.insert(String::from("private"), BencodeElem::Integer(1));
|
||||
} else {
|
||||
let mut extra = std::collections::HashMap::new();
|
||||
extra.insert(String::from("private"), BencodeElem::Integer(1));
|
||||
torrent.extra_info_fields = Some(extra);
|
||||
}
|
||||
/* torrent.extra_info_fields.as_mut()
|
||||
.unwrap_or(&mut std::collections::HashMap::new())
|
||||
.insert(String::from("private"), BencodeElem::Integer(1)); */
|
||||
|
||||
|
||||
info!("Torrent that will be uploaded: {:?}, private: {}", torrent.announce_list, torrent.is_private());
|
||||
|
||||
// Clone some fields from the torrent due to ownership issues with
|
||||
// torrent.encode()
|
||||
let name = torrent.name.clone();
|
||||
let hash = torrent.info_hash().clone();
|
||||
|
||||
match torrent.encode() {
|
||||
Ok(bytes) => {
|
||||
let upload = TorrentUpload::builder()
|
||||
.category(config.torrent_category())
|
||||
.tags(info.tags)
|
||||
.torrent_data(format!("{}.torrent", hash), bytes)
|
||||
//.paused()
|
||||
.build();
|
||||
|
||||
match torrent_client.add_torrent(&upload).await {
|
||||
Ok(()) => info!("Added cross-seed torrent {}!", name),
|
||||
Err(err) => error!("Error adding cross-seed torrent: {} (error: {:?}", name, err),
|
||||
}
|
||||
},
|
||||
Err(e) => error!("Error encoding torrent for upload: {}", e),
|
||||
}
|
||||
},
|
||||
Err(err) => error!("Error removing torrent from client: {} (error: {:?})", torrent.name, err),
|
||||
}
|
||||
} else {
|
||||
debug!("Adding trackers to torrent since they aren't private...");
|
||||
let torrent_announces = torrent_announces.iter()
|
||||
.map(|u| u.to_owned().to_owned())
|
||||
.collect();
|
||||
|
||||
if let Err(err) = torrent_client.add_torrent_trackers(&info, torrent_announces).await {
|
||||
error!("Error adding torrent trackers to torrent: {} (err: {:?})", torrent.name, err);
|
||||
}
|
||||
}
|
||||
},
|
||||
TorrentMode::InjectFile => {
|
||||
debug!("Cannot add trackers, uploading new torrent...");
|
||||
|
||||
// Clone some fields from the torrent due to ownership issues with
|
||||
// found_torrent.encode()
|
||||
let name = found_torrent.name.clone();
|
||||
let hash = found_torrent.info_hash().clone();
|
||||
|
||||
match found_torrent.encode() {
|
||||
Ok(bytes) => {
|
||||
let upload = TorrentUpload::builder()
|
||||
.torrent_data(format!("{}.torrent", hash), bytes)
|
||||
.category(config.torrent_category())
|
||||
//.paused() // TODO: don't pause new uploads
|
||||
.build();
|
||||
|
||||
match torrent_client.add_torrent(&upload).await {
|
||||
Ok(()) => info!("Added cross-seed torrent {}!", name),
|
||||
Err(err) => error!("Failure to add cross-seed torrent: {} (Error {:?})", name, err),
|
||||
}
|
||||
},
|
||||
Err(e) => warn!("Failure to encode ({}) {}", e, name),
|
||||
}
|
||||
},
|
||||
TorrentMode::Filesystem => {
|
||||
todo!(); // TODO: implement
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => debug!("Torrent is not done downloading, skipping..."),
|
||||
}
|
||||
|
||||
},
|
||||
None => info!("Torrent file {} was not found in the client, skipping...", torrent.name),
|
||||
}
|
||||
} else {
|
||||
debug!("Found the torrent in its original indexer, skipping...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use abstracttorrent::{client::qbittorrent, torrent::TorrentInfo, common::GetTorrentListParams};
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
pub struct TorrentClient {
|
||||
client: Box<dyn abstracttorrent::client::TorrentClient + Send + Sync>,
|
||||
}
|
||||
|
||||
impl TorrentClient {
|
||||
pub fn from_config(config: &Config) -> Self {
|
||||
// TODO: figure out which client to use if multiple are specified.
|
||||
|
||||
if let Some(qbittorrent) = &config.qbittorrent {
|
||||
TorrentClient {
|
||||
client: Box::new(qbittorrent::client::QBittorrentClient::new())
|
||||
}
|
||||
} else {
|
||||
panic!("Invalid config!");
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn login(&mut self, config: &Config) -> abstracttorrent::client::ClientResult<()> {
|
||||
let (url, username, password) = match &config.qbittorrent {
|
||||
Some(qb) => {
|
||||
(&qb.url, &qb.username, &qb.password)
|
||||
},
|
||||
None => {
|
||||
panic!("Invalid config!");
|
||||
}
|
||||
};
|
||||
|
||||
self.client.login(&url, username, password).await
|
||||
}
|
||||
|
||||
/* pub fn login_with_config(&self, config: &Config) -> abstracttorrent::client::ClientResult<()> {
|
||||
self.login(url, username, password)
|
||||
} */
|
||||
|
||||
pub async fn get_torrent_info(&self, torrent: &lava_torrent::torrent::v1::Torrent) -> abstracttorrent::client::ClientResult<Option<TorrentInfo>> {
|
||||
let params = GetTorrentListParams::builder()
|
||||
.hash(&torrent.info_hash())
|
||||
.build();
|
||||
|
||||
let results = self.client.get_torrent_list(Some(params)).await?;
|
||||
Ok(results.first().cloned())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for TorrentClient {
|
||||
type Target = Box<dyn abstracttorrent::client::TorrentClient + Send + Sync>;
|
||||
fn deref(&self) -> &Self::Target { &self.client }
|
||||
}
|
||||
|
||||
impl DerefMut for TorrentClient {
|
||||
fn deref_mut(&mut self) -> &mut Box<dyn abstracttorrent::client::TorrentClient + Send + Sync> { &mut self.client }
|
||||
}
|
Loading…
Reference in New Issue