intermediate

This commit is contained in:
Christoph J. Scherr 2023-09-20 14:32:25 +02:00
parent 9fb726b5df
commit f2bab05909
11 changed files with 198 additions and 127 deletions

View File

@ -12,9 +12,26 @@ members = [
] ]
default-members = [ default-members = [
"members/pt", "members/pt",
"members/pt-bin",
"members/pt-core", "members/pt-core",
"members/pt-py", "members/pt-py",
"members/pt-log", "members/pt-log",
"members/pt-math", "members/pt-math",
] ]
[workspace.package]
publish = false
default-run = "pt"
name = "libpt"
version = "0.1.7"
edition = "2021"
authors = ["Christoph J. Scherr <software@cscherr.de>"]
license = "MIT"
description = "Personal multitool"
readme = "README.md"
homepage = "https://git.cscherr.de/PlexSheep/pt"
repository = "https://git.cscherr.de/PlexSheep/pt"
keywords = ["cli", "python", "scriptable", "pyo3", "library"]
categories = ["command-line-utilities", "development-tools", "development-tools::ffi"]
[workspace.dependencies]
pyo3 = "0.19"

View File

@ -1,4 +1,5 @@
[package] [package]
autobins = true
name = "pt-bin" name = "pt-bin"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"

View File

@ -10,6 +10,7 @@ tracing = "0.1.37"
tracing-appender = "0.2.2" tracing-appender = "0.2.2"
tracing-subscriber = "0.3.17" tracing-subscriber = "0.3.17"
env_logger = "0.10.0" env_logger = "0.10.0"
pyo3 = {workspace = true}
[dev-dependencies] [dev-dependencies]
gag = "1.0.0" gag = "1.0.0"

View File

