mirror of
http://shenjack.top:5100/shenjack/icalingua-python-bot.git
synced 2024-11-23 12:41:05 +08:00
大的还没来(
This commit is contained in:
parent
f2ea1764ae
commit
00dc10f395
|
@ -9,6 +9,7 @@ edition = "2021"
|
|||
ed25519 = "2.2.3"
|
||||
ed25519-dalek = "2.1.1"
|
||||
hex = "0.4.3"
|
||||
blake3 = "1.5.0"
|
||||
rust_socketio = "0.4.4"
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
|
45
ica-rs/ica_typing.py
Normal file
45
ica-rs/ica_typing.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Python 兼容版本 3.8+
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class IcaStatus:
|
||||
@property
|
||||
def login(self) -> bool:
|
||||
...
|
||||
@property
|
||||
def online(self) -> bool:
|
||||
...
|
||||
@property
|
||||
def self_id(self) -> Optional[bool]:
|
||||
...
|
||||
@property
|
||||
def nick_name(self) -> Optional[str]:
|
||||
...
|
||||
@property
|
||||
def ica_version(self) -> Optional[str]:
|
||||
...
|
||||
@property
|
||||
def os_info(self) -> Optional[str]:
|
||||
...
|
||||
@property
|
||||
def resident_set_size(self) -> Optional[str]:
|
||||
...
|
||||
@property
|
||||
def head_used(self) -> Optional[str]:
|
||||
...
|
||||
@property
|
||||
def load_average(self) -> Optional[str]:
|
||||
...
|
||||
|
||||
|
||||
class NewMessage:
|
||||
...
|
||||
|
||||
|
||||
class ReplyMessage:
|
||||
...
|
||||
|
||||
|
||||
class SendMessage:
|
||||
...
|
0
ica-rs/plugins/test.py
Normal file
0
ica-rs/plugins/test.py
Normal file
|
@ -20,7 +20,7 @@ pub struct IcaConfig {
|
|||
/// 管理员列表
|
||||
pub admin_list: Vec<i64>,
|
||||
/// Python 插件路径
|
||||
pub py_plugin_path: String,
|
||||
pub py_plugin_path: Option<String>,
|
||||
}
|
||||
|
||||
impl IcaConfig {
|
||||
|
|
|
@ -21,7 +21,6 @@ fn main() {
|
|||
tracing_subscriber::fmt()
|
||||
.with_max_level(tracing::Level::DEBUG)
|
||||
.init();
|
||||
py::init_py();
|
||||
|
||||
// 从命令行获取 host 和 key
|
||||
// 从命令行获取配置文件路径
|
||||
|
@ -29,6 +28,7 @@ fn main() {
|
|||
unsafe {
|
||||
ClientStatus.update_config(ica_config.clone());
|
||||
}
|
||||
py::init_py(&ica_config);
|
||||
let ica_singer = client::IcalinguaSinger::new_from_config(&ica_config);
|
||||
|
||||
let socket = ClientBuilder::new(ica_singer.host.clone())
|
||||
|
|
|
@ -19,6 +19,16 @@ impl IcaStatusPy {
|
|||
unsafe { ClientStatus.login }
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_online(&self) -> bool {
|
||||
unsafe {
|
||||
match ClientStatus.online_data.as_ref() {
|
||||
Some(data) => data.online,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_self_id(&self) -> Option<i64> {
|
||||
unsafe {
|
||||
|
@ -30,7 +40,7 @@ impl IcaStatusPy {
|
|||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_nicn_name(&self) -> Option<String> {
|
||||
pub fn get_nick_name(&self) -> Option<String> {
|
||||
unsafe {
|
||||
match ClientStatus.online_data.as_ref() {
|
||||
Some(data) => Some(data.nick.clone()),
|
||||
|
@ -39,16 +49,6 @@ impl IcaStatusPy {
|
|||
}
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_online(&self) -> bool {
|
||||
unsafe {
|
||||
match ClientStatus.online_data.as_ref() {
|
||||
Some(data) => data.online,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[getter]
|
||||
pub fn get_ica_version(&self) -> Option<String> {
|
||||
unsafe {
|
||||
|
|
|
@ -1,7 +1,63 @@
|
|||
pub mod class;
|
||||
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use pyo3::{prelude::*, types::IntoPyDict};
|
||||
use tracing::{debug, info};
|
||||
use tracing::{debug, info, warn};
|
||||
use blake3::Hasher;
|
||||
|
||||
use crate::config::IcaConfig;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PyStatus {
|
||||
pub files: Option<HashMap<PathBuf, (Vec<u8>, String)>>,
|
||||
}
|
||||
|
||||
impl PyStatus {
|
||||
pub fn get_files() -> &'static HashMap<PathBuf, (Vec<u8>, String)> {
|
||||
unsafe {
|
||||
match PYSTATUS.files.as_ref() {
|
||||
Some(files) => files,
|
||||
None => {
|
||||
debug!("No files in py status");
|
||||
PYSTATUS.files = Some(HashMap::new());
|
||||
PYSTATUS.files.as_ref().unwrap()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_file(path: PathBuf, content: Vec<u8>, hash: String) {
|
||||
unsafe {
|
||||
match PYSTATUS.files.as_mut() {
|
||||
Some(files) => {
|
||||
files.insert(path, (content, hash));
|
||||
},
|
||||
None => {
|
||||
let mut files = HashMap::new();
|
||||
files.insert(path, (content, hash));
|
||||
PYSTATUS.files = Some(files);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify_file(path: &PathBuf, hash: &String) -> bool {
|
||||
unsafe {
|
||||
match PYSTATUS.files.as_ref() {
|
||||
Some(files) => {
|
||||
match files.get(path) {
|
||||
Some((_, file_hash)) => file_hash == hash,
|
||||
None => false,
|
||||
}
|
||||
},
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub static mut PYSTATUS: PyStatus = PyStatus { files: None };
|
||||
|
||||
pub fn run() {
|
||||
Python::with_gil(|py| {
|
||||
|
@ -9,12 +65,47 @@ pub fn run() {
|
|||
let _bot_status: &PyCell<_> = PyCell::new(py, bot_status).unwrap();
|
||||
|
||||
let locals = [("state", _bot_status)].into_py_dict(py);
|
||||
py.run("print(state)", None, Some(locals)).unwrap();
|
||||
py.run("from pathlib import Path\nprint(Path.cwd())\nprint(state)", None, Some(locals)).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
pub fn init_py() {
|
||||
pub fn load_py_file(path: &PathBuf) -> (Vec<u8>, String) {
|
||||
let mut hasher = Hasher::new();
|
||||
let content = std::fs::read(path).unwrap();
|
||||
hasher.update(&content);
|
||||
let hash = hasher.finalize().as_bytes().to_vec();
|
||||
(content, hex::encode(hash))
|
||||
}
|
||||
|
||||
pub fn init_py(config: &IcaConfig) {
|
||||
debug!("initing python threads");
|
||||
pyo3::prepare_freethreaded_python();
|
||||
if let Some(plugin_path) = &config.py_plugin_path {
|
||||
let path = PathBuf::from(plugin_path);
|
||||
if path.exists() {
|
||||
info!("finding plugins in: {:?}", path);
|
||||
// 搜索所有的 py 文件 和 文件夹单层下面的 py 文件
|
||||
match path.read_dir() {
|
||||
Err(e) => {
|
||||
warn!("failed to read plugin path: {:?}", e);
|
||||
}
|
||||
Ok(dir) => {
|
||||
for entry in dir {
|
||||
if let Ok(entry) = entry {
|
||||
let path = entry.path();
|
||||
if let Some(ext) = path.extension() {
|
||||
if ext == "py" {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("plugin path not exists: {:?}", path);
|
||||
}
|
||||
}
|
||||
|
||||
info!("python inited")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user