Check-in [374eadef45]
Logged in as anonymous
Overview
Comment:comments, reordering, better paging
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 374eadef45f782806bea6e38e9949b1a7cd3277cc31e04555d6079a550a744ea
User & Date: arcade on 2026-03-28 13:24:23.995
Other Links: manifest | tags
Context
2026-03-30
14:20
update workflow, get rid of TEXT MardownV2, rewrite handle, add more callbacks check-in: 3fd8c40aa8 user: arcade tags: trunk
2026-03-28
13:24
comments, reordering, better paging check-in: 374eadef45 user: arcade tags: trunk
2026-03-25
19:11
bump, rewrite sending, add feed fetching and test keyboard check-in: 9adc69d514 user: arcade tags: trunk
Changes
256
257
258
259
260
261
262
263

264
265

266
267
268
269
270
271
272
256
257
258
259
260
261
262

263
264

265
266
267
268
269
270
271
272







-
+

-
+







dependencies = [
 "aws-lc-sys",
 "zeroize",
]

[[package]]
name = "aws-lc-sys"
version = "0.39.0"
version = "0.39.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a"
checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399"
dependencies = [
 "cc",
 "cmake",
 "dunce",
 "fs_extra",
]

350
351
352
353
354
355
356
357

358
359

360
361
362
363
364
365
366
350
351
352
353
354
355
356

357
358

359
360
361
362
363
364
365
366







-
+

-
+







name = "bytes"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"

[[package]]
name = "cc"
version = "1.2.57"
version = "1.2.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423"
checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
dependencies = [
 "find-msvc-tools",
 "jobserver",
 "libc",
 "shlex",
]

394
395
396
397
398
399
400
401

402
403

404
405
406
407
408
409
410
394
395
396
397
398
399
400

401
402

403
404
405
406
407
408
409
410







-
+

-
+







 "serde",
 "wasm-bindgen",
 "windows-link",
]

[[package]]
name = "cmake"
version = "0.1.57"
version = "0.1.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d"
checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
dependencies = [
 "cc",
]

[[package]]
name = "combine"
version = "4.6.7"
1402
1403
1404
1405
1406
1407
1408
1409

1410
1411

1412


1413
1414
1415
1416
1417
1418
1419
1402
1403
1404
1405
1406
1407
1408

1409
1410

1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421







-
+

-
+

+
+







dependencies = [
 "getrandom 0.3.4",
 "libc",
]

[[package]]
name = "js-sys"
version = "0.3.91"
version = "0.3.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c"
checksum = "cc4c90f45aa2e6eacbe8645f77fdea542ac97a494bcd117a67df9ff4d611f995"
dependencies = [
 "cfg-if",
 "futures-util",
 "once_cell",
 "wasm-bindgen",
]

[[package]]
name = "lazy_static"
version = "1.5.0"
1536
1537
1538
1539
1540
1541
1542
1543

1544
1545

1546
1547
1548
1549
1550
1551
1552
1538
1539
1540
1541
1542
1543
1544

1545
1546

1547
1548
1549
1550
1551
1552
1553
1554







-
+

-
+







dependencies = [
 "adler2",
 "simd-adler32",
]

[[package]]
name = "mio"
version = "1.1.1"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [
 "libc",
 "wasi",
 "windows-sys 0.61.2",
]

[[package]]
2066
2067
2068
2069
2070
2071
2072
2073

2074
2075

2076
2077
2078
2079
2080
2081
2082
2068
2069
2070
2071
2072
2073
2074

2075
2076

2077
2078
2079
2080
2081
2082
2083
2084







-
+

-
+







 "toml",
 "ttl_cache",
 "url",
]

[[package]]
name = "rustc-hash"
version = "2.1.1"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"

