From 5ec49db2ce734130071568ff57adc8deba595e9a Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Sun, 23 Jun 2024 22:26:54 -0500 Subject: [PATCH] add time --- Cargo.lock | 9 +++++++ apps/journal/Cargo.toml | 1 + apps/journal/manifest.yml | 21 ++++++++++++---- apps/journal/src/lib.rs | 9 ++----- crates/panorama-app-sdk-macros/Cargo.toml | 9 +++++++ crates/panorama-app-sdk-macros/src/lib.rs | 1 + crates/panorama-app-sdk/Cargo.toml | 2 ++ crates/panorama-app-sdk/src/lib.rs | 10 ++++++-- crates/panorama-app-sdk/src/sys.rs | 3 +++ .../panorama-core/src/state/apps/internal.rs | 6 +++++ crates/panorama-core/src/state/apps/macros.rs | 1 + .../panorama-core/src/state/apps/manifest.rs | 20 ++++++++-------- crates/panorama-core/src/state/mod.rs | 12 ++++++++++ crates/panorama-core/src/tests/mod.rs | 2 ++ crates/panorama-daemon/Cargo.toml | 2 ++ crates/panorama-daemon/src/apps.rs | 15 ++++++++++++ crates/panorama-daemon/src/journal.rs | 4 ++-- crates/panorama-daemon/src/lib.rs | 1 + crates/panorama-daemon/src/mail.rs | 2 -- crates/panorama-daemon/src/main.rs | 24 ++++++++++++++++++- crates/panorama-daemon/src/node.rs | 9 +++---- docs/.gitignore | 1 + docs/src/custom_apps.md | 2 +- 23 files changed, 131 insertions(+), 35 deletions(-) create mode 100644 crates/panorama-app-sdk-macros/Cargo.toml create mode 100644 crates/panorama-app-sdk-macros/src/lib.rs create mode 100644 crates/panorama-daemon/src/apps.rs diff --git a/Cargo.lock b/Cargo.lock index 8295ee3..47ff1f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3478,9 +3478,15 @@ dependencies = [ name = "panorama-app-sdk" version = "0.1.0" dependencies = [ + "chrono", + "panorama-app-sdk-macros", "wee_alloc", ] +[[package]] +name = "panorama-app-sdk-macros" +version = "0.1.0" + [[package]] name = "panorama-core" version = "0.1.0" @@ -3514,11 +3520,13 @@ dependencies = [ "async-imap", "axum", "chrono", + "clap", "csv", "dirs 5.0.1", "futures", "itertools 0.13.0", "panorama-core", + "schemars", "serde", "serde_json", "sugars", @@ -3536,6 +3544,7 @@ dependencies = [ name = "panorama-journal" version = "0.1.0" dependencies = [ + "chrono", "panorama-app-sdk", ] diff --git a/apps/journal/Cargo.toml b/apps/journal/Cargo.toml index 2bb35b4..a555b0a 100644 --- a/apps/journal/Cargo.toml +++ b/apps/journal/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" crate-type = ["cdylib", "rlib"] [dependencies] +chrono = "0.4.38" panorama-app-sdk = { path = "../../crates/panorama-app-sdk" } diff --git a/apps/journal/manifest.yml b/apps/journal/manifest.yml index 51f22f4..f199e68 100644 --- a/apps/journal/manifest.yml +++ b/apps/journal/manifest.yml @@ -1,4 +1,4 @@ -name: journal +name: "@panorama/journal" version: 0.1.0 panorama_version: 0.1.0 description: Note taking app @@ -6,9 +6,22 @@ description: Note taking app # installer_path: ../../target/wasm32-unknown-unknown/wasm-release/panorama_journal.wasm installer_path: ../../target/wasm32-unknown-unknown/wasm-debug/panorama_journal.wasm +node_types: + - name: page + - name: block + +keys: + - name: page/content + type: text + + - name: page/day + type: date + endpoints: -- url: /date/:date - method: GET - export_name: get_date_info + - url: /date/:date + method: GET + export_name: get_date_info + permissions: + - "@panorama/current_time" triggers: \ No newline at end of file diff --git a/apps/journal/src/lib.rs b/apps/journal/src/lib.rs index 35337aa..7b9eeef 100644 --- a/apps/journal/src/lib.rs +++ b/apps/journal/src/lib.rs @@ -3,12 +3,7 @@ #[macro_use] extern crate panorama_app_sdk; -use panorama_app_sdk::prelude::*; - -panorama_app_sdk::init!(); - #[no_mangle] -pub fn install() -> i32 { - println!("SHIET"); - 123 +pub fn get_date_info() { + panorama_app_sdk::get_current_time(); } diff --git a/crates/panorama-app-sdk-macros/Cargo.toml b/crates/panorama-app-sdk-macros/Cargo.toml new file mode 100644 index 0000000..fd3b9b1 --- /dev/null +++ b/crates/panorama-app-sdk-macros/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "panorama-app-sdk-macros" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] diff --git a/crates/panorama-app-sdk-macros/src/lib.rs b/crates/panorama-app-sdk-macros/src/lib.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/crates/panorama-app-sdk-macros/src/lib.rs @@ -0,0 +1 @@ + diff --git a/crates/panorama-app-sdk/Cargo.toml b/crates/panorama-app-sdk/Cargo.toml index a21decd..1df07f2 100644 --- a/crates/panorama-app-sdk/Cargo.toml +++ b/crates/panorama-app-sdk/Cargo.toml @@ -8,3 +8,5 @@ crate-type = ["rlib"] [dependencies] wee_alloc = "0.4.5" +panorama-app-sdk-macros = { path = "../panorama-app-sdk-macros" } +chrono = "0.4.38" diff --git a/crates/panorama-app-sdk/src/lib.rs b/crates/panorama-app-sdk/src/lib.rs index b311a3a..ebdb40f 100644 --- a/crates/panorama-app-sdk/src/lib.rs +++ b/crates/panorama-app-sdk/src/lib.rs @@ -1,5 +1,7 @@ #![no_std] +use chrono::{DateTime, Utc}; + pub extern crate wee_alloc; #[macro_use] @@ -13,6 +15,10 @@ pub mod macros; pub mod internal; pub mod sys; -pub mod prelude { - // pub use crate::macros::println; +pub mod prelude {} + +/// Returns the current time +pub fn get_current_time() -> DateTime { + let result = unsafe { sys::_get_current_time() }; + DateTime::from_timestamp_nanos(result) } diff --git a/crates/panorama-app-sdk/src/sys.rs b/crates/panorama-app-sdk/src/sys.rs index 8b753d6..dd6e494 100644 --- a/crates/panorama-app-sdk/src/sys.rs +++ b/crates/panorama-app-sdk/src/sys.rs @@ -11,4 +11,7 @@ extern "C" { // callback: *mut RegisterCallback, callback_data: *mut c_void, ); + + /// Returns the current time in nanoseconds + pub fn _get_current_time() -> i64; } diff --git a/crates/panorama-core/src/state/apps/internal.rs b/crates/panorama-core/src/state/apps/internal.rs index c1604cb..42cbf2a 100644 --- a/crates/panorama-core/src/state/apps/internal.rs +++ b/crates/panorama-core/src/state/apps/internal.rs @@ -1,6 +1,7 @@ use std::io::{stdout, Write}; use anyhow::Result; +use chrono::{DateTime, Utc}; use wasmtime::{Caller, InstancePre, Linker, Memory}; pub struct WasmtimeModule { @@ -41,5 +42,10 @@ impl WasmtimeInstanceEnv { println!("Called print: {}", s); } + pub fn get_current_time(_: Caller<'_, Self>) -> i64 { + let now = Utc::now(); + now.timestamp_nanos_opt().unwrap() + } + pub fn register_endpoint(mut caller: Caller<'_, Self>) {} } diff --git a/crates/panorama-core/src/state/apps/macros.rs b/crates/panorama-core/src/state/apps/macros.rs index 0725311..d9fa4a2 100644 --- a/crates/panorama-core/src/state/apps/macros.rs +++ b/crates/panorama-core/src/state/apps/macros.rs @@ -2,6 +2,7 @@ macro_rules! abi_funcs { ($macro_name:ident) => { // TODO: Why is this "env"? How do i use another name $macro_name! { + "env"::get_current_time, "env"::print, "env"::register_endpoint, } diff --git a/crates/panorama-core/src/state/apps/manifest.rs b/crates/panorama-core/src/state/apps/manifest.rs index 67f0819..548e0fc 100644 --- a/crates/panorama-core/src/state/apps/manifest.rs +++ b/crates/panorama-core/src/state/apps/manifest.rs @@ -4,21 +4,21 @@ use schemars::JsonSchema; #[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct AppManifest { - name: String, - version: Option, - panorama_version: Option, - description: Option, - installer_path: PathBuf, + pub name: String, + pub version: Option, + pub panorama_version: Option, + pub description: Option, + pub installer_path: PathBuf, - endpoints: Vec, - triggers: Vec, + pub endpoints: Vec, + pub triggers: Vec, } #[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct AppManifestEndpoint { - url: String, - method: String, - export_name: String, + pub url: String, + pub method: String, + pub export_name: String, } #[derive(Debug, Serialize, Deserialize, JsonSchema)] diff --git a/crates/panorama-core/src/state/mod.rs b/crates/panorama-core/src/state/mod.rs index 11ae214..15c03d7 100644 --- a/crates/panorama-core/src/state/mod.rs +++ b/crates/panorama-core/src/state/mod.rs @@ -49,6 +49,14 @@ pub struct AppState { pub tantivy_field_map: BiMap, pub app_wasm_modules: HashMap, + // TODO: Compile this into a more efficient thing than just iter + pub app_routes: HashMap>, +} + +#[derive(Clone)] +pub struct AppRoute { + route: String, + handler_name: String, } impl AppState { @@ -82,6 +90,8 @@ impl AppState { db, tantivy_index, tantivy_field_map, + app_wasm_modules: Default::default(), + app_routes: Default::default(), }; state.init().await?; @@ -105,4 +115,6 @@ impl AppState { Ok(()) } + + pub fn handle_app_route() {} } diff --git a/crates/panorama-core/src/tests/mod.rs b/crates/panorama-core/src/tests/mod.rs index 4e68a6e..c9725de 100644 --- a/crates/panorama-core/src/tests/mod.rs +++ b/crates/panorama-core/src/tests/mod.rs @@ -18,6 +18,8 @@ pub async fn test_state() -> Result { db, tantivy_index, tantivy_field_map, + app_routes: Default::default(), + app_wasm_modules: Default::default(), }; Ok(state) diff --git a/crates/panorama-daemon/Cargo.toml b/crates/panorama-daemon/Cargo.toml index 56255e3..8835f57 100644 --- a/crates/panorama-daemon/Cargo.toml +++ b/crates/panorama-daemon/Cargo.toml @@ -9,12 +9,14 @@ edition = "2021" anyhow = "1.0.86" axum = "0.7.5" chrono = { version = "0.4.38", features = ["serde"] } +clap = { version = "4.5.7", features = ["derive"] } # cozo = { version = "0.7.6", features = ["storage-rocksdb"] } csv = "1.3.0" dirs = "5.0.1" futures = "0.3.30" itertools = "0.13.0" panorama-core = { path = "../panorama-core" } +schemars = "0.8.21" serde = { version = "1.0.202", features = ["derive"] } serde_json = "1.0.117" sugars = "3.0.1" diff --git a/crates/panorama-daemon/src/apps.rs b/crates/panorama-daemon/src/apps.rs new file mode 100644 index 0000000..103f3a8 --- /dev/null +++ b/crates/panorama-daemon/src/apps.rs @@ -0,0 +1,15 @@ +use axum::{ + routing::{method_routing, MethodFilter}, + Router, +}; +use panorama_core::AppState; +use utoipa::OpenApi; + +#[derive(OpenApi)] +#[openapi(paths(), components(schemas()))] +pub(super) struct AppsApi; + +pub(super) fn router() -> Router { + Router::new() + // .route("/app/:id/*path", method_routing::any(handler)) +} diff --git a/crates/panorama-daemon/src/journal.rs b/crates/panorama-daemon/src/journal.rs index 5e2c559..1a4a154 100644 --- a/crates/panorama-daemon/src/journal.rs +++ b/crates/panorama-daemon/src/journal.rs @@ -1,7 +1,7 @@ -use axum::{Router}; +use axum::Router; use utoipa::OpenApi; -use crate::{AppState}; +use crate::AppState; /// Node API #[derive(OpenApi)] diff --git a/crates/panorama-daemon/src/lib.rs b/crates/panorama-daemon/src/lib.rs index e05cbc8..bbb0283 100644 --- a/crates/panorama-daemon/src/lib.rs +++ b/crates/panorama-daemon/src/lib.rs @@ -7,6 +7,7 @@ extern crate serde_json; #[macro_use] extern crate sugars; +pub mod apps; mod error; mod journal; pub mod mail; diff --git a/crates/panorama-daemon/src/mail.rs b/crates/panorama-daemon/src/mail.rs index fbf5dd8..72c4ac7 100644 --- a/crates/panorama-daemon/src/mail.rs +++ b/crates/panorama-daemon/src/mail.rs @@ -1,5 +1,3 @@ - - // pub async fn get_mail_config( // State(state): State, // ) -> AppResult> { diff --git a/crates/panorama-daemon/src/main.rs b/crates/panorama-daemon/src/main.rs index 6adf129..646f980 100644 --- a/crates/panorama-daemon/src/main.rs +++ b/crates/panorama-daemon/src/main.rs @@ -1,10 +1,32 @@ use anyhow::Result; +use clap::{Parser, Subcommand}; +use panorama_core::state::apps::manifest::AppManifest; +use schemars::schema_for; + +#[derive(Debug, Parser)] +struct Opt { + #[clap(subcommand)] + command: Option, +} + +#[derive(Debug, Subcommand)] +enum Command { + GenerateConfigSchema, +} #[tokio::main] async fn main() -> Result<()> { + let opt = Opt::parse(); + tracing_subscriber::fmt::init(); - panorama_daemon::run().await?; + match opt.command { + Some(Command::GenerateConfigSchema) => { + let schema = schema_for!(AppManifest); + println!("{}", serde_json::to_string_pretty(&schema).unwrap()); + } + None => panorama_daemon::run().await?, + } Ok(()) } diff --git a/crates/panorama-daemon/src/node.rs b/crates/panorama-daemon/src/node.rs index 5ac8cd4..a5bd337 100644 --- a/crates/panorama-daemon/src/node.rs +++ b/crates/panorama-daemon/src/node.rs @@ -1,10 +1,7 @@ +use axum::Router; +use utoipa::OpenApi; -use axum::{ - Router, -}; -use utoipa::{OpenApi}; - -use crate::{AppState}; +use crate::AppState; /// Node API #[derive(OpenApi)] diff --git a/docs/.gitignore b/docs/.gitignore index 7585238..a8894e0 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1 +1,2 @@ book +src/generated \ No newline at end of file diff --git a/docs/src/custom_apps.md b/docs/src/custom_apps.md index 305dc50..5d78013 100644 --- a/docs/src/custom_apps.md +++ b/docs/src/custom_apps.md @@ -16,7 +16,7 @@ After this rolls out, most of the built-in panorama apps will also be converted To develop a custom app, you will need to provide: - - App metadata. This contains: + App metadata in a `manifest.yml`. This contains: - App display name. - Version + License.