feat: make db stateful + read scripts from disk
This commit is contained in:
parent
6416c45d12
commit
eb098ea0fd
@ -18,3 +18,4 @@ tower-http = { version = "0.6.4", features = ["fs"] }
|
|||||||
tracing = { version = "0.1.41", features = ["async-await"] }
|
tracing = { version = "0.1.41", features = ["async-await"] }
|
||||||
tracing-subscriber = "0.3.19"
|
tracing-subscriber = "0.3.19"
|
||||||
uuid = { version = "1.16.0", features = ["v4"] }
|
uuid = { version = "1.16.0", features = ["v4"] }
|
||||||
|
walkdir = "2.5.0"
|
||||||
|
@ -46,4 +46,9 @@
|
|||||||
[bool]$IsEnabled
|
[bool]$IsEnabled
|
||||||
)
|
)
|
||||||
|
|
||||||
process {}
|
process {
|
||||||
|
0..20 | %{
|
||||||
|
Write-Output "Info: $($_)"
|
||||||
|
Write-Warning "Warning: $($_)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
24
src/db.rs
24
src/db.rs
@ -12,6 +12,30 @@ pub async fn init_db(pool: &SqlitePool) -> Result<(), String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn open<T: AsRef<str>>(path: T) -> Result<SqlitePool, String> {
|
||||||
|
let db_url = format!("sqlite://{}", path.as_ref());
|
||||||
|
|
||||||
|
SqlitePool::connect(&db_url)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn new<T: AsRef<str>>(path: T) -> Result<SqlitePool, String> {
|
||||||
|
std::fs::File::create_new(path.as_ref()).map_err(|e| e.to_string())?;
|
||||||
|
let db_url = format!("sqlite://{}", path.as_ref());
|
||||||
|
|
||||||
|
SqlitePool::connect(&db_url)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn import_scripts(pool: &SqlitePool, scripts: Vec<Script>) -> Result<(), String> {
|
||||||
|
for script in scripts {
|
||||||
|
add_script(pool, &script).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Write the whole Script into the DB
|
// TODO: Write the whole Script into the DB
|
||||||
// TODO: Add Custom Error type
|
// TODO: Add Custom Error type
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
57
src/lib.rs
57
src/lib.rs
@ -1,21 +1,64 @@
|
|||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::expect_used)]
|
||||||
|
|
||||||
|
use db::import_scripts;
|
||||||
use router::new_router;
|
use router::new_router;
|
||||||
|
use script::Script;
|
||||||
|
use sqlx::SqlitePool;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
mod db;
|
mod db;
|
||||||
mod router;
|
mod router;
|
||||||
mod script;
|
mod script;
|
||||||
|
|
||||||
pub fn run() {
|
pub fn run<T: AsRef<str>>(db_path: T, script_path: T) {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().expect("async runtime should always be available");
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let app = new_router();
|
let db = if let Ok(db) = db::open(db_path.as_ref()).await {
|
||||||
|
db
|
||||||
|
} else {
|
||||||
|
db::new(db_path.as_ref())
|
||||||
|
.await
|
||||||
|
.expect("should always be able to create database")
|
||||||
|
};
|
||||||
|
|
||||||
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
let scripts = read_scripts(script_path.as_ref()).expect("failed to read scripts from dir");
|
||||||
info!("listening"=?listener.local_addr().unwrap());
|
|
||||||
axum::serve(listener, app).await.unwrap();
|
import_scripts(&db, scripts)
|
||||||
|
.await
|
||||||
|
.expect("failed to write scripts to db");
|
||||||
|
|
||||||
|
let app = new_router(db);
|
||||||
|
|
||||||
|
let listener = TcpListener::bind("0.0.0.0:3000")
|
||||||
|
.await
|
||||||
|
.expect("could not attach listener");
|
||||||
|
info!(
|
||||||
|
"listening" = format!(
|
||||||
|
"http://{}",
|
||||||
|
listener
|
||||||
|
.local_addr()
|
||||||
|
.expect("should always return local address")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
axum::serve(listener, app)
|
||||||
|
.await
|
||||||
|
.expect("should always serve app");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_scripts<T: AsRef<str>>(dir: T) -> Result<Vec<Script>, String> {
|
||||||
|
WalkDir::new(dir.as_ref())
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.filter(|e| {
|
||||||
|
let p = e.path();
|
||||||
|
p.is_file() && p.extension().is_some_and(|ext| ext == "ps1")
|
||||||
|
})
|
||||||
|
.map(|e| format!("{}", e.path().to_string_lossy()))
|
||||||
|
.map(Script::from_file)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
@ -18,7 +18,9 @@ use tokio::sync::mpsc; // Use std::process::Stdio
|
|||||||
type Tx = tokio::sync::mpsc::UnboundedSender<Message>;
|
type Tx = tokio::sync::mpsc::UnboundedSender<Message>;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
befehlswerk::run();
|
let db_path = "db_dev.db";
|
||||||
|
let script_path = "powershell";
|
||||||
|
befehlswerk::run(db_path, script_path);
|
||||||
}
|
}
|
||||||
// #[tokio::main]
|
// #[tokio::main]
|
||||||
// async fn main() {
|
// async fn main() {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use axum::routing::{get, get_service};
|
use axum::routing::{get, get_service};
|
||||||
use routes::scripts::get_scripts;
|
use routes::scripts::get_scripts;
|
||||||
|
use sqlx::SqlitePool;
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
mod routes;
|
mod routes;
|
||||||
|
|
||||||
pub fn new_router() -> axum::Router {
|
pub fn new_router(db: SqlitePool) -> axum::Router {
|
||||||
axum::Router::new()
|
axum::Router::new()
|
||||||
.fallback_service(get_service(ServeDir::new("assets")))
|
.fallback_service(get_service(ServeDir::new("assets")))
|
||||||
// .nest_service("/", ServeDir::new("assets"))
|
|
||||||
.route("/scripts", get(get_scripts))
|
.route("/scripts", get(get_scripts))
|
||||||
|
.with_state(db)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user