apps
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Michael Zhang 2023-07-18 19:20:56 -05:00
parent 38e21a8c56
commit 5c7b9f583c
6 changed files with 206 additions and 7 deletions

113
Cargo.lock generated
View file

@ -50,6 +50,12 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.10" version = "0.2.10"
@ -61,12 +67,40 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
[[package]]
name = "indexmap"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.147" version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.18.0" version = "1.18.0"
@ -89,6 +123,8 @@ dependencies = [
"once_cell", "once_cell",
"redb", "redb",
"serde", "serde",
"serde_yaml",
"toml",
"uuid", "uuid",
] ]
@ -186,6 +222,12 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.171" version = "1.0.171"
@ -206,6 +248,28 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "serde_spanned"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd5f51e3fdb5b9cdd1577e1cb7a733474191b1aca6a72c2e50913241632c1180"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.26" version = "2.0.26"
@ -243,12 +307,52 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "toml"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
]
[[package]]
name = "toml_datetime"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.19.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.11" version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unsafe-libyaml"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.4.1" version = "1.4.1"
@ -330,3 +434,12 @@ name = "windows_x86_64_msvc"
version = "0.48.0" version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
[[package]]
name = "winnow"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
dependencies = [
"memchr",
]

View file

@ -12,4 +12,6 @@ dirs = "5.0.1"
once_cell = "1.18.0" once_cell = "1.18.0"
redb = "1.0.5" redb = "1.0.5"
serde = { version = "1.0.171", features = ["derive"] } serde = { version = "1.0.171", features = ["derive"] }
serde_yaml = "0.9.24"
toml = "0.7.6"
uuid = { version = "1.4.1", features = ["v4", "v8", "fast-rng"] } uuid = { version = "1.4.1", features = ["v4", "v8", "fast-rng"] }

View file

@ -13,6 +13,8 @@ namespaces:
event-location: event-location:
description: description:
type: integer
event-location: event-location:
description: description:
type: integer

View file

@ -1,20 +1,92 @@
use std::path::Path; use std::{
collections::HashSet,
fs,
path::{Path, PathBuf},
};
use anyhow::Result; use anyhow::Result;
use redb::ReadableTable; use redb::ReadableTable;
use uuid::Uuid; use uuid::Uuid;
use crate::db_keys::{metadata_by_id, nodes_by_id}; use crate::{
apps::meta::{self, AppMetadata},
db_keys::{installed_apps, metadata_by_id, nodes_by_id},
};
pub struct PanoramaDb { pub struct PanoramaDb {
redb_db: redb::Database, redb_db: redb::Database,
app_path: PathBuf,
} }
impl PanoramaDb { impl PanoramaDb {
pub fn open(path: impl AsRef<Path>) -> Result<Self> { pub fn open(
let redb_db = redb::Database::create(path)?; db_path: impl AsRef<Path>,
app_path: impl AsRef<Path>,
) -> Result<Self> {
let redb_db = redb::Database::create(db_path)?;
let app_path = app_path.as_ref().to_path_buf();
let mut panorama = Self { redb_db, app_path };
Ok(Self { redb_db }) panorama.app_init()?;
Ok(panorama)
}
pub fn app_init(&mut self) -> Result<()> {
// Get list of on-disk apps
let on_disk_apps = {
let mut set = HashSet::new();
for entry in fs::read_dir(&self.app_path)? {
let entry = entry?;
let path = entry.path();
if !path.is_dir() {
continue;
}
let meta_file = path.join("meta.yml");
if !path.exists() {
continue;
}
let meta_content = fs::read_to_string(&meta_file)?;
let parsed_toml: AppMetadata = serde_yaml::from_str(&meta_content)?;
set.insert(parsed_toml.name);
}
set
};
println!("On-disk apps: {on_disk_apps:?}");
// Get list of installed apps (in the database)
let installed_apps = {
let mut set = HashSet::new();
let tx = self.redb_db.begin_read()?;
let table = tx.open_table(*installed_apps());
if let Ok(installed_apps_table) = table {
for entry in installed_apps_table.iter()? {
let (key, value) = entry?;
let key = key.value();
let value = value.value();
set.insert(key.to_string());
}
}
set
};
println!("Installed apps: {installed_apps:?}");
// Add new apps to database
let new_apps = on_disk_apps
.difference(&installed_apps)
.collect::<HashSet<_>>();
println!("New apps: {new_apps:?}");
// Remove existing apps
let deleted_apps = installed_apps
.difference(&on_disk_apps)
.collect::<HashSet<_>>();
println!("Deleted apps: {deleted_apps:?}");
Ok(())
} }
pub fn check(&mut self) -> Result<()> { pub fn check(&mut self) -> Result<()> {

View file

@ -2,7 +2,8 @@ use once_cell::sync::OnceCell;
use redb::TableDefinition; use redb::TableDefinition;
macro_rules! table_def { macro_rules! table_def {
($str:ident, $key:ty, $val:ty) => { ($(#[$meta:meta])* $str:ident, $key:ty, $val:ty) => {
$(#[$meta])*
pub fn $str() -> &'static TableDefinition<'static, $key, $val> { pub fn $str() -> &'static TableDefinition<'static, $key, $val> {
static INSTANCE: OnceCell<TableDefinition<'static, $key, $val>> = static INSTANCE: OnceCell<TableDefinition<'static, $key, $val>> =
OnceCell::new(); OnceCell::new();
@ -19,3 +20,12 @@ table_def!(
(&'static str, &'static str, &'static str), (&'static str, &'static str, &'static str),
() ()
); );
table_def!(
/// Table of installed apps
///
/// Maps "name" to (path installed from, json config)
installed_apps,
&'static str,
(&'static str, &'static str)
);

View file

@ -9,7 +9,7 @@ fn main() -> Result<()> {
fs::create_dir_all(&panorama_data_dir)?; fs::create_dir_all(&panorama_data_dir)?;
let database_file_path = panorama_data_dir.join("data.redb"); let database_file_path = panorama_data_dir.join("data.redb");
let database = PanoramaDb::open(database_file_path)?; let database = PanoramaDb::open(database_file_path, "./apps")?;
{ {
let write = database.begin_write()?; let write = database.begin_write()?;