diff --git a/Cargo.lock b/Cargo.lock
index c932230..427aee8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,6 +26,21 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "aquamarine"
version = "0.1.12"
@@ -39,6 +54,23 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "arc-swap"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
+
+[[package]]
+name = "async-trait"
+version = "0.1.74"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
[[package]]
name = "autocfg"
version = "1.1.0"
@@ -111,8 +143,11 @@ version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
"num-traits",
"serde",
+ "windows-targets",
]
[[package]]
@@ -189,6 +224,15 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "deranged"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"
+dependencies = [
+ "powerfmt",
+]
+
[[package]]
name = "derive_more"
version = "0.99.17"
@@ -202,6 +246,12 @@ dependencies = [
"syn 1.0.109",
]
+[[package]]
+name = "doc-comment"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
+
[[package]]
name = "dptree"
version = "0.3.0"
@@ -466,6 +516,12 @@ dependencies = [
"pin-project-lite",
]
+[[package]]
+name = "http-range-header"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f"
+
[[package]]
name = "httparse"
version = "1.8.0"
@@ -508,6 +564,34 @@ dependencies = [
"want",
]
+[[package]]
+name = "hyper-rustls"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
+dependencies = [
+ "futures-util",
+ "http",
+ "hyper",
+ "log",
+ "rustls",
+ "rustls-native-certs",
+ "tokio",
+ "tokio-rustls",
+]
+
+[[package]]
+name = "hyper-timeout"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
+dependencies = [
+ "hyper",
+ "pin-project-lite",
+ "tokio",
+ "tokio-io-timeout",
+]
+
[[package]]
name = "hyper-tls"
version = "0.5.0"
@@ -521,6 +605,29 @@ dependencies = [
"tokio-native-tls",
]
+[[package]]
+name = "iana-time-zone"
+version = "0.1.58"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -553,6 +660,16 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
+[[package]]
+name = "iri-string"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
[[package]]
name = "is-terminal"
version = "0.4.9"
@@ -588,6 +705,20 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "jsonwebtoken"
+version = "9.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "155c4d7e39ad04c172c5e3a99c434ea3b4a7ba7960b38ecd562b270b097cce09"
+dependencies = [
+ "base64",
+ "pem",
+ "ring",
+ "serde",
+ "serde_json",
+ "simple_asn1",
+]
+
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -678,6 +809,27 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
+[[package]]
+name = "num-bigint"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
[[package]]
name = "num-traits"
version = "0.2.17"
@@ -706,6 +858,43 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "octocrab"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abfeeafb5fa0da7046229ec3c7b3bd2981aae05c549871192c408d59fc0fffd5"
+dependencies = [
+ "arc-swap",
+ "async-trait",
+ "base64",
+ "bytes",
+ "cfg-if",
+ "chrono",
+ "either",
+ "futures",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-rustls",
+ "hyper-timeout",
+ "jsonwebtoken",
+ "once_cell",
+ "percent-encoding",
+ "pin-project",
+ "secrecy",
+ "serde",
+ "serde_json",
+ "serde_path_to_error",
+ "serde_urlencoded",
+ "snafu",
+ "tokio",
+ "tower",
+ "tower-http",
+ "tracing",
+ "url",
+]
+
[[package]]
name = "once_cell"
version = "1.18.0"
@@ -756,6 +945,16 @@ dependencies = [
"vcpkg",
]
+[[package]]
+name = "pem"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3163d2912b7c3b52d651a055f2c7eec9ba5cd22d26ef75b8dd3a59980b185923"
+dependencies = [
+ "base64",
+ "serde",
+]
+
[[package]]
name = "percent-encoding"
version = "2.3.0"
@@ -800,6 +999,12 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
[[package]]
name = "pretty_env_logger"
version = "0.5.0"
@@ -940,6 +1145,20 @@ dependencies = [
"winreg",
]
+[[package]]
+name = "ring"
+version = "0.17.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b"
+dependencies = [
+ "cc",
+ "getrandom",
+ "libc",
+ "spin",
+ "untrusted",
+ "windows-sys",
+]
+
[[package]]
name = "rustc-demangle"
version = "0.1.23"
@@ -961,6 +1180,7 @@ version = "0.1.0"
dependencies = [
"crates_io_api",
"log",
+ "octocrab",
"pretty_env_logger",
"serde",
"serde_json",
@@ -983,6 +1203,49 @@ dependencies = [
"windows-sys",
]
+[[package]]
+name = "rustls"
+version = "0.21.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9"
+dependencies = [
+ "log",
+ "ring",
+ "rustls-webpki",
+ "sct",
+]
+
+[[package]]
+name = "rustls-native-certs"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
+dependencies = [
+ "openssl-probe",
+ "rustls-pemfile",
+ "schannel",
+ "security-framework",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+dependencies = [
+ "base64",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.101.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
[[package]]
name = "ryu"
version = "1.0.15"
@@ -1004,6 +1267,25 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+[[package]]
+name = "sct"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "secrecy"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e"
+dependencies = [
+ "zeroize",
+]
+
[[package]]
name = "security-framework"
version = "2.9.2"
@@ -1107,6 +1389,18 @@ dependencies = [
"libc",
]
+[[package]]
+name = "simple_asn1"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085"
+dependencies = [
+ "num-bigint",
+ "num-traits",
+ "thiserror",
+ "time",
+]
+
[[package]]
name = "slab"
version = "0.4.9"
@@ -1116,6 +1410,29 @@ dependencies = [
"autocfg",
]
+[[package]]
+name = "snafu"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6"
+dependencies = [
+ "backtrace",
+ "doc-comment",
+ "snafu-derive",
+]
+
+[[package]]
+name = "snafu-derive"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
[[package]]
name = "socket2"
version = "0.4.10"
@@ -1136,6 +1453,12 @@ dependencies = [
"windows-sys",
]
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+
[[package]]
name = "strsim"
version = "0.10.0"
@@ -1308,6 +1631,35 @@ dependencies = [
"syn 2.0.39",
]
+[[package]]
+name = "time"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5"
+dependencies = [
+ "deranged",
+ "itoa",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
+[[package]]
+name = "time-macros"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
+dependencies = [
+ "time-core",
+]
+
[[package]]
name = "tinyvec"
version = "1.6.0"
@@ -1341,6 +1693,16 @@ dependencies = [
"windows-sys",
]
+[[package]]
+name = "tokio-io-timeout"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
+dependencies = [
+ "pin-project-lite",
+ "tokio",
+]
+
[[package]]
name = "tokio-macros"
version = "2.2.0"
@@ -1362,6 +1724,16 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "tokio-rustls"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
+dependencies = [
+ "rustls",
+ "tokio",
+]
+
[[package]]
name = "tokio-stream"
version = "0.1.14"
@@ -1387,6 +1759,50 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "tower"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project",
+ "pin-project-lite",
+ "tokio",
+ "tokio-util",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140"
+dependencies = [
+ "bitflags 2.4.1",
+ "bytes",
+ "futures-core",
+ "futures-util",
+ "http",
+ "http-body",
+ "http-range-header",
+ "iri-string",
+ "pin-project-lite",
+ "tower",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
+
[[package]]
name = "tower-service"
version = "0.3.2"
@@ -1399,10 +1815,23 @@ version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
+ "log",
"pin-project-lite",
+ "tracing-attributes",
"tracing-core",
]
+[[package]]
+name = "tracing-attributes"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.39",
+]
+
[[package]]
name = "tracing-core"
version = "0.1.32"
@@ -1448,6 +1877,12 @@ dependencies = [
"tinyvec",
]
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
[[package]]
name = "url"
version = "2.4.1"
@@ -1616,6 +2051,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+[[package]]
+name = "windows-core"
+version = "0.51.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
+dependencies = [
+ "windows-targets",
+]
+
[[package]]
name = "windows-sys"
version = "0.48.0"
@@ -1691,3 +2135,9 @@ dependencies = [
"cfg-if",
"windows-sys",
]
+
+[[package]]
+name = "zeroize"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
diff --git a/Cargo.toml b/Cargo.toml
index 3c17fb6..f1a754b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,3 +15,4 @@ crates_io_api = "0.8.2"
uuid = { version = "1.5.0", features = ["v4"] }
serde_json = "1.0.108"
serde = { version = "1.0.192", features = ["derive"] }
+octocrab = { version = "0.32.0" }
diff --git a/delta/latest.ts b/delta/latest.ts
deleted file mode 100644
index 38d30b3..0000000
--- a/delta/latest.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { Composer, Context, InlineKeyboard } from "../deps.ts";
-import type { Release } from "../types/Github.d.ts";
-import { last } from "../utils/generator.ts";
-import hecker from "../utils/checker.ts";
-import { reply } from "../utils/sender.ts";
-
-const composer = new Composer();
-
-export const message = async (data: Release) =>
- // make a message about the release date of the new release
- `Hozirgi eng oxirgi versiya bu ${data.tag_name} va ushbu reliz ${
- new Date(data.published_at).toLocaleDateString("uz")
- }
da e'lon qilingan ${data.author.login} tomonidan` +
- `\n` +
- `\n` +
- `Ushbu oxirgi relizni o'rnatish uchun terminalingizda rustup update
buyrug'ini ishga tushuring!`;
-
-export const keyboard = (data: Release) =>
- new InlineKeyboard().url("Ko'proq ma'lumotlar", data.html_url);
-
-composer.command("last", async (ctx: Context): Promise => {
- const req = await last();
- await reply(ctx, await message(req), keyboard(req));
-});
-
-export default composer;
diff --git a/delta/mod.ts b/delta/mod.ts
index bc91709..d760e89 100644
--- a/delta/mod.ts
+++ b/delta/mod.ts
@@ -3,15 +3,11 @@ import { Bot } from "../deps.ts";
import channel from "./channel.ts";
import trigger from "./trigger.ts";
import useful from "./useful.ts";
-import latest from "./latest.ts";
-import version from "./version.ts";
export default async (bot: Bot) => {
await bot
.use(which)
.use(useful)
- .use(latest)
- .use(version)
.use(trigger)
.use(channel);
};
diff --git a/delta/version.ts b/delta/version.ts
deleted file mode 100644
index ef5a680..0000000
--- a/delta/version.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import { Composer, Context, InlineKeyboard } from "../deps.ts";
-import { finder, pager as generator } from "../utils/generator.ts";
-import hecker from "../utils/checker.ts";
-import { reply } from "../utils/sender.ts";
-
-const composer = new Composer();
-const ctxMenuText = "Rust Dasturlash tili versiyalari:";
-
-composer.command("version", async (ctx: Context): Promise => {
- const keyboard = new InlineKeyboard();
-
- for (const release of await generator(1)) {
- keyboard.text(
- release.tag_name,
- `changelog_${1}_${release.id}`,
- ).row();
- }
-
- if ((await generator(2)).length > 0) {
- keyboard.text(`Keyingi ➡️`, `version_2`);
- }
-
- await reply(ctx, ctxMenuText, keyboard, {
- disable_web_page_preview: true,
- });
-});
-
-composer.callbackQuery(/^version_(\d+)$/, async (ctx: Context) => {
- const page = Number(ctx.match![1]);
- const keyboard = new InlineKeyboard();
-
- for (const release of await generator(page)) {
- keyboard.text(
- release.tag_name,
- `changelog_${page}_${release.id}`,
- ).row();
- }
-
- if (page > 1) {
- keyboard.text(`⬅️ Oldingi`, `version_${page - 1}`);
- }
-
- if ((await generator(page + 1)).length > 0) {
- keyboard.text(`Keyingi ➡️`, `version_${page + 1}`);
- }
-
- await ctx.editMessageText(ctxMenuText, {
- parse_mode: "HTML",
- reply_markup: keyboard,
- disable_web_page_preview: true,
- });
-});
-
-composer.callbackQuery(/^changelog_(\d+)_(\d+)$/, async (ctx: Context) => {
- const keyboard = new InlineKeyboard();
- const page = Number(ctx.match![1]);
- const data = await finder(Number(ctx.match![2]));
-
- keyboard.url(
- `📝 GitHub da o'qish`,
- data.html_url,
- );
-
- keyboard.row().text(`🔙 Orqaga`, `version_${page}`);
-
- await ctx.editMessageText(
- `${data.name}` +
- `\n` +
- `\n` +
- `Yaratildi: ${
- new Date(data.created_at).toLocaleDateString("uz")
- }` +
- `\n` +
- `E'lon qilindi: ${
- new Date(data.published_at).toLocaleDateString("uz")
- }` +
- `\n` +
- `O'rnatish: rustup install ${data.tag_name}
` +
- `\n` +
- `\n` +
- `"Instant view" yoki quyidagi tugma orqali ko'proq ma'lumot oling:`,
- {
- parse_mode: "HTML",
- reply_markup: keyboard,
- },
- );
-});
-
-export default composer;
diff --git a/src/functions/groups.rs b/src/functions/groups.rs
index 316d0d6..fc89106 100644
--- a/src/functions/groups.rs
+++ b/src/functions/groups.rs
@@ -1,4 +1,7 @@
-use crate::utils::{group_manager::{Groups, Group}, keyboard_manager::Keyboard};
+use crate::utils::{
+ group_manager::{Group, Groups},
+ keyboard_manager::Keyboard,
+};
use teloxide::{
payloads::SendMessageSetters,
prelude::*,
@@ -44,7 +47,7 @@ pub async fn callback_detail(bot: &Bot, q: &CallbackQuery, args: &Vec<&str>) ->
if let Some(Message { id, chat, .. }) = q.message.clone() {
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))
+ .reply_markup(keyboard_detail(args[0].parse().unwrap_or(1), &find))
.await?;
} else if let Some(id) = q.inline_message_id.clone() {
bot.edit_message_text_inline(id, "Oopsie, something went wrong...")
@@ -58,11 +61,12 @@ pub async fn callback_detail(bot: &Bot, q: &CallbackQuery, args: &Vec<&str>) ->
pub fn view_detail(data: &Option) -> String {
match data {
Some(d) => {
- format!("{}\n\n{}\n\nUse the following buttons to get to the links:", d.name, d.about)
- },
- None => {
- "Ushbu guruh mavjud emas!".to_string()
+ format!(
+ "{}\n\n{}\n\nUse the following buttons to get to the links:",
+ d.name, d.about
+ )
}
+ None => "Ushbu guruh mavjud emas!".to_string(),
}
}
@@ -97,7 +101,7 @@ pub fn keyboard_detail(page: i32, data: &Option) -> InlineKeyboardMarkup
if let Some(group) = data {
keyboard.url("Telegram", &format!("https://t.me/{}", group.telegram));
-
+
if group.link.is_some() {
keyboard.url("Web", &group.link.clone().unwrap());
}
diff --git a/src/functions/latest.rs b/src/functions/latest.rs
new file mode 100644
index 0000000..e69b8d5
--- /dev/null
+++ b/src/functions/latest.rs
@@ -0,0 +1,38 @@
+use crate::utils::{github::GitHub, keyboard_manager::Keyboard};
+use octocrab::models::repos::Release;
+use teloxide::{
+ payloads::SendMessageSetters,
+ prelude::*,
+ types::{InlineKeyboardMarkup, ParseMode},
+};
+
+pub async fn command(bot: &Bot, github: GitHub, msg: &Message) -> ResponseResult<()> {
+ let latest = github.get_latest().await.unwrap();
+
+ bot.send_message(msg.chat.id, view(&latest))
+ .parse_mode(ParseMode::Html)
+ .reply_markup(keyboard(&latest))
+ .await?;
+
+ Ok(())
+}
+
+pub fn view(release: &Release) -> String {
+ format!(
+ "Hozirgi eng oxirgi versiya bu \
+ {} va ushbu reliz {}
da e'lon qilingan \
+ {} tomonidan.\
+ \n\n\
+ ",
+ format!("https://releases.rs/docs/{}", release.tag_name),
+ release.tag_name,
+ release.published_at.unwrap().date_naive(),
+ release.author.html_url,
+ release.author.login,
+ )
+}
+
+pub fn keyboard(release: &Release) -> InlineKeyboardMarkup {
+ let mut keyboard = Keyboard::new();
+ keyboard.url("Ko'proq ma'lumotlar", release.html_url.as_str())
+}
diff --git a/src/functions/mod.rs b/src/functions/mod.rs
index 627bc5c..3990967 100644
--- a/src/functions/mod.rs
+++ b/src/functions/mod.rs
@@ -2,11 +2,14 @@ pub mod about;
pub mod groups;
pub mod help;
pub mod inline;
+pub mod latest;
pub mod rules;
pub mod start;
+pub mod version;
pub use inline::inline;
+use crate::utils::github::GitHub;
use crate::Command;
use std::error::Error;
use teloxide::prelude::*;
@@ -16,6 +19,7 @@ pub async fn commands(
_me: teloxide::types::Me,
msg: Message,
cmd: Command,
+ github: GitHub,
) -> Result<(), Box> {
let _ = match cmd {
Command::Start => crate::functions::start::command(&bot, &msg).await,
@@ -23,12 +27,18 @@ pub async fn commands(
Command::Rules => crate::functions::rules::command(&bot, &msg).await,
Command::About => crate::functions::about::command(&bot, &msg).await,
Command::Groups => crate::functions::groups::command(&bot, &msg).await,
+ Command::Latest => crate::functions::latest::command(&bot, github, &msg).await,
+ Command::Version => crate::functions::version::command(&bot, github, &msg).await,
};
Ok(())
}
-pub async fn callback(bot: Bot, q: CallbackQuery) -> Result<(), Box> {
+pub async fn callback(
+ bot: Bot,
+ q: CallbackQuery,
+ github: GitHub,
+) -> Result<(), Box> {
let mut args: Vec<&str> = Vec::new();
if let Some(data) = q.data.clone() {
@@ -41,6 +51,8 @@ pub async fn callback(bot: Bot, q: CallbackQuery) -> Result<(), Box crate::functions::groups::callback_list(&bot, &q, &args).await,
"detail" => crate::functions::groups::callback_detail(&bot, &q, &args).await,
+ "version" => crate::functions::version::callback_list(&bot, &q, &args, github).await,
+ "changelog" => crate::functions::version::callback_detail(&bot, &q, &args, github).await,
_ => Ok(()),
};
}
diff --git a/src/functions/version.rs b/src/functions/version.rs
new file mode 100644
index 0000000..db4c6bd
--- /dev/null
+++ b/src/functions/version.rs
@@ -0,0 +1,118 @@
+use crate::utils::{github::GitHub, keyboard_manager::Keyboard};
+use octocrab::models::repos::Release;
+use teloxide::{
+ payloads::SendMessageSetters,
+ prelude::*,
+ types::{InlineKeyboardMarkup, ParseMode},
+};
+
+static TEXT: &str = "Rust Dasturlash tili versiyalari:";
+
+pub async fn command(bot: &Bot, github: GitHub, msg: &Message) -> ResponseResult<()> {
+ let versions = github.get_list(1).await.unwrap();
+ let next_page = github.get_list(2).await.unwrap();
+
+ bot.send_message(msg.chat.id, TEXT)
+ .parse_mode(ParseMode::Html)
+ .reply_markup(keyboard_list(1, versions, Some(next_page)))
+ .await?;
+
+ Ok(())
+}
+
+pub async fn callback_list(
+ bot: &Bot,
+ q: &CallbackQuery,
+ args: &Vec<&str>,
+ github: GitHub,
+) -> ResponseResult<()> {
+ let page = args[0].parse::().unwrap();
+ let versions: Vec = github.get_list(page).await.unwrap();
+ 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)
+ .parse_mode(ParseMode::Html)
+ .reply_markup(keyboard_list(page, versions, Some(next_page)))
+ .await?;
+ } else if let Some(id) = q.inline_message_id.clone() {
+ bot.edit_message_text_inline(id, "Oopsie, something went wrong...")
+ .await?;
+ }
+ }
+
+ Ok(())
+}
+
+
+pub async fn callback_detail(bot: &Bot, q: &CallbackQuery, args: &Vec<&str>, github: GitHub) -> ResponseResult<()> {
+ let page = args[0].parse::().unwrap();
+ let version: Release = github.get_detail(args[1]).await.unwrap();
+
+ if !args.is_empty() {
+ if let Some(Message { id, chat, .. }) = q.message.clone() {
+ bot.edit_message_text(chat.id, id, view_detail(&version))
+ .parse_mode(ParseMode::Html)
+ .reply_markup(keyboard_detail(page, version))
+ .await?;
+ } else if let Some(id) = q.inline_message_id.clone() {
+ bot.edit_message_text_inline(id, "Oopsie, something went wrong...")
+ .await?;
+ }
+ }
+
+ Ok(())
+}
+
+pub fn view_detail(release: &Release) -> String {
+ format!(
+ "{}\n\n\
+ Yaratildi: {}\n\
+ E'lon qilindi: {}\n\
+ O'rnatish: rustup install {}
\n\n\
+ \"Instant view\" yoki quyidagi tugma orqali ko'proq ma'lumot oling:",
+ release.html_url,
+ release.name.clone().unwrap(),
+ release.created_at.unwrap().format("%d.%m.%Y"),
+ release.published_at.unwrap().format("%d.%m.%Y"),
+ release.tag_name
+ )
+}
+
+pub fn keyboard_list(
+ page: u32,
+ releases: Vec,
+ next_page: Option>,
+) -> InlineKeyboardMarkup {
+ let mut keyboard = Keyboard::new();
+
+ for release in releases {
+ keyboard.text(&release.tag_name, &format!("changelog_{}_{}", page, release.tag_name));
+ keyboard.row();
+ }
+
+ if page > 1 {
+ keyboard.text("⬅️ Oldingi", &format!("version_{}", page - 1));
+ }
+
+ if next_page.is_some() && !next_page.unwrap().is_empty() {
+ keyboard.text("Keyingi ➡️", &format!("version_{}", page + 1));
+ }
+
+ keyboard.get()
+}
+
+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.row();
+ keyboard.text("🔙 Orqaga", &format!("version_{}", page));
+
+ keyboard.get()
+}
+
diff --git a/src/lib.rs b/src/lib.rs
index d690ac6..f45474b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -22,6 +22,12 @@ pub enum Command {
/// Available groups
Groups,
+
+ /// Latest version
+ Latest,
+
+ /// Specific version
+ Version,
}
pub fn handler() -> UpdateHandler> {
diff --git a/src/main.rs b/src/main.rs
index 80099d7..864af7e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,5 @@
use crates_io_api::AsyncClient;
-use rustina::handler;
+use rustina::{handler, utils::github::GitHub};
use std::error::Error;
use teloxide::prelude::*;
@@ -16,8 +16,10 @@ async fn main() -> Result<(), Box> {
)
.unwrap();
+ let github = GitHub::new();
+
Dispatcher::builder(bot, handler())
- .dependencies(dptree::deps![crates_client])
+ .dependencies(dptree::deps![crates_client, github])
// If no handler succeeded to handle an update, this closure will be called
.default_handler(|upd| async move {
log::warn!("Unhandled update: {:?}", upd);
diff --git a/src/utils/github.rs b/src/utils/github.rs
new file mode 100644
index 0000000..3f984f5
--- /dev/null
+++ b/src/utils/github.rs
@@ -0,0 +1,65 @@
+use octocrab::{models::repos::Release, Octocrab};
+use std::error::Error;
+
+#[derive(Clone, Debug)]
+pub struct GitHub {
+ client: Octocrab,
+}
+
+impl GitHub {
+ pub fn new() -> Self {
+ Self {
+ client: Octocrab::builder()
+ .add_header(
+ "User-Agent".parse().unwrap(),
+ "Rustina Assistant (rust@maid.uz)".to_string(),
+ )
+ .add_header(
+ "Authorization".parse().unwrap(),
+ std::env::var("GITHUB_TOKEN").unwrap(),
+ )
+ .build()
+ .unwrap(),
+ }
+ }
+
+ pub async fn get_latest(&self) -> Result> {
+ let latest = self
+ .client
+ .repos("rust-lang", "rust")
+ .releases()
+ .get_latest()
+ .await?;
+
+ Ok(latest)
+ }
+
+ pub async fn get_list(&self, page: u32) -> Result, Box> {
+ let versions = self
+ .client
+ .repos("rust-lang", "rust")
+ .releases()
+ .list()
+ .per_page(5)
+ .page(page)
+ .send()
+ .await?
+ .take_items();
+
+ Ok(versions)
+ }
+
+ pub async fn get_detail(
+ &self,
+ tag_name: &str,
+ ) -> Result> {
+ let detail = self
+ .client
+ .repos("rust-lang", "rust")
+ .releases()
+ .get_by_tag(tag_name)
+ .await?;
+
+ Ok(detail)
+ }
+}
diff --git a/src/utils/group_manager.rs b/src/utils/group_manager.rs
index 11179dd..b3c240c 100644
--- a/src/utils/group_manager.rs
+++ b/src/utils/group_manager.rs
@@ -42,7 +42,11 @@ impl Groups {
}
pub fn find_group(&self, query: String) -> Option {
- let search: Vec<&Group> = self.groups.iter().filter(|group| group.telegram[1..] == query).collect();
+ let search: Vec<&Group> = self
+ .groups
+ .iter()
+ .filter(|group| group.telegram[1..] == query)
+ .collect();
if search.is_empty() {
return None;
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index 39d3ae4..701861c 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -1,3 +1,4 @@
+pub mod github;
pub mod group_manager;
pub mod inline_manager;
pub mod keyboard_manager;