generated from PlexSheep/rs-base
refactor(admin): use warp instead
cargo devel CI / cargo CI (push) Successful in 1m59s
Details
cargo devel CI / cargo CI (push) Successful in 1m59s
Details
This commit is contained in:
parent
8bd156b5fc
commit
1fe799e1c0
|
@ -16,10 +16,11 @@ anyhow = "1.0.86"
|
||||||
async-trait = "0.1.82"
|
async-trait = "0.1.82"
|
||||||
clap = { version = "4.5.17", features = ["derive"] }
|
clap = { version = "4.5.17", features = ["derive"] }
|
||||||
libpt = { version = "0.7.1", features = ["cli", "log"] }
|
libpt = { version = "0.7.1", features = ["cli", "log"] }
|
||||||
|
minijinja = { version = "2.2.0", optional = true }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
serde = { version = "1.0.209", features = ["derive"] }
|
serde = { version = "1.0.209", features = ["derive"] }
|
||||||
serde_json = "1.0.128"
|
serde_json = "1.0.128"
|
||||||
tide = { version = "0.16.0", optional = true }
|
thiserror = "1.0.63"
|
||||||
tokio = { version = "1.40.0", features = [
|
tokio = { version = "1.40.0", features = [
|
||||||
"macros",
|
"macros",
|
||||||
"net",
|
"net",
|
||||||
|
@ -28,7 +29,8 @@ tokio = { version = "1.40.0", features = [
|
||||||
"rt",
|
"rt",
|
||||||
"sync",
|
"sync",
|
||||||
] }
|
] }
|
||||||
|
warp = { version = "0.3.7", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["admin-interface"]
|
default = ["admin-interface"]
|
||||||
admin-interface = ["dep:tide"]
|
admin-interface = ["dep:warp", "dep:minijinja"]
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
|
<meta name="author" content="{AUTHOR}">
|
||||||
<meta name="generator" content="Hugo 0.122.0">
|
<meta name="generator" content="Hugo 0.122.0">
|
||||||
<title>Starter Template · Bootstrap v5.3</title>
|
<title>Starter Template · Bootstrap v5.3</title>
|
||||||
|
|
||||||
|
@ -21,19 +21,15 @@
|
||||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
|
||||||
<!-- Favicons -->
|
<!-- Favicons -->
|
||||||
<!-- <link rel="apple-touch-icon" href="/docs/5.3/assets/img/favicons/apple-touch-icon.png" sizes="180x180"> -->
|
<link rel="icon" href="https://icons.getbootstrap.com/assets/icons/safe-fill.svg">
|
||||||
<!-- <link rel="icon" href="/docs/5.3/assets/img/favicons/favicon-32x32.png" sizes="32x32" type="image/png"> -->
|
<meta name="theme-color" content="#712cf9">
|
||||||
<!-- <link rel="icon" href="/docs/5.3/assets/img/favicons/favicon-16x16.png" sizes="16x16" type="image/png"> -->
|
|
||||||
<!-- <link rel="manifest" href="/docs/5.3/assets/img/favicons/manifest.json"> -->
|
|
||||||
<!-- <link rel="mask-icon" href="/docs/5.3/assets/img/favicons/safari-pinned-tab.svg" color="#712cf9"> -->
|
|
||||||
<!-- <link rel="icon" href="/docs/5.3/assets/img/favicons/favicon.ico"> -->
|
|
||||||
<!-- <meta name="theme-color" content="#712cf9"> -->
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="/styles.css">
|
<link rel="stylesheet" href="/styles.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<!-- All the svgs we use later -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
|
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
|
||||||
<symbol id="check2" viewBox="0 0 16 16">
|
<symbol id="check2" viewBox="0 0 16 16">
|
||||||
<path
|
<path
|
||||||
|
@ -52,8 +48,19 @@
|
||||||
<path
|
<path
|
||||||
d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" />
|
d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" />
|
||||||
</symbol>
|
</symbol>
|
||||||
|
<symbol id="arrow-right-circle" viewBox="0 0 16 16">
|
||||||
|
<path
|
||||||
|
d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zM4.5 7.5a.5.5 0 0 0 0 1h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5H4.5z" />
|
||||||
|
</symbol>
|
||||||
|
<symbol id="vault" viewBox="0 0 16 16">
|
||||||
|
<title>Bootstrap</title>
|
||||||
|
<path d="M9.778 9.414A2 2 0 1 1 6.95 6.586a2 2 0 0 1 2.828 2.828" />
|
||||||
|
<path
|
||||||
|
d="M2.5 0A1.5 1.5 0 0 0 1 1.5V3H.5a.5.5 0 0 0 0 1H1v3.5H.5a.5.5 0 0 0 0 1H1V12H.5a.5.5 0 0 0 0 1H1v1.5A1.5 1.5 0 0 0 2.5 16h12a1.5 1.5 0 0 0 1.5-1.5v-13A1.5 1.5 0 0 0 14.5 0zm3.036 4.464 1.09 1.09a3 3 0 0 1 3.476 0l1.09-1.09a.5.5 0 1 1 .707.708l-1.09 1.09c.74 1.037.74 2.44 0 3.476l1.09 1.09a.5.5 0 1 1-.707.708l-1.09-1.09a3 3 0 0 1-3.476 0l-1.09 1.09a.5.5 0 1 1-.708-.708l1.09-1.09a3 3 0 0 1 0-3.476l-1.09-1.09a.5.5 0 1 1 .708-.708M14 6.5v3a.5.5 0 0 1-1 0v-3a.5.5 0 0 1 1 0" />
|
||||||
|
</symbol>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
<!-- theme switcher -->
|
||||||
<div class="dropdown position-fixed bottom-0 end-0 mb-3 me-3 bd-mode-toggle">
|
<div class="dropdown position-fixed bottom-0 end-0 mb-3 me-3 bd-mode-toggle">
|
||||||
<button class="btn btn-bd-primary py-2 dropdown-toggle d-flex align-items-center" id="bd-theme" type="button"
|
<button class="btn btn-bd-primary py-2 dropdown-toggle d-flex align-items-center" id="bd-theme" type="button"
|
||||||
aria-expanded="false" data-bs-toggle="dropdown" aria-label="Toggle theme (auto)">
|
aria-expanded="false" data-bs-toggle="dropdown" aria-label="Toggle theme (auto)">
|
||||||
|
@ -102,27 +109,14 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- basically everything but with some margin -->
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
|
|
||||||
<symbol id="arrow-right-circle" viewBox="0 0 16 16">
|
|
||||||
<path
|
|
||||||
d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zM4.5 7.5a.5.5 0 0 0 0 1h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5H4.5z" />
|
|
||||||
</symbol>
|
|
||||||
<symbol id="bootstrap" viewBox="0 0 118 94">
|
|
||||||
<title>Bootstrap</title>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
|
||||||
d="M24.509 0c-6.733 0-11.715 5.893-11.492 12.284.214 6.14-.064 14.092-2.066 20.577C8.943 39.365 5.547 43.485 0 44.014v5.972c5.547.529 8.943 4.649 10.951 11.153 2.002 6.485 2.28 14.437 2.066 20.577C12.794 88.106 17.776 94 24.51 94H93.5c6.733 0 11.714-5.893 11.491-12.284-.214-6.14.064-14.092 2.066-20.577 2.009-6.504 5.396-10.624 10.943-11.153v-5.972c-5.547-.529-8.934-4.649-10.943-11.153-2.002-6.484-2.28-14.437-2.066-20.577C105.214 5.894 100.233 0 93.5 0H24.508zM80 57.863C80 66.663 73.436 72 62.543 72H44a2 2 0 01-2-2V24a2 2 0 012-2h18.437c9.083 0 15.044 4.92 15.044 12.474 0 5.302-4.01 10.049-9.119 10.88v.277C75.317 46.394 80 51.21 80 57.863zM60.521 28.34H49.948v14.934h8.905c6.884 0 10.68-2.772 10.68-7.727 0-4.643-3.264-7.207-9.012-7.207zM49.948 49.2v16.458H60.91c7.167 0 10.964-2.876 10.964-8.281 0-5.406-3.903-8.178-11.425-8.178H49.948z">
|
|
||||||
</path>
|
|
||||||
</symbol>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<div class="col-lg-8 mx-auto p-4 py-md-5">
|
<div class="col-lg-8 mx-auto p-4 py-md-5">
|
||||||
<header class="d-flex align-items-center pb-3 mb-5 border-bottom">
|
<header class="d-flex align-items-center pb-3 mb-5 border-bottom">
|
||||||
<a href="/" class="d-flex align-items-center text-body-emphasis text-decoration-none">
|
<a href="/" class="d-flex align-items-center text-body-emphasis text-decoration-none">
|
||||||
<svg class="bi me-2" width="40" height="32">
|
<svg class="bi me-2" width="40" height="32">
|
||||||
<use xlink:href="#bootstrap" />
|
<use xlink:href="#vault" />
|
||||||
</svg>
|
</svg>
|
||||||
<span class="fs-4">Starter template</span>
|
<span class="fs-4">{TITLE}</span>
|
||||||
</a>
|
</a>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
@ -1,41 +1,75 @@
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use libpt::log::warn;
|
||||||
|
use minijinja::context;
|
||||||
|
use minijinja::Environment;
|
||||||
use serde;
|
use serde;
|
||||||
use tide::http::mime;
|
use thiserror::Error;
|
||||||
use tide::prelude::*;
|
use warp::reject;
|
||||||
use tide::Request;
|
use warp::reply::Reply;
|
||||||
use tide::Response;
|
use warp::reply::Response;
|
||||||
|
use warp::Filter;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::vault::VaultRef;
|
use crate::vault::VaultRef;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Interface {
|
pub struct Service<'tp> {
|
||||||
vault: VaultRef,
|
vault: VaultRef,
|
||||||
config: Config,
|
config: Config,
|
||||||
|
env: Environment<'tp>,
|
||||||
|
}
|
||||||
|
impl<'tp> Service<'tp> {
|
||||||
|
fn new(vault: VaultRef, config: Config, env: Environment<'tp>) -> Arc<Self> {
|
||||||
|
Self { vault, config, env }.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn serve(vault: VaultRef, config: Config) -> Result<()> {
|
pub async fn serve(vault: VaultRef, config: Config) -> Result<()> {
|
||||||
let mut app = tide::with_state(Interface { vault, config });
|
let mut env = Environment::new();
|
||||||
app.at("/").get(overview);
|
env.add_template("index", include_str!("../../data/www/admin.html"))?;
|
||||||
app.at("/styles.css").get(styles);
|
|
||||||
app.listen("127.0.0.1:8000").await?;
|
let service = Service::new(vault, config, env);
|
||||||
|
let service2 = service.clone();
|
||||||
|
|
||||||
|
let routes = warp::path::end()
|
||||||
|
.map(move || service2.clone())
|
||||||
|
.and_then(overview);
|
||||||
|
|
||||||
|
warp::serve(routes)
|
||||||
|
.run(service.config.addr_admin.unwrap())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
warn!("exited the admin interface");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn overview(req: Request<Interface>) -> tide::Result {
|
#[derive(Debug, Error)]
|
||||||
let r = Response::builder(200)
|
struct TemplateError(#[from] minijinja::Error);
|
||||||
.content_type(mime::HTML)
|
|
||||||
.body(format!(
|
|
||||||
include_str!("../../data/www/admin.html"),
|
|
||||||
TITLE = "Wooly-Vault"
|
|
||||||
));
|
|
||||||
|
|
||||||
Ok(r.into())
|
impl reject::Reject for TemplateError {}
|
||||||
|
impl Display for TemplateError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "something went wrong with producing this page")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn styles(_req: Request<Interface>) -> tide::Result {
|
async fn overview(serv: Arc<Service<'_>>) -> Result<Box<dyn warp::Reply>, warp::Rejection> {
|
||||||
let r = Response::builder(200)
|
let r = Response::new(
|
||||||
.content_type(mime::CSS)
|
serv.env
|
||||||
.body(include_str!("../../data/www/styles.css"));
|
.get_template("index")
|
||||||
Ok(r.into())
|
.map_err(TemplateError::from)?
|
||||||
|
.render(context!(TITLE => "Wooly-Vault", AUTHOR => env!("CARGO_PKG_AUTHORS")))
|
||||||
|
.map_err(TemplateError::from)?
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Box::new(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn styles() -> Result<Box<dyn warp::Reply>, warp::Rejection> {
|
||||||
|
let r = include_str!("../../data/www/styles.css").to_string();
|
||||||
|
Ok(Box::new(r))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue