This commit is contained in:
2025-08-26 15:27:26 +04:00
parent c44751a91e
commit 3972656c61
6 changed files with 624 additions and 57 deletions

5
.gitignore vendored
View File

@@ -1,2 +1,7 @@
/target /target
/.direnv /.direnv
/db
/.env
/result
/telegram-exporter-arx
/channels.json

414
Cargo.lock generated
View File

@@ -59,6 +59,12 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.9.2" version = "2.9.2"
@@ -71,6 +77,12 @@ version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.10.1" version = "1.10.1"
@@ -88,9 +100,9 @@ dependencies = [
[[package]] [[package]]
name = "cfg-expr" name = "cfg-expr"
version = "0.20.0" version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e34e221e91c7eb5e8315b5c9cf1a61670938c0626451f954a51693ed44b37f45" checksum = "c8d458d63f0f0f482c8da9b7c8b76c21bd885a02056cc94c6404d861ca2b8206"
dependencies = [ dependencies = [
"smallvec", "smallvec",
"target-lexicon", "target-lexicon",
@@ -115,12 +127,59 @@ dependencies = [
"windows-link", "windows-link",
] ]
[[package]]
name = "console"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"unicode-width 0.2.1",
"windows-sys 0.60.2",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.7" version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "crc32fast"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossterm"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
dependencies = [
"bitflags 1.3.2",
"crossterm_winapi",
"libc",
"mio 0.8.11",
"parking_lot",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.20.11" version = "0.20.11"
@@ -142,7 +201,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn", "syn 2.0.106",
] ]
[[package]] [[package]]
@@ -153,7 +212,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn", "syn 2.0.106",
] ]
[[package]] [[package]]
@@ -187,6 +246,35 @@ dependencies = [
"windows-sys 0.60.2", "windows-sys 0.60.2",
] ]
[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "dotenv_codegen"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56966279c10e4f8ee8c22123a15ed74e7c8150b658b26c619c53f4a56eb4a8aa"
dependencies = [
"dotenv_codegen_implementation",
"proc-macro-hack",
]
[[package]]
name = "dotenv_codegen_implementation"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e737a3522cd45f6adc19b644ce43ef53e1e9045f2d2de425c1f468abd4cf33"
dependencies = [
"dotenv",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "dotenvy" name = "dotenvy"
version = "0.15.7" version = "0.15.7"
@@ -199,12 +287,29 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.2" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "flate2"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
dependencies = [
"crc32fast",
"libz-sys",
"miniz_oxide",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@@ -226,6 +331,24 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "fuzzy-matcher"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
dependencies = [
"thread_local",
]
[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.16" version = "0.2.16"
@@ -319,13 +442,43 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "indicatif"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70a646d946d06bedbbc4cac4c218acf4bbf2d87757a784857025f4d447e4e1cd"
dependencies = [
"console",
"portable-atomic",
"unicode-width 0.2.1",
"unit-prefix",
"web-time",
]
[[package]]
name = "inquire"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a"
dependencies = [
"bitflags 2.9.2",
"crossterm",
"dyn-clone",
"fuzzy-matcher",
"fxhash",
"newline-converter",
"once_cell",
"unicode-segmentation",
"unicode-width 0.1.14",
]
[[package]] [[package]]
name = "io-uring" name = "io-uring"
version = "0.7.9" version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.9.2",
"cfg-if", "cfg-if",
"libc", "libc",
] ]
@@ -358,10 +511,21 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.9.2",
"libc", "libc",
] ]
[[package]]
name = "libz-sys"
version = "1.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d"
dependencies = [
"cc",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.13" version = "0.4.13"
@@ -393,6 +557,18 @@ dependencies = [
"adler2", "adler2",
] ]
[[package]]
name = "mio"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "1.0.4" version = "1.0.4"
@@ -404,6 +580,15 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "newline-converter"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "num-conv" name = "num-conv"
version = "0.1.0" version = "0.1.0"
@@ -475,12 +660,24 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "portable-atomic"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
[[package]] [[package]]
name = "powerfmt" name = "powerfmt"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "proc-macro-hack"
version = "0.5.20+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.101" version = "1.0.101"
@@ -505,7 +702,7 @@ version = "0.5.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77"
dependencies = [ dependencies = [
"bitflags", "bitflags 2.9.2",
] ]
[[package]] [[package]]
@@ -536,7 +733,7 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
] ]
[[package]] [[package]]
@@ -604,14 +801,14 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
] ]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.142" version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
@@ -657,7 +854,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
] ]
[[package]] [[package]]
@@ -666,6 +863,27 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
dependencies = [
"libc",
"signal-hook-registry",
]
[[package]]
name = "signal-hook-mio"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
dependencies = [
"libc",
"mio 0.8.11",
"signal-hook",
]
[[package]] [[package]]
name = "signal-hook-registry" name = "signal-hook-registry"
version = "1.4.6" version = "1.4.6"
@@ -703,6 +921,17 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.106" version = "2.0.106"
@@ -770,7 +999,13 @@ checksum = "87cbdfae498e57fb48d380fff8eb5c9c98d4497c998f6de0d30d5d6b12f5358b"
name = "telegram-exporter" name = "telegram-exporter"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"dotenv_codegen",
"dotenvy", "dotenvy",
"flate2",
"indicatif",
"inquire",
"serde",
"serde_json",
"tdlib-rs", "tdlib-rs",
"tokio", "tokio",
] ]
@@ -792,7 +1027,16 @@ checksum = "44d29feb33e986b6ea906bd9c3559a856983f92371b3eaa5e83782a351623de0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
]
[[package]]
name = "thread_local"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
] ]
[[package]] [[package]]
@@ -836,7 +1080,7 @@ dependencies = [
"bytes", "bytes",
"io-uring", "io-uring",
"libc", "libc",
"mio", "mio 1.0.4",
"parking_lot", "parking_lot",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
@@ -854,7 +1098,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
] ]
[[package]] [[package]]
@@ -897,6 +1141,36 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unicode-width"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "unicode-width"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
[[package]]
name = "unit-prefix"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version-compare" name = "version-compare"
version = "0.2.0" version = "0.2.0"
@@ -931,7 +1205,7 @@ dependencies = [
"log", "log",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@@ -953,7 +1227,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@@ -967,6 +1241,38 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "web-time"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-core" name = "windows-core"
version = "0.61.2" version = "0.61.2"
@@ -988,7 +1294,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
] ]
[[package]] [[package]]
@@ -999,7 +1305,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.106",
] ]
[[package]] [[package]]
@@ -1026,6 +1332,15 @@ dependencies = [
"windows-link", "windows-link",
] ]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.59.0"
@@ -1044,6 +1359,21 @@ dependencies = [
"windows-targets 0.53.3", "windows-targets 0.53.3",
] ]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.6" version = "0.52.6"
@@ -1077,6 +1407,12 @@ dependencies = [
"windows_x86_64_msvc 0.53.0", "windows_x86_64_msvc 0.53.0",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.6" version = "0.52.6"
@@ -1089,6 +1425,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.6" version = "0.52.6"
@@ -1101,6 +1443,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.6" version = "0.52.6"
@@ -1125,6 +1473,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.6" version = "0.52.6"
@@ -1137,6 +1491,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.6" version = "0.52.6"
@@ -1149,6 +1509,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.6" version = "0.52.6"
@@ -1161,6 +1527,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.6" version = "0.52.6"
@@ -1175,9 +1547,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.7.12" version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]

View File

@@ -4,7 +4,13 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
dotenv_codegen = "0.15.0"
dotenvy = "0.15.7" dotenvy = "0.15.7"
flate2 = { version = "1.1.2", features = ["zlib"] }
indicatif = "0.18.0"
inquire = "0.7.5"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.143"
tdlib-rs = { version = "1.1.0", features = ["pkg-config"] } tdlib-rs = { version = "1.1.0", features = ["pkg-config"] }
tokio = { version = "1.47.1", features = ["full"] } tokio = { version = "1.47.1", features = ["full"] }
@@ -13,3 +19,10 @@ tdlib-rs = { version = "1.1.0", features = ["pkg-config"] }
[package.metadata.system-deps] [package.metadata.system-deps]
tdjson = "1.8.29" tdjson = "1.8.29"
[profile.release]
codegen-units = 1
lto = true
opt-level = "z"
strip = true
panic = "abort"

18
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": { "nodes": {
"crane": { "crane": {
"locked": { "locked": {
"lastModified": 1748970125, "lastModified": 1755993354,
"narHash": "sha256-UDyigbDGv8fvs9aS95yzFfOKkEjx1LO3PL3DsKopohA=", "narHash": "sha256-FCRRAzSaL/+umLIm3RU3O/+fJ2ssaPHseI2SSFL8yZU=",
"owner": "ipetkov", "owner": "ipetkov",
"repo": "crane", "repo": "crane",
"rev": "323b5746d89e04b22554b061522dfce9e4c49b18", "rev": "25bd41b24426c7734278c2ff02e53258851db914",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -35,11 +35,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1748929857, "lastModified": 1756125398,
"narHash": "sha256-lcZQ8RhsmhsK8u7LIFsJhsLh/pzR9yZ8yqpTzyGdj+Q=", "narHash": "sha256-XexyKZpf46cMiO5Vbj+dWSAXOnr285GHsMch8FBoHbc=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c2a03962b8e24e669fb37b7df10e7c79531ff1a4", "rev": "3b9f00d7a7bf68acd4c4abb9d43695afb04e03a5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -81,11 +81,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1749091064, "lastModified": 1756175826,
"narHash": "sha256-TGtYjzRX0sueFhwYsnNNFF5TTKnpnloznpIghLzxeXo=", "narHash": "sha256-cQNnntKWve+vnqo6pGGXl4NFT4dgnMKXl4+bpwLELvU=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "12419593ce78f2e8e1e89a373c6515885e218acb", "rev": "d137b47bde8a6783b961db81254013b454eab46a",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -31,6 +31,19 @@
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
overlays = [ overlays = [
(final: prev: {
tdlib = prev.tdlib.overrideAttrs (_: {
version = "1.8.29";
src = prev.fetchFromGitHub {
owner = "tdlib";
repo = "td";
rev = "af69dd4397b6dc1bf23ba0fd0bf429fcba6454f6";
hash = "sha256-2RhKSxy0AvuA74LHI86pqUxv9oJZ+ZxxDe4TPI5UYxE=";
# hash = "sha256-mbhxuJjrV3nC8Ja7N0WWF9ByHovJLmoLLuuzoU4khjU=";
};
});
})
(import rust-overlay) (import rust-overlay)
]; ];
}; };
@@ -48,29 +61,33 @@
]; ];
} }
); );
src = craneLib.cleanCargoSource ./.; src = lib.cleanSourceWith {
src = ./.;
filter = (
path: type: (craneLib.filterCargoSources path type) || (builtins.match ".*/\.env$" path != null)
);
name = "source";
};
commonArgs = { commonArgs = {
inherit src; inherit src;
strictDeps = true; strictDeps = true;
}; nativeBuildInputs = with pkgs; [
cargoArtifacts = craneLib.buildDepsOnly commonArgs; pkg-config
individualCrateArgs = commonArgs // { ];
inherit cargoArtifacts; buildInputs = with pkgs; [
inherit (craneLib.crateNameFromCargoToml { inherit src; }) version; tdlib
}; openssl
fileSetForCrate =
crate:
lib.fileset.toSource {
root = ./.;
fileset = lib.fileset.unions [
./Cargo.toml
./Cargo.lock
]; ];
}; };
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
server = craneLib.buildPackage ( server = craneLib.buildPackage (
individualCrateArgs commonArgs
// { // {
inherit cargoArtifacts;
inherit (craneLib.crateNameFromCargoToml { inherit src; }) version;
postInstall = ''
${pkgs.upx}/bin/upx --lzma --best $out/bin/telegram-exporter
'';
} }
); );
in in
@@ -81,6 +98,8 @@
config = (import ./process-compose.nix { inherit pkgs; }); config = (import ./process-compose.nix { inherit pkgs; });
modules = [ ]; modules = [ ];
}; };
default = server;
inherit server;
}; };
devShells.default = craneLib.devShell { devShells.default = craneLib.devShell {

View File

@@ -6,8 +6,16 @@ use std::{
}, },
}; };
use dotenv_codegen::dotenv;
use flate2::write::ZlibEncoder;
use indicatif::{ProgressBar, ProgressStyle};
use inquire::{Password, Text, validator::StringValidator};
use serde::{Deserialize, Serialize};
use tdlib_rs::{ use tdlib_rs::{
enums::{self, AuthorizationState, Update, User}, enums::{
self, AuthorizationState, Chat, ChatPhoto, Chats, Supergroup, SupergroupFullInfo, Update,
User,
},
functions, functions,
}; };
use tokio::sync::mpsc::{self, Receiver, Sender}; use tokio::sync::mpsc::{self, Receiver, Sender};
@@ -18,10 +26,36 @@ async fn handle_update(update: Update, auth_tx: &Sender<AuthorizationState>) {
auth_tx.send(state.authorization_state).await.unwrap(); auth_tx.send(state.authorization_state).await.unwrap();
} }
_ => { _ => {
println!("Received update: {:?}", update); // println!("Received update: {:?}", update);
} }
} }
} }
#[derive(Debug, Clone)]
struct NumberValidator;
impl NumberValidator {
fn new() -> Self {
Self
}
}
impl StringValidator for NumberValidator {
fn validate(
&self,
input: &str,
) -> Result<inquire::validator::Validation, inquire::CustomUserError> {
if input
.chars()
.all(|c| c.is_ascii_digit() || c == '+' || c == '-')
&& input.len() >= 4
{
Ok(inquire::validator::Validation::Valid)
} else {
Ok(inquire::validator::Validation::Invalid(
"Please enter a valid phone number.".into(),
))
}
}
}
fn ask_user(string: &str) -> String { fn ask_user(string: &str) -> String {
println!("{string}"); println!("{string}");
let mut input = String::new(); let mut input = String::new();
@@ -38,15 +72,15 @@ async fn handle_authorization_state(
AuthorizationState::WaitTdlibParameters => { AuthorizationState::WaitTdlibParameters => {
let response = functions::set_tdlib_parameters( let response = functions::set_tdlib_parameters(
false, false,
"get_me_db".into(), "db".into(),
String::new(), String::new(),
String::new(), String::new(),
false, false,
false, false,
false, false,
false, false,
env::var("API_ID").unwrap().parse().unwrap(), dotenv!("APP_ID").parse().unwrap(),
env::var("API_HASH").unwrap().into(), dotenv!("APP_HASH").into(),
"en".into(), "en".into(),
"Desktop".into(), "Desktop".into(),
String::new(), String::new(),
@@ -60,9 +94,16 @@ async fn handle_authorization_state(
} }
} }
AuthorizationState::WaitPhoneNumber => loop { AuthorizationState::WaitPhoneNumber => loop {
let input = ask_user("Enter your phone number (include the country calling code):"); // let input = ask_user("Enter your phone number (include the country calling code):");
let number =
Text::new("Enter your phone number (include the country calling code):")
.with_initial_value("+")
.with_validator(NumberValidator::new())
.prompt()
.unwrap();
let response = let response =
functions::set_authentication_phone_number(input, None, client_id).await; functions::set_authentication_phone_number(number, None, client_id).await;
match response { match response {
Ok(_) => break, Ok(_) => break,
Err(e) => println!("{}", e.message), Err(e) => println!("{}", e.message),
@@ -99,7 +140,9 @@ async fn handle_authorization_state(
} }
AuthorizationState::WaitCode(_) => loop { AuthorizationState::WaitCode(_) => loop {
let input = ask_user("Enter the verification code:"); let input = Text::new("Enter the authentication code you received:")
.prompt()
.unwrap();
let response = functions::check_authentication_code(input, client_id).await; let response = functions::check_authentication_code(input, client_id).await;
match response { match response {
Ok(_) => break, Ok(_) => break,
@@ -115,7 +158,11 @@ async fn handle_authorization_state(
.unwrap(); .unwrap();
} }
AuthorizationState::WaitPassword(_x) => { AuthorizationState::WaitPassword(_x) => {
let password = ask_user("Please enter password: "); let password = Password::new("Please enter your password:")
.with_display_mode(inquire::PasswordDisplayMode::Masked)
.without_confirmation()
.prompt()
.unwrap();
functions::check_authentication_password(password, client_id) functions::check_authentication_password(password, client_id)
.await .await
.unwrap(); .unwrap();
@@ -135,6 +182,37 @@ async fn handle_authorization_state(
auth_rx auth_rx
} }
#[derive(Debug, Serialize, Deserialize)]
struct ChannelInfo {
id: i64,
name: String,
description: String,
minithumbnail: Option<String>,
member_count: i32,
linked_chat_id: i64,
invite_link: Option<ChannelInviteLink>,
usernames: Option<ChannelUsernameInfo>,
}
#[derive(Debug, Serialize, Deserialize)]
struct ChannelInviteLink {
invite_link: String,
name: String,
is_primary: bool,
is_revoked: bool,
}
#[derive(Debug, Serialize, Deserialize)]
struct ChannelUsernameInfo {
active: Vec<String>,
inactive: Vec<String>,
editable: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct TotalData {
total: usize,
channels: Vec<ChannelInfo>,
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
@@ -158,7 +236,7 @@ async fn main() {
} }
}); });
functions::set_log_verbosity_level(2, client_id) functions::set_log_verbosity_level(0, client_id)
.await .await
.unwrap(); .unwrap();
@@ -167,14 +245,94 @@ async fn main() {
// Run the get_me() method to get user information // Run the get_me() method to get user information
let User::User(me) = functions::get_me(client_id).await.unwrap(); let User::User(me) = functions::get_me(client_id).await.unwrap();
println!("Hi, I'm {}", me.first_name); println!("logged in as {}", me.first_name);
let chats = functions::get_chats(None, i32::MAX, client_id)
.await
.unwrap();
let Chats::Chats(chats) = chats;
// println!("I have {} chats", chats.chat_ids.len());
let chat_ids = chats
.chat_ids
.iter()
.filter_map(|f| {
f.to_string()
.strip_prefix("-100")
.and_then(|s| s.parse::<i64>().ok())
.map(|a| (a, *f))
})
.collect::<Vec<_>>();
println!(
"{} total chats {} of which are channels",
chats.chat_ids.len(),
chat_ids.len()
);
println!("Fetching channel info...");
let mut chat_vec = vec![];
let progress = ProgressBar::new(chat_ids.len() as u64);
progress.set_style(
ProgressStyle::with_template(
"{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta})",
)
.unwrap()
.progress_chars("#>-"),
);
for (chat_id, chat_id_origin) in chat_ids {
let sgfi = functions::get_supergroup_full_info(chat_id, client_id)
.await
.unwrap();
let sg = functions::get_supergroup(chat_id, client_id).await.unwrap();
let chat = functions::get_chat(chat_id_origin, client_id)
.await
.unwrap();
let Supergroup::Supergroup(sg) = sg;
let Chat::Chat(chat) = chat;
let SupergroupFullInfo::SupergroupFullInfo(sgfi) = sgfi;
let photo = sgfi.photo.and_then(|p| p.minithumbnail);
let channel_info = ChannelInfo {
id: chat_id_origin,
name: chat.title,
description: sgfi.description,
member_count: sgfi.member_count,
linked_chat_id: sgfi.linked_chat_id,
invite_link: sgfi.invite_link.map(|il| ChannelInviteLink {
invite_link: il.invite_link,
name: il.name,
is_primary: il.is_primary,
is_revoked: il.is_revoked,
}),
minithumbnail: photo.map(|p| p.data),
usernames: sg.usernames.map(|u| ChannelUsernameInfo {
active: u.active_usernames,
inactive: u.disabled_usernames,
editable: u.editable_username,
}),
};
chat_vec.push(channel_info);
progress.inc(1);
}
println!("Fetched info for {} channels", chat_vec.len());
let data = TotalData {
total: chats.chat_ids.len(),
channels: chat_vec,
};
progress.finish_and_clear();
let data = serde_json::to_string_pretty(&data).unwrap();
let mut encoder = ZlibEncoder::new(Vec::new(), flate2::Compression::best());
std::io::copy(&mut data.as_bytes(), &mut encoder).unwrap();
let compressed_data = encoder.finish().unwrap();
std::fs::write("channels.json", &compressed_data).unwrap();
println!("Written to channels.json, {} bytes", compressed_data.len());
// Tell the client to close // Tell the client to close
functions::close(client_id).await.unwrap(); functions::close(client_id).await.unwrap();
println!("Client closed");
// Handle the authorization state to wait for the "Closed" state // Handle the authorization state to wait for the "Closed" state
handle_authorization_state(client_id, auth_rx, run_flag.clone()).await; handle_authorization_state(client_id, auth_rx, run_flag.clone()).await;
// Wait for the previously spawned task to end the execution // Wait for the previously spawned task to end the execution
handle.await.unwrap(); handle.await.unwrap();
println!("Exiting...");
} }