diff --git a/showbits-thermal-printer-ui/src/components/CDocumentCatfishing.vue b/showbits-thermal-printer-ui/src/components/CDocumentCatfishing.vue
new file mode 100644
index 0000000..a72de6d
--- /dev/null
+++ b/showbits-thermal-printer-ui/src/components/CDocumentCatfishing.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
diff --git a/showbits-thermal-printer-ui/src/components/CSelector.vue b/showbits-thermal-printer-ui/src/components/CSelector.vue
index 3dcc0db..5b4bfb8 100644
--- a/showbits-thermal-printer-ui/src/components/CSelector.vue
+++ b/showbits-thermal-printer-ui/src/components/CSelector.vue
@@ -2,6 +2,7 @@
import { ref } from "vue";
import CDocumentBanner from "./CDocumentBanner.vue";
import CDocumentCalendar from "./CDocumentCalendar.vue";
+import CDocumentsCatfishing from "./CDocumentCatfishing.vue";
import CDocumentCells from "./CDocumentCells.vue";
import CDocumentChat from "./CDocumentChat.vue";
import CDocumentEgg from "./CDocumentEgg.vue";
@@ -14,6 +15,7 @@ import CDocumentXkcd from "./CDocumentXkcd.vue";
const mode = ref<
| "banner"
| "calendar"
+ | "catfishing"
| "cells"
| "chat"
| "egg"
@@ -30,6 +32,7 @@ const mode = ref<
+
@@ -44,6 +47,7 @@ const mode = ref<
+
diff --git a/showbits-thermal-printer/src/documents.rs b/showbits-thermal-printer/src/documents.rs
index 3d297ec..55f00bd 100644
--- a/showbits-thermal-printer/src/documents.rs
+++ b/showbits-thermal-printer/src/documents.rs
@@ -10,6 +10,7 @@ pub mod sunrise;
pub mod text;
pub mod tictactoe;
pub mod xkcd;
+pub mod catfishing;
fn typst_with_lib() -> Typst {
Typst::new().with_file("/lib/main.typ", include_str!("documents/lib/main.typ"))
diff --git a/showbits-thermal-printer/src/documents/catfishing/data.json b/showbits-thermal-printer/src/documents/catfishing/data.json
new file mode 100644
index 0000000..1283f3c
--- /dev/null
+++ b/showbits-thermal-printer/src/documents/catfishing/data.json
@@ -0,0 +1,223 @@
+{
+ "day": 448,
+ "articles": [
+ {
+ "title": "Met Gala",
+ "categories": [
+ "1948 establishments in New York City",
+ "Annual events in New York City",
+ "Balls in the United States",
+ "Fashion events in the United States",
+ "Metropolitan Museum of Art",
+ "Recurring events established in 1948",
+ "Vogue (magazine)"
+ ]
+ },
+ {
+ "title": "Auto-Tune",
+ "categories": [
+ "1990s in music",
+ "2000s in music",
+ "2010s in music",
+ "Audiovisual introductions in 1997",
+ "Effects units",
+ "Music controversies",
+ "Pitch modification software"
+ ]
+ },
+ {
+ "title": "Claus von Stauffenberg",
+ "categories": [
+ "1907 births",
+ "1944 deaths",
+ "Counts in Germany",
+ "Executed failed assassins of Adolf Hitler",
+ "Executed German assassins",
+ "Executed members of the 20 July plot",
+ "Executed military personnel",
+ "Eyepatch wearers",
+ "Failed assassins of Heinrich Himmler",
+ "German amputees",
+ "German anti-communists",
+ "German Army officers of World War II",
+ "German blind people",
+ "German military personnel who were court-martialed",
+ "German nationalist assassins",
+ "German Roman Catholics",
+ "Military personnel from the Kingdom of Bavaria",
+ "People educated at Eberhard-Ludwigs-Gymnasium",
+ "People executed by Nazi Germany by firing squad",
+ "People from Bavaria executed by Nazi Germany",
+ "People from Günzburg (district)",
+ "Recipients of the Gold German Cross",
+ "Reichswehr personnel",
+ "Roman Catholics in the German Resistance"
+ ]
+ },
+ {
+ "title": "Apollo Theater",
+ "categories": [
+ "1910s architecture in the United States",
+ "1914 establishments in New York City",
+ "African-American arts organizations",
+ "African-American culture",
+ "African-American theatre",
+ "Black theatre",
+ "Burlesque theatres",
+ "George Keister buildings",
+ "Historically African-American theaters and music venues",
+ "Music venues in Manhattan",
+ "Neoclassical architecture in New York City",
+ "New York City Designated Landmarks in Manhattan",
+ "New York City interior landmarks",
+ "Theatres completed in 1914",
+ "Theatres in Harlem",
+ "Theatres on the National Register of Historic Places in Manhattan",
+ "Tourist attractions in Manhattan"
+ ]
+ },
+ {
+ "title": "Atomium",
+ "categories": [
+ "Buildings and structures completed in 1958",
+ "Buildings and structures in Brussels",
+ "Copyright infringement",
+ "Expo 58",
+ "Modernist architecture",
+ "Modernist architecture in Belgium",
+ "Symbols of Brussels",
+ "Tourist attractions in Brussels",
+ "World's fair architecture in Belgium"
+ ]
+ },
+ {
+ "title": "Manufacturing Consent",
+ "categories": [
+ "1988 non-fiction books",
+ "Books about media bias",
+ "Books about politics of the United States",
+ "Books about propaganda",
+ "Books about public opinion",
+ "Books by Edward S. Herman",
+ "Books by Noam Chomsky",
+ "Collaborative non-fiction books",
+ "English-language non-fiction books",
+ "Non-fiction books adapted into films",
+ "Pantheon Books books",
+ "Works about the information economy"
+ ]
+ },
+ {
+ "title": "The Shining (film)",
+ "categories": [
+ "1980 films",
+ "1980 horror films",
+ "1980s American films",
+ "1980s British films",
+ "1980s English-language films",
+ "1980s ghost films",
+ "American haunted house films",
+ "American psychological horror films",
+ "British haunted house films",
+ "British psychological horror films",
+ "English-language horror films",
+ "Fiction about familicide",
+ "Fiction about haunted houses",
+ "Films about alcoholism",
+ "Films about domestic violence",
+ "Films about dysfunctional families",
+ "Films about father-son relationships",
+ "Films about mother-son relationships",
+ "Films about telepathy",
+ "Films about twin sisters",
+ "Films about writers",
+ "Films based on American horror novels",
+ "Films based on works by Stephen King",
+ "Films directed by Stanley Kubrick",
+ "Films produced by Stanley Kubrick",
+ "Films scored by Wendy Carlos",
+ "Films set during snowstorms",
+ "Films set in Colorado",
+ "Films set in hotels",
+ "Films set in mazes",
+ "Films shot at EMI-Elstree Studios",
+ "Films shot in chronological order",
+ "Films shot in Hertfordshire",
+ "Films shot in Montana",
+ "Films shot in Oregon",
+ "Films with screenplays by Diane Johnson",
+ "Films with screenplays by Stanley Kubrick",
+ "Saturn Award-winning films",
+ "United States National Film Registry films",
+ "Warner Bros. films"
+ ]
+ },
+ {
+ "title": "Witch of Endor",
+ "categories": [
+ "11th-century BC women",
+ "Ancient occultists",
+ "Necromancy",
+ "People from the Kingdom of Israel (united monarchy)",
+ "Samuel",
+ "Saul",
+ "Spiritual mediums",
+ "Unnamed people of the Bible",
+ "Ventriloquists",
+ "Women in the Hebrew Bible"
+ ]
+ },
+ {
+ "title": "Nowruz",
+ "categories": [
+ "Ancient Iranian religion",
+ "Culture of Iran",
+ "Festivals in Albania",
+ "Festivals in Azerbaijan",
+ "Festivals in Georgia (country)",
+ "Festivals in Iran",
+ "Festivals in Iraq",
+ "Festivals in Kazakhstan",
+ "Festivals in Kosovo",
+ "Festivals in Kyrgyzstan",
+ "Festivals in Russia",
+ "Festivals in Syria",
+ "Festivals in Turkey",
+ "Festivals in Uzbekistan",
+ "Goldfish in culture",
+ "Intangible Cultural Heritage of India",
+ "March observances",
+ "Masterpieces of the Oral and Intangible Heritage of Humanity",
+ "National symbols of Iran",
+ "New Year celebrations",
+ "Observances on non-Gregorian calendars",
+ "Observances set by the Solar Hijri calendar",
+ "Persian culture",
+ "Persian festivals",
+ "Persian words and phrases",
+ "Public holidays in Afghanistan",
+ "Public holidays in Albania",
+ "Public holidays in Azerbaijan",
+ "Public holidays in Georgia (country)",
+ "Public holidays in Iraq",
+ "Public holidays in Kazakhstan",
+ "Public holidays in Kyrgyzstan",
+ "Public holidays in Uzbekistan",
+ "Spring (season) in Iran",
+ "Spring equinox",
+ "Zoroastrian festivals"
+ ]
+ },
+ {
+ "title": "Nagorno-Karabakh",
+ "categories": [
+ "Armenia-Azerbaijan relations",
+ "Armenian irredentism",
+ "Enclaves and exclaves",
+ "Historical regions in Azerbaijan",
+ "Subdivisions of Azerbaijan"
+ ]
+ }
+ ],
+ "feed": false
+}
diff --git a/showbits-thermal-printer/src/documents/catfishing/lib b/showbits-thermal-printer/src/documents/catfishing/lib
new file mode 120000
index 0000000..dc598c5
--- /dev/null
+++ b/showbits-thermal-printer/src/documents/catfishing/lib
@@ -0,0 +1 @@
+../lib
\ No newline at end of file
diff --git a/showbits-thermal-printer/src/documents/catfishing/main.typ b/showbits-thermal-printer/src/documents/catfishing/main.typ
new file mode 100644
index 0000000..86265b4
--- /dev/null
+++ b/showbits-thermal-printer/src/documents/catfishing/main.typ
@@ -0,0 +1,19 @@
+#import "lib/main.typ" as lib;
+#show: it => lib.init(it)
+
+#let data = json("data.json")
+
+= Catfishing (day #data.day)
+
+#for article in data.articles [
+ #v(24pt)
+ #for cat in article.categories [
+ - #cat
+ ]
+ #v(24pt)
+ #line(length: 100%)
+]
+
+#if data.feed {
+ lib.feed
+}
diff --git a/showbits-thermal-printer/src/documents/catfishing/mod.rs b/showbits-thermal-printer/src/documents/catfishing/mod.rs
new file mode 100644
index 0000000..11d5733
--- /dev/null
+++ b/showbits-thermal-printer/src/documents/catfishing/mod.rs
@@ -0,0 +1,55 @@
+use axum::{
+ Form,
+ extract::State,
+ response::{IntoResponse, Response},
+};
+use serde::{Deserialize, Serialize};
+
+use crate::server::{Server, somehow};
+
+#[derive(Serialize, Deserialize)]
+struct ArticleInfo {
+ title: String,
+ categories: Vec
,
+}
+
+#[derive(Serialize)]
+struct Data {
+ day: u32,
+ articles: Vec,
+ feed: bool,
+}
+
+#[derive(Deserialize)]
+pub struct FormData {
+ pub day: u32,
+ pub feed: bool,
+}
+
+pub async fn post(server: State, Form(form): Form) -> somehow::Result {
+ let client = reqwest::Client::builder()
+ .user_agent(crate::USER_AGENT)
+ .build()?;
+
+ let url = format!("https://static.catfishing.net/daily/{}.json", form.day);
+
+ let articles = client
+ .get(url)
+ .send()
+ .await?
+ .json::>()
+ .await?;
+
+ let data = Data {
+ day: form.day,
+ articles,
+ feed: form.feed,
+ };
+
+ let typst = super::typst_with_lib()
+ .with_json("/data.json", &data)
+ .with_main_file(include_str!("main.typ"));
+
+ server.print_typst(typst).await?;
+ Ok(().into_response())
+}
diff --git a/showbits-thermal-printer/src/server.rs b/showbits-thermal-printer/src/server.rs
index c3619ab..1f90557 100644
--- a/showbits-thermal-printer/src/server.rs
+++ b/showbits-thermal-printer/src/server.rs
@@ -45,6 +45,7 @@ pub async fn run(
// API
.route("/api/banner", post(documents::banner::post))
.route("/api/calendar", post(documents::calendar::post))
+ .route("/api/catfishing", post(documents::catfishing::post))
.route("/api/cells", post(documents::cells::post))
.route("/api/chat", post(documents::chat::post))
.route("/api/egg", post(documents::egg::post))