[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
2388
2389
2390
2391
2392
2393
2394
2395

2396
2397

2398
2399
2400
2401
2402
2403
2404
2390
2391
2392
2393
2394
2395
2396

2397
2398

2399
2400
2401
2402
2403
2404
2405
2406







-
+

-
+







dependencies = [
 "digest",
 "rand_core 0.6.4",
]

[[package]]
name = "simd-adler32"
version = "0.3.8"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"

[[package]]
name = "slab"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"

3140
3141
3142
3143
3144
3145
3146
3147

3148
3149

3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160

3161
3162

3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174

3175
3176

3177
3178
3179
3180
3181
3182
3183
3184

3185
3186

3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197

3198
3199

3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219

3220
3221

3222
3223
3224
3225
3226
3227
3228
3142
3143
3144
3145
3146
3147
3148

3149
3150

3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161

3162
3163

3164
3165


3166

3167

3168
3169
3170
3171

3172
3173

3174
3175
3176
3177
3178
3179
3180
3181

3182
3183

3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194

3195
3196

3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216

3217
3218

3219
3220
3221
3222
3223
3224
3225
3226







-
+

-
+










-
+

-
+

-
-

-

-




-
+

-
+







-
+

-
+










-
+

-
+



















-
+

-
+







name = "wasite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"

[[package]]
name = "wasm-bindgen"
version = "0.2.114"
version = "0.2.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e"
checksum = "6523d69017b7633e396a89c5efab138161ed5aafcbc8d3e5c5a42ae38f50495a"
dependencies = [
 "cfg-if",
 "once_cell",
 "rustversion",
 "wasm-bindgen-macro",
 "wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-futures"
version = "0.4.64"
version = "0.4.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8"
checksum = "2d1faf851e778dfa54db7cd438b70758eba9755cb47403f3496edd7c8fc212f0"
dependencies = [
 "cfg-if",
 "futures-util",
 "js-sys",
 "once_cell",
 "wasm-bindgen",
 "web-sys",
]

[[package]]
name = "wasm-bindgen-macro"
version = "0.2.114"
version = "0.2.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6"
checksum = "4e3a6c758eb2f701ed3d052ff5737f5bfe6614326ea7f3bbac7156192dc32e67"
dependencies = [
 "quote",
 "wasm-bindgen-macro-support",
]

[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.114"
version = "0.2.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3"
checksum = "921de2737904886b52bcbb237301552d05969a6f9c40d261eb0533c8b055fedf"
dependencies = [
 "bumpalo",
 "proc-macro2",
 "quote",
 "syn",
 "wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-shared"
version = "0.2.114"
version = "0.2.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16"
checksum = "a93e946af942b58934c604527337bad9ae33ba1d5c6900bbb41c2c07c2364a93"
dependencies = [
 "unicode-ident",
]

[[package]]
name = "wasm-streams"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
dependencies = [
 "futures-util",
 "js-sys",
 "wasm-bindgen",
 "wasm-bindgen-futures",
 "web-sys",
]

[[package]]
name = "web-sys"
version = "0.3.91"
version = "0.3.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9"
checksum = "84cde8507f4d7cfcb1185b8cb5890c494ffea65edbe1ba82cfd63661c805ed94"
dependencies = [
 "js-sys",
 "wasm-bindgen",
]

[[package]]
name = "web-time"
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65







-
+







}

pub async fn test (core: &Core, msg: &Message) -> Result<()> {
	let sender: i64 = msg.sender.get_user_id()
		.stack_err("Ignoring unreal users.")?.into();
	let feeds = core.get_feeds(sender).await.stack()?;
	let kb = get_kb(&Callback::list("", 0), feeds).await.stack()?;
	core.tg.send(MyMessage::html_to_kb(format!("List of feeds owned by {:?}:", msg.sender), msg.chat.get_id(), kb)).await.stack()?;
	core.tg.send(MyMessage::html_to_kb(format!("List of feeds owned by {:?}:", msg.sender.get_user_username()), msg.chat.get_id(), kb)).await.stack()?;
	Ok(())
}

/// Handle channel-management commands that operate on a single numeric source ID.
///
/// This validates that exactly one numeric argument is provided, performs the requested
/// operation (check, clean, enable, delete, disable) against the database or core,
80
81
82
83
84
85
86

87
88

89
90
91
92
93
94
95
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96







+

-
+







			Err(err) => format!("I need a number.\n{}", &err).into(),
			Ok(number) => match command {
				"/check" => core.check(number, false, None).await
					.context("Channel check failed.")?.into(),
				"/clean" => conn.clean(number, sender).await.stack()?,
				"/enable" => conn.enable(number, sender).await.stack()?.into(),
				"/delete" => {
					let res = conn.delete(number, sender).await.stack()?;
					core.rm_feed(sender.into(), &number).await.stack()?;
					conn.delete(number, sender).await.stack()?
					res
				}
				"/disable" => conn.disable(number, sender).await.stack()?.into(),
				_ => bail!("Command {command} {words:?} not handled."),
			},
		}
	} else {
		"This command needs exactly one number.".into()
359
360
361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373
374
375
376







-



+







			reply.push(row.to_string());
		};
		Ok(reply.join("\n\n"))
	}

	/// Returns current cached list of feed for requested user, or loads data from database
	pub async fn get_feeds (&self, owner: i64) -> Result<Arc<Mutex<HashMap<i32, String>>>> {
		let mut conn = self.db.begin().await.stack()?;
		let mut feeds = self.feeds.lock_arc().await;
		Ok(match feeds.get(&owner) {
			None => {
				let mut conn = self.db.begin().await.stack()?;
				let feed_list = conn.get_feeds(owner).await.stack()?;
				let mut map = HashMap::new();
				for feed in feed_list {
					map.insert(feed.source_id, feed.channel);
				};
				let res = Arc::new(Mutex::new(map));
				feeds.insert(owner, res.clone(), Duration::from_secs(60 * 60 * 3));
388
389
390
391
392
393
394


395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411

412
413
414
415
416
417
418
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421







+
+

















+







			if let Some(feed) = feeds.get_mut(&owner) {
				let mut feed = feed.lock_arc().await;
				feed.insert(source_id, channel);
			} else {
				inserted = false;
			}
		}
		// in case insert failed - we miss the entry we needed to expand, reload everything from
		// database
		if !inserted {
			self.get_feeds(owner).await.stack()?;
		}
		Ok(())
	}

	/// Removes feed from cached list
	pub async fn rm_feed (&self, owner: i64, source_id: &i32) -> Result<()> {
		let mut dropped = false;
		{
			let mut feeds = self.feeds.lock_arc().await;
			if let Some(feed) = feeds.get_mut(&owner) {
				let mut feed = feed.lock_arc().await;
				feed.remove(source_id);
				dropped = true;
			}
		}
		// in case we failed to found feed we need to remove - just reload everything from database
		if !dropped {
			self.get_feeds(owner).await.stack()?;
		}
		Ok(())
	}
}

232
233
234
235
236
237
238

239
240
241
242
243
244
245
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246







+







	where I: Into<i64> {
		sqlx::query("update rsstg_source set last_scrape = now() where source_id = $1;")
			.bind(id.into())
			.execute(&mut *self.0).await.stack()?;
		Ok(())
	}

	#[allow(clippy::too_many_arguments)] // XXX at least for now…
	pub async fn update <I> (&mut self, update: Option<i32>, channel: &str, channel_id: i64, url: &str, iv_hash: Option<&str>, url_re: Option<&str>, owner: I) -> Result<&str>
	where I: Into<i64> {
		match match update {
				Some(id) => {
					sqlx::query("update rsstg_source set channel_id = $2, url = $3, iv_hash = $4, owner = $5, channel = $6, url_re = $7 where source_id = $1")
						.bind(id)
				},
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87















88
89
90
91
92
93
94


















95
96
97








98
99
100
101
102
103
104
70
71
72
73
74
75
76
77











78
79
80
81
82
83
84
85
86
87
88
89
90
91
92







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125







+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+







			let long = feeds.len() > 6;
			let (start, end) = if long {
				(page * 5, 5 + page * 5)
			} else {
				(0, 6)
			};
			let mut i = 0;
			if name.is_empty() {
			for (id, name) in feeds.iter() {
				if i < start { continue }
				if i > end { break }
				i += 1;
				kb.push(vec![
					InlineKeyboardButton::for_callback_data(
						format!("{}. {}", id, name),
						Callback::list("xxx", *page).to_string()), // XXX edit
				])
			}
			if name.is_empty() {
				for (id, name) in feeds.iter() {
					if i < start { continue }
					if i > end { break }
					i += 1;
					kb.push(vec![
						InlineKeyboardButton::for_callback_data(
							format!("{}. {}", id, name),
							Callback::list("xxx", *page).to_string()), // XXX edit
					]);
				}
			} else {
				let mut found = false;
				let mut first_page = None;
				for (id, feed_name) in feeds.iter() {
					if name == feed_name {
				// no name - reverting to pages, any unknown number means last page
				kb.push(vec![
					InlineKeyboardButton::for_callback_data("1",
						Callback::list("xxx", 0).to_string()),
				])
			} else {
				kb.push(vec![
						found = true;
					}
					i += 1;
					kb.push(vec![
						InlineKeyboardButton::for_callback_data(
							format!("{}. {}", id, feed_name),
							Callback::list("xxx", *page).to_string()), // XXX edit
					]);
					if i > end {
						// page complete, if found we got the right page, if not - reset and
						// continue.
						if found {
							break
						} else {
							if first_page.is_none() {
								first_page = Some(kb);
							}
							kb = vec![];
					InlineKeyboardButton::for_callback_data("1",
						Callback::list("xxx", 0).to_string()),
				])
							i = 0
						}
					}
				}
				if !found {
					// name not found, showing first page
					kb = first_page.unwrap_or_default();
				}
			}
			if long {
				kb.push(vec![
					InlineKeyboardButton::for_callback_data("<<",
						Callback::list("", if *page == 0 { *page } else { page - 1 } ).to_string()),
					InlineKeyboardButton::for_callback_data(">>",
						Callback::list("", page + 1).to_string()),