aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/config.rs60
-rw-r--r--src/handlers/api.rs18
-rw-r--r--src/handlers/mod.rs9
-rw-r--r--src/main.rs2
-rw-r--r--src/tmpl/mod.rs24
-rw-r--r--src/tmpl/nag.rs25
6 files changed, 128 insertions, 10 deletions
diff --git a/src/app/config.rs b/src/app/config.rs
index 6499e72..d3d93ca 100644
--- a/src/app/config.rs
+++ b/src/app/config.rs
@@ -4,7 +4,6 @@ use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fmt::{self, Display},
- path::PathBuf,
};
#[derive(Clone, Deserialize, Default)]
@@ -16,8 +15,6 @@ pub struct Config {
pub port: u16,
#[serde(rename = "clackSet")]
pub clack_set: Vec<String>,
- #[serde(rename = "resumeFname")]
- pub resume_fname: PathBuf,
#[serde(rename = "miToken")]
pub mi_token: String,
#[serde(rename = "jobHistory")]
@@ -30,6 +27,63 @@ pub struct Config {
pub notable_projects: Vec<Link>,
#[serde(rename = "contactLinks")]
pub contact_links: Vec<Link>,
+ pub pronouns: Vec<PronounSet>,
+}
+
+#[derive(Clone, Deserialize, Serialize, Default)]
+pub struct PronounSet {
+ nominative: String,
+ accusative: String,
+ #[serde(rename = "possessiveDeterminer")]
+ possessive_determiner: String,
+ possessive: String,
+ reflexive: String,
+ singular: bool,
+}
+
+impl Render for PronounSet {
+ fn render(&self) -> Markup {
+ html! {
+ big { (self.nominative) "/" (self.accusative) }
+ table {
+ tr {
+ th { "Subject" }
+ td {(self.nominative)}
+ }
+ tr {
+ th { "Object" }
+ td {(self.accusative)}
+ }
+ tr {
+ th { "Dependent Possessive" }
+ td {(self.possessive_determiner)}
+ }
+ tr {
+ th { "Independent Possessive" }
+ td {(self.possessive)}
+ }
+ tr {
+ th { "Reflexive" }
+ td {(self.reflexive)}
+ }
+ }
+ p {"Here are some example sentences with these pronouns:"}
+ ul {
+ li { i{(self.nominative)} " went to the park." }
+ li { "I went with " i{(self.accusative)} "." }
+ li { i{(self.nominative)} " brought " i{(self.possessive_determiner)} " frisbee." }
+ li { "At least I think it was " i{(self.possessive)} "." }
+ li { i{(self.nominative)} " threw the frisbee to " i{(self.reflexive)} "." }
+ }
+ @if !self.singular {
+ p {
+ "Please note that this pronoun is normally a plural pronoun. It is used here to refer to a single person. For more information on this, see "
+ a href="https://www.merriam-webster.com/words-at-play/singular-nonbinary-they" {"this page from Merriam-Webster"}
+ " that will explain in more detail."
+ }
+ }
+ }
+ }
}
#[derive(Clone, Deserialize, Serialize, Default)]
diff --git a/src/handlers/api.rs b/src/handlers/api.rs
index 835d282..828f93c 100644
--- a/src/handlers/api.rs
+++ b/src/handlers/api.rs
@@ -1,5 +1,5 @@
use crate::{
- app::{config::Job, State},
+ app::{config::Job, PronounSet, State},
handlers::Result,
post::Post,
};
@@ -27,8 +27,22 @@ pub async fn salary_transparency(Extension(state): Extension<Arc<State>>) -> Jso
super::HIT_COUNTER
.with_label_values(&["salary_transparency_json"])
.inc();
+ let state = state.clone();
+ let cfg = state.cfg.clone();
- Json(state.clone().cfg.clone().job_history.clone())
+ Json(cfg.job_history.clone())
+}
+
+#[axum_macros::debug_handler]
+#[instrument(skip(state))]
+pub async fn pronouns(Extension(state): Extension<Arc<State>>) -> Json<Vec<PronounSet>> {
+ super::HIT_COUNTER
+ .with_label_values(&["pronouns_json"])
+ .inc();
+ let state = state.clone();
+ let cfg = state.cfg.clone();
+
+ Json(cfg.pronouns.clone())
}
#[instrument(skip(state))]
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs
index a20d654..7284ec9 100644
--- a/src/handlers/mod.rs
+++ b/src/handlers/mod.rs
@@ -86,6 +86,15 @@ pub async fn contact(Extension(state): Extension<Arc<State>>) -> Markup {
crate::tmpl::contact(&cfg.contact_links)
}
+#[instrument(skip(state))]
+pub async fn pronouns(Extension(state): Extension<Arc<State>>) -> Markup {
+ HIT_COUNTER.with_label_values(&["pronouns"]).inc();
+ let state = state.clone();
+ let cfg = state.cfg.clone();
+
+ crate::tmpl::pronoun_page(&cfg.pronouns)
+}
+
#[instrument]
pub async fn feeds() -> Markup {
HIT_COUNTER.with_label_values(&["feeds"]).inc();
diff --git a/src/main.rs b/src/main.rs
index 3952975..37c0a4d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -161,6 +161,7 @@ async fn main() -> Result<()> {
),
)
// api
+ .route("/api/pronouns", get(handlers::api::pronouns))
.route("/api/new_post", get(handlers::feeds::new_post))
.route(
"/api/salary_transparency.json",
@@ -176,6 +177,7 @@ async fn main() -> Result<()> {
.route("/patrons", get(handlers::patrons))
.route("/signalboost", get(handlers::signalboost))
.route("/salary-transparency", get(handlers::salary_transparency))
+ .route("/pronouns", get(handlers::pronouns))
// feeds
.route("/blog.json", get(handlers::feeds::jsonfeed))
.route("/blog.atom", get(handlers::feeds::atom))
diff --git a/src/tmpl/mod.rs b/src/tmpl/mod.rs
index 1fbb239..2ad62c0 100644
--- a/src/tmpl/mod.rs
+++ b/src/tmpl/mod.rs
@@ -582,3 +582,27 @@ fn salary_history(jobs: &Vec<Job>) -> Markup {
}
}
}
+
+pub fn pronoun_page(pronouns: &Vec<PronounSet>) -> Markup {
+ base(
+ Some("Pronouns"),
+ None,
+ html! {
+ h1 {"Pronouns"}
+ p {"This page lists the pronouns you should use for me. Please try to use one of these sets:"}
+ .grid {
+ @for ps in pronouns {
+ .card.cell."-4of12" {
+ (ps)
+ }
+ }
+ }
+
+ (xesite_templates::conv("Mara".to_string(), "happy".to_string(), html!{
+ "You can access this data with "
+ a href="/api/pronouns" {"an API call"}
+ " too!"
+ }))
+ },
+ )
+}
diff --git a/src/tmpl/nag.rs b/src/tmpl/nag.rs
index 707c16c..7231c56 100644
--- a/src/tmpl/nag.rs
+++ b/src/tmpl/nag.rs
@@ -5,13 +5,14 @@ use regex::Regex;
lazy_static! {
static ref LOBSTERS: Regex = Regex::new(r#"^https?://lobste.rs"#).unwrap();
+ static ref HACKER_NEWS: Regex = Regex::new(r#"^https?://news.ycombinator.com"#).unwrap();
}
#[cfg(debug_assertions)]
pub fn referer(_: Option<String>) -> Markup {
html! {
.warning {
- "This is a development instance of xesite. Things here are probably unfinished or in drafting. Don't take anything here super seriously. If you want to share this to an online aggregator, please don't. Drafts are not finalized yet for a reason."
+ "This is a development instance of xesite. Things here are probably unfinished or in drafting. Don't take anything here super seriously. If you want to share this to an online aggregator, please don't. Drafts are not finalized yet for a reason. Please don't be the reason I need to implement more advanced security than just obscurity."
}
br;
}
@@ -27,12 +28,26 @@ pub fn referer(referer: Option<String>) -> Markup {
let referer = referer.unwrap();
+ if HACKER_NEWS.is_match(&referer) {
+ return xeblog_conv(
+ "Mara".into(),
+ "hacker".into(),
+ html! {
+ "Hello. Before commenting about the author, please read "
+ a href="/pronouns" {"this page"}
+ " that explains the pronouns that you should be using. tl;dr: the author of this website is NOT male. Please do not use \"he\" or \"him\" when referring to the author."
+ },
+ );
+ }
+
if LOBSTERS.is_match(&referer) {
- return html! {
- (xeblog_conv("Mara".into(), "happy".into(), html!{
+ return xeblog_conv(
+ "Mara".into(),
+ "happy".into(),
+ html! {
"Hey, thanks for reading Lobsters! We've disabled the ads to thank you for choosing to use a more ethical aggregator."
- }))
- };
+ },
+ );
}
xesite_templates::advertiser_nag()