diff --git a/Cargo.lock b/Cargo.lock
index 398e07d..2f937d8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -92,15 +92,16 @@ dependencies = [
[[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.91",
]
[[package]]
@@ -128,18 +129,19 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "axum"
-version = "0.6.20"
+version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
+checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
dependencies = [
"async-trait",
"axum-core",
- "bitflags 1.3.2",
"bytes",
"futures-util",
- "http",
- "http-body",
- "hyper",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "http-body-util",
+ "hyper 1.5.2",
+ "hyper-util",
"itoa",
"matchit",
"memchr",
@@ -151,28 +153,33 @@ dependencies = [
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
- "sync_wrapper",
+ "sync_wrapper 1.0.2",
"tokio",
- "tower",
+ "tower 0.5.2",
"tower-layer",
"tower-service",
+ "tracing",
]
[[package]]
name = "axum-core"
-version = "0.3.4"
+version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
+checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
dependencies = [
"async-trait",
"bytes",
"futures-util",
- "http",
- "http-body",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "http-body-util",
"mime",
+ "pin-project-lite",
"rustversion",
+ "sync_wrapper 1.0.2",
"tower-layer",
"tower-service",
+ "tracing",
]
[[package]]
@@ -222,6 +229,7 @@ dependencies = [
"crates_io_api",
"log",
"octocrab",
+ "orzklv",
"pretty_env_logger",
"serde",
"serde_json",
@@ -654,7 +662,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
- "http",
+ "http 0.2.12",
"indexmap",
"slab",
"tokio",
@@ -697,6 +705,17 @@ dependencies = [
"itoa",
]
+[[package]]
+name = "http"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
[[package]]
name = "http-body"
version = "0.4.6"
@@ -704,7 +723,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
- "http",
+ "http 0.2.12",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "http-body"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http 1.2.0",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
+dependencies = [
+ "bytes",
+ "futures-util",
+ "http 1.2.0",
+ "http-body 1.0.1",
"pin-project-lite",
]
@@ -743,8 +785,8 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
- "http",
- "http-body",
+ "http 0.2.12",
+ "http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
@@ -756,6 +798,25 @@ dependencies = [
"want",
]
+[[package]]
+name = "hyper"
+version = "1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "smallvec",
+ "tokio",
+]
+
[[package]]
name = "hyper-rustls"
version = "0.24.2"
@@ -763,8 +824,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
"futures-util",
- "http",
- "hyper",
+ "http 0.2.12",
+ "hyper 0.14.32",
"log",
"rustls",
"rustls-native-certs",
@@ -778,7 +839,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
- "hyper",
+ "hyper 0.14.32",
"pin-project-lite",
"tokio",
"tokio-io-timeout",
@@ -791,12 +852,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
- "hyper",
+ "hyper 0.14.32",
"native-tls",
"tokio",
"tokio-native-tls",
]
+[[package]]
+name = "hyper-util"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
+dependencies = [
+ "bytes",
+ "futures-util",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "hyper 1.5.2",
+ "pin-project-lite",
+ "tokio",
+ "tower-service",
+]
+
[[package]]
name = "iana-time-zone"
version = "0.1.61"
@@ -965,6 +1042,25 @@ dependencies = [
"icu_properties",
]
+[[package]]
+name = "include_dir"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd"
+dependencies = [
+ "include_dir_macros",
+]
+
+[[package]]
+name = "include_dir_macros"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
[[package]]
name = "indexmap"
version = "2.7.0"
@@ -1010,9 +1106,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[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",
]
@@ -1137,12 +1233,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-bigint"
version = "0.4.6"
@@ -1201,9 +1291,9 @@ dependencies = [
"either",
"futures",
"futures-util",
- "http",
- "http-body",
- "hyper",
+ "http 0.2.12",
+ "http-body 0.4.6",
+ "hyper 0.14.32",
"hyper-rustls",
"hyper-timeout",
"jsonwebtoken",
@@ -1217,7 +1307,7 @@ dependencies = [
"serde_urlencoded",
"snafu",
"tokio",
- "tower",
+ "tower 0.4.13",
"tower-http 0.4.4",
"tracing",
"url",
@@ -1273,6 +1363,20 @@ dependencies = [
"vcpkg",
]
+[[package]]
+name = "orzklv"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8129cb8be2fb2db50a1b78c25e747788ac8291d2dcda5fa7e310d32b932c79e8"
+dependencies = [
+ "async-trait",
+ "teloxide",
+ "thiserror",
+ "tokio",
+ "toml",
+ "url",
+]
+
[[package]]
name = "pem"
version = "3.0.4"
@@ -1474,9 +1578,9 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
- "http",
- "http-body",
- "hyper",
+ "http 0.2.12",
+ "http-body 0.4.6",
+ "hyper 0.14.32",
"hyper-tls",
"ipnet",
"js-sys",
@@ -1491,7 +1595,7 @@ dependencies = [
"serde",
"serde_json",
"serde_urlencoded",
- "sync_wrapper",
+ "sync_wrapper 0.1.2",
"system-configuration",
"tokio",
"tokio-native-tls",
@@ -1708,6 +1812,15 @@ dependencies = [
"serde",
]
+[[package]]
+name = "serde_spanned"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@@ -1720,6 +1833,16 @@ dependencies = [
"serde",
]
+[[package]]
+name = "serde_with"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff"
+dependencies = [
+ "serde",
+ "serde_with_macros",
+]
+
[[package]]
name = "serde_with_macros"
version = "1.5.2"
@@ -1859,6 +1982,12 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
+[[package]]
+name = "sync_wrapper"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
+
[[package]]
name = "synstructure"
version = "0.13.1"
@@ -1905,15 +2034,16 @@ checksum = "20f34339676cdcab560c9a82300c4c2581f68b9369aedf0fae86f2ff9565ff3e"
[[package]]
name = "teloxide"
-version = "0.12.2"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c63345cf32a8850ebddcdd769dc2d5193d5e231262d5dada264b79da01a664da"
+checksum = "5f79dd283eb21b90451c03fa7c7f83b9985130efb876b33bad89a2c208ccbc16"
dependencies = [
"aquamarine",
"axum",
"bytes",
"derive_more",
"dptree",
+ "either",
"futures",
"log",
"mime",
@@ -1921,23 +2051,22 @@ dependencies = [
"rand",
"serde",
"serde_json",
- "serde_with_macros",
"teloxide-core",
"teloxide-macros",
"thiserror",
"tokio",
"tokio-stream",
"tokio-util",
- "tower",
- "tower-http 0.3.5",
+ "tower 0.4.13",
+ "tower-http 0.5.2",
"url",
]
[[package]]
name = "teloxide-core"
-version = "0.9.1"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "303db260110c238e3af77bb9dff18bf7a5b5196f783059b0852aab75f91d5a16"
+checksum = "9e1642a7ef10e7af63b8298c8d13c0f986d4fc646d42649ff060359607f62f69"
dependencies = [
"bitflags 1.3.2",
"bytes",
@@ -1947,14 +2076,13 @@ dependencies = [
"futures",
"log",
"mime",
- "never",
"once_cell",
"pin-project",
"rc-box",
"reqwest",
"serde",
"serde_json",
- "serde_with_macros",
+ "serde_with",
"take_mut",
"takecell",
"thiserror",
@@ -1966,9 +2094,9 @@ dependencies = [
[[package]]
name = "teloxide-macros"
-version = "0.7.1"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f1d653b093dba5e44cada57a516f572167df37b8a619443e59c8c517bb6d804"
+checksum = "7e2d33d809c3e7161a9ab18bedddf98821245014f0a78fa4d2c9430b2ec018c1"
dependencies = [
"heck 0.4.1",
"proc-macro2",
@@ -2141,6 +2269,40 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "toml"
+version = "0.8.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.22.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
+dependencies = [
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
[[package]]
name = "tower"
version = "0.4.13"
@@ -2159,19 +2321,16 @@ dependencies = [
]
[[package]]
-name = "tower-http"
-version = "0.3.5"
+name = "tower"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858"
+checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
- "bitflags 1.3.2",
- "bytes",
"futures-core",
"futures-util",
- "http",
- "http-body",
- "http-range-header",
"pin-project-lite",
+ "sync_wrapper 1.0.2",
+ "tokio",
"tower-layer",
"tower-service",
"tracing",
@@ -2187,12 +2346,29 @@ dependencies = [
"bytes",
"futures-core",
"futures-util",
- "http",
- "http-body",
+ "http 0.2.12",
+ "http-body 0.4.6",
"http-range-header",
"iri-string",
"pin-project-lite",
- "tower",
+ "tower 0.4.13",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
+dependencies = [
+ "bitflags 2.6.0",
+ "bytes",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "http-body-util",
+ "pin-project-lite",
"tower-layer",
"tower-service",
"tracing",
@@ -2588,6 +2764,15 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+[[package]]
+name = "winnow"
+version = "0.6.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "winreg"
version = "0.50.0"
diff --git a/Cargo.toml b/Cargo.toml
index d69ad07..2d74784 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,7 +9,7 @@ repository = "https://github.com/rust-lang-uz/telegram"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-teloxide = { version = "0.12", features = [
+teloxide = { version = "0.13", features = [
"macros",
"webhooks",
"webhooks-axum",
@@ -24,6 +24,7 @@ serde_json = "1.0.108"
serde = { version = "1.0.192", features = ["derive"] }
octocrab = { version = "0.32.0" }
clap = { version = "4.5.23", features = ["derive"] }
+orzklv = { version = "0.1.8", features = ["full"] }
[profile.release]
strip = true
diff --git a/data/topics.json b/data/topics.json
index 003eb9d..2fcf667 100644
--- a/data/topics.json
+++ b/data/topics.json
@@ -1,11 +1,38 @@
-{
- "asosiy": 1,
- "learning": 26210,
- "offtopic": 9400,
- "yordam": 146749,
- "explore": 26603,
- "showroom": 26382,
- "livestreams": 22577,
- "jobs": 27940,
- "l10n": 22990
-}
+[
+ {
+ "name": "asosiy",
+ "id": 1
+ },
+ {
+ "name": "learning",
+ "id": 26210
+ },
+ {
+ "name": "yordam",
+ "id": 146749
+ },
+ {
+ "name": "explore",
+ "id": 26603
+ },
+ {
+ "name": "showroom",
+ "id": 26382
+ },
+ {
+ "name": "livestreams",
+ "id": 22577
+ },
+ {
+ "name": "jobs",
+ "id": 27940
+ },
+ {
+ "name": "l10n",
+ "id": 22990
+ },
+ {
+ "name": "offtopic",
+ "id": 0
+ }
+]
diff --git a/src/bot.rs b/src/bot.rs
index 12395e6..9e65668 100644
--- a/src/bot.rs
+++ b/src/bot.rs
@@ -31,7 +31,7 @@ pub enum Command {
Version,
/// Report offtopic
- Off,
+ Warn,
/// Useful resources
Useful,
diff --git a/src/functions/about.rs b/src/functions/about.rs
index 3005fba..07b4b1f 100644
--- a/src/functions/about.rs
+++ b/src/functions/about.rs
@@ -1,7 +1,5 @@
-use crate::{
- hooks,
- utils::{keyboard::Keyboard, message::Rustina},
-};
+use crate::hooks;
+use orzklv::telegram::{keyboard::Keyboard, topic::Topics};
use teloxide::{
payloads::SendMessageSetters,
prelude::*,
@@ -29,5 +27,7 @@ pub async fn command(bot: &Bot, msg: &Message) -> ResponseResult<()> {
pub fn keyboard() -> InlineKeyboardMarkup {
let mut keyboard = Keyboard::new();
- keyboard.url("Ochiq Havolalar", "https://github.com/rust-lang-uz/rustina")
+ keyboard
+ .url("Ochiq Havolalar", "https://github.com/rust-lang-uz/rustina")
+ .unwrap()
}
diff --git a/src/functions/check.rs b/src/functions/check.rs
index a83488b..1f1d753 100644
--- a/src/functions/check.rs
+++ b/src/functions/check.rs
@@ -1,4 +1,4 @@
-use crate::utils::message::Rustina;
+use orzklv::telegram::topic::Topics;
use teloxide::{payloads::SendMessageSetters, prelude::*, types::ParseMode};
pub async fn command(bot: &Bot, msg: &Message) -> ResponseResult<()> {
diff --git a/src/functions/groups.rs b/src/functions/groups.rs
index cfcfb86..0fbfa0f 100644
--- a/src/functions/groups.rs
+++ b/src/functions/groups.rs
@@ -1,13 +1,6 @@
-use crate::utils::{
- groups::{Group, Groups},
- keyboard::Keyboard,
- message::Rustina,
-};
-use teloxide::{
- payloads::{EditMessageTextSetters, SendMessageSetters},
- prelude::*,
- types::{InlineKeyboardMarkup, ParseMode},
-};
+use crate::utils::groups::{Group, Groups};
+use orzklv::telegram::{keyboard::Keyboard, topic::Topics};
+use teloxide::{payloads::EditMessageTextSetters, prelude::*, types::*};
static TEXT: &str = "Telegramdagi Rust Hamjamiyatlari yoki Guruhlari:\nAgar o'zingizni guruhingizni qo'shmoqchi bo'lsangiz, bizni community.json ni yangilang!";
@@ -15,7 +8,13 @@ pub async fn command(bot: &Bot, msg: &Message, groups: &Groups) -> ResponseResul
bot.send_message_tf(msg.chat.id, TEXT, msg)
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_list(groups, 1))
- .disable_web_page_preview(true)
+ .link_preview_options(LinkPreviewOptions {
+ is_disabled: true,
+ url: None,
+ prefer_small_media: false,
+ prefer_large_media: false,
+ show_above_text: false,
+ })
.await?;
Ok(())
@@ -28,11 +27,22 @@ pub async fn callback_list(
groups: &Groups,
) -> ResponseResult<()> {
if !args.is_empty() {
- if let Some(Message { id, chat, .. }) = q.message.clone() {
- bot.edit_message_text(chat.id, id, TEXT)
+ let om = match q.message.clone() {
+ Some(m) => m,
+ None => return Ok(()),
+ };
+
+ if let Some(Message { id, chat, .. }) = om.regular_message() {
+ bot.edit_message_text(chat.id, *id, TEXT)
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_list(groups, args[0].parse().unwrap_or(1)))
- .disable_web_page_preview(true)
+ .link_preview_options(LinkPreviewOptions {
+ is_disabled: true,
+ url: None,
+ prefer_small_media: false,
+ prefer_large_media: false,
+ show_above_text: false,
+ })
.await?;
} else if let Some(id) = q.inline_message_id.clone() {
bot.edit_message_text_inline(id, "Oopsie, something went wrong...")
@@ -48,8 +58,13 @@ pub async fn callback_detail(bot: &Bot, q: &CallbackQuery, args: &[&str]) -> Res
let find = groups.find_group(args[1..].join("_").to_string());
if !args.is_empty() {
- if let Some(Message { id, chat, .. }) = q.message.clone() {
- bot.edit_message_text(chat.id, id, view_detail(&find))
+ let om = match q.message.clone() {
+ Some(m) => m,
+ None => return Ok(()),
+ };
+
+ if let Some(Message { id, chat, .. }) = om.regular_message() {
+ bot.edit_message_text(chat.id, *id, view_detail(&find))
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_detail(args[0].parse().unwrap_or(1), &find))
.await?;
@@ -104,10 +119,12 @@ pub fn keyboard_detail(page: i32, data: &Option) -> InlineKeyboardMarkup
let mut keyboard = Keyboard::new();
if let Some(group) = data {
- keyboard.url("Telegram", &format!("https://t.me/{}", group.telegram));
+ keyboard
+ .url("Telegram", &format!("https://t.me/{}", group.telegram))
+ .unwrap();
if group.link.is_some() {
- keyboard.url("Web", &group.link.clone().unwrap());
+ keyboard.url("Web", &group.link.clone().unwrap()).unwrap();
}
keyboard.row();
diff --git a/src/functions/help.rs b/src/functions/help.rs
index 836a321..c0cac27 100644
--- a/src/functions/help.rs
+++ b/src/functions/help.rs
@@ -1,6 +1,7 @@
use super::start::keyboard;
-use crate::{bot::Command, utils::message::Rustina};
-use teloxide::{payloads::SendMessageSetters, prelude::*, types::ParseMode};
+use crate::bot::Command;
+use orzklv::telegram::topic::Topics;
+use teloxide::{prelude::*, types::ParseMode};
static TEXT: &[(&str, &str)] = &[
("help", "ushbu xabarni qayta ko'rsatish"),
diff --git a/src/functions/inline.rs b/src/functions/inline.rs
index 1359557..5135b4f 100644
--- a/src/functions/inline.rs
+++ b/src/functions/inline.rs
@@ -19,7 +19,13 @@ pub async fn inline(
InputMessageContent::Text(
InputMessageContentText::new(NO_INPUT)
.parse_mode(ParseMode::Html)
- .disable_web_page_preview(true),
+ .link_preview_options(LinkPreviewOptions {
+ is_disabled: true,
+ url: None,
+ prefer_small_media: false,
+ prefer_large_media: false,
+ show_above_text: false,
+ }),
),
)
.reply_markup(err_keyboard())
@@ -47,11 +53,17 @@ pub async fn inline(
"Xatolik yuz berdi!",
InputMessageContent::Text(
InputMessageContentText::new(
- format!("{} ga oid natija mavjud emas!\nIltimos, boshqattan ushbu qidirmoqchi bo'lgan paketingiz yozib qidirib ko'ring!",
+ format!("{} ga oid natija mavjud emas!\nIltimos, boshqattan ushbu qidirmoqchi bo'lgan paketingiz yozib qidirib ko'ring!",
q.query.clone())
)
.parse_mode(ParseMode::Html)
- .disable_web_page_preview(true),
+ .link_preview_options(LinkPreviewOptions {
+ is_disabled: true,
+ url: None,
+ prefer_small_media: false,
+ prefer_large_media: false,
+ show_above_text: false,
+ }),
),
)
.reply_markup(err_keyboard())
@@ -72,7 +84,13 @@ pub async fn inline(
InputMessageContent::Text(
InputMessageContentText::new(view_generate(c))
.parse_mode(ParseMode::Html)
- .disable_web_page_preview(true),
+ .link_preview_options(LinkPreviewOptions {
+ is_disabled: true,
+ url: None,
+ prefer_small_media: false,
+ prefer_large_media: false,
+ show_above_text: false,
+ }),
),
)
.description(c.description.clone().unwrap())
diff --git a/src/functions/joined.rs b/src/functions/joined.rs
index d6b83cd..489b8c9 100644
--- a/src/functions/joined.rs
+++ b/src/functions/joined.rs
@@ -1,7 +1,6 @@
+use orzklv::telegram::{timer::Timer, topic::Topics};
use teloxide::{prelude::*, types::*};
-use crate::utils::message::{delete_timer, Rustina};
-
static TEXT: &str = "Salom bo'lajak Rustacean!\n\n\
Sizlarni bu guruhda ko'rib turganimizdan mamnunmiz. Bu guruh Rust dasturlash tiliga qaratilgan hisoblanib, \
bu yerda ushbu til haqida gaplashish, savollar berish yoki o'z fikrlaringiz bilan bo'lishishingiz mumkin. \
@@ -15,7 +14,9 @@ pub async fn trigger(bot: &Bot, msg: &Message) -> ResponseResult<()> {
.parse_mode(ParseMode::Html)
.await?;
- delete_timer(bot, &message, 60 * 5).await?;
+ bot.delete_timer(message.chat.id, message.id, 60 * 5)
+ .await
+ .await?;
Ok(())
}
diff --git a/src/functions/latest.rs b/src/functions/latest.rs
index 8935a26..91fd290 100644
--- a/src/functions/latest.rs
+++ b/src/functions/latest.rs
@@ -1,7 +1,7 @@
-use crate::utils::{github::GitHub, keyboard::Keyboard, message::Rustina};
+use crate::utils::github::GitHub;
use octocrab::models::repos::Release;
+use orzklv::telegram::{keyboard::Keyboard, topic::Topics};
use teloxide::{
- payloads::SendMessageSetters,
prelude::*,
types::{InlineKeyboardMarkup, ParseMode},
};
@@ -34,5 +34,7 @@ pub fn view(release: &Release) -> String {
pub fn keyboard(release: &Release) -> InlineKeyboardMarkup {
let mut keyboard = Keyboard::new();
- keyboard.url("Ko'proq ma'lumotlar", release.html_url.as_str())
+ keyboard
+ .url("Ko'proq ma'lumotlar", release.html_url.as_str())
+ .unwrap()
}
diff --git a/src/functions/mod.rs b/src/functions/mod.rs
index b127e1b..695952e 100644
--- a/src/functions/mod.rs
+++ b/src/functions/mod.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::too_many_arguments)]
+
pub mod about;
pub mod check;
pub mod groups;
@@ -5,17 +7,17 @@ pub mod help;
pub mod inline;
pub mod joined;
pub mod latest;
-pub mod offtop;
pub mod roadmap;
pub mod rules;
pub mod start;
pub mod useful;
pub mod version;
+pub mod warn;
pub use inline::inline;
use crate::bot::Command;
-use crate::utils::{github::GitHub, groups::Groups, resources::Resources};
+use crate::utils::{github::GitHub, groups::Groups, resources::Resources, topics::Topics};
use std::error::Error;
use teloxide::{prelude::*, types::*};
@@ -26,6 +28,7 @@ pub async fn commands(
cmd: Command,
github: GitHub,
groups: Groups,
+ topics: Topics,
resources: Resources,
) -> Result<(), Box> {
let _ = match cmd {
@@ -36,7 +39,7 @@ pub async fn commands(
Command::Group => crate::functions::groups::command(&bot, &msg, &groups).await,
Command::Latest => crate::functions::latest::command(&bot, github, &msg).await,
Command::Version => crate::functions::version::command(&bot, github, &msg).await,
- Command::Off => crate::functions::offtop::command(&bot, &msg, &me).await,
+ Command::Warn => crate::functions::warn::command(&bot, &msg, &me, &topics).await,
Command::Useful => crate::functions::useful::command(&bot, &msg, &resources).await,
Command::Roadmap => crate::functions::roadmap::command(&bot, &msg).await,
Command::Check => crate::functions::check::command(&bot, &msg).await,
@@ -50,6 +53,7 @@ pub async fn callback(
q: CallbackQuery,
github: GitHub,
groups: Groups,
+ topics: Topics,
resources: Resources,
) -> Result<(), Box> {
let mut args: Vec<&str> = Vec::new();
@@ -76,6 +80,7 @@ pub async fn callback(
crate::functions::useful::callback_material_detail(&bot, &q, &args, &resources)
.await
}
+ "warn" => warn::callback(&bot, &q, &args, &topics).await,
_ => Ok(()),
};
}
@@ -84,7 +89,7 @@ pub async fn callback(
}
pub async fn triggers(bot: Bot, msg: Message) -> Result<(), Box> {
- if let Some(user) = msg.from() {
+ if let Some(ref user) = msg.from {
if let Some(username) = user.username.clone() {
if username == "Channel_Bot" {
// Try to delete message and ignore error
diff --git a/src/functions/offtop.rs b/src/functions/offtop.rs
deleted file mode 100644
index d71e4c9..0000000
--- a/src/functions/offtop.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-use crate::utils::{keyboard::Keyboard, message::Rustina};
-use teloxide::{prelude::*, types::*};
-
-static TEXT_FAIL: &str = "Ha-ha... yaxshi urinish!";
-static TEXT_NON_REPLY: &str = "↪ Reply bilan ko'rsatingchi habarni!";
-
-pub async fn command(bot: &Bot, msg: &Message, me: &Me) -> ResponseResult<()> {
- if msg.reply_to_message().is_none() {
- return {
- bot.send_message_tf(msg.chat.id, TEXT_NON_REPLY, msg)
- .await?;
- Ok(())
- };
- }
-
- // if replied person is bot itself, send fail message
- if let Some(user) = msg.reply_to_message().as_ref().unwrap().from() {
- if user.username.is_some() && user.username.clone().unwrap() == me.username() {
- return {
- bot.send_message_tf(msg.chat.id, TEXT_FAIL, msg).await?;
- Ok(())
- };
- }
- }
-
- bot.delete_message(msg.chat.id, msg.id).await?;
- bot.delete_message(msg.chat.id, msg.reply_to_message().unwrap().id)
- .await?;
-
- bot.send_message_tf(msg.chat.id, view(msg.reply_to_message().unwrap()), msg)
- .parse_mode(ParseMode::Html)
- .reply_markup(keyboard())
- .await?;
-
- Ok(())
-}
-
-pub fn view(msg: &Message) -> String {
- format!(
- "Hurmatli {},\
- \n\n\
- Tushunishim bo'yicha siz mavzudan chetlayashayabsiz. Iltimos, \
- quyidagi tugmachani bosish orqali bizning offtop guruhga o'tib oling! \
- Offtopic guruhimizda istalgan mavzuda suhbatlashish ruxsat etiladi. Boshqalarga halaqit qilmayliga 😉\
- \n\n\
- Hurmat ila, Rustina (Rastina)",
- msg.from().unwrap().id,
- msg.from().unwrap().first_name
- )
-}
-
-pub fn keyboard() -> InlineKeyboardMarkup {
- let mut keyboard = Keyboard::new();
- keyboard.url("Offtopic", "https://t.me/rustlanguz/9400")
-}
diff --git a/src/functions/roadmap.rs b/src/functions/roadmap.rs
index 87fc0a5..23df225 100644
--- a/src/functions/roadmap.rs
+++ b/src/functions/roadmap.rs
@@ -1,5 +1,5 @@
use crate::hooks;
-use crate::utils::keyboard::Keyboard;
+use orzklv::telegram::keyboard::Keyboard;
use teloxide::{
payloads::SendMessageSetters,
prelude::*,
@@ -38,7 +38,7 @@ pub fn keyboard() -> InlineKeyboardMarkup {
let mut keyboard = Keyboard::new();
for link in LINKS {
- keyboard.url(link.0, link.1);
+ keyboard.url(link.0, link.1).unwrap();
keyboard.row();
}
diff --git a/src/functions/rules.rs b/src/functions/rules.rs
index a811539..a1cfa2d 100644
--- a/src/functions/rules.rs
+++ b/src/functions/rules.rs
@@ -1,4 +1,5 @@
-use crate::{hooks, utils::keyboard::Keyboard};
+use crate::hooks;
+use orzklv::telegram::keyboard::Keyboard;
use teloxide::{
payloads::SendMessageSetters,
prelude::*,
@@ -34,5 +35,7 @@ pub async fn command(bot: &Bot, msg: &Message) -> ResponseResult<()> {
pub fn keyboard() -> InlineKeyboardMarkup {
let mut keyboard = Keyboard::new();
- keyboard.url("Guruhga qaytish", "https://t.me/rustlanguz")
+ keyboard
+ .url("Guruhga qaytish", "https://t.me/rustlanguz")
+ .unwrap()
}
diff --git a/src/functions/start.rs b/src/functions/start.rs
index 2a114fa..648b3f3 100644
--- a/src/functions/start.rs
+++ b/src/functions/start.rs
@@ -1,4 +1,4 @@
-use crate::utils::{keyboard::Keyboard, message::Rustina};
+use orzklv::telegram::{keyboard::Keyboard, topic::Topics};
use teloxide::{
payloads::SendMessageSetters,
prelude::*,
@@ -22,6 +22,6 @@ pub async fn command(bot: &Bot, msg: &Message) -> ResponseResult<()> {
pub fn keyboard() -> InlineKeyboardMarkup {
let mut keyboard = Keyboard::new();
- keyboard.url("Jamiyat", "https://t.me/rustlanguz");
- keyboard.url("Web Sahifa", "https://rust-lang.uz")
+ keyboard.url("Jamiyat", "https://t.me/rustlanguz").unwrap();
+ keyboard.url("Web Sahifa", "https://rust-lang.uz").unwrap()
}
diff --git a/src/functions/useful.rs b/src/functions/useful.rs
index 1127f42..1285da0 100644
--- a/src/functions/useful.rs
+++ b/src/functions/useful.rs
@@ -1,13 +1,6 @@
-use crate::utils::{
- keyboard::Keyboard,
- message::Rustina,
- resources::{Resource, Resources},
-};
-use teloxide::{
- payloads::SendMessageSetters,
- prelude::*,
- types::{InlineKeyboardMarkup, ParseMode},
-};
+use crate::utils::resources::{Resource, Resources};
+use orzklv::telegram::{keyboard::Keyboard, topic::Topics};
+use teloxide::{payloads::SendMessageSetters, prelude::*, types::*};
static TEXT: &str = "Rustga oid foydali materiallar:\n\
Agar o'zingizdan material qo'shmoqchi bo'lsangiz, bizni \
@@ -20,7 +13,13 @@ pub async fn command(bot: &Bot, msg: &Message, resources: &Resources) -> Respons
bot.send_message_tf(msg.chat.id, TEXT, msg)
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_list(categories))
- .disable_web_page_preview(true)
+ .link_preview_options(LinkPreviewOptions {
+ is_disabled: true,
+ url: None,
+ prefer_small_media: false,
+ prefer_large_media: false,
+ show_above_text: false,
+ })
.await?;
Ok(())
@@ -33,11 +32,22 @@ pub async fn callback_list(
) -> ResponseResult<()> {
let categories = resources.get_keys();
- if let Some(Message { id, chat, .. }) = q.message.clone() {
- bot.edit_message_text(chat.id, id, TEXT)
+ let om = match q.message.clone() {
+ Some(m) => m,
+ None => return Ok(()),
+ };
+
+ if let Some(Message { id, chat, .. }) = om.regular_message() {
+ bot.edit_message_text(chat.id, *id, TEXT)
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_list(categories))
- .disable_web_page_preview(true)
+ .link_preview_options(LinkPreviewOptions {
+ is_disabled: true,
+ url: None,
+ prefer_small_media: false,
+ prefer_large_media: false,
+ show_above_text: false,
+ })
.await?;
} else if let Some(id) = q.inline_message_id.clone() {
bot.edit_message_text_inline(id, "Oopsie, something went wrong...")
@@ -56,8 +66,13 @@ pub async fn callback_category_list(
let find = resources.get_materials(args.join("_").as_str()).unwrap();
if !args.is_empty() {
- if let Some(Message { id, chat, .. }) = q.message.clone() {
- bot.edit_message_text(chat.id, id, view_category_list(&args.join(" ")))
+ let om = match q.message.clone() {
+ Some(m) => m,
+ None => return Ok(()),
+ };
+
+ if let Some(Message { id, chat, .. }) = om.regular_message() {
+ bot.edit_message_text(chat.id, *id, view_category_list(&args.join(" ")))
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_category_list(find, args.join("_")))
.await?;
@@ -81,8 +96,13 @@ pub async fn callback_material_detail(
.unwrap();
if !args.is_empty() {
- if let Some(Message { id, chat, .. }) = q.message.clone() {
- bot.edit_message_text(chat.id, id, view_material_detail(find))
+ let om = match q.message.clone() {
+ Some(m) => m,
+ None => return Ok(()),
+ };
+
+ if let Some(Message { id, chat, .. }) = om.regular_message() {
+ bot.edit_message_text(chat.id, *id, view_material_detail(find))
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_material_detail(find, args[1..].join("_")))
.await?;
@@ -148,7 +168,7 @@ pub fn keyboard_category_list(material: &[Resource], category: String) -> Inline
pub fn keyboard_material_detail(resource: &Resource, category: String) -> InlineKeyboardMarkup {
let mut keyboard = Keyboard::new();
- keyboard.url("Web Sahifasi", &resource.link);
+ keyboard.url("Web Sahifasi", &resource.link).unwrap();
keyboard.row();
keyboard.text("🔙 Orqaga", &format!("category_{}", category));
diff --git a/src/functions/version.rs b/src/functions/version.rs
index 1fc78c0..5356385 100644
--- a/src/functions/version.rs
+++ b/src/functions/version.rs
@@ -1,5 +1,6 @@
-use crate::utils::{github::GitHub, keyboard::Keyboard, message::Rustina};
+use crate::utils::github::GitHub;
use octocrab::models::repos::Release;
+use orzklv::telegram::{keyboard::Keyboard, topic::Topics};
use teloxide::{
payloads::SendMessageSetters,
prelude::*,
@@ -31,8 +32,13 @@ pub async fn callback_list(
let next_page = github.get_list(page + 1).await.unwrap();
if !args.is_empty() {
- if let Some(Message { id, chat, .. }) = q.message.clone() {
- bot.edit_message_text(chat.id, id, TEXT)
+ let om = match q.message.clone() {
+ Some(m) => m,
+ None => return Ok(()),
+ };
+
+ if let Some(Message { id, chat, .. }) = om.regular_message() {
+ bot.edit_message_text(chat.id, *id, TEXT)
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_list(page, versions, Some(next_page)))
.await?;
@@ -54,9 +60,14 @@ pub async fn callback_detail(
let page = args[0].parse::().unwrap();
let version: Release = github.get_detail(args[1]).await.unwrap();
+ let om = match q.message.clone() {
+ Some(m) => m,
+ None => return Ok(()),
+ };
+
if !args.is_empty() {
- if let Some(Message { id, chat, .. }) = q.message.clone() {
- bot.edit_message_text(chat.id, id, view_detail(&version))
+ if let Some(Message { id, chat, .. }) = om.regular_message() {
+ bot.edit_message_text(chat.id, *id, view_detail(&version))
.parse_mode(ParseMode::Html)
.reply_markup(keyboard_detail(page, version))
.await?;
@@ -113,7 +124,9 @@ pub fn keyboard_list(
pub fn keyboard_detail(page: u32, release: Release) -> InlineKeyboardMarkup {
let mut keyboard = Keyboard::new();
- keyboard.url("📝 GitHub da o'qish", release.html_url.as_str());
+ keyboard
+ .url("📝 GitHub da o'qish", release.html_url.as_str())
+ .unwrap();
keyboard.row();
keyboard.text("🔙 Orqaga", &format!("version_{}", page));
diff --git a/src/functions/warn.rs b/src/functions/warn.rs
new file mode 100644
index 0000000..efd4980
--- /dev/null
+++ b/src/functions/warn.rs
@@ -0,0 +1,349 @@
+// Nigga won't let me use cloned instance,
+// but forcefully copy from instance that
+// doesn't fucking implement Copy trait
+#![allow(clippy::clone_on_copy)]
+
+use crate::utils::topics::Topics;
+use orzklv::{
+ string::Transform,
+ telegram::{keyboard::Keyboard, topic::Topics as TopicsTrait},
+};
+use std::fmt::Display;
+use teloxide::{prelude::*, types::*};
+
+static TEXT_FAIL: &str = "Ha-ha... yaxshi urinish!";
+static TEXT_NON_REPLY: &str = "↪ Reply bilan ko'rsatingchi habarni!";
+static NON_COMMUNITY: &str = "Ebe hay, biz O'zbek Rust hamjamiyati guruhida emasga o'xshaymiz...";
+
+pub async fn command(bot: &Bot, msg: &Message, me: &Me, topics: &Topics) -> ResponseResult<()> {
+ // if chat is not rust uzbekistan, delete
+ if msg.chat.id != ChatId(-1001518595284) {
+ return {
+ bot.send_message_tf(msg.chat.id, NON_COMMUNITY, msg).await?;
+ Ok(())
+ };
+ }
+
+ // try to delete the message that tried to trigger
+ let attempt = bot.delete_message(msg.chat.id, msg.id).await;
+ match attempt {
+ Ok(_) => {}
+ Err(_) => {
+ bot.send_message_tf(
+ msg.chat.id,
+ "Ebe hay, men habarlar o'chirish uchun yetarlicha imtiyozim yo'q!",
+ msg,
+ )
+ .await?;
+ return Ok(());
+ }
+ }
+
+ let reply_to = match msg.reply_to_message() {
+ Some(m) => m,
+ None => {
+ return {
+ bot.send_message_tf(msg.chat.id, TEXT_NON_REPLY, msg)
+ .await?;
+
+ Ok(())
+ }
+ }
+ };
+
+ // if there's no replied message, warn
+ if msg.thread_id.is_some() && (msg.id == reply_to.id) {
+ return {
+ bot.send_message_tf(msg.chat.id, TEXT_NON_REPLY, msg)
+ .await?;
+ Ok(())
+ };
+ }
+
+ // if replied person is bot itself, send a fail message
+ if let Some(user) = &reply_to.from {
+ if let Some(username) = &user.username {
+ if username == me.username() {
+ return {
+ bot.send_message_tf(msg.chat.id, TEXT_FAIL, msg).await?;
+ Ok(())
+ };
+ }
+ }
+ }
+
+ let replied_person = match &reply_to.from {
+ None => {
+ bot.send_message_tf(
+ msg.chat.id,
+ "Hmmm, qiziq odam ekan reply qilingan odam...",
+ msg,
+ )
+ .await?;
+
+ return Ok(());
+ }
+ Some(p) => p,
+ };
+
+ let from = match &msg.from {
+ None => {
+ bot.send_message_tf(
+ msg.chat.id,
+ "Hmmm, qiziq odam ekan reply qilgan odam...",
+ msg,
+ )
+ .await?;
+
+ return Ok(());
+ }
+ Some(p) => p,
+ };
+
+ let conclusion = bot.send_message_tf(
+ msg.chat.id,
+ format!(
+ "Xo'sh, {}. Qaysi mavzu taraflama yozgan odam chetlashdi?",
+ from.id,
+ from.first_name
+ ),
+ msg,
+ )
+ .parse_mode(ParseMode::Html)
+ .reply_markup(keyboard(
+ topics.list(),
+ from.id,
+ &replied_person.id,
+ &replied_person.first_name,
+ &reply_to.id
+ ))
+ .await;
+
+ match conclusion {
+ Ok(_) => {}
+ Err(_) => {
+ bot.send_message(
+ msg.chat.id,
+ format!(
+ "Xo'sh, {}. Qaysi mavzu taraflama yozgan odam chetlashdi?",
+ from.id,
+ from.first_name
+ )
+ )
+ .parse_mode(ParseMode::Html)
+ .reply_markup(keyboard(
+ topics.list(),
+ from.id,
+ &replied_person.id,
+ &replied_person.first_name,
+ &reply_to.id // replied message id for deleting & forwarding
+ ))
+ .await?;
+ }
+ };
+
+ Ok(())
+}
+
+pub async fn callback(
+ bot: &Bot,
+ q: &CallbackQuery,
+ args: &[&str],
+ topics: &Topics,
+) -> ResponseResult<()> {
+ let message = match q.regular_message() {
+ Some(m) => m,
+ None => {
+ return {
+ bot.send_message(
+ ChatId(-1001518595284),
+ "Qaysidir thread da xabarni tushuna olmadim, akalar meni loglarim qarab ko'rasizlarmi?",
+ )
+ .message_thread_id(ThreadId(MessageId(255895)))
+ .await?;
+
+ Ok(())
+ }
+ }
+ };
+
+ let replied_person = UserId(match args[0].parse::() {
+ Ok(r) => r,
+ Err(_) => {
+ return {
+ bot.send_message_tf(
+ message.chat.id,
+ "Hmmm, qiziq odam ekan reply qilgan odam...",
+ message,
+ )
+ .await?;
+ Ok(())
+ }
+ }
+ });
+
+ if q.from.id != replied_person {
+ bot.answer_callback_query(q.id.clone())
+ .text("Sen chaqirmadingku komandani! Nimaga o'z boshimchalik qilayabsan...")
+ .show_alert(true)
+ .send()
+ .await?;
+
+ return Ok(());
+ }
+
+ let title = args[1];
+ let code = topics.get(title);
+ let sender = (args[2], args[3]);
+ let replied_message = MessageId(match args[4].parse::() {
+ Ok(a) => a,
+ Err(_) => {
+ return {
+ bot.send_message_tf(
+ message.chat.id,
+ "Reply qilingan xabarni ochib o'qiy olmadim, uzrasizlar-a?",
+ message,
+ )
+ .await?;
+
+ Ok(())
+ }
+ }
+ });
+
+ match code {
+ None => {
+ bot.delete_message(message.chat.id, message.id).await?;
+ bot.send_message_tf(
+ message.chat.id,
+ "Unaqa topic borga o'xshamaydi do'stlar...",
+ message,
+ )
+ .await?;
+
+ Ok(())
+ }
+ Some(c) => {
+ bot.delete_message(message.chat.id, message.id).await?;
+
+ let parsed_topic = match i32::try_from(c.clone()) {
+ Ok(m) => m,
+ Err(_) => {
+ return {
+ bot.send_message_tf(
+ message.chat.id,
+ "Xabarni o'chirishdan avval qayerga jo'natishni tushunmadim...",
+ message,
+ )
+ .await?;
+
+ Ok(())
+ }
+ }
+ };
+
+ let forward = bot.forward_message(message.chat.id, message.chat.id, replied_message);
+ match parsed_topic {
+ 1 => {
+ forward.await?;
+ }
+ _ => {
+ forward
+ .message_thread_id(ThreadId(MessageId(parsed_topic)))
+ .await?;
+ }
+ };
+
+ // try to delete the replied message
+ let attempt = bot.delete_message(message.chat.id, replied_message).await;
+ match attempt {
+ Ok(_) => {}
+ Err(_) => {
+ bot.send_message_tf(
+ message.chat.id,
+ "Ebe hay, men habarlar o'chirish uchun yetarlicha imtiyozim yo'q!",
+ message,
+ )
+ .await?;
+ return Ok(());
+ }
+ }
+
+ bot.send_message_tf(
+ message.chat.id,
+ view_detail(sender, title.to_string()),
+ message,
+ )
+ .reply_markup(callback_keyboard(title, c))
+ .parse_mode(ParseMode::Html)
+ .await?;
+
+ Ok(())
+ }
+ }
+}
+
+pub fn view_detail(from: (&str, &str), topic: String) -> String {
+ format!(
+ "Hurmatli {},\
+ \n\n\
+ Tushunishim bo'yicha siz mavzudan chetlayashayabsiz. Iltimos, \
+ quyidagi tugmachani bosish orqali bizning {} guruhga o'tib oling! \
+ {} guruhimizda ushbu mavzuga oid narsalar haqida suhbatlashish ruxsat etiladi. \
+ Boshqalarga halaqit qilmayliga 😉\
+ \n\n\
+ Hurmat ila, Rustina",
+ from.0,
+ from.1,
+ topic,
+ topic.capitalize()
+ )
+}
+
+pub fn keyboard(
+ list: Vec,
+ owner: UserId,
+ replied: &UserId,
+ name: T,
+ replied_message: &MessageId,
+) -> InlineKeyboardMarkup
+where
+ T: AsRef + Display,
+{
+ let mut keyboard = Keyboard::new();
+
+ for (index, topic) in list.iter().enumerate() {
+ keyboard.text(
+ topic,
+ &format!(
+ "warn_{}_{}_{}_{}_{}",
+ owner.0, topic, replied.0, name, replied_message
+ ),
+ );
+
+ if index % 2 == 1 {
+ keyboard.row();
+ }
+ }
+
+ keyboard.get()
+}
+
+pub fn callback_keyboard(title: T, topic: &u32) -> InlineKeyboardMarkup
+where
+ T: AsRef + Display + ToString,
+{
+ let mut keyboard = Keyboard::new();
+
+ let url: String = match topic {
+ 0 => "https://t.me/flossuzc".to_string(),
+ _ => format!("https://t.me/rustlanguz/{}", topic),
+ };
+
+ keyboard
+ .url(
+ &format!("{} Chat", title.to_string().capitalize()),
+ &url.to_string(),
+ )
+ .unwrap()
+}
diff --git a/src/hooks/is_private.rs b/src/hooks/is_private.rs
index 4843501..73466ec 100644
--- a/src/hooks/is_private.rs
+++ b/src/hooks/is_private.rs
@@ -4,16 +4,15 @@ use teloxide::{
types::{InlineKeyboardMarkup, ParseMode},
};
-use crate::utils::{
- keyboard::Keyboard,
- message::{delete_timer, Rustina},
-};
+use orzklv::telegram::{keyboard::Keyboard, timer::Timer, topic::Topics};
static TEXT: &str = "⚠️ Bu komanda faqat shaxsiy chat uchun!";
pub fn keyboard() -> InlineKeyboardMarkup {
let mut keyboard: Keyboard = Keyboard::new();
- keyboard.url("Shaxsiy Chat", "https://t.me/rustinabot")
+ keyboard
+ .url("Shaxsiy Chat", "https://t.me/rustinabot")
+ .unwrap()
}
pub async fn is_private(bot: &Bot, msg: &Message) -> ResponseResult {
@@ -32,7 +31,9 @@ pub async fn is_private(bot: &Bot, msg: &Message) -> ResponseResult {
.reply_markup(keyboard())
.await?;
- delete_timer(bot, &message, 10).await?;
+ bot.delete_timer(message.chat.id, message.id, 10)
+ .await
+ .await?;
Ok(false)
}
diff --git a/src/main.rs b/src/main.rs
index be64dff..4dbd595 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
use bot::bot::dispatch;
use bot::config::{Config, Field};
-use bot::utils::{clog, github::GitHub};
+use bot::utils::{clog, github::GitHub, topics::Topics};
use bot::utils::{groups::Groups, resources::Resources};
use bot::{Cli, Commands};
use clap::Parser;
@@ -16,6 +16,7 @@ async fn main() -> Result<(), Box> {
// Global instances
let groups = Groups::new();
+ let topics = Topics::new();
let resources = Resources::new();
let mut config = Config::default();
let crates_client = AsyncClient::new(
@@ -43,7 +44,7 @@ async fn main() -> Result<(), Box> {
let github = GitHub::new(Some(config.github));
// Dependencies
- let deps = dptree::deps![crates_client, github, groups, resources];
+ let deps = dptree::deps![crates_client, github, groups, resources, topics];
let mut dispatcher = dispatch(&bot, deps);
@@ -77,7 +78,7 @@ async fn main() -> Result<(), Box> {
let github = GitHub::new(Some(config.github));
// Dependencies
- let deps = dptree::deps![crates_client, github, groups, resources];
+ let deps = dptree::deps![crates_client, github, groups, resources, topics];
let mut dispatcher = dispatch(&bot, deps);
@@ -105,7 +106,7 @@ async fn main() -> Result<(), Box> {
let github = GitHub::new(std::env::var("GITHUB_TOKEN").ok());
// Dependencies
- let deps = dptree::deps![crates_client, github, groups, resources];
+ let deps = dptree::deps![crates_client, github, groups, resources, topics];
let mut dispatcher = dispatch(&bot, deps);
diff --git a/src/utils/inlines.rs b/src/utils/inlines.rs
index 62d0167..b1b2230 100644
--- a/src/utils/inlines.rs
+++ b/src/utils/inlines.rs
@@ -1,5 +1,5 @@
-use super::keyboard::Keyboard;
use crates_io_api::Crate;
+use orzklv::telegram::keyboard::Keyboard;
use teloxide::types::*;
pub static NO_INPUT: &str = r#"
@@ -7,7 +7,7 @@ pub static NO_INPUT: &str = r#"
Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz crates.io Rust dasturlash tili paketlar registridan web sahifani ishlatmasdan turib telegram o'zida kerakli paketlarni qidirishingiz mumkin! Ushbu qulaylik yozish uchun o'zimizning API SDK ishlatildi.
-Qidirishni boshlash uchun:
+Qidirishni boshlash uchun:
@rustaceanbot <nomi>
"#;
@@ -62,23 +62,31 @@ pub fn view_generate(c: &Crate) -> String {
pub fn kb_generate(c: &Crate) -> InlineKeyboardMarkup {
let mut keyboard = Keyboard::new();
- keyboard.url(
- "Crate",
- format!("https://crates.io/crates/{}", c.name).as_str(),
- );
+ keyboard
+ .url(
+ "Crate",
+ format!("https://crates.io/crates/{}", c.name).as_str(),
+ )
+ .unwrap();
if c.homepage.is_some() {
- keyboard.url("Asosiy", &c.homepage.clone().unwrap());
+ keyboard
+ .url("Asosiy", &c.homepage.clone().unwrap())
+ .unwrap();
keyboard.row();
}
if c.documentation.is_some() {
- keyboard.url("Dokumentatsiya", &c.documentation.clone().unwrap());
+ keyboard
+ .url("Dokumentatsiya", &c.documentation.clone().unwrap())
+ .unwrap();
keyboard.row();
}
if c.repository.is_some() {
- keyboard.url("Repozitoriya", &c.repository.clone().unwrap());
+ keyboard
+ .url("Repozitoriya", &c.repository.clone().unwrap())
+ .unwrap();
keyboard.row();
}
diff --git a/src/utils/keyboard.rs b/src/utils/keyboard.rs
deleted file mode 100644
index e1ebf4d..0000000
--- a/src/utils/keyboard.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-use teloxide::types::{InlineKeyboardButton, InlineKeyboardMarkup};
-use url::Url;
-
-#[derive(Clone)]
-pub struct Keyboard {
- keyboard: Vec>,
-}
-
-impl Default for Keyboard {
- fn default() -> Self {
- Keyboard::new()
- }
-}
-
-impl Keyboard {
- pub fn new() -> Self {
- Self {
- keyboard: vec![vec![]],
- }
- }
-
- /// Add a text callback to keyboard
- pub fn text(&mut self, text: &str, callback: &str) -> InlineKeyboardMarkup {
- self.keyboard
- .last_mut()
- .unwrap()
- .push(InlineKeyboardButton::callback(text, callback));
-
- self.get()
- }
-
- /// Add an url button to keyboard
- pub fn url(&mut self, text: &str, url: &str) -> InlineKeyboardMarkup {
- let parsed_url = Url::parse(url).unwrap();
-
- self.keyboard
- .last_mut()
- .unwrap()
- .push(InlineKeyboardButton::url(text, parsed_url));
-
- self.get()
- }
-
- pub fn switch_inline_current(&mut self, text: &str, query: &str) -> InlineKeyboardMarkup {
- self.keyboard.last_mut().unwrap().push(
- InlineKeyboardButton::switch_inline_query_current_chat(text, query),
- );
-
- self.get()
- }
-
- /// Add next buttons from new line
- pub fn row(&mut self) -> InlineKeyboardMarkup {
- self.keyboard.push(vec![]);
- self.get()
- }
-
- /// Return the final result
- pub fn get(&self) -> InlineKeyboardMarkup {
- InlineKeyboardMarkup::new(self.keyboard.clone())
- }
-}
diff --git a/src/utils/message.rs b/src/utils/message.rs
deleted file mode 100644
index 7028fb5..0000000
--- a/src/utils/message.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-use teloxide::{
- prelude::*,
- requests::JsonRequest,
- types::*,
- {payloads, payloads::*},
-};
-
-pub trait Rustina {
- type Err: std::error::Error + Send;
- type SendMessageTF: Request;
-
- /// For Telegram documentation see [`SendMessage`].
- fn send_message_tf(&self, chat_id: C, text: T, message: &Message) -> Self::SendMessageTF
- where
- C: Into,
- T: Into;
-}
-
-impl Rustina for Bot {
- type Err = teloxide::errors::RequestError;
- type SendMessageTF = JsonRequest;
-
- fn send_message_tf(&self, chat_id: C, text: T, message: &Message) -> Self::SendMessageTF
- where
- C: Into,
- T: Into,
- {
- match message.thread_id {
- Some(thread_id) => {
- Self::SendMessageTF::new(self.clone(), payloads::SendMessage::new(chat_id, text))
- .message_thread_id(thread_id)
- }
- None => {
- Self::SendMessageTF::new(self.clone(), payloads::SendMessage::new(chat_id, text))
- }
- }
- }
-}
-
-// Delete a message after a certain time
-pub async fn delete_timer(bot: &Bot, message: &Message, timer: u64) -> ResponseResult<()> {
- let bot = bot.clone();
- let message = message.clone();
-
- tokio::spawn(async move {
- tokio::time::sleep(tokio::time::Duration::from_secs(timer)).await;
- match bot.delete_message(message.chat.id, message.id).await {
- Ok(_) => {}
- Err(_) => {}
- };
- });
-
- Ok(())
-}
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index 70c2b4b..2f6bf18 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -1,9 +1,8 @@
pub mod github;
pub mod groups;
pub mod inlines;
-pub mod keyboard;
-pub mod message;
pub mod resources;
+pub mod topics;
pub fn clog(title: &str, message: &str) {
let title = if title.len() > 12 {
diff --git a/src/utils/topics.rs b/src/utils/topics.rs
new file mode 100644
index 0000000..f6fd195
--- /dev/null
+++ b/src/utils/topics.rs
@@ -0,0 +1,50 @@
+use std::collections::HashMap;
+
+const CONTENT: &str = include_str!("../../data/topics.json");
+
+#[derive(serde::Deserialize)]
+pub struct Content {
+ name: String,
+ id: Option,
+}
+
+type Contents = Vec;
+
+#[derive(Clone, Debug)]
+pub struct Topics {
+ topics: HashMap,
+}
+
+impl Default for Topics {
+ fn default() -> Self {
+ Topics::new()
+ }
+}
+
+impl Topics {
+ pub fn new() -> Topics {
+ let mut result: HashMap = HashMap::new();
+ let content = serde_json::from_str::(CONTENT).unwrap();
+
+ for item in content {
+ match item.id {
+ Some(id) => result.insert(item.name, id),
+ None => result.insert(item.name, 1),
+ };
+ }
+
+ Topics { topics: result }
+ }
+
+ pub fn add(&mut self, topic: String, id: u32) {
+ self.topics.insert(topic, id);
+ }
+
+ pub fn get(&self, topic: &str) -> Option<&u32> {
+ self.topics.get(topic)
+ }
+
+ pub fn list(&self) -> Vec {
+ self.topics.keys().cloned().collect()
+ }
+}