From 351069d9f91edab96425bcd221858529acb7e08a Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Wed, 4 Jan 2023 14:37:22 -0500 Subject: implement pronouns support Signed-off-by: Xe Iaso --- dhall/authors.dhall | 7 +++++- dhall/authors/xe.dhall | 4 +-- dhall/package.dhall | 6 +++-- dhall/pronouns.dhall | 15 +++++++++++ dhall/pronouns/she.dhall | 10 ++++++++ dhall/pronouns/they.dhall | 10 ++++++++ dhall/types/Author.dhall | 40 ++++++++++++++++------------- dhall/types/Config.dhall | 6 +++-- dhall/types/PronounSet.dhall | 17 +++++++++++++ dhall/types/package.dhall | 1 + src/app/config.rs | 60 +++++++++++++++++++++++++++++++++++++++++--- src/handlers/api.rs | 18 +++++++++++-- src/handlers/mod.rs | 9 +++++++ src/main.rs | 2 ++ src/tmpl/mod.rs | 24 ++++++++++++++++++ src/tmpl/nag.rs | 25 ++++++++++++++---- 16 files changed, 218 insertions(+), 36 deletions(-) create mode 100644 dhall/pronouns.dhall create mode 100644 dhall/pronouns/she.dhall create mode 100644 dhall/pronouns/they.dhall create mode 100644 dhall/types/PronounSet.dhall diff --git a/dhall/authors.dhall b/dhall/authors.dhall index a921222..be71e14 100644 --- a/dhall/authors.dhall +++ b/dhall/authors.dhall @@ -21,7 +21,12 @@ let authors = "https://cdn.xeiaso.net/file/christine-static/img/FFVV1InX0AkDX3f_cropped_smol.jpg" , inSystem = True } - , Author::{ name = "Nicole", handle = "Twi", inSystem = True } + , Author::{ + , name = "Nicole Brennan" + , handle = "Twi" + , url = Some "https://tech.lgbt/@twi" + , inSystem = True + } , Author::{ name = "Mai", handle = "Mai", inSystem = True } , Author::{ name = "Sephira", handle = "sephiraloveboo", inSystem = True } ] diff --git a/dhall/authors/xe.dhall b/dhall/authors/xe.dhall index 718de7f..6ea9540 100644 --- a/dhall/authors/xe.dhall +++ b/dhall/authors/xe.dhall @@ -1,6 +1,4 @@ -let xesite = ../types/package.dhall - -let Author = xesite.Author +let Author = ../types/Author.dhall in Author::{ , name = "Xe Iaso" diff --git a/dhall/package.dhall b/dhall/package.dhall index 6a4d639..e1e6996 100644 --- a/dhall/package.dhall +++ b/dhall/package.dhall @@ -23,10 +23,11 @@ in Config::{ , title = "Aura" , description = "PonyvilleFM live DJ recording bot" } - , Link::{ + , Link::{ , url = "https://h.within.lgbt" , title = "The h Programming Language" - , description = "An esoteric programming language that compiles to WebAssembly" + , description = + "An esoteric programming language that compiles to WebAssembly" } , Link::{ , url = "https://github.com/Xe/olin" @@ -80,4 +81,5 @@ in Config::{ , Link::{ url = "https://t.me/miamorecadenza", title = "Telegram" } , Link::{ url = "irc://irc.libera.chat/#xeserv", title = "IRC" } ] + , pronouns = ./pronouns.dhall } diff --git a/dhall/pronouns.dhall b/dhall/pronouns.dhall new file mode 100644 index 0000000..1479cd2 --- /dev/null +++ b/dhall/pronouns.dhall @@ -0,0 +1,15 @@ +let xesite = ./types/package.dhall + +let Pronouns = xesite.PronounSet + +in [ Pronouns::{ + , nominative = "xe" + , accusative = "xer" + , possessiveDeterminer = "xer" + , possessive = "xers" + , reflexive = "xerself" + , singular = True + } + , ./pronouns/they.dhall + , ./pronouns/she.dhall + ] diff --git a/dhall/pronouns/she.dhall b/dhall/pronouns/she.dhall new file mode 100644 index 0000000..61d2021 --- /dev/null +++ b/dhall/pronouns/she.dhall @@ -0,0 +1,10 @@ +let Pronouns = ../types/PronounSet.dhall + +in Pronouns::{ + , nominative = "she" + , accusative = "her" + , possessiveDeterminer = "her" + , possessive = "hers" + , reflexive = "herself" + , singular = True + } diff --git a/dhall/pronouns/they.dhall b/dhall/pronouns/they.dhall new file mode 100644 index 0000000..efd2a08 --- /dev/null +++ b/dhall/pronouns/they.dhall @@ -0,0 +1,10 @@ +let Pronouns = ../types/PronounSet.dhall + +in Pronouns::{ + , nominative = "they" + , accusative = "them" + , possessiveDeterminer = "their" + , possessive = "theirs" + , reflexive = "themselves" + , singular = False + } diff --git a/dhall/types/Author.dhall b/dhall/types/Author.dhall index 79cab6c..47a850f 100644 --- a/dhall/types/Author.dhall +++ b/dhall/types/Author.dhall @@ -1,19 +1,23 @@ -{ Type = - { name : Text - , handle : Text - , image : Optional Text - , url : Optional Text - , sameAs : List Text - , jobTitle : Text - , inSystem : Bool +let PronounSet = ./PronounSet.dhall + +in { Type = + { name : Text + , handle : Text + , image : Optional Text + , url : Optional Text + , sameAs : List Text + , jobTitle : Text + , inSystem : Bool + , pronouns : PronounSet.Type + } + , default = + { name = "" + , handle = "" + , image = None Text + , url = None Text + , sameAs = [] : List Text + , jobTitle = "" + , inSystem = False + , pronouns = ../pronouns/she.dhall + } } -, default = - { name = "" - , handle = "" - , image = None Text - , url = None Text - , sameAs = [] : List Text - , jobTitle = "" - , inSystem = False - } -} diff --git a/dhall/types/Config.dhall b/dhall/types/Config.dhall index 914c89a..245c645 100644 --- a/dhall/types/Config.dhall +++ b/dhall/types/Config.dhall @@ -10,6 +10,8 @@ let NagMessage = ./NagMessage.dhall let SeriesDescription = ./SeriesDescription.dhall +let PronounSet = ./PronounSet.dhall + let Prelude = ../Prelude.dhall let defaultPort = env:PORT ? 3030 @@ -24,7 +26,6 @@ in { Type = , authors : Prelude.Map.Type Text Author.Type , port : Natural , clackSet : List Text - , resumeFname : Text , webMentionEndpoint : Text , miToken : Text , jobHistory : List Job.Type @@ -32,6 +33,7 @@ in { Type = , seriesDescMap : Prelude.Map.Type Text Text , notableProjects : List Link.Type , contactLinks : List Link.Type + , pronouns : List PronounSet.Type } , default = { signalboost = [] : List Person.Type @@ -39,7 +41,6 @@ in { Type = , authors = [] : List Author.Type , port = defaultPort , clackSet = [ "Ashlynn" ] - , resumeFname = "./static/resume/resume.md" , webMentionEndpoint = defaultWebMentionEndpoint , miToken = "${env:MI_TOKEN as Text ? ""}" , jobHistory = [] : List Job.Type @@ -47,5 +48,6 @@ in { Type = , seriesDescMap = [] : Prelude.Map.Type Text Text , notableProjects = [] : List Link.Type , contactLinks = [] : List Link.Type + , pronouns = [] : List PronounSet.Type } } diff --git a/dhall/types/PronounSet.dhall b/dhall/types/PronounSet.dhall new file mode 100644 index 0000000..13384b3 --- /dev/null +++ b/dhall/types/PronounSet.dhall @@ -0,0 +1,17 @@ +{ Type = + { nominative : Text + , accusative : Text + , possessiveDeterminer : Text + , possessive : Text + , reflexive : Text + , singular : Bool + } +, default = + { nominative = "xe" + , accusative = "xer" + , possessiveDeterminer = "xer" + , possessive = "xers" + , reflexive = "xerself" + , singular = True + } +} diff --git a/dhall/types/package.dhall b/dhall/types/package.dhall index 4f4166e..4226d77 100644 --- a/dhall/types/package.dhall +++ b/dhall/types/package.dhall @@ -6,6 +6,7 @@ , Location = ./Location.dhall , NagMessage = ./NagMessage.dhall , Person = ./Person.dhall +, PronounSet = ./PronounSet.dhall , Resume = ./Resume.dhall , Salary = ./Salary.dhall , SeriesDescription = ./SeriesDescription.dhall 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, - #[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, #[serde(rename = "contactLinks")] pub contact_links: Vec, + pub pronouns: Vec, +} + +#[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>) -> 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>) -> Json> { + 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>) -> Markup { crate::tmpl::contact(&cfg.contact_links) } +#[instrument(skip(state))] +pub async fn pronouns(Extension(state): Extension>) -> 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) -> Markup { } } } + +pub fn pronoun_page(pronouns: &Vec) -> 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) -> 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) -> 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() -- cgit v1.2.3