mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-09-23 23:32:05 +00:00
refactor(send): apply ponytail audit cuts 2, 4, 6
- updated_sequence_task: clone the Task and mutate the two fields instead of rebuilding all 12 by hand (-22 lines; new fields no longer need a sync here) - unify unix_now with db::now_f64 (unix_now() = now_f64() as i64), moved to db.rs next to its clock source - classify_to_send_error takes the MediaFetchFailure label, folding the duplicated inline match in send_batch_via_upload (-8 lines)
This commit is contained in:
@@ -160,3 +160,9 @@ pub fn now_f64() -> f64 {
|
|||||||
.map(|d| d.as_secs_f64())
|
.map(|d| d.as_secs_f64())
|
||||||
.unwrap_or(0.0)
|
.unwrap_or(0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unix timestamp in whole seconds. Same clock as [`now_f64`], for fields
|
||||||
|
/// that store integer seconds (chat-state expiry, edit prompts).
|
||||||
|
pub fn unix_now() -> i64 {
|
||||||
|
now_f64() as i64
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
use super::urls::enqueue_retry;
|
use super::urls::enqueue_retry;
|
||||||
use super::{CHAT_STORE, CONFIG, TASK_QUEUE};
|
use super::{CHAT_STORE, CONFIG, TASK_QUEUE};
|
||||||
|
use crate::db::unix_now;
|
||||||
use crate::send::{self, Task};
|
use crate::send::{self, Task};
|
||||||
use crate::state::unix_now;
|
|
||||||
use teloxide::RequestError;
|
use teloxide::RequestError;
|
||||||
use teloxide::prelude::*;
|
use teloxide::prelude::*;
|
||||||
use teloxide::types::{CallbackQuery, ChatId, MessageId, ParseMode};
|
use teloxide::types::{CallbackQuery, ChatId, MessageId, ParseMode};
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
//! URL is blocked by hotlink protection; the bot downloads the file itself
|
//! URL is blocked by hotlink protection; the bot downloads the file itself
|
||||||
//! and uploads it via multipart).
|
//! and uploads it via multipart).
|
||||||
|
|
||||||
|
use crate::db::unix_now;
|
||||||
use crate::handlers::{CHAT_STORE, LINK_CACHE, TASK_QUEUE, log_key};
|
use crate::handlers::{CHAT_STORE, LINK_CACHE, TASK_QUEUE, log_key};
|
||||||
use crate::link_cache::{CachedMedia, CachedMediaKind, CachedPost, LinkCache};
|
use crate::link_cache::{CachedMedia, CachedMediaKind, CachedPost, LinkCache};
|
||||||
use crate::media_sender::MediaSender;
|
use crate::media_sender::MediaSender;
|
||||||
use crate::photo::{self, MAX_UPLOAD_BYTES, PhotoPrep};
|
use crate::photo::{self, MAX_UPLOAD_BYTES, PhotoPrep};
|
||||||
use crate::queue::QueueError;
|
use crate::queue::QueueError;
|
||||||
use crate::state::{EditMessage, unix_now};
|
use crate::state::EditMessage;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@@ -392,8 +393,7 @@ pub enum SendError {
|
|||||||
Retryable { delay_seconds: f64, task: Box<Task> },
|
Retryable { delay_seconds: f64, task: Box<Task> },
|
||||||
Permanent { message: String, task: Box<Task> },
|
Permanent { message: String, task: Box<Task> },
|
||||||
}
|
}
|
||||||
|
fn classify_to_send_error(e: &RequestError, task: Task, fetch_failure_label: &str) -> SendError {
|
||||||
fn classify_to_send_error(e: &RequestError, task: Task) -> SendError {
|
|
||||||
match classify_request_error(e) {
|
match classify_request_error(e) {
|
||||||
Classification::Retryable { delay_seconds } => SendError::Retryable {
|
Classification::Retryable { delay_seconds } => SendError::Retryable {
|
||||||
delay_seconds,
|
delay_seconds,
|
||||||
@@ -404,7 +404,7 @@ fn classify_to_send_error(e: &RequestError, task: Task) -> SendError {
|
|||||||
task: Box::new(task),
|
task: Box::new(task),
|
||||||
},
|
},
|
||||||
Classification::MediaFetchFailure => SendError::Permanent {
|
Classification::MediaFetchFailure => SendError::Permanent {
|
||||||
message: "media fetch failed".into(),
|
message: fetch_failure_label.into(),
|
||||||
task: Box::new(task),
|
task: Box::new(task),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -879,54 +879,24 @@ async fn send_batch_via_upload(
|
|||||||
drop(keep_alive);
|
drop(keep_alive);
|
||||||
match result {
|
match result {
|
||||||
Ok(messages) => Ok(messages),
|
Ok(messages) => Ok(messages),
|
||||||
Err(e) => Err(match classify_request_error(&e) {
|
Err(e) => Err(classify_to_send_error(&e, task, "upload failed")),
|
||||||
Classification::Retryable { delay_seconds } => SendError::Retryable {
|
|
||||||
delay_seconds,
|
|
||||||
task: Box::new(task.clone()),
|
|
||||||
},
|
|
||||||
Classification::Permanent { message } => SendError::Permanent {
|
|
||||||
message,
|
|
||||||
task: Box::new(task),
|
|
||||||
},
|
|
||||||
Classification::MediaFetchFailure => SendError::Permanent {
|
|
||||||
message: "upload failed".into(),
|
|
||||||
task: Box::new(task),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn updated_sequence_task(task: &Task, batch_index: usize, sent_message_ids: Vec<i64>) -> Task {
|
fn updated_sequence_task(task: &Task, batch_index: usize, sent_message_ids: Vec<i64>) -> Task {
|
||||||
match task {
|
let mut updated = task.clone();
|
||||||
|
match &mut updated {
|
||||||
Task::SendMediaSequence {
|
Task::SendMediaSequence {
|
||||||
chat_id,
|
batch_index: index,
|
||||||
reply_to_message_id,
|
sent_message_ids: ids,
|
||||||
caption,
|
..
|
||||||
media_batches,
|
} => {
|
||||||
batch_index: _,
|
*index = batch_index;
|
||||||
sent_message_ids: _,
|
*ids = sent_message_ids;
|
||||||
source_url,
|
}
|
||||||
edit_before_forward,
|
|
||||||
forward_channel_id,
|
|
||||||
notify_chat_id,
|
|
||||||
notify_message_id,
|
|
||||||
cache_data,
|
|
||||||
} => Task::SendMediaSequence {
|
|
||||||
chat_id: *chat_id,
|
|
||||||
reply_to_message_id: *reply_to_message_id,
|
|
||||||
caption: caption.clone(),
|
|
||||||
media_batches: media_batches.clone(),
|
|
||||||
batch_index,
|
|
||||||
sent_message_ids,
|
|
||||||
source_url: source_url.clone(),
|
|
||||||
edit_before_forward: *edit_before_forward,
|
|
||||||
forward_channel_id: *forward_channel_id,
|
|
||||||
notify_chat_id: *notify_chat_id,
|
|
||||||
notify_message_id: *notify_message_id,
|
|
||||||
cache_data: cache_data.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!("updated_sequence_task requires a SendMediaSequence task"),
|
_ => unreachable!("updated_sequence_task requires a SendMediaSequence task"),
|
||||||
}
|
}
|
||||||
|
updated
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends the media batches starting at `task.batch_index`, extending
|
/// Sends the media batches starting at `task.batch_index`, extending
|
||||||
@@ -1014,6 +984,7 @@ pub async fn send_media_sequence(
|
|||||||
return Err(classify_to_send_error(
|
return Err(classify_to_send_error(
|
||||||
&e,
|
&e,
|
||||||
updated_sequence_task(task, idx, sent),
|
updated_sequence_task(task, idx, sent),
|
||||||
|
"media fetch failed",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1115,13 +1086,21 @@ pub async fn send_animation(sender: &dyn MediaSender, task: &Task) -> Result<Vec
|
|||||||
cache_animation_send(task, &message).await;
|
cache_animation_send(task, &message).await;
|
||||||
Ok(vec![id])
|
Ok(vec![id])
|
||||||
}
|
}
|
||||||
Err(e) => Err(classify_to_send_error(&e, task.clone())),
|
Err(e) => Err(classify_to_send_error(
|
||||||
|
&e,
|
||||||
|
task.clone(),
|
||||||
|
"media fetch failed",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => Err(SendError::from_fallback(e, task.clone())),
|
Err(e) => Err(SendError::from_fallback(e, task.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => Err(classify_to_send_error(&e, task.clone())),
|
Err(e) => Err(classify_to_send_error(
|
||||||
|
&e,
|
||||||
|
task.clone(),
|
||||||
|
"media fetch failed",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1158,7 +1137,11 @@ pub async fn forward_messages(sender: &dyn MediaSender, task: &Task) -> Result<(
|
|||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(classify_to_send_error(&e, task.clone())),
|
Err(e) => Err(classify_to_send_error(
|
||||||
|
&e,
|
||||||
|
task.clone(),
|
||||||
|
"media fetch failed",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
//! Per-chat state with SQLite persistence (table `chat_state` in
|
//! Per-chat state with SQLite persistence (table `chat_state` in
|
||||||
//! `data/task_queue.db`, shared with the task queue).
|
//! `data/task_queue.db`, shared with the task queue).
|
||||||
|
|
||||||
|
use crate::db::unix_now;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use rusqlite::params;
|
use rusqlite::params;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::Duration;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Default, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Default, Clone, Debug)]
|
||||||
pub struct ChatData {
|
pub struct ChatData {
|
||||||
@@ -40,13 +41,6 @@ pub struct ChatStore {
|
|||||||
pool: Arc<crate::db::DbPool>,
|
pool: Arc<crate::db::DbPool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unix_now() -> i64 {
|
|
||||||
SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.map(|d| d.as_secs() as i64)
|
|
||||||
.unwrap_or(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChatStore {
|
impl ChatStore {
|
||||||
/// Wraps the shared DB pool (schema initialized once by
|
/// Wraps the shared DB pool (schema initialized once by
|
||||||
/// [`crate::db::open_store`]; the `chat_state` table lives in the merged
|
/// [`crate::db::open_store`]; the `chat_state` table lives in the merged
|
||||||
|
|||||||
Reference in New Issue
Block a user