Add wait_for_event route & update deps
This commit is contained in:
1037
Cargo.lock
generated
1037
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -16,11 +16,15 @@ futures = "0.3"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
sled = "0.34"
|
||||
semver = "0.11"
|
||||
uuid = { version = "0.7", features = ["serde", "v4"] }
|
||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||
duplicate = "0.2"
|
||||
bincode = "1"
|
||||
handlebars = "3"
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1"
|
||||
features = ["sync", "time"]
|
||||
|
||||
[dependencies.rocket]
|
||||
#version = "0.4"
|
||||
git = "https://github.com/SergioBenitez/Rocket"
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
use crate::routes::pages;
|
||||
use rocket::{
|
||||
catch,
|
||||
form::{Form, FromForm},
|
||||
http::{Cookie, CookieJar, Status},
|
||||
post,
|
||||
request::{Form, FromForm, FromRequest, Outcome, Request},
|
||||
request::{FromRequest, Outcome, Request},
|
||||
response::Redirect,
|
||||
uri, State,
|
||||
};
|
||||
@ -26,10 +27,10 @@ pub struct Authorized;
|
||||
pub struct Unauthorized;
|
||||
|
||||
#[rocket::async_trait]
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for Authorized {
|
||||
impl<'a> FromRequest<'a> for Authorized {
|
||||
type Error = Unauthorized;
|
||||
|
||||
async fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
|
||||
async fn from_request(request: &'a Request<'_>) -> Outcome<Self, Self::Error> {
|
||||
let cookies = request.cookies();
|
||||
|
||||
match cookies.get_private(AUTH_COOKIE_KEY) {
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
use crate::database::v2;
|
||||
|
||||
pub fn get_category() -> () {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn get_all_categories() -> Result<HashMap< {
|
||||
todo!()
|
||||
}
|
||||
@ -3,11 +3,13 @@ mod database;
|
||||
mod handlebars_util;
|
||||
mod routes;
|
||||
mod status_json;
|
||||
mod util;
|
||||
|
||||
use crate::auth::MasterPassword;
|
||||
use crate::database::migrations::migrate;
|
||||
use crate::database::unversioned::global::schema_version;
|
||||
use crate::database::SCHEMA_VERSION;
|
||||
use crate::util::EventNotifier;
|
||||
use bincode::{deserialize, serialize};
|
||||
use dotenv::dotenv;
|
||||
use rocket_contrib::serve::StaticFiles;
|
||||
@ -46,12 +48,13 @@ async fn main() -> io::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
let rocket = rocket::ignite()
|
||||
let rocket = rocket::build()
|
||||
.attach(Template::custom(|engines| {
|
||||
handlebars_util::register_helpers(engines)
|
||||
}))
|
||||
.manage(sled)
|
||||
.manage(master_pass)
|
||||
.manage(EventNotifier::new())
|
||||
.mount("/static", StaticFiles::from("static"))
|
||||
.mount(
|
||||
"/",
|
||||
@ -73,10 +76,11 @@ async fn main() -> io::Result<()> {
|
||||
routes::api::end_session,
|
||||
routes::api::bump_session,
|
||||
routes::api::delete_session,
|
||||
routes::api::wait_for_event,
|
||||
auth::login,
|
||||
],
|
||||
)
|
||||
.register(rocket::catchers![auth::login_page,]);
|
||||
.register("/", rocket::catchers![auth::login_page,]);
|
||||
|
||||
rocket.launch().await.expect("rocket failed to launch");
|
||||
|
||||
|
||||
@ -3,14 +3,16 @@ use crate::database::latest::trees::{categories, sessions};
|
||||
use crate::database::util::category::get_all_categories;
|
||||
use crate::routes::pages;
|
||||
use crate::status_json::StatusJson;
|
||||
use crate::util::EventNotifier;
|
||||
use bincode::{deserialize, serialize};
|
||||
use chrono::{Duration, Local, NaiveDateTime, TimeZone};
|
||||
use rocket::form::{Form, FromForm};
|
||||
use rocket::http::Status;
|
||||
use rocket::request::{Form, FromForm};
|
||||
use rocket::response::Redirect;
|
||||
use rocket::{get, post, uri, State};
|
||||
use rocket_contrib::json::Json;
|
||||
use rocket_contrib::uuid::Uuid;
|
||||
use serde::Serialize;
|
||||
use sled::Transactional;
|
||||
use std::collections::HashMap;
|
||||
|
||||
@ -101,23 +103,26 @@ pub fn bump_session(
|
||||
pub fn start_session(
|
||||
_auth: Authorized,
|
||||
category_uuid: Uuid,
|
||||
event_notifier: State<'_, EventNotifier>,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<StatusJson, StatusJson> {
|
||||
toggle_category_session(category_uuid, true, db)
|
||||
toggle_category_session(category_uuid, true, event_notifier, db)
|
||||
}
|
||||
|
||||
#[post("/category/<category_uuid>/end_session")]
|
||||
pub fn end_session(
|
||||
_auth: Authorized,
|
||||
category_uuid: Uuid,
|
||||
event_notifier: State<'_, EventNotifier>,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<StatusJson, StatusJson> {
|
||||
toggle_category_session(category_uuid, false, db)
|
||||
toggle_category_session(category_uuid, false, event_notifier, db)
|
||||
}
|
||||
|
||||
pub fn toggle_category_session(
|
||||
category_uuid: Uuid,
|
||||
set_active: bool,
|
||||
event_notifier: State<'_, EventNotifier>,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<StatusJson, StatusJson> {
|
||||
let category_uuid_s = sled::IVec::from(serialize(&category_uuid.into_inner())?);
|
||||
@ -158,6 +163,7 @@ pub fn toggle_category_session(
|
||||
}
|
||||
|
||||
tx_categories.insert(&category_uuid_s, serialize(&category).unwrap())?;
|
||||
event_notifier.notify_event();
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,3 +247,26 @@ pub fn delete_session(
|
||||
// Ok(Ok(Redirect::to(uri!(pages::history))))
|
||||
// })??)
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct WaitForEvent {
|
||||
timeout: bool,
|
||||
}
|
||||
|
||||
#[get("/wait_for_event?<timeout>")]
|
||||
pub async fn wait_for_event(
|
||||
_auth: Authorized,
|
||||
timeout: Option<u64>,
|
||||
event_notifier: State<'_, EventNotifier>,
|
||||
) -> Json<WaitForEvent> {
|
||||
use std::time::Duration;
|
||||
match tokio::time::timeout(
|
||||
Duration::from_secs(timeout.unwrap_or(30)),
|
||||
event_notifier.wait_for_event(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Json(WaitForEvent { timeout: false }),
|
||||
Err(_) => Json(WaitForEvent { timeout: true }),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
use crate::auth::Authorized;
|
||||
use crate::database::latest::trees::{categories, sessions};
|
||||
use crate::database::util::category::get_category;
|
||||
use crate::status_json::StatusJson;
|
||||
use bincode::{deserialize, serialize};
|
||||
use bincode::deserialize;
|
||||
use chrono::{DateTime, Local, Timelike};
|
||||
use rocket::http::Status;
|
||||
use rocket::{get, State};
|
||||
@ -38,15 +39,11 @@ pub fn single_stats(
|
||||
category_uuid: Uuid,
|
||||
db: State<'_, sled::Db>,
|
||||
) -> Result<Template, StatusJson> {
|
||||
let category_uuid_s = sled::IVec::from(serialize(&category_uuid.into_inner())?);
|
||||
|
||||
let categories_tree = db.open_tree(categories::NAME)?;
|
||||
let sessions_tree = db.open_tree(sessions::NAME)?;
|
||||
|
||||
let category: categories::V = match categories_tree.get(category_uuid_s)? {
|
||||
None => Err(Status::NotFound)?,
|
||||
Some(data) => deserialize(&data).unwrap(),
|
||||
};
|
||||
let category: categories::V =
|
||||
get_category(&categories_tree, &category_uuid)?.ok_or(Status::NotFound)?;
|
||||
|
||||
let sessions: HashMap<sessions::K, sessions::V> = sessions_tree
|
||||
.iter()
|
||||
|
||||
21
src/util.rs
Normal file
21
src/util.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use tokio::sync::Notify;
|
||||
|
||||
pub struct EventNotifier {
|
||||
notify: Notify,
|
||||
}
|
||||
|
||||
impl EventNotifier {
|
||||
pub fn new() -> Self {
|
||||
EventNotifier {
|
||||
notify: Notify::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn wait_for_event(&self) {
|
||||
self.notify.notified().await;
|
||||
}
|
||||
|
||||
pub fn notify_event(&self) {
|
||||
self.notify.notify_waiters();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user