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 = "2.2.3"
|
||||||
ed25519-dalek = "2.1.1"
|
ed25519-dalek = "2.1.1"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
blake3 = "1.5.0"
|
||||||
rust_socketio = "0.4.4"
|
rust_socketio = "0.4.4"
|
||||||
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
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>,
|
pub admin_list: Vec<i64>,
|
||||||
/// Python 插件路径
|
/// Python 插件路径
|
||||||
pub py_plugin_path: String,
|
pub py_plugin_path: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IcaConfig {
|
impl IcaConfig {
|
||||||
|
|
|
@ -21,7 +21,6 @@ fn main() {
|
||||||
tracing_subscriber::fmt()
|
tracing_subscriber::fmt()
|
||||||
.with_max_level(tracing::Level::DEBUG)
|
.with_max_level(tracing::Level::DEBUG)
|
||||||
.init();
|
.init();
|
||||||
py::init_py();
|
|
||||||
|
|
||||||
// 从命令行获取 host 和 key
|
// 从命令行获取 host 和 key
|
||||||
// 从命令行获取配置文件路径
|
// 从命令行获取配置文件路径
|
||||||
|
@ -29,6 +28,7 @@ fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
ClientStatus.update_config(ica_config.clone());
|
ClientStatus.update_config(ica_config.clone());
|
||||||
}
|
}
|
||||||
|
py::init_py(&ica_config);
|
||||||
let ica_singer = client::IcalinguaSinger::new_from_config(&ica_config);
|
let ica_singer = client::IcalinguaSinger::new_from_config(&ica_config);
|
||||||
|
|
||||||
let socket = ClientBuilder::new(ica_singer.host.clone())
|
let socket = ClientBuilder::new(ica_singer.host.clone())
|
||||||
|
|
|
@ -19,6 +19,16 @@ impl IcaStatusPy {
|
||||||
unsafe { ClientStatus.login }
|
unsafe { ClientStatus.login }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
pub fn get_online(&self) -> bool {
|
||||||
|
unsafe {
|
||||||
|
match ClientStatus.online_data.as_ref() {
|
||||||
|
Some(data) => data.online,
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[getter]
|
#[getter]
|
||||||
pub fn get_self_id(&self) -> Option<i64> {
|
pub fn get_self_id(&self) -> Option<i64> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -30,7 +40,7 @@ impl IcaStatusPy {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[getter]
|
#[getter]
|
||||||
pub fn get_nicn_name(&self) -> Option<String> {
|
pub fn get_nick_name(&self) -> Option<String> {
|
||||||
unsafe {
|
unsafe {
|
||||||
match ClientStatus.online_data.as_ref() {
|
match ClientStatus.online_data.as_ref() {
|
||||||
Some(data) => Some(data.nick.clone()),
|
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]
|
#[getter]
|
||||||
pub fn get_ica_version(&self) -> Option<String> {
|
pub fn get_ica_version(&self) -> Option<String> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -1,7 +1,63 @@
|
||||||
pub mod class;
|
pub mod class;
|
||||||
|
|
||||||
|
use std::{collections::HashMap, path::PathBuf};
|
||||||
|
|
||||||
use pyo3::{prelude::*, types::IntoPyDict};
|
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() {
|
pub fn run() {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
|
@ -9,12 +65,47 @@ pub fn run() {
|
||||||
let _bot_status: &PyCell<_> = PyCell::new(py, bot_status).unwrap();
|
let _bot_status: &PyCell<_> = PyCell::new(py, bot_status).unwrap();
|
||||||
|
|
||||||
let locals = [("state", _bot_status)].into_py_dict(py);
|
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");
|
debug!("initing python threads");
|
||||||
pyo3::prepare_freethreaded_python();
|
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")
|
info!("python inited")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user