diff --git a/Cargo.lock b/Cargo.lock index f4ddd7c..9db0791 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,19 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "anyhow" version = "1.0.75" @@ -25,15 +38,16 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "aquamarine" -version = "0.1.12" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a941c39708478e8eea39243b5983f1c42d2717b3620ee91f4a52115fd02ac43f" +checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e" dependencies = [ + "include_dir", "itertools", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.37", ] [[package]] @@ -508,6 +522,25 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "include_dir" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -518,6 +551,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indoc" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" + [[package]] name = "ipnet" version = "2.8.0" @@ -526,9 +565,9 @@ checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "itertools" -version = "0.9.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -566,6 +605,16 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.20" @@ -578,6 +627,15 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -620,6 +678,7 @@ version = "0.1.0" dependencies = [ "anyhow", "dotenv", + "pyo3", "teloxide", "tokio", ] @@ -642,12 +701,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "never" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91" - [[package]] name = "num-traits" version = "0.2.16" @@ -726,6 +779,29 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets", +] + [[package]] name = "percent-encoding" version = "2.3.0" @@ -803,6 +879,67 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pyo3" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a89dc7a5850d0e983be1ec2a463a171d20990487c3cfcd68b5363f1ee3d6fe0" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset", + "parking_lot", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07426f0d8fe5a601f26293f300afd1a7b1ed5e78b2a705870c5f30893c5163be" +dependencies = [ + "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb7dec17e17766b46bca4f1a4215a85006b4c2ecde122076c562dd058da6cf1" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f738b4e40d50b5711957f142878cfa0f28e054aa0ebdfc3fd137a843f74ed3" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc910d4851847827daf9d6cdd4a823fbdaab5b8818325c5e97a86da79e8881f" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "quote" version = "1.0.33" @@ -830,6 +967,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "reqwest" version = "0.11.22" @@ -1022,6 +1168,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + [[package]] name = "socket2" version = "0.4.9" @@ -1103,23 +1255,29 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20f34339676cdcab560c9a82300c4c2581f68b9369aedf0fae86f2ff9565ff3e" +[[package]] +name = "target-lexicon" +version = "0.12.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" + [[package]] name = "teloxide" version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c63345cf32a8850ebddcdd769dc2d5193d5e231262d5dada264b79da01a664da" +source = "git+https://github.com/teloxide/teloxide#4adfcecef37b6c86e0d189946079d8e93adbfb19" dependencies = [ + "ahash", "aquamarine", "bytes", "derive_more", "dptree", + "either", "futures", "log", "mime", "pin-project", "serde", "serde_json", - "serde_with_macros", "teloxide-core", "teloxide-macros", "thiserror", @@ -1132,8 +1290,7 @@ dependencies = [ [[package]] name = "teloxide-core" version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "303db260110c238e3af77bb9dff18bf7a5b5196f783059b0852aab75f91d5a16" +source = "git+https://github.com/teloxide/teloxide#4adfcecef37b6c86e0d189946079d8e93adbfb19" dependencies = [ "bitflags 1.3.2", "bytes", @@ -1143,7 +1300,6 @@ dependencies = [ "futures", "log", "mime", - "never", "once_cell", "pin-project", "rc-box", @@ -1163,8 +1319,7 @@ dependencies = [ [[package]] name = "teloxide-macros" version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1d653b093dba5e44cada57a516f572167df37b8a619443e59c8c517bb6d804" +source = "git+https://github.com/teloxide/teloxide#4adfcecef37b6c86e0d189946079d8e93adbfb19" dependencies = [ "heck", "proc-macro2", @@ -1180,7 +1335,7 @@ checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "redox_syscall 0.3.5", "rustix", "windows-sys", ] @@ -1346,6 +1501,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unindent" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" + [[package]] name = "url" version = "2.4.1" @@ -1580,3 +1741,23 @@ dependencies = [ "cfg-if", "windows-sys", ] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] diff --git a/Cargo.toml b/Cargo.toml index aac67f1..e53bc80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,5 +8,6 @@ edition = "2021" [dependencies] anyhow = "1.0.75" dotenv = "0.15.0" -teloxide = { version = "0.12.2", features = ["macros"] } tokio = { version = "1.32.0", features = ["rt-multi-thread", "macros"] } +teloxide = { version = "0.12.2", git ="https://github.com/teloxide/teloxide", features = ["macros"] } +pyo3 = { version = "0.20.2", features = ["extension-module", "auto-initialize"] } diff --git a/src/dl.rs b/src/dl.rs new file mode 100644 index 0000000..674b799 --- /dev/null +++ b/src/dl.rs @@ -0,0 +1 @@ +pub mod download; diff --git a/src/dl/download.rs b/src/dl/download.rs new file mode 100644 index 0000000..f12903b --- /dev/null +++ b/src/dl/download.rs @@ -0,0 +1,29 @@ +use pyo3::prelude::*; +use tokio::task::{spawn_blocking, JoinError}; + +// TODO: Switch to Command::new for true multithreading and async +pub async fn download_url(url: String) -> Result { + spawn_blocking(move || { + let res: PyResult<()> = Python::with_gil(|py| { + let yt_dlp = PyModule::import(py, "yt_dlp")?; + let yt = yt_dlp.getattr("YoutubeDL")?; + + let yt_obj = yt.call((), None)?; + + yt_obj.call_method0("__enter__")?; + yt_obj.call_method1("download", (url,))?; + yt_obj.call_method0("__exit__")?; + + Ok(()) + }); + + match res { + Ok(_) => true, + Err(e) => { + println!("{}", e); + false + } + } + }) + .await +} diff --git a/src/main.rs b/src/main.rs index a09ffb3..1eac791 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,9 @@ use teloxide::dispatching::dialogue::InMemStorage; use teloxide::dispatching::UpdateHandler; use teloxide::{prelude::*, update_listeners::Polling, utils::command::BotCommands}; +mod dl; +use dl::download::download_url; + type State = (); type MyDialogue = Dialogue>; @@ -57,7 +60,9 @@ fn schema() -> UpdateHandler { use dptree::case; let command_handler = - teloxide::filter_command::().branch(case![Command::Test].endpoint(test)); + teloxide::filter_command::() + .branch(case![Command::Test].endpoint(test)) + .branch(case![Command::Download(url)].endpoint(download)); let message_handler = Update::filter_message().branch(command_handler); let raw_message_handler = Update::filter_message().branch(dptree::endpoint(handle_message)); @@ -71,6 +76,9 @@ fn schema() -> UpdateHandler { #[command(rename_rule = "lowercase")] enum Command { Test, + + #[command(alias = "dl")] + Download(String), } async fn test(bot: Bot, msg: Message) -> HandlerResult { @@ -79,6 +87,15 @@ async fn test(bot: Bot, msg: Message) -> HandlerResult { Ok(()) } +async fn download(bot: Bot, msg: Message, url: String) -> HandlerResult { + match download_url(url).await { + Ok(_) => bot.send_message(msg.chat.id, "downloaded"), + Err(_) => bot.send_message(msg.chat.id, "failed to download") + }.await?; + + Ok(()) +} + async fn handle_message(_bot: Bot, _dialogue: MyDialogue, msg: Message) -> HandlerResult { println!( "msg {} kind {:?} text {}", @@ -89,13 +106,3 @@ async fn handle_message(_bot: Bot, _dialogue: MyDialogue, msg: Message) -> Handl Ok(()) } - -async fn _answer(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> { - match cmd { - Command::Test => { - bot.send_message(msg.chat.id, "test response").await?; - } - } - - Ok(()) -}