tmtd/src/web.rs

155 lines
4.9 KiB
Rust
Raw Normal View History

2022-04-05 09:48:29 -05:00
/*
* tmtd - Suckless To Do list
2022-04-09 10:31:10 -05:00
* Copyright (C) 2022 C4TG1RL5
2022-04-05 09:48:29 -05:00
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
use std::sync::Arc;
2022-04-09 10:30:20 -05:00
use async_sqlx_session::PostgresSessionStore;
use chrono::Duration;
use sqlx::types::chrono::Utc;
2022-04-09 20:05:18 -05:00
use tera::{Tera, Context};
2022-04-05 09:48:29 -05:00
use tokio::sync::broadcast;
2022-04-08 11:54:08 -05:00
use tracing::info;
2022-04-09 10:30:20 -05:00
use warp::Filter;
use warp_sessions::{CookieOptions, SameSiteCookieOption, SessionWithStore};
use crate::{Config, Database};
macro_rules! warp_try {
($expr:expr) => {
match $expr {
Ok(o) => o,
Err(e) => {
warn!("Error in a request handler: {}", e);
return reply::with_status(
format!("Error: {}", e),
StatusCode::INTERNAL_SERVER_ERROR,
)
.into_response();
}
}
};
($store:expr, $expr:expr) => {
match $expr {
Ok(o) => o,
Err(e) => {
warn!("Error in a request handler: {}", e);
return (
reply::with_status(format!("Error: {}", e), StatusCode::INTERNAL_SERVER_ERROR)
.into_response(),
$store,
);
}
}
};
}
macro_rules! warp_session {
($filter:expr, $store:expr, $then:expr) => {
$filter
.and(
warp_sessions::request::with_session(
$store.clone(),
Some(CookieOptions {
cookie_name: "tmtd_sid",
cookie_value: None,
max_age: Some(86400*7),
domain: None,
path: None,
secure: true,
http_only: true,
same_site: Some(SameSiteCookieOption::Strict),
}),
)
.map(|mut s: SessionWithStore<PostgresSessionStore>| {
s.session.set_expiry(Utc::now() + Duration::days(7));
s
}),
)
.then($then)
.untuple_one()
.and_then(warp_sessions::reply::with_session)
};
}
2022-04-05 09:48:29 -05:00
pub struct App {
config: Arc<Config>,
db: Arc<Database>,
2022-04-09 10:30:20 -05:00
session_store: PostgresSessionStore,
tera: Arc<Tera>,
2022-04-05 09:48:29 -05:00
}
impl App {
2022-04-09 10:30:20 -05:00
pub fn new(
config: Arc<Config>,
db: Arc<Database>,
session_store: PostgresSessionStore,
) -> Result<Self, tera::Error> {
2022-04-05 09:48:29 -05:00
Ok(Self {
config,
db,
2022-04-09 10:30:20 -05:00
session_store,
tera: Arc::new(Tera::new("templates/*.html")?),
2022-04-05 09:48:29 -05:00
})
}
pub async fn run(self, mut cancel: broadcast::Receiver<()>) {
2022-04-09 10:30:20 -05:00
let route = warp_session!(
warp::path::end(),
self.session_store,
move |mut s: SessionWithStore<PostgresSessionStore>| async move {
s.session.insert_raw("test", "something".into());
(
warp::reply::html(format!("session id: {}", s.session.id())),
s,
)
2022-04-08 11:54:08 -05:00
}
2022-04-09 20:05:18 -05:00
)
// example route, remove later or something
.or(warp::path!("hello" / String).map({
let tera = self.tera.clone();
move |name: String| {
let mut ctx = Context::new();
ctx.insert("name", &name);
warp::reply::html(tera.render("hello.html", &ctx).unwrap())
}
}))
.or(warp::path!("tmtd" / String).map({
let tera = self.tera.clone(); {
move |_| {
let mut ctx = Context::new();
ctx.insert("tasks", &vec!["test1", "test2"]);
ctx.insert("task_title", "TODO");
ctx.insert("description", "TODO");
ctx.insert("task_date", "TODO");
ctx.insert("status", "TODO");
ctx.insert("assignee", "TODO");
warp::reply::html(tera.render("task_page.html", &ctx).unwrap())
}
}
}));
2022-04-05 09:48:29 -05:00
let (_, server) =
2022-04-09 10:30:20 -05:00
warp::serve(route).bind_with_graceful_shutdown(self.config.listen_addr, async move {
2022-04-05 09:48:29 -05:00
cancel.recv().await.unwrap();
});
server.await;
2022-04-09 10:30:20 -05:00
info!("Web app has been shut down");
2022-04-05 09:48:29 -05:00
}
2022-04-08 11:54:08 -05:00
}