fix(cli): serve new SPA version

develop
Tomáš Mládek 2024-01-26 22:41:43 +01:00
parent c0daf59d46
commit 309a968550
6 changed files with 198 additions and 50 deletions

153
Cargo.lock generated
View File

@ -283,6 +283,56 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "actix-web-lab"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7675c1a84eec1b179c844cdea8488e3e409d8e4984026e92fa96c87dd86f33c6"
dependencies = [
"actix-files",
"actix-http",
"actix-router",
"actix-service",
"actix-utils",
"actix-web",
"actix-web-lab-derive",
"ahash 0.8.3",
"arc-swap",
"async-trait",
"bytes",
"bytestring",
"csv",
"derive_more",
"futures-core",
"futures-util",
"http",
"impl-more",
"itertools",
"local-channel",
"mediatype",
"mime",
"once_cell",
"pin-project-lite",
"regex",
"serde",
"serde_html_form",
"serde_json",
"tokio",
"tokio-stream",
"tracing",
]
[[package]]
name = "actix-web-lab-derive"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aa0b287c8de4a76b691f29dbb5451e8dd5b79d777eaf87350c9b0cbfdb5e968"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.29",
]
[[package]]
name = "actix_derive"
version = "0.6.0"
@ -431,6 +481,12 @@ version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "arc-swap"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
[[package]]
name = "arrayref"
version = "0.3.7"
@ -449,6 +505,17 @@ version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
[[package]]
name = "async-trait"
version = "0.1.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.29",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -752,6 +819,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
[[package]]
name = "constcat"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d5cd0c57ef83705837b1cb872c973eff82b070846d3e23668322b2c0f8246d0"
[[package]]
name = "convert_case"
version = "0.4.0"
@ -889,6 +962,27 @@ dependencies = [
"typenum",
]
[[package]]
name = "csv"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe"
dependencies = [
"csv-core",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
dependencies = [
"memchr",
]
[[package]]
name = "darling"
version = "0.14.4"
@ -1491,6 +1585,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "impl-more"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d"
[[package]]
name = "indexmap"
version = "1.9.3"
@ -1532,6 +1632,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "itertools"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.9"
@ -1757,6 +1866,12 @@ dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "mediatype"
version = "0.19.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a018c36a54f4e12c30464bbc59311f85d3f6f4d6c1b4fa4ea9db2b174ddefc"
[[package]]
name = "memchr"
version = "2.6.0"
@ -2598,6 +2713,19 @@ dependencies = [
"syn 2.0.29",
]
[[package]]
name = "serde_html_form"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224e6a14f315852940f3ec103125aa6482f0e224732ed91ed3330ed633077c34"
dependencies = [
"form_urlencoded",
"indexmap 2.0.0",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_json"
version = "1.0.105"
@ -2962,9 +3090,21 @@ dependencies = [
"pin-project-lite",
"signal-hook-registry",
"socket2 0.5.3",
"tokio-macros",
"windows-sys",
]
[[package]]
name = "tokio-macros"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.29",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
@ -2975,6 +3115,17 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.8"
@ -3178,11 +3329,13 @@ dependencies = [
"actix-multipart",
"actix-rt",
"actix-web",
"actix-web-lab",
"actix_derive",
"anyhow",
"bytes",
"chrono",
"clap",
"constcat",
"diesel",
"diesel_migrations",
"filebuffer",

View File

@ -89,6 +89,8 @@ url = "2"
bytes = "1.4.0"
signal-hook = "0.3.15"
actix-web-lab = { version = "0.20.2", features = ["spa"] }
constcat = "0.4.1"
[build-dependencies]
shadow-rs = { version = "0.23", default-features = false }

View File

@ -1,29 +1,17 @@
use std::{env::current_exe, path::PathBuf};
use constcat::concat;
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use shadow_rs::{is_debug, shadow};
use shadow_rs::shadow;
shadow!(build);
pub fn get_resource_path<S: AsRef<str>>(dir: S) -> Result<std::path::PathBuf> {
let base_path = if is_debug() {
let cwd = build::CARGO_MANIFEST_DIR.parse::<PathBuf>()?;
cwd.join("./tmp/resources")
} else {
current_exe()?
.parent()
.ok_or(anyhow!("couldn't locate resource path, binary in root"))?
.join("../share/upend")
};
#[cfg(not(debug_assertions))]
pub const RESOURCE_PATH: &str = "../share/upend";
let result = base_path.join(dir.as_ref());
if result.exists() {
Ok(result)
} else {
Err(anyhow!("Path {result:?} doesn't exist."))
}
}
#[cfg(debug_assertions)]
pub const RESOURCE_PATH: &str = "./tmp/resources";
pub const WEBUI_PATH: &str = concat!(RESOURCE_PATH, "/webui");
lazy_static! {
static ref APP_USER_AGENT: String = format!("upend / {}", build::PKG_VERSION);

View File

@ -1,7 +1,7 @@
#[macro_use]
extern crate upend_db;
use crate::common::{get_resource_path, REQWEST_ASYNC_CLIENT};
use crate::common::{REQWEST_ASYNC_CLIENT, WEBUI_PATH};
use crate::config::UpEndConfig;
use actix_web::HttpServer;
use anyhow::Result;
@ -342,20 +342,20 @@ async fn main() -> Result<()> {
FsStore::from_path(args.store_path.unwrap_or_else(|| vault_path.clone())).unwrap(),
) as Box<dyn UpStore + Send + Sync>);
let ui_path = if args.no_ui {
None
let webui_enabled = if args.no_ui {
false
} else {
let ui_path = get_resource_path("webui");
if ui_path.is_err() {
let exists = Path::new(WEBUI_PATH).exists();
if !exists {
warn!(
"Couldn't locate Web UI directory ({:?}), disabling...",
ui_path
WEBUI_PATH
);
}
ui_path.ok()
exists
};
let browser_enabled = !args.no_desktop && ui_path.is_some() && !args.no_browser;
let browser_enabled = !args.no_desktop && webui_enabled && !args.no_browser;
let preview_path = upend.path.join("previews");
#[cfg(feature = "previews")]
@ -425,11 +425,10 @@ async fn main() -> Result<()> {
let mut cnt = 0;
let server = loop {
let state = state.clone();
let ui_path = ui_path.clone();
let allowed_origins = args.allow_host.clone();
let server = HttpServer::new(move || {
serve::get_app(ui_path.clone(), allowed_origins.clone(), state.clone())
serve::get_app(webui_enabled, allowed_origins.clone(), state.clone())
});
let bind_result = server.bind(&bind);
@ -475,7 +474,7 @@ async fn main() -> Result<()> {
#[cfg(feature = "desktop")]
{
if browser_enabled && ui_path.is_some() {
if browser_enabled {
let ui_result = webbrowser::open(&format!("http://localhost:{}", bind.port()));
if ui_result.is_err() {
warn!("Could not open UI in browser!");

View File

@ -1048,10 +1048,11 @@ mod tests {
#[actix_web::test]
async fn test_get_info() {
let app = actix_web::test::init_service(crate::serve::get_app::<
std::path::PathBuf,
Vec<String>,
>(None, vec![], get_state()))
let app = actix_web::test::init_service(crate::serve::get_app::<Vec<String>>(
false,
vec![],
get_state(),
))
.await;
let req = actix_web::test::TestRequest::get()
.uri("/api/info")
@ -1070,10 +1071,11 @@ mod tests {
#[actix_web::test]
async fn test_get_hier() {
let app = actix_web::test::init_service(crate::serve::get_app::<
std::path::PathBuf,
Vec<String>,
>(None, vec![], get_state()))
let app = actix_web::test::init_service(crate::serve::get_app::<Vec<String>>(
false,
vec![],
get_state(),
))
.await;
let req = actix_web::test::TestRequest::get()
@ -1125,10 +1127,11 @@ mod tests {
#[actix_web::test]
async fn test_obj_entity_info() {
let app = actix_web::test::init_service(crate::serve::get_app::<
std::path::PathBuf,
Vec<String>,
>(None, vec![], get_state()))
let app = actix_web::test::init_service(crate::serve::get_app::<Vec<String>>(
false,
vec![],
get_state(),
))
.await;
let digest = UpMultihash::from_sha256([1, 2, 3, 4, 5]).unwrap();

View File

@ -1,8 +1,8 @@
use crate::routes;
use std::path::Path;
use actix_web_lab::web::spa;
pub fn get_app<P, S>(
ui_path: Option<P>,
pub fn get_app<S>(
ui_enabled: bool,
allowed_origins: S,
state: crate::routes::State,
) -> actix_web::App<
@ -15,7 +15,6 @@ pub fn get_app<P, S>(
>,
>
where
P: AsRef<Path> + Clone,
S: IntoIterator<Item = String> + Clone,
{
let allowed_origins: Vec<String> = allowed_origins.into_iter().collect();
@ -69,9 +68,13 @@ where
.service(routes::put_options)
.service(routes::get_user_entries);
if let Some(ui_path) = ui_path {
return app
.service(actix_files::Files::new("/", ui_path.as_ref()).index_file("index.html"));
if ui_enabled {
return app.service(
spa()
.index_file(crate::common::WEBUI_PATH.to_owned() + "/index.html")
.static_resources_location(crate::common::WEBUI_PATH)
.finish(),
);
}
#[actix_web::get("/")]