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 = [
"members/pt",
"members/pt-bin",
"members/pt-core",
"members/pt-py",
"members/pt-log",
"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]
autobins = true
name = "pt-bin"
version = "0.1.0"
edition = "2021"

View File

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

View File

@ -18,6 +18,7 @@
#![warn(clippy::pedantic)]
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
use pyo3::{exceptions::PyException, PyErr};
use tracing::subscriber::SetGlobalDefaultError;
//// 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 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@ -82,3 +96,4 @@ impl std::fmt::Display for Error {
//// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////

View File

@ -25,6 +25,8 @@ use error::*;
pub use tracing::{debug, error, info, trace, warn, Level};
use tracing_appender;
use tracing_subscriber::{prelude::*, fmt::format::FmtSpan};
use pyo3::prelude::*;
//// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
/// The log level used when none is specified
pub const DEFAULT_LOG_LEVEL: Level = Level::INFO;
@ -52,6 +54,7 @@ static INITIALIZED: AtomicBool = AtomicBool::new(false);
/// - `Info`
/// - `Warn`
/// - `Error`
#[pyclass]
pub struct Logger {}
//// 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 {
/// ## Debug representation for [`Logger`]
@ -203,3 +261,4 @@ impl fmt::Debug for Logger {
//// PUBLIC 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
[dependencies]
pt = { version = "0.1.0", path = "../pt" }
pyo3 = { workspace = true }

View File

@ -1,14 +1,98 @@
use pt::*;
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]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
pub fn is_loaded() -> bool {
true
}
/// A Python module implemented in Rust.
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
/// ## Python module: logger
#[pymodule]
fn pt_py(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
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(())
}

View File

@ -1,18 +1,7 @@
[package]
publish = true
autobins = true
default-run = "pt"
name = "libpt"
version = "0.1.6"
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"]
name = "pt"
version = "0.1.0"
# 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"
openssl = "0.10.55"
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"
reqwest = { version = "0.11.18", features = ["blocking"] }
serde = { version = "1.0.171", features = ["derive"] }

View File

@ -21,109 +21,7 @@
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
/// contains useful code, such as macros, for general use
pub mod common;
/// logger used by libpt
pub mod logger;
/// networking tools
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(())
}
pub use pt_core;
pub use pt_log;
pub use pt_net;
pub use pt_hedu;