2 Commits

Author SHA1 Message Date
VC
d70fbdac98 Merge branch '4-use-original-source-file-when-possible' into 'master'
: add peertube source video file

Closes #4

See merge request veretcle/tootube!19
2024-05-14 08:42:25 +00:00
VC
982dc8b954 : add peertube source video file 2024-05-14 10:38:37 +02:00
8 changed files with 435 additions and 136 deletions

243
Cargo.lock generated
View File

@@ -28,47 +28,48 @@ dependencies = [
[[package]]
name = "anstream"
version = "0.6.13"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.2"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
@@ -98,9 +99,9 @@ dependencies = [
[[package]]
name = "autocfg"
version = "1.2.0"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "backtrace"
@@ -149,9 +150,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
[[package]]
name = "cc"
version = "1.0.92"
version = "1.0.97"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41"
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
[[package]]
name = "cfg-if"
@@ -188,9 +189,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]]
name = "colorchoice"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "console"
@@ -257,9 +258,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.8"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -267,9 +268,9 @@ dependencies = [
[[package]]
name = "fastrand"
version = "2.0.2"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
[[package]]
name = "fnv"
@@ -389,9 +390,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.14.3"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hermit-abi"
@@ -535,6 +536,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
[[package]]
name = "itoa"
version = "1.0.11"
@@ -558,9 +565,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.153"
version = "0.2.154"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
[[package]]
name = "linux-raw-sys"
@@ -570,9 +577,9 @@ checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "lock_api"
version = "0.4.11"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
@@ -721,9 +728,9 @@ dependencies = [
[[package]]
name = "parking_lot"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
dependencies = [
"lock_api",
"parking_lot_core",
@@ -731,15 +738,15 @@ dependencies = [
[[package]]
name = "parking_lot_core"
version = "0.9.9"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets 0.48.5",
"windows-targets 0.52.5",
]
[[package]]
@@ -774,9 +781,9 @@ checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
[[package]]
name = "proc-macro2"
version = "1.0.79"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
dependencies = [
"unicode-ident",
]
@@ -792,11 +799,11 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.4.1"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
dependencies = [
"bitflags 1.3.2",
"bitflags 2.5.0",
]
[[package]]
@@ -872,16 +879,37 @@ dependencies = [
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
name = "rpassword"
version = "7.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f"
dependencies = [
"libc",
"rtoolbox",
"windows-sys 0.48.0",
]
[[package]]
name = "rtoolbox"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e"
dependencies = [
"libc",
"windows-sys 0.48.0",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustix"
version = "0.38.32"
version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [
"bitflags 2.5.0",
"errno",
@@ -901,9 +929,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.17"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "schannel"
@@ -922,11 +950,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
version = "2.10.0"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
dependencies = [
"bitflags 1.3.2",
"bitflags 2.5.0",
"core-foundation",
"core-foundation-sys",
"libc",
@@ -935,9 +963,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
version = "2.10.0"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
dependencies = [
"core-foundation-sys",
"libc",
@@ -945,18 +973,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.197"
version = "1.0.201"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.197"
version = "1.0.201"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
dependencies = [
"proc-macro2",
"quote",
@@ -965,9 +993,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.115"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
dependencies = [
"itoa",
"ryu",
@@ -988,9 +1016,9 @@ dependencies = [
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
dependencies = [
"libc",
]
@@ -1012,9 +1040,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
version = "0.5.6"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -1028,9 +1056,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.58"
version = "2.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704"
dependencies = [
"proc-macro2",
"quote",
@@ -1142,16 +1170,15 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.7.10"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
"tracing",
]
[[package]]
@@ -1165,7 +1192,7 @@ dependencies = [
[[package]]
name = "tootube"
version = "0.5.5"
version = "0.6.0"
dependencies = [
"async-stream",
"clap",
@@ -1174,6 +1201,7 @@ dependencies = [
"indicatif",
"log",
"reqwest",
"rpassword",
"serde",
"tokio",
"toml",
@@ -1242,9 +1270,9 @@ dependencies = [
[[package]]
name = "unicode-width"
version = "0.1.11"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
[[package]]
name = "url"
@@ -1379,37 +1407,15 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
dependencies = [
"winapi",
"windows-sys 0.52.0",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.48.0"
@@ -1425,7 +1431,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.4",
"windows-targets 0.52.5",
]
[[package]]
@@ -1445,17 +1451,18 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
"windows_aarch64_gnullvm 0.52.4",
"windows_aarch64_msvc 0.52.4",
"windows_i686_gnu 0.52.4",
"windows_i686_msvc 0.52.4",
"windows_x86_64_gnu 0.52.4",
"windows_x86_64_gnullvm 0.52.4",
"windows_x86_64_msvc 0.52.4",
"windows_aarch64_gnullvm 0.52.5",
"windows_aarch64_msvc 0.52.5",
"windows_i686_gnu 0.52.5",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.5",
"windows_x86_64_gnu 0.52.5",
"windows_x86_64_gnullvm 0.52.5",
"windows_x86_64_msvc 0.52.5",
]
[[package]]
@@ -1466,9 +1473,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
@@ -1478,9 +1485,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
@@ -1490,9 +1497,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
@@ -1502,9 +1515,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
@@ -1514,9 +1527,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -1526,9 +1539,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
@@ -1538,9 +1551,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "winreg"

View File

@@ -1,12 +1,13 @@
[package]
name = "tootube"
authors = ["VC <veretcle+framagit@mateu.be>"]
version = "0.5.5"
version = "0.6.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rpassword = "^7.3"
reqwest = { version = "^0.11", features = ["json", "stream", "multipart"] }
tokio = { version = "^1", features = ["full"] }
clap = "^4"

View File

@@ -13,6 +13,7 @@ So consider this a work in progress that will slowly get better with time.
# What does it do exactly?
* it retrieves the latest PeerTube video download URL from an instance
* if you register the app into your PeerTube instance (optional), you can retrieve the latest video source instead of the highest quality encoded video
* it creates a resumable upload into the target YouTube account
* it downloads/uploads the latest PeerTube video to YouTube without using a cache (stream-to-stream)
@@ -46,6 +47,15 @@ Create your `tootube.toml` config file:
```toml
[peertube]
base_url="https://p.nintendojo.fr"
# optional
# allows you to delete the original video source file once its uploaded to YouTube
delete_video_source_after_transfer=true # this option is only available if you have Administrator privileges
# optional
# everything below is given by the register command with --peertube option
[peertube.oauth2]
client_id="<YOUR CLIENT_ID>"
client_secret="<YOUR CLIENT_SECRET"
refresh_token="/var/lib/tootube/refresh_token" # refresh_token are single use only in PeerTube so we need to store it in a separate file
[youtube]
refresh_token="" # leave empty for now
@@ -56,7 +66,19 @@ client_secret="<YOUR CLIENT_SECRET>"
Then run:
```bash
tootube register --config <PATH TO YOUR TOOTUBE.TOML FILE>
tootube register --youtube --config <PATH TO YOUR TOOTUBE.TOML FILE>
```
Youll be then prompted with all the necessary information to register `tootube`. Youll end with a `refresh_token` that you can now paste inside your tootube configuration.
If you wish to register `tootube` on PeerTube, you can do so by using:
```bash
tootube register --peertube --config <PATH TO YOUR TOOTUBE.TOML FILE>
```
It will require your username/password (beware that 2FA is not supported for this feature as of now) and generate a first `refresh_token` that you will put inside the aformentioned file:
```bash
echo -n '<REFRESH_TOKEN>' > /var/lib/tootube/refresh_token
```

View File

@@ -13,6 +13,26 @@ pub struct Config {
#[derive(Debug, Deserialize)]
pub struct PeertubeConfig {
pub base_url: String,
#[serde(default)]
pub delete_video_source_after_transfer: bool,
pub oauth2: Option<PeertubeConfigOauth2>,
}
impl Default for PeertubeConfig {
fn default() -> Self {
PeertubeConfig {
base_url: "".to_string(),
delete_video_source_after_transfer: false,
oauth2: None,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct PeertubeConfigOauth2 {
pub client_id: String,
pub client_secret: String,
pub refresh_token: String,
}
#[derive(Debug, Deserialize)]

View File

@@ -7,10 +7,11 @@ pub use config::parse_toml;
use config::Config;
mod peertube;
use peertube::get_latest_video;
pub use peertube::register as register_peertube;
use peertube::{delete_original_video_source, get_latest_video, get_original_video_source};
mod youtube;
pub use youtube::register;
pub use youtube::register as register_youtube;
use youtube::{add_video_to_playlists, create_resumable_upload, now_kiss};
#[tokio::main]
@@ -22,13 +23,29 @@ pub async fn run(config: Config, pl: Vec<String>) {
panic!("Cannot retrieve the latest video, something must have gone terribly wrong: {e}")
});
let dl_url = latest_vid.streaming_playlists.as_ref().unwrap()[0]
// We have a refresh_token, try to use it
let source_url = match &config.peertube.oauth2 {
Some(_) => get_original_video_source(&latest_vid.uuid, &config.peertube)
.await
.ok(),
None => None,
};
// Whatever happens, collect the highest quality possible
let high_quality_url = latest_vid.streaming_playlists.as_ref().unwrap()[0]
.files
.iter()
.max()
.unwrap()
.file_download_url
.clone();
// dl_url corresponds to source url if available, best quality if not
let dl_url = match source_url {
Some(s) => s,
None => high_quality_url,
};
debug!("PT download URL: {}", &dl_url);
let resumable_upload_url = create_resumable_upload(&config.youtube, &latest_vid)
@@ -51,4 +68,13 @@ pub async fn run(config: Config, pl: Vec<String>) {
.await
.unwrap_or_else(|e| panic!("Cannot add video to playlist(s): {e}"));
}
// delete the source video if requested (it wont be used anymore)
if config.peertube.delete_video_source_after_transfer {
delete_original_video_source(&latest_vid.uuid, &config.peertube)
.await
.unwrap_or_else(|e| panic!("Cannot delete source video: {e}"));
debug!("Original Video {} has been deleted", &latest_vid.uuid);
}
}

View File

@@ -10,6 +10,7 @@ fn main() {
.arg(
Arg::new("config")
.short('c')
.global(true)
.long("config")
.value_name("CONFIG_FILE")
.help("TOML config file for tootube")
@@ -29,32 +30,45 @@ fn main() {
.arg(
Arg::new("vice")
.long("vice")
.alias("chybrare")
.alias("coquinou")
.aliases(["chybrare", "coquinou"])
.action(clap::ArgAction::SetTrue)
.display_order(3),
)
.subcommand(
Command::new("register")
.version(env!("CARGO_PKG_VERSION"))
.about("Command to register to YouTube OAuth2.0")
.about("Command to register to YouTube or PeerTube OAuth2.0")
.arg(
Arg::new("config")
.short('c')
.long("config")
.value_name("CONFIG_FILE")
.help("TOML config file for tootube")
.num_args(1)
.default_value(DEFAULT_CONFIG_PATH)
.display_order(1),
Arg::new("youtube")
.long("youtube")
.short('y')
.required(true)
.conflicts_with("peertube")
.action(clap::ArgAction::SetTrue),
)
.arg(
Arg::new("peertube")
.long("peertube")
.short('p')
.required(true)
.action(clap::ArgAction::SetTrue),
),
)
.get_matches();
if let Some(("register", sub_m)) = matches.subcommand() {
let config = parse_toml(sub_m.get_one::<String>("config").unwrap());
register(&config.youtube)
.unwrap_or_else(|e| panic!("Cannot register to YouTube API: {}", e));
if sub_m.get_flag("youtube") {
register_youtube(&config.youtube)
.unwrap_or_else(|e| panic!("Cannot register to YouTube API: {}", e));
}
if sub_m.get_flag("peertube") {
register_peertube(&config.peertube)
.unwrap_or_else(|e| panic!("Cannot register to PeerTube API: {}", e));
}
return;
}

View File

@@ -1,5 +1,10 @@
use serde::Deserialize;
use std::{boxed::Box, cmp::Ordering, error::Error};
use crate::{config::PeertubeConfig, error::TootubeError};
use log::debug;
use reqwest::Client;
use rpassword::prompt_password;
use serde::{Deserialize, Serialize};
use std::{boxed::Box, cmp::Ordering, error::Error, io::stdin};
use tokio::fs::{read_to_string, write};
#[derive(Debug, Deserialize)]
pub struct PeerTubeVideos {
@@ -22,6 +27,44 @@ pub struct PeerTubeVideoStreamingPlaylists {
pub files: Vec<PeerTubeVideoStreamingPlaylistsFiles>,
}
#[derive(Debug, Deserialize)]
struct PeerTubeOauthClientsLocalResponse {
client_id: String,
client_secret: String,
}
#[derive(Debug, Serialize)]
struct PeerTubeUsersToken {
client_id: String,
client_secret: String,
grant_type: String,
password: Option<String>,
username: Option<String>,
refresh_token: Option<String>,
}
#[derive(Debug, Deserialize)]
struct PeerTubeUsersTokenResponse {
refresh_token: String,
access_token: String,
}
#[derive(Debug, Deserialize)]
struct PeerTubeVideoSourceResponse {
#[serde(rename = "fileDownloadUrl")]
pub file_download_url: String,
}
#[derive(Debug, Deserialize)]
struct PeerTubeVideoTokenResponse {
files: PeerTubeVideoTokenResponseFiles,
}
#[derive(Debug, Deserialize)]
struct PeerTubeVideoTokenResponseFiles {
token: String,
}
#[derive(Eq, Debug, Deserialize)]
pub struct PeerTubeVideoStreamingPlaylistsFiles {
pub id: u64,
@@ -74,3 +117,163 @@ async fn get_video_detail(u: &str, v: &str) -> Result<PeerTubeVideo, Box<dyn Err
Ok(body)
}
/// This function makes the registration process a little bit easier
#[tokio::main]
pub async fn register(config: &PeertubeConfig) -> Result<(), Box<dyn Error>> {
// Get client ID/secret
let oauth2_client = reqwest::get(format!("{}/api/v1/oauth-clients/local", config.base_url))
.await?
.json::<PeerTubeOauthClientsLocalResponse>()
.await?;
println!(
"Please type your PeerTube username for instance {}:",
config.base_url
);
let mut username = String::new();
stdin()
.read_line(&mut username)
.expect("Unable to read back the username!");
let password = prompt_password("Your password: ").expect("Unable to read back the password!");
let params = PeerTubeUsersToken {
client_id: oauth2_client.client_id.clone(),
client_secret: oauth2_client.client_secret.clone(),
grant_type: "password".to_string(),
username: Some(username.trim().to_string()),
password: Some(password.clone()),
refresh_token: None,
};
let client = Client::new();
let oauth2_token = client
.post(format!("{}/api/v1/users/token", config.base_url))
.form(&params)
.send()
.await?
.json::<PeerTubeUsersTokenResponse>()
.await?;
println!("You can now paste the following lines inside the `peertube` section of your tootube.toml file:");
println!();
println!("[peertube.oauth2]");
println!("client_id=\"{}\"", oauth2_client.client_id);
println!("client_secret=\"{}\"", oauth2_client.client_secret);
println!("refresh_token=<path to refresh_token>");
println!();
println!("Finally, add the refresh token inside the refresh_token path:");
println!("{}", oauth2_token.refresh_token);
Ok(())
}
async fn get_refresh_token(config: &PeertubeConfig) -> Result<String, Box<dyn Error>> {
// unwrap is safe here, this function is only called when oauth2 is present
let oauth2_config = config.oauth2.as_ref().unwrap().clone();
// retrieve the refresh_token from the file
let refresh_token = read_to_string(&oauth2_config.refresh_token).await?;
debug!(
"Opened file {} to retrieve Token",
&oauth2_config.refresh_token
);
let params = PeerTubeUsersToken {
client_id: oauth2_config.client_id.clone(),
client_secret: oauth2_config.client_secret.clone(),
grant_type: "refresh_token".to_string(),
refresh_token: Some(refresh_token),
username: None,
password: None,
};
let client = Client::new();
let oauth2_token = client
.post(format!("{}/api/v1/users/token", config.base_url))
.form(&params)
.send()
.await?
.json::<PeerTubeUsersTokenResponse>()
.await?;
debug!("Retrieved access_token: {}", &oauth2_token.access_token);
// write the new refresh token to the file
write(&oauth2_config.refresh_token, oauth2_token.refresh_token).await?;
debug!(
"Written refresh_token to file {}",
&oauth2_config.refresh_token
);
Ok(oauth2_token.access_token)
}
pub async fn get_original_video_source(
uuid: &str,
config: &PeertubeConfig,
) -> Result<String, Box<dyn Error>> {
let access_token = get_refresh_token(config).await?;
let client = Client::new();
let source_vid = client
.get(format!("{}/api/v1/videos/{}/source", config.base_url, uuid))
.header("Authorization", format!("Bearer {}", &access_token))
.send()
.await?
.json::<PeerTubeVideoSourceResponse>()
.await?;
debug!("Got the Source Vid URL: {}", &source_vid.file_download_url);
let video_file_token = client
.post(format!("{}/api/v1/videos/{}/token", config.base_url, uuid))
.header("Authorization", format!("Bearer {}", &access_token))
.send()
.await?
.json::<PeerTubeVideoTokenResponse>()
.await?;
debug!("Got the File Token: {}", &video_file_token.files.token);
Ok(format!(
"{}?videoFileToken={}",
source_vid.file_download_url, video_file_token.files.token
))
}
pub async fn delete_original_video_source(
uuid: &str,
config: &PeertubeConfig,
) -> Result<(), Box<dyn Error>> {
let access_token = get_refresh_token(config).await?;
let client = Client::new();
let res = client
.delete(format!(
"{}/api/v1/videos/{}/source/file",
config.base_url, uuid
))
.header("Authorization", format!("Bearer {}", &access_token))
.send()
.await?;
if !res.status().is_success() {
return Err(TootubeError::new(&format!(
"Cannot delete source video file {}: {}",
uuid,
res.text().await?
))
.into());
}
Ok(())
}

View File

@@ -253,7 +253,7 @@ async fn get_playlist_ids(
// if nextPageToken is present, continue the loop
match local_pl.next_page_token {
None => break,
Some(a) => page_token = a.clone(),
Some(a) => page_token.clone_from(&a),
}
}