1
Fork 0
dokku-hosts-api/src/main.rs

74 lines
1.7 KiB
Rust

use async_std::path::PathBuf;
use async_std::stream::StreamExt;
use axum::extract::State;
use axum::{routing::get, Router};
use std::net::SocketAddr;
use tokio::task::JoinSet;
mod dokku;
mod utils;
use dokku::DokkuApp;
#[derive(Clone)]
struct AppState {
dokku_root: PathBuf,
}
async fn hosts(State(state): State<AppState>) -> axum::Json<Vec<DokkuApp>> {
let mut dir_entries = state.dokku_root.read_dir().await.unwrap();
let mut join_set = JoinSet::new();
while let Some(Ok(dir_entry)) = dir_entries.next().await {
// Skip hidden folders / files
if utils::osstring_starts_with(dir_entry.file_name(), '.') {
continue;
}
let path = dir_entry.path();
if !path.is_dir().await {
continue;
}
join_set.spawn(DokkuApp::try_from_path(path));
}
let mut apps: Vec<DokkuApp> = Vec::new();
while let Some(res) = join_set.join_next().await {
if let Some(app) = res.unwrap() {
apps.push(app)
}
}
axum::Json(apps)
}
#[tokio::main]
async fn main() {
let dokku_root = match dokku::get_dokku_root() {
Some(path) => path,
None => {
println!("Failed to find dokku root");
std::process::exit(1);
}
};
println!("Using dokku root: {}", dokku_root.display());
let state = AppState {
dokku_root: PathBuf::from(dokku_root),
};
let app = Router::new().route("/hosts", get(hosts)).with_state(state);
let addr = &SocketAddr::new(utils::get_bind_host(), utils::get_port());
println!("Listening on {addr}");
axum::Server::bind(addr)
.serve(app.into_make_service())
.await
.unwrap();
}