diff --git a/ica-rs/Cargo.toml b/ica-rs/Cargo.toml index 12a2aa6..aa584a8 100644 --- a/ica-rs/Cargo.toml +++ b/ica-rs/Cargo.toml @@ -42,7 +42,7 @@ colored = "3.0" # runtime tokio = { version = "1.43", features = ["full"] } futures-util = "0.3.30" -pyo3 = { version = "0.23", features = ["experimental-async", "py-clone", "abi3-py38"] } +pyo3 = { version = "0.23", features = ["experimental-async", "py-clone"] } anyhow = { version = "1.0", features = ["backtrace"] } # async 这玩意以后在搞 # pyo3-async = "0.3.2" diff --git a/ica-rs/src/ica/events.rs b/ica-rs/src/ica/events.rs index 4d2f637..98c5b5a 100644 --- a/ica-rs/src/ica/events.rs +++ b/ica-rs/src/ica/events.rs @@ -175,9 +175,7 @@ pub async fn failed_message(payload: Payload, _client: Client) { } } -pub async fn fetch_history(client: Client, room: RoomId) { - let mut request_body = json!(room); -} +pub async fn fetch_history(client: Client, room: RoomId) { let mut request_body = json!(room); } pub async fn fetch_messages(client: &Client, room: RoomId) { let mut request_body = json!(room); diff --git a/ica-rs/src/py/mod.rs b/ica-rs/src/py/mod.rs index 6fdd064..8f79e9d 100644 --- a/ica-rs/src/py/mod.rs +++ b/ica-rs/src/py/mod.rs @@ -2,7 +2,7 @@ pub mod call; pub mod class; pub mod config; -use std::ffi::CString; +use std::ffi::{CString, OsStr}; use std::fmt::Display; use std::path::Path; use std::sync::OnceLock; @@ -422,8 +422,61 @@ pub fn init_py() { let plugin_path = MainStatus::global_config().py().plugin_path; - event!(Level::INFO, "正在初始化 python"); - pyo3::prepare_freethreaded_python(); + // 根据 VIRTUAL_ENV 环境变量 进行一些处理 + match std::env::var("VIRTUAL_ENV") { + Ok(virtual_env) => { + event!(Level::INFO, "找到 VIRTUAL_ENV 环境变量: {} 正在初始化", virtual_env); + // 使用 Py_InitializeFromConfig 初始化 python + unsafe { + let mut config = std::mem::zeroed::(); + let config_ptr = &mut config as *mut pyo3::ffi::PyConfig; + // 初始化配置 + // pyo3::ffi::PyConfig_InitIsolatedConfig(config_ptr); + pyo3::ffi::PyConfig_InitPythonConfig(config_ptr); + + #[cfg(target_os = "linux")] + use std::os::unix::ffi::OsStrExt; + #[cfg(target_os = "windows")] + use std::os::windows::ffi::OsStrExt; + + let wide_path = OsStr::new(&virtual_env).encode_wide().collect::>(); + + // 设置 prefix 和 exec_prefix + pyo3::ffi::PyConfig_SetString( + config_ptr, + &mut config.prefix as *mut _, + wide_path.as_ptr() as *mut _, + ); + pyo3::ffi::PyConfig_SetString( + config_ptr, + &mut config.exec_prefix as *mut _, + wide_path.as_ptr() as *mut _, + ); + + // init py + let status = pyo3::ffi::Py_InitializeFromConfig(&config as *const _); + // 清理配置 + pyo3::ffi::PyConfig_Clear(config_ptr); + match status._type { + pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_OK => { + event!(Level::INFO, "根据配置初始化 python 完成"); + } + pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_EXIT => { + event!(Level::ERROR, "初始化 python 时发生错误: EXIT"); + } + pyo3::ffi::_PyStatus_TYPE::_PyStatus_TYPE_ERROR => { + event!(Level::ERROR, "初始化 python 时发生错误: ERROR"); + pyo3::ffi::Py_ExitStatusException(status); + } + } + } + } + Err(_) => { + event!(Level::INFO, "未找到 VIRTUAL_ENV 环境变量, 正常初始化"); + pyo3::prepare_freethreaded_python(); + event!(Level::INFO, "prepare_freethreaded_python 完成"); + } + } PyStatus::init(); let plugin_path = PathBuf::from(plugin_path);