use pyo3::prelude::*;
use pyo3::types::{PyString, PyBool, PyIterator};
use std::collections::HashMap;
pub use pyo3::exceptions::*;
pub struct Galaxy {
db: Py<PyAny>
}
impl Galaxy {
pub fn new (module_path: &str, api_path: &str, silent: bool) -> Self {
match Python::with_gil(|py| -> PyResult<Self> {
let db: Py<PyAny> = PyModule::import(py, "galaxy")?
.getattr("galaxy")?
.getattr("Galaxy")?
.call1((silent, module_path, api_path))?
.into();
Ok(Galaxy { db })
}) {
Ok(x) => x,
Err(_) => todo!(),
}
}
pub fn with_dir (dir: &str, module_path: &str, api_path: &str, silent: bool) -> Self {
Python::with_gil(|py| {
PyModule::import(py, "os").unwrap()
.getattr("chdir").unwrap()
.call1((dir,)).unwrap();
});
Self::new(module_path, api_path, silent)
}
pub fn registry_handler (&self) -> RegistryHandler {
let res: PyResult<RegistryHandler> = Python::with_gil(|py| {
let handler: Py<PyAny> = PyModule::import(py, "galaxy")?
.getattr("registry")?
.into();
Ok(RegistryHandler::new(handler))
});
match res {
Ok(x) => x,
Err(_) => todo!()
}
}
pub fn load_node (&mut self, loc: &str) -> Result<(), PyErr> {
Python::with_gil(|py| {
self.db.as_ref(py)
.getattr("load_node")
.expect("Galaxy object should have attribute load_node")
.call1((loc,))?;
Ok(())
})
}
pub fn process_new_match (&mut self, srcnode: &str) -> Result<(), PyErr> {
Python::with_gil(|py| {
self.db.as_ref(py)
.getattr("process_new_match")
.expect("Galaxy object should have attribute process_new_match")
.call1((srcnode,))?;
Ok(())
})
}
pub fn flush (&mut self) -> Result<(), PyErr> {
Python::with_gil(|py| {
self.db.as_ref(py)
.getattr("flush")
.expect("Galaxy object should have attribute flush")
.call0()?;
Ok(())
})
}
pub fn get (&self, node: &str) -> Result<Node, PyErr> {
Python::with_gil(|py| {
let output = self.db.as_ref(py)
.getattr("get")
.expect("Galaxy object should have attribute get")
.call1((node,))?;
Ok(Node::new(output.into()))
})
}
pub fn nodes (&self) -> Result<HashMap<String, Node>, PyErr> {
Python::with_gil(|py| {
let db = self.db.as_ref(py);
let nodes = db.getattr("nodes").expect("Galaxy object should have nodes");
let mut output: HashMap<String, Node> = HashMap::new();
for i in nodes.iter()? {
let key = i?.downcast::<PyString>()?.to_str()?;
let node: Node = Node::new(nodes.get_item(key)?.into());
output.insert(String::from(key), node);
}
Ok(output)
})
}
pub fn modules (&self) -> Result<Vec<String>, PyErr> {
Python::with_gil(|py| {
Ok(self.db.as_ref(py)
.getattr("modules").expect("Galaxy object should have modules")
.getattr("keys").expect("Python dict object should have keys method")
.call0().expect("Python dict.keys() should not error")
.iter().expect("Python dict.keys() should be iterable")
.map(|x| String::from(x.unwrap().downcast::<PyString>().unwrap().to_str().unwrap()))
.collect())
})
}
pub fn silent (&self) -> Result<bool, PyErr> {
Python::with_gil(|py| {
Ok(self.db.as_ref(py)
.getattr("silent").expect("Galaxy object should have bool silent")
.downcast::<PyBool>().expect("silent flag should be bool")
.extract().unwrap())
})
}
}
pub struct Node {
py_obj: Py<PyAny>,
}
impl Node {
fn new (py_obj: Py<PyAny>) -> Self {
Node {
py_obj
}
}
pub fn content (&self) -> Result<String, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.getattr("content")?
.downcast::<PyString>()?
.to_str()?;
Ok(String::from(result))
})
}
pub fn match_data (&self) -> Result<String, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.getattr("match_data")?
.downcast::<PyString>()?
.to_str()?;
Ok(String::from(result))
})
}
pub fn parsed_data (&self) -> Result<NodeData, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.getattr("parsed_data")?
.into();
Ok(NodeData::new(result))
})
}
}
pub struct NodeData {
py_obj: Py<PyAny>,
}
impl NodeData {
fn new (py_obj: Py<PyAny>) -> Self {
Self {
py_obj
}
}
pub fn title (&self) -> Result<String, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.get_item("title")?
.downcast::<PyString>()?
.to_str()?;
Ok(String::from(result))
})
}
pub fn data_type (&self) -> Result<String, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.get_item("type")?
.downcast::<PyString>()?
.to_str()?;
Ok(String::from(result))
})
}
pub fn source (&self) -> Result<String, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.get_item("source")?
.downcast::<PyString>()?
.to_str()?;
Ok(String::from(result))
})
}
pub fn links (&self) -> Result<Vec<Link>, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.get_item("links")?
.iter()?
.map(|i| Link::new((i.unwrap()).into()))
.collect();
Ok(result)
})
}
pub fn flush (&self) -> Result<(), PyErr> {
Python::with_gil(|py| {
self.py_obj.as_ref(py)
.getattr("flush")?
.call0()?;
Ok(())
})
}
}
pub struct Link {
py_obj: Py<PyAny>
}
impl Link {
fn new (py_obj: Py<PyAny>) -> Self {
Self {
py_obj
}
}
pub fn target (&self) -> Result<String, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.get_item("target")?
.downcast::<PyString>()?
.to_str()?;
Ok(String::from(result))
})
}
pub fn strength (&self) -> Result<i64, PyErr> {
Python::with_gil(|py| {
let result = self.py_obj.as_ref(py)
.get_item("strength")?
.extract()?;
Ok(result)
})
}
}
fn from_pystring_unchecked (x: PyResult<&PyAny>) -> String {
String::from(x.unwrap().downcast::<PyString>().unwrap().to_str().unwrap())
}
pub struct RegistryHandler {
py_obj: Py<PyAny>
}
impl RegistryHandler {
fn new (py_obj: Py<PyAny>) -> Self {
Self {
py_obj
}
}
fn node_registry (&self) -> Py<PyAny> {
Python::with_gil(|py| {
self.py_obj.as_ref(py)
.getattr("NODE_REGISTRY").expect("Node Registry should exist")
.into()
})
}
fn ingest_manager_registry (&self) -> Py<PyAny> {
Python::with_gil(|py| {
self.py_obj.as_ref(py)
.getattr("INGEST_MANAGER_REGISTRY").expect("Ingest Manager Registry should exist")
.into()
})
}
fn keys (x: &PyAny) -> &PyIterator {
x.getattr("keys").expect("Registry object should have keys")
.iter().expect("Python list should be iterable")
}
pub fn registered_nodes (&self) -> Vec<String> {
Python::with_gil(|py| {
Self::keys(self.node_registry().as_ref(py))
.map(from_pystring_unchecked)
.collect()
})
}
pub fn registered_ingest_managers (&self) -> Vec<String> {
Python::with_gil(|py| {
Self::keys(self.ingest_manager_registry().as_ref(py))
.map(from_pystring_unchecked)
.collect()
})
}
}