consolidate API routes
Signed-off-by: Xe Iaso <me@christine.website>
This commit is contained in:
parent
18ae8a01f8
commit
b32f5a25af
|
@ -0,0 +1,78 @@
|
||||||
|
use crate::{
|
||||||
|
app::{config::Job, State},
|
||||||
|
handlers::Result,
|
||||||
|
post::Post,
|
||||||
|
};
|
||||||
|
use axum::extract::{Extension, Json, Path};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref BLOG: IntCounterVec = register_int_counter_vec!(
|
||||||
|
opts!("blogpost_json_hits", "Number of hits to blogposts"),
|
||||||
|
&["name"]
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
static ref TALK: IntCounterVec = register_int_counter_vec!(
|
||||||
|
opts!("talks_json_hits", "Number of hits to talks images"),
|
||||||
|
&["name"]
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[axum_macros::debug_handler]
|
||||||
|
#[instrument(skip(state))]
|
||||||
|
pub async fn salary_transparency(Extension(state): Extension<Arc<State>>) -> Json<Vec<Job>> {
|
||||||
|
super::HIT_COUNTER
|
||||||
|
.with_label_values(&["salary_transparency_json"])
|
||||||
|
.inc();
|
||||||
|
|
||||||
|
Json(state.clone().cfg.clone().job_history.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(state))]
|
||||||
|
pub async fn blog(
|
||||||
|
Path(name): Path<String>,
|
||||||
|
Extension(state): Extension<Arc<State>>,
|
||||||
|
) -> Result<Json<xe_jsonfeed::Item>> {
|
||||||
|
let mut want: Option<Post> = None;
|
||||||
|
let want_link = format!("blog/{}", name);
|
||||||
|
|
||||||
|
for post in &state.blog {
|
||||||
|
if post.link == want_link {
|
||||||
|
want = Some(post.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match want {
|
||||||
|
None => Err(super::Error::PostNotFound(name)),
|
||||||
|
Some(post) => {
|
||||||
|
BLOG.with_label_values(&[name.clone().as_str()]).inc();
|
||||||
|
Ok(Json(post.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(state))]
|
||||||
|
pub async fn talk(
|
||||||
|
Path(name): Path<String>,
|
||||||
|
Extension(state): Extension<Arc<State>>,
|
||||||
|
) -> Result<Json<xe_jsonfeed::Item>> {
|
||||||
|
let mut want: Option<Post> = None;
|
||||||
|
let want_link = format!("talks/{}", name);
|
||||||
|
|
||||||
|
for post in &state.talks {
|
||||||
|
if post.link == want_link {
|
||||||
|
want = Some(post.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match want {
|
||||||
|
None => Err(super::Error::PostNotFound(name)),
|
||||||
|
Some(post) => {
|
||||||
|
TALK.with_label_values(&[name.clone().as_str()]).inc();
|
||||||
|
Ok(Json(post.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ use crate::{app::State, post::Post, templates};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Extension, Path},
|
extract::{Extension, Path},
|
||||||
response::Html,
|
response::Html,
|
||||||
Json,
|
|
||||||
};
|
};
|
||||||
use http::HeaderMap;
|
use http::HeaderMap;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
@ -17,11 +16,6 @@ lazy_static! {
|
||||||
&["name"]
|
&["name"]
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
static ref HIT_COUNTER_JSON: IntCounterVec = register_int_counter_vec!(
|
|
||||||
opts!("blogpost_json_hits", "Number of hits to blogposts"),
|
|
||||||
&["name"]
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
|
@ -114,28 +108,3 @@ pub async fn post_view(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(state))]
|
|
||||||
pub async fn post_json(
|
|
||||||
Path(name): Path<String>,
|
|
||||||
Extension(state): Extension<Arc<State>>,
|
|
||||||
) -> Result<Json<xe_jsonfeed::Item>> {
|
|
||||||
let mut want: Option<Post> = None;
|
|
||||||
let want_link = format!("blog/{}", name);
|
|
||||||
|
|
||||||
for post in &state.blog {
|
|
||||||
if post.link == want_link {
|
|
||||||
want = Some(post.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match want {
|
|
||||||
None => Err(super::Error::PostNotFound(name)),
|
|
||||||
Some(post) => {
|
|
||||||
HIT_COUNTER_JSON
|
|
||||||
.with_label_values(&[name.clone().as_str()])
|
|
||||||
.inc();
|
|
||||||
Ok(Json(post.into()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
use crate::{
|
use crate::{app::State, templates};
|
||||||
app::{Job, State},
|
|
||||||
templates,
|
|
||||||
};
|
|
||||||
use axum::{
|
use axum::{
|
||||||
body,
|
body,
|
||||||
extract::Extension,
|
extract::Extension,
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
response::{Html, IntoResponse, Response},
|
response::{Html, IntoResponse, Response},
|
||||||
Json,
|
|
||||||
};
|
};
|
||||||
use chrono::{Datelike, Timelike, Utc, Weekday};
|
use chrono::{Datelike, Timelike, Utc, Weekday};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
@ -15,6 +11,7 @@ use prometheus::{opts, register_int_counter_vec, IntCounterVec};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
pub mod api;
|
||||||
pub mod blog;
|
pub mod blog;
|
||||||
pub mod feeds;
|
pub mod feeds;
|
||||||
pub mod gallery;
|
pub mod gallery;
|
||||||
|
@ -52,7 +49,7 @@ fn month_to_name(m: u32) -> &'static str {
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref HIT_COUNTER: IntCounterVec =
|
pub 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 = {
|
pub static ref LAST_MODIFIED: String = {
|
||||||
|
@ -106,16 +103,6 @@ pub async fn salary_transparency(Extension(state): Extension<Arc<State>>) -> Res
|
||||||
Ok(Html(result))
|
Ok(Html(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[axum_macros::debug_handler]
|
|
||||||
#[instrument(skip(state))]
|
|
||||||
pub async fn salary_transparency_json(Extension(state): Extension<Arc<State>>) -> Json<Vec<Job>> {
|
|
||||||
HIT_COUNTER
|
|
||||||
.with_label_values(&["salary_transparency_json"])
|
|
||||||
.inc();
|
|
||||||
|
|
||||||
Json(state.clone().cfg.clone().job_history.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[axum_macros::debug_handler]
|
#[axum_macros::debug_handler]
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
pub async fn resume(Extension(state): Extension<Arc<State>>) -> Result {
|
pub async fn resume(Extension(state): Extension<Arc<State>>) -> Result {
|
||||||
|
|
|
@ -3,7 +3,6 @@ use crate::{app::State, post::Post, templates};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Extension, Path},
|
extract::{Extension, Path},
|
||||||
response::Html,
|
response::Html,
|
||||||
Json,
|
|
||||||
};
|
};
|
||||||
use http::header::HeaderMap;
|
use http::header::HeaderMap;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
@ -17,11 +16,6 @@ lazy_static! {
|
||||||
&["name"]
|
&["name"]
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
static ref HIT_COUNTER_JSON: IntCounterVec = register_int_counter_vec!(
|
|
||||||
opts!("talks_json_hits", "Number of hits to talks images"),
|
|
||||||
&["name"]
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(state))]
|
#[instrument(skip(state))]
|
||||||
|
@ -67,28 +61,3 @@ pub async fn post_view(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(state))]
|
|
||||||
pub async fn post_json(
|
|
||||||
Path(name): Path<String>,
|
|
||||||
Extension(state): Extension<Arc<State>>,
|
|
||||||
) -> Result<Json<xe_jsonfeed::Item>> {
|
|
||||||
let mut want: Option<Post> = None;
|
|
||||||
let want_link = format!("talks/{}", name);
|
|
||||||
|
|
||||||
for post in &state.talks {
|
|
||||||
if post.link == want_link {
|
|
||||||
want = Some(post.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match want {
|
|
||||||
None => Err(super::Error::PostNotFound(name)),
|
|
||||||
Some(post) => {
|
|
||||||
HIT_COUNTER_JSON
|
|
||||||
.with_label_values(&[name.clone().as_str()])
|
|
||||||
.inc();
|
|
||||||
Ok(Json(post.into()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -156,12 +156,13 @@ async fn main() -> Result<()> {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
// api
|
// api
|
||||||
|
.route("/api/new_post", get(handlers::feeds::new_post))
|
||||||
.route(
|
.route(
|
||||||
"/api/salary_transparency.json",
|
"/api/salary_transparency.json",
|
||||||
get(handlers::salary_transparency_json),
|
get(handlers::api::salary_transparency),
|
||||||
)
|
)
|
||||||
.route("/api/blog/:name", get(handlers::blog::post_json))
|
.route("/api/blog/:name", get(handlers::api::blog))
|
||||||
.route("/api/talks/:name", get(handlers::talks::post_json))
|
.route("/api/talks/:name", get(handlers::api::talk))
|
||||||
// static pages
|
// static pages
|
||||||
.route("/", get(handlers::index))
|
.route("/", get(handlers::index))
|
||||||
.route("/contact", get(handlers::contact))
|
.route("/contact", get(handlers::contact))
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
@use super::{header_html, footer_html};
|
@use super::{header_html, footer_html};
|
||||||
@use crate::{post::Post, tmpl::nag};
|
@use crate::{post::Post, tmpl::nag};
|
||||||
@use chrono::prelude::*;
|
|
||||||
|
|
||||||
@(post: Post, body: impl ToHtml, referer: Option<String>)
|
@(post: Post, body: impl ToHtml, referer: Option<String>)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue