2022-03-22 00:14:14 +00:00
|
|
|
use crate::{app::State, templates};
|
|
|
|
use axum::{
|
|
|
|
body,
|
|
|
|
extract::Extension,
|
|
|
|
http::StatusCode,
|
|
|
|
response::{Html, IntoResponse, Response},
|
2020-07-16 19:32:30 +00:00
|
|
|
};
|
2021-03-13 14:03:19 +00:00
|
|
|
use chrono::{Datelike, Timelike, Utc};
|
2020-07-16 19:32:30 +00:00
|
|
|
use lazy_static::lazy_static;
|
|
|
|
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
2022-03-22 00:14:14 +00:00
|
|
|
use std::sync::Arc;
|
2021-01-23 02:11:48 +00:00
|
|
|
use tracing::instrument;
|
2022-03-22 00:14:14 +00:00
|
|
|
|
|
|
|
pub mod blog;
|
|
|
|
pub mod feeds;
|
|
|
|
pub mod gallery;
|
|
|
|
pub mod talks;
|
2020-07-16 19:32:30 +00:00
|
|
|
|
|
|
|
lazy_static! {
|
|
|
|
static ref HIT_COUNTER: IntCounterVec =
|
|
|
|
register_int_counter_vec!(opts!("hits", "Number of hits to various pages"), &["page"])
|
|
|
|
.unwrap();
|
2021-03-13 14:03:19 +00:00
|
|
|
pub static ref LAST_MODIFIED: String = {
|
|
|
|
let now = Utc::now();
|
|
|
|
format!(
|
|
|
|
"{dayname}, {day} {month} {year} {hour}:{minute}:{second} GMT",
|
|
|
|
dayname = now.weekday(),
|
|
|
|
day = now.day(),
|
|
|
|
month = now.month(),
|
|
|
|
year = now.year(),
|
|
|
|
hour = now.hour(),
|
|
|
|
minute = now.minute(),
|
|
|
|
second = now.second()
|
|
|
|
)
|
|
|
|
};
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
|
2020-10-02 22:36:57 +00:00
|
|
|
#[instrument]
|
2022-03-22 00:14:14 +00:00
|
|
|
pub async fn index() -> Result {
|
2020-07-16 19:32:30 +00:00
|
|
|
HIT_COUNTER.with_label_values(&["index"]).inc();
|
2022-03-22 00:14:14 +00:00
|
|
|
let mut result: Vec<u8> = vec![];
|
|
|
|
templates::index_html(&mut result)?;
|
|
|
|
Ok(Html(result))
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
|
2020-10-02 22:36:57 +00:00
|
|
|
#[instrument]
|
2022-03-22 00:14:14 +00:00
|
|
|
pub async fn contact() -> Result {
|
2020-07-16 19:32:30 +00:00
|
|
|
HIT_COUNTER.with_label_values(&["contact"]).inc();
|
2022-03-22 00:14:14 +00:00
|
|
|
let mut result: Vec<u8> = vec![];
|
|
|
|
templates::contact_html(&mut result)?;
|
|
|
|
Ok(Html(result))
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
|
2020-10-02 22:36:57 +00:00
|
|
|
#[instrument]
|
2022-03-22 00:14:14 +00:00
|
|
|
pub async fn feeds() -> Result {
|
2020-07-16 19:32:30 +00:00
|
|
|
HIT_COUNTER.with_label_values(&["feeds"]).inc();
|
2022-03-22 00:14:14 +00:00
|
|
|
let mut result: Vec<u8> = vec![];
|
|
|
|
templates::feeds_html(&mut result)?;
|
|
|
|
Ok(Html(result))
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
#[axum_macros::debug_handler]
|
2020-10-02 22:36:57 +00:00
|
|
|
#[instrument(skip(state))]
|
2022-03-22 00:14:14 +00:00
|
|
|
pub async fn resume(Extension(state): Extension<Arc<State>>) -> Result {
|
2020-07-16 19:32:30 +00:00
|
|
|
HIT_COUNTER.with_label_values(&["resume"]).inc();
|
|
|
|
let state = state.clone();
|
2022-03-22 00:14:14 +00:00
|
|
|
let mut result: Vec<u8> = vec![];
|
|
|
|
templates::resume_html(&mut result, templates::Html(state.resume.clone()))?;
|
|
|
|
Ok(Html(result))
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
|
2020-10-02 22:36:57 +00:00
|
|
|
#[instrument(skip(state))]
|
2022-03-22 00:14:14 +00:00
|
|
|
pub async fn patrons(Extension(state): Extension<Arc<State>>) -> Result {
|
2020-07-16 19:32:30 +00:00
|
|
|
HIT_COUNTER.with_label_values(&["patrons"]).inc();
|
|
|
|
let state = state.clone();
|
2022-03-22 00:14:14 +00:00
|
|
|
let mut result: Vec<u8> = vec![];
|
2020-07-16 19:32:30 +00:00
|
|
|
match &state.patrons {
|
2022-03-22 00:14:14 +00:00
|
|
|
None => Err(Error::NoPatrons),
|
|
|
|
Some(patrons) => {
|
|
|
|
templates::patrons_html(&mut result, patrons.clone())?;
|
|
|
|
Ok(Html(result))
|
|
|
|
}
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
#[axum_macros::debug_handler]
|
2020-10-02 22:36:57 +00:00
|
|
|
#[instrument(skip(state))]
|
2022-03-22 00:14:14 +00:00
|
|
|
pub async fn signalboost(Extension(state): Extension<Arc<State>>) -> Result {
|
2020-07-16 19:32:30 +00:00
|
|
|
HIT_COUNTER.with_label_values(&["signalboost"]).inc();
|
|
|
|
let state = state.clone();
|
2022-03-22 00:14:14 +00:00
|
|
|
let mut result: Vec<u8> = vec![];
|
|
|
|
templates::signalboost_html(&mut result, state.signalboost.clone())?;
|
|
|
|
Ok(Html(result))
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
|
2020-10-02 22:36:57 +00:00
|
|
|
#[instrument]
|
2022-03-22 00:14:14 +00:00
|
|
|
pub async fn not_found() -> Result {
|
2020-07-16 19:32:30 +00:00
|
|
|
HIT_COUNTER.with_label_values(&["not_found"]).inc();
|
2022-03-22 00:14:14 +00:00
|
|
|
let mut result: Vec<u8> = vec![];
|
|
|
|
templates::notfound_html(&mut result, "some path".into())?;
|
|
|
|
Ok(Html(result))
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, thiserror::Error)]
|
2022-03-22 00:14:14 +00:00
|
|
|
pub enum Error {
|
|
|
|
#[error("series not found: {0}")]
|
|
|
|
SeriesNotFound(String),
|
2020-07-16 19:32:30 +00:00
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
#[error("post not found: {0}")]
|
|
|
|
PostNotFound(String),
|
2020-07-16 19:32:30 +00:00
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
#[error("patreon key not working, poke me to get this fixed")]
|
|
|
|
NoPatrons,
|
2020-07-16 19:32:30 +00:00
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
#[error("io error: {0}")]
|
|
|
|
IO(#[from] std::io::Error),
|
2020-07-16 19:32:30 +00:00
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
#[error("axum http error: {0}")]
|
|
|
|
AxumHTTP(#[from] axum::http::Error),
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
pub type Result<T = Html<Vec<u8>>> = std::result::Result<T, Error>;
|
2020-07-16 19:32:30 +00:00
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
impl IntoResponse for Error {
|
|
|
|
fn into_response(self) -> Response {
|
|
|
|
let mut result: Vec<u8> = vec![];
|
|
|
|
templates::error_html(&mut result, format!("{}", self)).unwrap();
|
2020-07-16 19:32:30 +00:00
|
|
|
|
2022-03-22 00:14:14 +00:00
|
|
|
let body = body::boxed(body::Full::from(result));
|
2020-07-16 19:32:30 +00:00
|
|
|
|
|
|
|
Response::builder()
|
2022-03-22 00:14:14 +00:00
|
|
|
.status(match self {
|
|
|
|
Error::SeriesNotFound(_) | Error::PostNotFound(_) => StatusCode::NOT_FOUND,
|
|
|
|
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
|
|
|
})
|
|
|
|
.body(body)
|
|
|
|
.unwrap()
|
|
|
|
}
|
2020-07-16 19:32:30 +00:00
|
|
|
}
|