2024-05-25 10:04:05 +00:00
|
|
|
#[macro_use]
|
|
|
|
extern crate anyhow;
|
|
|
|
#[macro_use]
|
2024-05-25 11:45:23 +00:00
|
|
|
extern crate serde;
|
|
|
|
#[macro_use]
|
2024-05-25 10:04:05 +00:00
|
|
|
extern crate serde_json;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate sugars;
|
|
|
|
|
|
|
|
mod error;
|
2024-05-27 02:56:12 +00:00
|
|
|
mod export;
|
2024-05-25 10:04:05 +00:00
|
|
|
mod journal;
|
|
|
|
mod migrations;
|
|
|
|
mod node;
|
2024-05-27 02:56:12 +00:00
|
|
|
mod query_builder;
|
2024-05-25 10:04:05 +00:00
|
|
|
|
|
|
|
use std::fs;
|
|
|
|
|
|
|
|
use anyhow::Result;
|
2024-05-25 11:45:23 +00:00
|
|
|
use axum::{
|
|
|
|
http::Method,
|
2024-05-27 05:43:09 +00:00
|
|
|
routing::{get, post, put},
|
2024-05-25 11:45:23 +00:00
|
|
|
Router,
|
|
|
|
};
|
2024-05-25 10:04:05 +00:00
|
|
|
use cozo::DbInstance;
|
|
|
|
use serde_json::Value;
|
|
|
|
use tokio::net::TcpListener;
|
|
|
|
use tower::ServiceBuilder;
|
|
|
|
use tower_http::cors::{self, CorsLayer};
|
|
|
|
|
|
|
|
use crate::{
|
2024-05-27 02:56:12 +00:00
|
|
|
export::export,
|
2024-05-25 11:45:23 +00:00
|
|
|
journal::get_todays_journal_id,
|
|
|
|
migrations::run_migrations,
|
2024-05-27 05:43:09 +00:00
|
|
|
node::{create_node, get_node, node_types, search_nodes, update_node},
|
2024-05-25 10:04:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct AppState {
|
|
|
|
db: DbInstance,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() -> Result<()> {
|
|
|
|
let data_dir = dirs::data_dir().unwrap();
|
|
|
|
let panorama_dir = data_dir.join("panorama");
|
|
|
|
let db_path = panorama_dir.join("db.sqlite");
|
|
|
|
fs::create_dir_all(panorama_dir)?;
|
|
|
|
|
|
|
|
let db = DbInstance::new(
|
|
|
|
"sqlite",
|
|
|
|
db_path.display().to_string(),
|
|
|
|
Default::default(),
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
run_migrations(&db).await?;
|
|
|
|
|
|
|
|
let state = AppState { db };
|
|
|
|
|
|
|
|
let cors = CorsLayer::new()
|
2024-05-27 06:27:17 +00:00
|
|
|
.allow_methods([Method::GET, Method::POST, Method::PUT])
|
2024-05-27 04:07:02 +00:00
|
|
|
.allow_headers(cors::Any)
|
2024-05-25 10:04:05 +00:00
|
|
|
.allow_origin(cors::Any);
|
|
|
|
|
|
|
|
// build our application with a single route
|
|
|
|
let app = Router::new()
|
|
|
|
.route("/", get(|| async { "Hello, World!" }))
|
2024-05-27 02:56:12 +00:00
|
|
|
.route("/export", get(export))
|
2024-05-27 05:43:09 +00:00
|
|
|
.route("/node", put(create_node))
|
|
|
|
.route("/node/search", get(search_nodes))
|
2024-05-25 10:37:25 +00:00
|
|
|
.route("/node/:id", get(get_node))
|
2024-05-25 11:45:23 +00:00
|
|
|
.route("/node/:id", post(update_node))
|
2024-05-25 15:11:34 +00:00
|
|
|
.route("/node/types", get(node_types))
|
2024-05-25 10:04:05 +00:00
|
|
|
.route("/journal/get_todays_journal_id", get(get_todays_journal_id))
|
|
|
|
.layer(ServiceBuilder::new().layer(cors))
|
|
|
|
.with_state(state);
|
|
|
|
|
|
|
|
let listener = TcpListener::bind("0.0.0.0:5195").await?;
|
2024-05-25 15:11:34 +00:00
|
|
|
println!("Listening... {:?}", listener);
|
2024-05-25 10:04:05 +00:00
|
|
|
axum::serve(listener, app).await?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn ensure_ok(s: &str) -> Result<()> {
|
|
|
|
let status: Value = serde_json::from_str(&s)?;
|
|
|
|
let status = status.as_object().unwrap();
|
|
|
|
let ok = status.get("ok").unwrap().as_bool().unwrap_or(false);
|
|
|
|
if !ok {
|
|
|
|
bail!("shit (error: {s})")
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|