css/gruvbox-dark: enable light mode if the os tells me to (#342)
* css/gruvbox-dark: enable light mode if the os tells me to Signed-off-by: Christine Dodrill <me@christine.website> * handlers: add Last-Modified support Signed-off-by: Christine Dodrill <me@christine.website>
This commit is contained in:
parent
8b97cde7a5
commit
9b43f16d80
|
@ -1 +1,238 @@
|
||||||
.gruvbox-dark{background-color:#282828;color:#ebdbb2}.gruvbox-dark h1,.gruvbox-dark h2,.gruvbox-dark h3,.gruvbox-dark h4,.gruvbox-dark h5,.gruvbox-dark h6{color:#98971a}.gruvbox-dark h1 a,.gruvbox-dark h2 a,.gruvbox-dark h3 a,.gruvbox-dark h4 a,.gruvbox-dark h5 a,.gruvbox-dark h6 a{color:#d79921;border-bottom-color:#d79921}.gruvbox-dark h1 a:hover,.gruvbox-dark h2 a:hover,.gruvbox-dark h3 a:hover,.gruvbox-dark h4 a:hover,.gruvbox-dark h5 a:hover,.gruvbox-dark h6 a:hover{background-color:#d79921;color:#fbf1c7}.gruvbox-dark pre{background-color:#1d2021;padding:0;border:none}.gruvbox-dark pre code{color:#689d6a}.gruvbox-dark .progress-bar-filled:after,.gruvbox-dark .progress-bar-filled:before,.gruvbox-dark code,.gruvbox-dark strong{color:#98971a}.gruvbox-dark code{font-weight:100}.gruvbox-dark .progress-bar-filled{background-color:#98971a}.gruvbox-dark table{color:#fdf4c1}.gruvbox-dark table td,.gruvbox-dark table th{border-color:#b0bec5}.gruvbox-dark table tbody td:first-child{color:#b0bec5}.gruvbox-dark .form-control,.gruvbox-dark .form-group label{color:#fdf4c1;border-color:#98971a}.gruvbox-dark .form-group.form-textarea label:after{background-color:#282828}.gruvbox-dark .form-control:focus{border-color:#bdae93;color:#bdae93}.gruvbox-dark textarea.form-control{color:#fdf4c1}.gruvbox-dark .card{border-color:#98971a}.gruvbox-dark .card .card-header{background-color:transparent;color:#fdf4c1;border-bottom:1px solid #98971a}.gruvbox-dark .btn.btn-ghost.btn-default{border-color:#607d8b;color:#607d8b}.gruvbox-dark .btn.btn-ghost.btn-default:focus,.gruvbox-dark .btn.btn-ghost.btn-default:hover{z-index:1;border-color:#ebdbb2;color:#ebdbb2}.gruvbox-dark .btn.btn-ghost.btn-primary:focus,.gruvbox-dark .btn.btn-ghost.btn-primary:hover{border-color:#689d6a;color:#689d6a}.gruvbox-dark .btn.btn-ghost.btn-success:focus,.gruvbox-dark .btn.btn-ghost.btn-success:hover{border-color:#98971a;color:#98971a}.gruvbox-dark .btn.btn-ghost.btn-info:focus,.gruvbox-dark .btn.btn-ghost.btn-info:hover{border-color:#458588;color:#458588}.gruvbox-dark .btn.btn-ghost.btn-error:focus,.gruvbox-dark .btn.btn-ghost.btn-error:hover{border-color:#cc241d;color:#cc241d}.gruvbox-dark .btn.btn-ghost.btn-warning:focus,.gruvbox-dark .btn.btn-ghost.btn-warning:hover{border-color:#d79931;color:#d79931}.gruvbox-dark .avatarholder,.gruvbox-dark .placeholder{background-color:transparent;border-color:#3c3836}.gruvbox-dark .menu .menu-item{color:#fdf4c1;border-color:#98971a}.gruvbox-dark .menu .menu-item.active,.gruvbox-dark .menu .menu-item:hover{color:#fdf4c1;border-color:#fdf4c1}.gruvbox-dark a:visited{color:#a89984;border-color:#a89984}.gruvbox-dark a:visited:hover{color:#fdf4c1;background-color:#a89984}
|
|
||||||
|
|
||||||
|
.gruvbox-dark {
|
||||||
|
background-color: #282828;
|
||||||
|
color: #ebdbb2
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark h1,
|
||||||
|
.gruvbox-dark h2,
|
||||||
|
.gruvbox-dark h3,
|
||||||
|
.gruvbox-dark h4,
|
||||||
|
.gruvbox-dark h5,
|
||||||
|
.gruvbox-dark h6 {
|
||||||
|
color: #98971a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark h1 a,
|
||||||
|
.gruvbox-dark h2 a,
|
||||||
|
.gruvbox-dark h3 a,
|
||||||
|
.gruvbox-dark h4 a,
|
||||||
|
.gruvbox-dark h5 a,
|
||||||
|
.gruvbox-dark h6 a {
|
||||||
|
color: #d79921;
|
||||||
|
border-bottom-color: #d79921
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark h1 a:hover,
|
||||||
|
.gruvbox-dark h2 a:hover,
|
||||||
|
.gruvbox-dark h3 a:hover,
|
||||||
|
.gruvbox-dark h4 a:hover,
|
||||||
|
.gruvbox-dark h5 a:hover,
|
||||||
|
.gruvbox-dark h6 a:hover {
|
||||||
|
background-color: #d79921;
|
||||||
|
color: #fbf1c7
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark pre {
|
||||||
|
background-color: #1d2021;
|
||||||
|
padding: 0;
|
||||||
|
border: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark pre code {
|
||||||
|
color: #689d6a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .progress-bar-filled:after,
|
||||||
|
.gruvbox-dark .progress-bar-filled:before,
|
||||||
|
.gruvbox-dark code,
|
||||||
|
.gruvbox-dark strong {
|
||||||
|
color: #98971a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark code {
|
||||||
|
font-weight: 100
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .progress-bar-filled {
|
||||||
|
background-color: #98971a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark table {
|
||||||
|
color: #fdf4c1
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark table td,
|
||||||
|
.gruvbox-dark table th {
|
||||||
|
border-color: #b0bec5
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark table tbody td:first-child {
|
||||||
|
color: #b0bec5
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .form-control,
|
||||||
|
.gruvbox-dark .form-group label {
|
||||||
|
color: #fdf4c1;
|
||||||
|
border-color: #98971a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .form-group.form-textarea label:after {
|
||||||
|
background-color: #282828
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .form-control:focus {
|
||||||
|
border-color: #bdae93;
|
||||||
|
color: #bdae93
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark textarea.form-control {
|
||||||
|
color: #fdf4c1
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .card {
|
||||||
|
border-color: #98971a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .card .card-header {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #fdf4c1;
|
||||||
|
border-bottom: 1px solid #98971a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-default {
|
||||||
|
border-color: #607d8b;
|
||||||
|
color: #607d8b
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-default:focus,
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-default:hover {
|
||||||
|
z-index: 1;
|
||||||
|
border-color: #ebdbb2;
|
||||||
|
color: #ebdbb2
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-primary:focus,
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-primary:hover {
|
||||||
|
border-color: #689d6a;
|
||||||
|
color: #689d6a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-success:focus,
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-success:hover {
|
||||||
|
border-color: #98971a;
|
||||||
|
color: #98971a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-info:focus,
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-info:hover {
|
||||||
|
border-color: #458588;
|
||||||
|
color: #458588
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-error:focus,
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-error:hover {
|
||||||
|
border-color: #cc241d;
|
||||||
|
color: #cc241d
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-warning:focus,
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-warning:hover {
|
||||||
|
border-color: #d79931;
|
||||||
|
color: #d79931
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .avatarholder,
|
||||||
|
.gruvbox-dark .placeholder {
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: #3c3836
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .menu .menu-item {
|
||||||
|
color: #fdf4c1;
|
||||||
|
border-color: #98971a
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark .menu .menu-item.active,
|
||||||
|
.gruvbox-dark .menu .menu-item:hover {
|
||||||
|
color: #fdf4c1;
|
||||||
|
border-color: #fdf4c1
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark a:visited {
|
||||||
|
color: #a89984;
|
||||||
|
border-color: #a89984
|
||||||
|
}
|
||||||
|
|
||||||
|
.gruvbox-dark a:visited:hover {
|
||||||
|
color: #fdf4c1;
|
||||||
|
background-color: #a89984
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
.gruvbox-dark {
|
||||||
|
background-color: #fbf1c7;
|
||||||
|
color: #282828;
|
||||||
|
}
|
||||||
|
.gruvbox-dark h1 a:hover,
|
||||||
|
.gruvbox-dark h2 a:hover,
|
||||||
|
.gruvbox-dark h3 a:hover,
|
||||||
|
.gruvbox-dark h4 a:hover,
|
||||||
|
.gruvbox-dark h5 a:hover,
|
||||||
|
.gruvbox-dark h6 a:hover {
|
||||||
|
background-color: #d79921;
|
||||||
|
color: #282828;
|
||||||
|
}
|
||||||
|
.gruvbox-dark pre {
|
||||||
|
background-color: #f9f5d7;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.gruvbox-dark table {
|
||||||
|
color: #1d2021;
|
||||||
|
}
|
||||||
|
.gruvbox-dark .form-control,
|
||||||
|
.gruvbox-dark .form-group label {
|
||||||
|
color: #1d2021;
|
||||||
|
border-color: #98971a
|
||||||
|
}
|
||||||
|
.gruvbox-dark .form-group.form-textarea label:after {
|
||||||
|
background-color: #3c3836;
|
||||||
|
}
|
||||||
|
.gruvbox-dark .form-control:focus {
|
||||||
|
border-color: #665c54;
|
||||||
|
color: #665c54;
|
||||||
|
}
|
||||||
|
.gruvbox-dark textarea.form-control {
|
||||||
|
color: #282828;
|
||||||
|
}
|
||||||
|
.gruvbox-dark .card .card-header {
|
||||||
|
background-color: transparent;
|
||||||
|
color: #282828;
|
||||||
|
border-bottom: 1px solid #98971a
|
||||||
|
}
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-default:focus,
|
||||||
|
.gruvbox-dark .btn.btn-ghost.btn-default:hover {
|
||||||
|
z-index: 1;
|
||||||
|
border-color: #3c3836;
|
||||||
|
color: #3c3836;
|
||||||
|
}
|
||||||
|
.gruvbox-dark .menu .menu-item {
|
||||||
|
color: #282828;
|
||||||
|
border-color: #98971a
|
||||||
|
}
|
||||||
|
.gruvbox-dark .menu .menu-item.active,
|
||||||
|
.gruvbox-dark .menu .menu-item:hover {
|
||||||
|
color: #282828;
|
||||||
|
border-color: #282828;
|
||||||
|
}
|
||||||
|
.gruvbox-dark a:visited {
|
||||||
|
color: #7c6f64;
|
||||||
|
border-color: #7c6f64;
|
||||||
|
}
|
||||||
|
.gruvbox-dark a:visited:hover {
|
||||||
|
color: #3c3836;
|
||||||
|
background-color: #bdae93;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{PostNotFound, SeriesNotFound};
|
use super::{PostNotFound, SeriesNotFound, LAST_MODIFIED};
|
||||||
use crate::{
|
use crate::{
|
||||||
app::State,
|
app::State,
|
||||||
post::Post,
|
post::Post,
|
||||||
|
@ -21,7 +21,9 @@ lazy_static! {
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
pub async fn index(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
pub async fn index(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
Response::builder().html(|o| templates::blogindex_html(o, state.blog.clone()))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::blogindex_html(o, state.blog.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
|
@ -38,7 +40,9 @@ pub async fn series(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
||||||
series.sort();
|
series.sort();
|
||||||
series.dedup();
|
series.dedup();
|
||||||
|
|
||||||
Response::builder().html(|o| templates::series_html(o, series))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::series_html(o, series))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
|
@ -60,7 +64,9 @@ pub async fn series_view(series: String, state: Arc<State>) -> Result<impl Reply
|
||||||
error!("series not found");
|
error!("series not found");
|
||||||
Err(SeriesNotFound(series).into())
|
Err(SeriesNotFound(series).into())
|
||||||
} else {
|
} else {
|
||||||
Response::builder().html(|o| templates::series_posts_html(o, series, &posts))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::series_posts_html(o, series, &posts))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +87,9 @@ pub async fn post_view(name: String, state: Arc<State>) -> Result<impl Reply, Re
|
||||||
.with_label_values(&[name.clone().as_str()])
|
.with_label_values(&[name.clone().as_str()])
|
||||||
.inc();
|
.inc();
|
||||||
let body = Html(post.body_html.clone());
|
let body = Html(post.body_html.clone());
|
||||||
Response::builder().html(|o| templates::blogpost_html(o, post, body))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::blogpost_html(o, post, body))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use super::LAST_MODIFIED;
|
||||||
use crate::{app::State, templates};
|
use crate::{app::State, templates};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
||||||
|
@ -6,7 +7,7 @@ use tracing::instrument;
|
||||||
use warp::{http::Response, Rejection, Reply};
|
use warp::{http::Response, Rejection, Reply};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref HIT_COUNTER: IntCounterVec = register_int_counter_vec!(
|
pub static ref HIT_COUNTER: IntCounterVec = register_int_counter_vec!(
|
||||||
opts!("feed_hits", "Number of hits to various feeds"),
|
opts!("feed_hits", "Number of hits to various feeds"),
|
||||||
&["kind"]
|
&["kind"]
|
||||||
)
|
)
|
||||||
|
@ -56,6 +57,7 @@ pub async fn atom(state: Arc<State>, since: Option<String>) -> Result<impl Reply
|
||||||
.status(200)
|
.status(200)
|
||||||
.header("Content-Type", "application/atom+xml")
|
.header("Content-Type", "application/atom+xml")
|
||||||
.header("ETag", ETAG.clone())
|
.header("ETag", ETAG.clone())
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
.body(buf)
|
.body(buf)
|
||||||
.map_err(RenderError::Build)
|
.map_err(RenderError::Build)
|
||||||
.map_err(warp::reject::custom)
|
.map_err(warp::reject::custom)
|
||||||
|
@ -88,6 +90,7 @@ pub async fn rss(state: Arc<State>, since: Option<String>) -> Result<impl Reply,
|
||||||
.status(200)
|
.status(200)
|
||||||
.header("Content-Type", "application/rss+xml")
|
.header("Content-Type", "application/rss+xml")
|
||||||
.header("ETag", ETAG.clone())
|
.header("ETag", ETAG.clone())
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
.body(buf)
|
.body(buf)
|
||||||
.map_err(RenderError::Build)
|
.map_err(RenderError::Build)
|
||||||
.map_err(warp::reject::custom)
|
.map_err(warp::reject::custom)
|
||||||
|
@ -100,6 +103,7 @@ pub async fn sitemap(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
||||||
Response::builder()
|
Response::builder()
|
||||||
.status(200)
|
.status(200)
|
||||||
.header("Content-Type", "application/xml")
|
.header("Content-Type", "application/xml")
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
.body(state.sitemap.clone())
|
.body(state.sitemap.clone())
|
||||||
.map_err(RenderError::Build)
|
.map_err(RenderError::Build)
|
||||||
.map_err(warp::reject::custom)
|
.map_err(warp::reject::custom)
|
||||||
|
|
|
@ -5,14 +5,16 @@ use crate::{
|
||||||
templates::{self, Html, RenderRucte},
|
templates::{self, Html, RenderRucte},
|
||||||
};
|
};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use prometheus::{IntCounterVec, register_int_counter_vec, opts};
|
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use warp::{http::Response, Rejection, Reply};
|
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
use warp::{http::Response, Rejection, Reply};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref HIT_COUNTER: IntCounterVec =
|
static ref HIT_COUNTER: IntCounterVec = register_int_counter_vec!(
|
||||||
register_int_counter_vec!(opts!("gallery_hits", "Number of hits to gallery images"), &["name"])
|
opts!("gallery_hits", "Number of hits to gallery images"),
|
||||||
|
&["name"]
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +37,9 @@ pub async fn post_view(name: String, state: Arc<State>) -> Result<impl Reply, Re
|
||||||
match want {
|
match want {
|
||||||
None => Err(PostNotFound("gallery".into(), name).into()),
|
None => Err(PostNotFound("gallery".into(), name).into()),
|
||||||
Some(post) => {
|
Some(post) => {
|
||||||
HIT_COUNTER.with_label_values(&[name.clone().as_str()]).inc();
|
HIT_COUNTER
|
||||||
|
.with_label_values(&[name.clone().as_str()])
|
||||||
|
.inc();
|
||||||
let body = Html(post.body_html.clone());
|
let body = Html(post.body_html.clone());
|
||||||
Response::builder().html(|o| templates::gallerypost_html(o, post, body))
|
Response::builder().html(|o| templates::gallerypost_html(o, post, body))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::{
|
||||||
app::State,
|
app::State,
|
||||||
templates::{self, Html, RenderRucte},
|
templates::{self, Html, RenderRucte},
|
||||||
};
|
};
|
||||||
|
use chrono::{Datelike, Timelike, Utc};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
||||||
use std::{convert::Infallible, fmt, sync::Arc};
|
use std::{convert::Infallible, fmt, sync::Arc};
|
||||||
|
@ -15,31 +16,52 @@ lazy_static! {
|
||||||
static ref HIT_COUNTER: IntCounterVec =
|
static ref HIT_COUNTER: IntCounterVec =
|
||||||
register_int_counter_vec!(opts!("hits", "Number of hits to various pages"), &["page"])
|
register_int_counter_vec!(opts!("hits", "Number of hits to various pages"), &["page"])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
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()
|
||||||
|
)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
pub async fn index() -> Result<impl Reply, Rejection> {
|
pub async fn index() -> Result<impl Reply, Rejection> {
|
||||||
HIT_COUNTER.with_label_values(&["index"]).inc();
|
HIT_COUNTER.with_label_values(&["index"]).inc();
|
||||||
Response::builder().html(|o| templates::index_html(o))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::index_html(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
pub async fn contact() -> Result<impl Reply, Rejection> {
|
pub async fn contact() -> Result<impl Reply, Rejection> {
|
||||||
HIT_COUNTER.with_label_values(&["contact"]).inc();
|
HIT_COUNTER.with_label_values(&["contact"]).inc();
|
||||||
Response::builder().html(|o| templates::contact_html(o))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::contact_html(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
pub async fn feeds() -> Result<impl Reply, Rejection> {
|
pub async fn feeds() -> Result<impl Reply, Rejection> {
|
||||||
HIT_COUNTER.with_label_values(&["feeds"]).inc();
|
HIT_COUNTER.with_label_values(&["feeds"]).inc();
|
||||||
Response::builder().html(|o| templates::feeds_html(o))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::feeds_html(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
pub async fn resume(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
pub async fn resume(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
||||||
HIT_COUNTER.with_label_values(&["resume"]).inc();
|
HIT_COUNTER.with_label_values(&["resume"]).inc();
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
Response::builder().html(|o| templates::resume_html(o, Html(state.resume.clone())))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::resume_html(o, Html(state.resume.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
|
@ -53,7 +75,9 @@ pub async fn patrons(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
||||||
"Could not load patrons, let me know the API token expired again".to_string(),
|
"Could not load patrons, let me know the API token expired again".to_string(),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
Some(patrons) => Response::builder().html(|o| templates::patrons_html(o, patrons.clone())),
|
Some(patrons) => Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::patrons_html(o, patrons.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,13 +85,17 @@ pub async fn patrons(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
||||||
pub async fn signalboost(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
pub async fn signalboost(state: Arc<State>) -> Result<impl Reply, Rejection> {
|
||||||
HIT_COUNTER.with_label_values(&["signalboost"]).inc();
|
HIT_COUNTER.with_label_values(&["signalboost"]).inc();
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
Response::builder().html(|o| templates::signalboost_html(o, state.signalboost.clone()))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::signalboost_html(o, state.signalboost.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
pub async fn not_found() -> Result<impl Reply, Rejection> {
|
pub async fn not_found() -> Result<impl Reply, Rejection> {
|
||||||
HIT_COUNTER.with_label_values(&["not_found"]).inc();
|
HIT_COUNTER.with_label_values(&["not_found"]).inc();
|
||||||
Response::builder().html(|o| templates::notfound_html(o, "some path".into()))
|
Response::builder()
|
||||||
|
.header("Last-Modified", &*LAST_MODIFIED)
|
||||||
|
.html(|o| templates::notfound_html(o, "some path".into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod blog;
|
pub mod blog;
|
||||||
|
|
|
@ -5,14 +5,16 @@ use crate::{
|
||||||
templates::{self, Html, RenderRucte},
|
templates::{self, Html, RenderRucte},
|
||||||
};
|
};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use prometheus::{IntCounterVec, register_int_counter_vec, opts};
|
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use warp::{http::Response, Rejection, Reply};
|
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
use warp::{http::Response, Rejection, Reply};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref HIT_COUNTER: IntCounterVec =
|
static ref HIT_COUNTER: IntCounterVec = register_int_counter_vec!(
|
||||||
register_int_counter_vec!(opts!("talks_hits", "Number of hits to talks images"), &["name"])
|
opts!("talks_hits", "Number of hits to talks images"),
|
||||||
|
&["name"]
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +37,9 @@ pub async fn post_view(name: String, state: Arc<State>) -> Result<impl Reply, Re
|
||||||
match want {
|
match want {
|
||||||
None => Err(PostNotFound("talks".into(), name).into()),
|
None => Err(PostNotFound("talks".into(), name).into()),
|
||||||
Some(post) => {
|
Some(post) => {
|
||||||
HIT_COUNTER.with_label_values(&[name.clone().as_str()]).inc();
|
HIT_COUNTER
|
||||||
|
.with_label_values(&[name.clone().as_str()])
|
||||||
|
.inc();
|
||||||
let body = Html(post.body_html.clone());
|
let body = Html(post.body_html.clone());
|
||||||
Response::builder().html(|o| templates::talkpost_html(o, post, body))
|
Response::builder().html(|o| templates::talkpost_html(o, post, body))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue