diff --git a/ica-rs/Cargo.toml b/ica-rs/Cargo.toml index 28e5a14..63f9f16 100644 --- a/ica-rs/Cargo.toml +++ b/ica-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ica-rs" -version = "0.4.10" +version = "0.4.11" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/ica-rs/ica_typing.py b/ica-rs/ica_typing.py index d7ba009..7c52b75 100644 --- a/ica-rs/ica_typing.py +++ b/ica-rs/ica_typing.py @@ -1,6 +1,6 @@ # Python 兼容版本 3.8+ -from typing import Optional, Callable +from typing import Callable """ pub type RoomId = i64; @@ -14,6 +14,10 @@ MessageId = str class IcaStatus: + """ + ica状态信息 + 此类并不存储信息, 所有方法都是实时获取 + """ @property def login(self) -> bool: ... @@ -21,25 +25,25 @@ class IcaStatus: def online(self) -> bool: ... @property - def self_id(self) -> Optional[UserId]: + def self_id(self) -> UserId: ... @property - def nick_name(self) -> Optional[str]: + def nick_name(self) -> str: ... @property - def ica_version(self) -> Optional[str]: + def ica_version(self) -> str: ... @property - def os_info(self) -> Optional[str]: + def os_info(self) -> str: ... @property - def resident_set_size(self) -> Optional[str]: + def resident_set_size(self) -> str: ... @property - def head_used(self) -> Optional[str]: + def head_used(self) -> str: ... @property - def load_average(self) -> Optional[str]: + def load_average(self) -> str: ... @@ -62,9 +66,16 @@ class SendMessage: return self +class DeleteMessage: + def __str__(self): + ... + + class NewMessage: def reply_with(self, message: str) -> SendMessage: ... + def as_deleted(self) -> DeleteMessage: + ... def __str__(self) -> str: ... @property @@ -94,6 +105,8 @@ class IcaClient: """ def send_message(self, message: SendMessage) -> bool: ... + def delete_message(self, message: DeleteMessage) -> bool: + ... @property def status() -> IcaStatus: diff --git a/ica-rs/src/client.rs b/ica-rs/src/client.rs index ff77a4e..0356ee9 100644 --- a/ica-rs/src/client.rs +++ b/ica-rs/src/client.rs @@ -1,6 +1,8 @@ use crate::config::IcaConfig; -use crate::data_struct::messages::SendMessage; -use crate::data_struct::{all_rooms::Room, online_data::OnlineData}; +use crate::data_struct::all_rooms::Room; +use crate::data_struct::messages::{DeleteMessage, SendMessage}; +use crate::data_struct::online_data::OnlineData; +use crate::data_struct::RoomId; use crate::ClientStatus; use colored::Colorize; @@ -24,10 +26,31 @@ pub async fn send_message(client: &Client, message: &SendMessage) -> bool { } } } +/// "安全" 的 删除一条消息 +pub async fn delete_message(client: &Client, message: &DeleteMessage) -> bool { + let value = message.as_value(); + match client.emit("deleteMessage", value).await { + Ok(_) => { + debug!("delete_message {}", format!("{:#?}", message).yellow()); + true + } + Err(e) => { + warn!("delete_message faild:{}", format!("{:#?}", e).red()); + false + } + } +} +/// "安全" 的 获取历史消息 +/// ```typescript +/// async fetchHistory(messageId: string, roomId: number, currentLoadedMessagesCount: number) +/// ``` +pub async fn fetch_history(client: &Client, roomd_id: RoomId) -> bool { false } #[derive(Debug, Clone)] pub struct IcalinguaStatus { pub login: bool, + /// currentLoadedMessagesCount + pub current_loaded_messages_count: u64, pub online_data: Option, pub rooms: Option>, pub config: Option, @@ -37,26 +60,58 @@ impl IcalinguaStatus { pub fn new() -> Self { Self { login: false, + current_loaded_messages_count: 0, online_data: None, rooms: None, config: Some(IcaConfig::new_from_cli()), } } - pub fn update_online_data(&mut self, online_data: OnlineData) { - self.online_data = Some(online_data); + #[inline] + pub fn update_online_data(online_data: OnlineData) { + unsafe { + ClientStatus.online_data = Some(online_data); + } } - - pub fn update_rooms(&mut self, rooms: Vec) { self.rooms = Some(rooms); } - - pub fn update_login_status(&mut self, login: bool) { self.login = login; } - - pub fn update_config(&mut self, config: IcaConfig) { self.config = Some(config); } - + #[inline] + pub fn update_rooms(rooms: Vec) { + unsafe { + ClientStatus.rooms = Some(rooms); + } + } + #[inline] + pub fn update_login_status(login: bool) { + unsafe { + ClientStatus.login = login; + } + } + #[inline] + pub fn update_config(config: IcaConfig) { + unsafe { + ClientStatus.config = Some(config); + } + } + #[inline] + pub fn update_loaded_messages_count(count: u64) { + unsafe { + ClientStatus.current_loaded_messages_count = count; + } + } + #[inline] + pub fn get_login_status() -> bool { unsafe { ClientStatus.login } } + #[inline] + pub fn get_rooms() -> &'static Vec { + unsafe { ClientStatus.rooms.as_ref().expect("rooms should be set") } + } + #[inline] + pub fn get_loaded_messages_count() -> u64 { + unsafe { ClientStatus.current_loaded_messages_count } + } + #[inline] pub fn get_online_data() -> &'static OnlineData { unsafe { ClientStatus.online_data.as_ref().expect("online_data should be set") } } - + #[inline] pub fn get_config() -> &'static IcaConfig { unsafe { ClientStatus.config.as_ref().expect("config should be set") } } diff --git a/ica-rs/src/data_struct/messages.rs b/ica-rs/src/data_struct/messages.rs index ea187b5..696a531 100644 --- a/ica-rs/src/data_struct/messages.rs +++ b/ica-rs/src/data_struct/messages.rs @@ -277,6 +277,14 @@ impl NewMessage { pub fn reply_with(&self, content: &String) -> SendMessage { SendMessage::new(content.clone(), self.room_id, Some(self.msg.as_reply())) } + + /// 作为被删除的消息 + pub fn as_deleted(&self) -> DeleteMessage { + DeleteMessage { + room_id: self.room_id, + message_id: self.msg.msg_id.clone(), + } + } } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -303,6 +311,25 @@ impl SendMessage { pub fn as_value(&self) -> JsonValue { serde_json::to_value(self).unwrap() } } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DeleteMessage { + #[serde(rename = "roomId")] + pub room_id: RoomId, + #[serde(rename = "messageId")] + pub message_id: MessageId, +} + +impl DeleteMessage { + pub fn new(room_id: RoomId, message_id: MessageId) -> Self { + Self { + room_id, + message_id, + } + } + + pub fn as_value(&self) -> JsonValue { serde_json::to_value(self).unwrap() } +} + // #[cfg(test)] // mod test { // use serde_json::json; diff --git a/ica-rs/src/events.rs b/ica-rs/src/events.rs index d4a610b..e6b9cc1 100644 --- a/ica-rs/src/events.rs +++ b/ica-rs/src/events.rs @@ -15,9 +15,7 @@ pub async fn get_online_data(payload: Payload, _client: Client) { if let Some(value) = values.first() { let online_data = OnlineData::new_from_json(value); info!("update_online_data {}", format!("{:?}", online_data).cyan()); - unsafe { - crate::ClientStatus.update_online_data(online_data); - } + IcalinguaStatus::update_online_data(online_data); } } } @@ -78,9 +76,7 @@ pub async fn update_all_room(payload: Payload, _client: Client) { if let Some(raw_rooms) = value.as_array() { let rooms: Vec = raw_rooms.iter().map(|room| Room::new_from_json(room)).collect(); - unsafe { - crate::ClientStatus.update_rooms(rooms.clone()); - } + IcalinguaStatus::update_rooms(rooms.clone()); info!("update_all_room {}", rooms.len()); } } diff --git a/ica-rs/src/main.rs b/ica-rs/src/main.rs index 56c1f3c..e5eee01 100644 --- a/ica-rs/src/main.rs +++ b/ica-rs/src/main.rs @@ -14,6 +14,7 @@ mod py; #[allow(non_upper_case_globals)] pub static mut ClientStatus: client::IcalinguaStatus = client::IcalinguaStatus { login: false, + current_loaded_messages_count: 0, online_data: None, rooms: None, config: None, @@ -41,9 +42,7 @@ async fn main() { // 从命令行获取 host 和 key // 从命令行获取配置文件路径 let ica_config = config::IcaConfig::new_from_cli(); - unsafe { - ClientStatus.update_config(ica_config.clone()); - } + client::IcalinguaStatus::update_config(ica_config.clone()); py::init_py(&ica_config); let socket = ClientBuilder::new(ica_config.host.clone()) diff --git a/ica-rs/src/py/class.rs b/ica-rs/src/py/class.rs index 5732fb4..9bcd989 100644 --- a/ica-rs/src/py/class.rs +++ b/ica-rs/src/py/class.rs @@ -3,8 +3,10 @@ use rust_socketio::asynchronous::Client; use tokio::runtime::Runtime; use tracing::{debug, info, warn}; -use crate::client::send_message; -use crate::data_struct::messages::{MessageTrait, NewMessage, ReplyMessage, SendMessage}; +use crate::client::{delete_message, send_message, IcalinguaStatus}; +use crate::data_struct::messages::{ + DeleteMessage, MessageTrait, NewMessage, ReplyMessage, SendMessage, +}; use crate::data_struct::MessageId; use crate::ClientStatus; @@ -16,88 +18,39 @@ pub struct IcaStatusPy {} impl IcaStatusPy { #[new] pub fn py_new() -> Self { Self {} } - #[getter] pub fn get_login(&self) -> bool { unsafe { ClientStatus.login } } - #[getter] - pub fn get_online(&self) -> bool { - unsafe { - match ClientStatus.online_data.as_ref() { - Some(data) => data.online, - None => false, - } - } + pub fn get_online(&self) -> bool { IcalinguaStatus::get_online_data().online } + #[getter] + pub fn get_self_id(&self) -> i64 { IcalinguaStatus::get_online_data().qqid } + #[getter] + pub fn get_nick_name(&self) -> String { IcalinguaStatus::get_online_data().nick.clone() } + #[getter] + pub fn get_loaded_messages_count(&self) -> u64 { IcalinguaStatus::get_loaded_messages_count() } + #[getter] + pub fn get_ica_version(&self) -> String { + IcalinguaStatus::get_online_data().icalingua_info.ica_version.clone() } #[getter] - pub fn get_self_id(&self) -> Option { - unsafe { - match ClientStatus.online_data.as_ref() { - Some(data) => Some(data.qqid), - None => None, - } - } + pub fn get_os_info(&self) -> String { + IcalinguaStatus::get_online_data().icalingua_info.os_info.clone() } #[getter] - pub fn get_nick_name(&self) -> Option { - unsafe { - match ClientStatus.online_data.as_ref() { - Some(data) => Some(data.nick.clone()), - None => None, - } - } + pub fn get_resident_set_size(&self) -> String { + IcalinguaStatus::get_online_data().icalingua_info.resident_set_size.clone() } #[getter] - pub fn get_ica_version(&self) -> Option { - unsafe { - match ClientStatus.online_data.as_ref() { - Some(data) => Some(data.icalingua_info.ica_version.clone()), - None => None, - } - } + pub fn get_heap_used(&self) -> String { + IcalinguaStatus::get_online_data().icalingua_info.heap_used.clone() } #[getter] - pub fn get_os_info(&self) -> Option { - unsafe { - match ClientStatus.online_data.as_ref() { - Some(data) => Some(data.icalingua_info.os_info.clone()), - None => None, - } - } - } - - #[getter] - pub fn get_resident_set_size(&self) -> Option { - unsafe { - match ClientStatus.online_data.as_ref() { - Some(data) => Some(data.icalingua_info.resident_set_size.clone()), - None => None, - } - } - } - - #[getter] - pub fn get_heap_used(&self) -> Option { - unsafe { - match ClientStatus.online_data.as_ref() { - Some(data) => Some(data.icalingua_info.heap_used.clone()), - None => None, - } - } - } - - #[getter] - pub fn get_load(&self) -> Option { - unsafe { - match ClientStatus.online_data.as_ref() { - Some(data) => Some(data.icalingua_info.load.clone()), - None => None, - } - } + pub fn get_load(&self) -> String { + IcalinguaStatus::get_online_data().icalingua_info.load.clone() } } @@ -117,7 +70,7 @@ impl NewMessagePy { pub fn reply_with(&self, content: String) -> SendMessagePy { SendMessagePy::new(self.msg.reply_with(&content)) } - + pub fn as_deleted(&self) -> DeleteMessagePy { DeleteMessagePy::new(self.msg.as_deleted()) } pub fn __str__(&self) -> String { format!("{:?}", self.msg) } #[getter] pub fn get_id(&self) -> MessageId { self.msg.msg_id().clone() } @@ -176,6 +129,22 @@ impl SendMessagePy { pub fn new(msg: SendMessage) -> Self { Self { msg } } } +#[derive(Clone)] +#[pyclass] +#[pyo3(name = "DeleteMessage")] +pub struct DeleteMessagePy { + pub msg: DeleteMessage, +} + +#[pymethods] +impl DeleteMessagePy { + pub fn __str__(&self) -> String { format!("{:?}", self.msg) } +} + +impl DeleteMessagePy { + pub fn new(msg: DeleteMessage) -> Self { Self { msg } } +} + #[derive(Clone)] #[pyclass] #[pyo3(name = "IcaClient")] @@ -192,6 +161,13 @@ impl IcaClientPy { }) } + pub fn delete_message(&self, message: DeleteMessagePy) -> bool { + tokio::task::block_in_place(|| { + let rt = Runtime::new().unwrap(); + rt.block_on(delete_message(&self.client, &message.msg)) + }) + } + /// 仅作占位 /// (因为目前来说, rust调用 Python端没法启动一个异步运行时 /// 所以只能 tokio::task::block_in_place 转换成同步调用) diff --git a/news.md b/news.md index ee28c5e..68c7f65 100644 --- a/news.md +++ b/news.md @@ -1,5 +1,26 @@ # 更新日志 +## 0.4.11 + +这几天就是在刷版本号的感觉 + +- 添加 + - `DeleteMessage` 用于删除消息 + - `NewMessage.as_delete` 用于将消息转换为删除消息 + - `client::delete_message` 用于删除消息 + - `client::fetch_history` 用于获取历史消息 TODO + - `py::class::DeleteMessagePy` 用于删除消息 的 Python 侧 API + - `py::class::IcaClientPy.delete_message` 用于删除消息 的 Python 侧 API + - `IcalinguaStatus.current_loaded_messages_count` + - 用于以后加载信息计数 +- 修改 + - `py::class::IcaStatusPy` + - 大部分方法从手动 `unsafe` + `Option` + - 改成直接调用 `IcalinguaStatus` 的方法 + - `IcalinguaStatus` + - 所有方法均改成 直接对着 `IcalinguaStatus` 的方法调用 + - 补全没有的方法 + ## 0.4.10 好家伙, 我感觉都快能叫 0.5 了