@ -18,6 +18,7 @@
#![warn(clippy::pedantic)] #![warn(clippy::pedantic)]
//// IMPORTS /////////////////////////////////////////////////////////////////////////////////////// //// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
use pyo3::{exceptions::PyException, PyErr};
use tracing::subscriber::SetGlobalDefaultError; use tracing::subscriber::SetGlobalDefaultError;
//// TYPES ///////////////////////////////////////////////////////////////////////////////////////// //// TYPES /////////////////////////////////////////////////////////////////////////////////////////
@ -57,6 +58,19 @@ impl From<SetGlobalDefaultError> for Error {
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
impl Into<PyErr> for Error {
fn into(self) -> PyErr {
match self {
Error::IO(err) => PyException::new_err(format!("LoggerError: IO {err:?}")),
Error::Usage(err) => PyException::new_err(format!("LoggerError: Usage {err}")),
Error::SetGlobalDefaultFail(err) => {
PyException::new_err(format!("LoggerError: SetGlobalDefaultFail {err}"))
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
impl std::fmt::Debug for Error { impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@ -82,3 +96,4 @@ impl std::fmt::Display for Error {
//// PUBLIC FUNCTIONS ////////////////////////////////////////////////////////////////////////////// //// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
//// PRIVATE FUNCTIONS ///////////////////////////////////////////////////////////////////////////// //// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////

View File

@ -25,6 +25,8 @@ use error::*;
pub use tracing::{debug, error, info, trace, warn, Level}; pub use tracing::{debug, error, info, trace, warn, Level};
use tracing_appender; use tracing_appender;
use tracing_subscriber::{prelude::*, fmt::format::FmtSpan}; use tracing_subscriber::{prelude::*, fmt::format::FmtSpan};
use pyo3::prelude::*;
//// CONSTANTS ///////////////////////////////////////////////////////////////////////////////////// //// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
/// The log level used when none is specified /// The log level used when none is specified
pub const DEFAULT_LOG_LEVEL: Level = Level::INFO; pub const DEFAULT_LOG_LEVEL: Level = Level::INFO;
@ -52,6 +54,7 @@ static INITIALIZED: AtomicBool = AtomicBool::new(false);
/// - `Info` /// - `Info`
/// - `Warn` /// - `Warn`
/// - `Error` /// - `Error`
#[pyclass]
pub struct Logger {} pub struct Logger {}
//// IMPLEMENTATION //////////////////////////////////////////////////////////////////////////////// //// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
@ -188,6 +191,61 @@ impl Logger {
} }
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Implementation of the python interface
#[pymethods]
impl Logger {
/// ## Python version of [`new()`](Logger::new)
#[new]
pub fn py_new() -> PyResult<Self> {
Ok(Logger::new())
}
/// ## Python version of [`init()`](Logger::init)
#[pyo3(name = "init")]
#[staticmethod]
pub fn py_init(log_dir: Option<PathBuf>, max_level: Option<String>) -> Result<()> {
Self::init(
log_dir,
match max_level {
Some(s) => match s.to_uppercase().as_str() {
"TRACE" => Some(tracing::Level::TRACE),
"DEBUG" => Some(tracing::Level::DEBUG),
"INFO" => Some(tracing::Level::INFO),
"WARN" => Some(tracing::Level::WARN),
"ERROR" => Some(tracing::Level::ERROR),
_ => return Err(Error::Usage(format!("'{s}' is not a valid log level"))),
},
None => None,
},
)
}
/// ## Python version of [`error()`](Logger::error)
#[pyo3(name = "error")]
pub fn py_error(&self, printable: String) {
self.error(printable)
}
/// ## Python version of [`warn()`](Logger::warn)
#[pyo3(name = "warn")]
pub fn py_warn(&self, printable: String) {
self.warn(printable)
}
/// ## Python version of [`info()`](Logger::info)
#[pyo3(name = "info")]
pub fn py_info(&self, printable: String) {
self.info(printable)
}
/// ## Python version of [`debug()`](Logger::debug)
#[pyo3(name = "debug")]
pub fn py_debug(&self, printable: String) {
self.debug(printable)
}
/// ## Python version of [`trace()`](Logger::trace)
#[pyo3(name = "trace")]
pub fn py_trace(&self, printable: String) {
self.trace(printable)
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
impl fmt::Debug for Logger { impl fmt::Debug for Logger {
/// ## Debug representation for [`Logger`] /// ## Debug representation for [`Logger`]
@ -203,3 +261,4 @@ impl fmt::Debug for Logger {
//// PUBLIC FUNCTIONS ////////////////////////////////////////////////////////////////////////////// //// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
//// PRIVATE FUNCTIONS ///////////////////////////////////////////////////////////////////////////// //// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////

View File

@ -6,3 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
pt = { version = "0.1.0", path = "../pt" }
pyo3 = { workspace = true }

View File

@ -1,14 +1,98 @@
use pt::*;
use pyo3::prelude::*; use pyo3::prelude::*;
/// Formats the sum of two numbers as string. //// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
/// ## Check if [`libpt`](crate) has been loaded
///
/// Always returns `true` if you can execute it.
#[pyfunction] #[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> { pub fn is_loaded() -> bool {
Ok((a + b).to_string()) true
} }
/// A Python module implemented in Rust. //// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
/// ## Python module: logger
#[pymodule] #[pymodule]
fn pt_py(_py: Python, m: &PyModule) -> PyResult<()> { fn py_logger(py: Python, parent: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?; let module = PyModule::new(py, "logger")?;
module.add_class::<Logger>()?;
parent.add_submodule(module)?;
Ok(()) Ok(())
} }
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: common
#[pymodule]
fn py_common(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "common")?;
py_common_printing(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: common.printing
#[pymodule]
fn py_common_printing(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "printing")?;
module.add_function(wrap_pyfunction!(common::printing::divider, module)?)?;
module.add_function(wrap_pyfunction!(common::printing::print_divider, module)?)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking
#[pymodule]
fn py_networking(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "networking")?;
py_networking_monitoring(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking.monitoring
#[pymodule]
fn py_networking_monitoring(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "monitoring")?;
py_networking_monitoring_uptime(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking.monitoring.uptime
#[pymodule]
fn py_networking_monitoring_uptime(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "uptime")?;
module.add_class::<networking::monitoring::uptime::UptimeStatus>()?;
module.add_function(wrap_pyfunction!(
networking::monitoring::uptime::py_continuous_uptime_monitor,
module
)?)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: root
///
/// This function is the entry point of [`PyO3`](pyo3). This is where the main module is built.
#[pymodule]
fn _libpt(py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(is_loaded, m)?)?;
// load sub modules
py_common(py, m)?;
py_logger(py, m)?;
py_networking(py, m)?;
Ok(())
}

View File

@ -1,18 +1,7 @@
[package] [package]
publish = true
autobins = true
default-run = "pt" default-run = "pt"
name = "libpt" name = "pt"
version = "0.1.6" version = "0.1.0"
edition = "2021"
authors = ["Christoph J. Scherr <software@cscherr.de>"]
license = "GPL-3.0-or-later"
description = "Personal multitool"
readme = "README.md"
homepage = "https://git.cscherr.de/PlexSheep/pt"
repository = "https://git.cscherr.de/PlexSheep/pt"
keywords = ["cli", "python", "scriptable", "pyo3", "library"]
categories = ["command-line-utilities", "development-tools", "development-tools::ffi"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -39,7 +28,12 @@ num = "0.4.0"
num-traits = "0.2.16" num-traits = "0.2.16"
openssl = "0.10.55" openssl = "0.10.55"
openssl-sys = "0.9.90" openssl-sys = "0.9.90"
pyo3 = "0.18.1" pt-bin = { version = "0.1.0", path = "../pt-bin" }
pt-core = { version = "0.1.0", path = "../pt-core" }
pt-hedu = { version = "0.1.0", path = "../pt-hedu" }
pt-log = { version = "0.1.0", path = "../pt-log" }
pt-math = { version = "0.1.0", path = "../pt-math" }
pt-net = { version = "0.1.0", path = "../pt-net" }
regex = "1.9.1" regex = "1.9.1"
reqwest = { version = "0.11.18", features = ["blocking"] } reqwest = { version = "0.11.18", features = ["blocking"] }
serde = { version = "1.0.171", features = ["derive"] } serde = { version = "1.0.171", features = ["derive"] }

View File

@ -21,109 +21,7 @@
//// IMPORTS /////////////////////////////////////////////////////////////////////////////////////// //// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
/// contains useful code, such as macros, for general use /// contains useful code, such as macros, for general use
pub mod common; pub use pt_core;
/// logger used by libpt pub use pt_log;
pub mod logger; pub use pt_net;
/// networking tools pub use pt_hedu;
pub mod networking;
/// math tools
pub mod math;
use crate::logger::Logger;
use pyo3::prelude::*;
//// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
/// ## Check if [`libpt`](crate) has been loaded
///
/// Always returns `true` if you can execute it.
#[pyfunction]
pub fn is_loaded() -> bool {
true
}
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
/// ## Python module: logger
#[pymodule]
fn py_logger(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "logger")?;
module.add_class::<Logger>()?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: common
#[pymodule]
fn py_common(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "common")?;
py_common_printing(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: common.printing
#[pymodule]
fn py_common_printing(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "printing")?;
module.add_function(wrap_pyfunction!(common::printing::divider, module)?)?;
module.add_function(wrap_pyfunction!(common::printing::print_divider, module)?)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking
#[pymodule]
fn py_networking(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "networking")?;
py_networking_monitoring(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking.monitoring
#[pymodule]
fn py_networking_monitoring(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "monitoring")?;
py_networking_monitoring_uptime(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking.monitoring.uptime
#[pymodule]
fn py_networking_monitoring_uptime(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "uptime")?;
module.add_class::<networking::monitoring::uptime::UptimeStatus>()?;
module.add_function(wrap_pyfunction!(
networking::monitoring::uptime::py_continuous_uptime_monitor,
module
)?)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: root
///
/// This function is the entry point of [`PyO3`](pyo3). This is where the main module is built.
#[pymodule]
fn _libpt(py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(is_loaded, m)?)?;
// load sub modules
py_common(py, m)?;
py_logger(py, m)?;
py_networking(py, m)?;
Ok(())
}