Add catfishing endpoint and UI
This commit is contained in:
parent
804000f681
commit
746d4b9fee
8 changed files with 353 additions and 0 deletions
|
|
@ -0,0 +1,49 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useApiRequest } from "@/apiRequest";
|
||||||
|
import { ref, useTemplateRef } from "vue";
|
||||||
|
import CError from "./CError.vue";
|
||||||
|
|
||||||
|
const { disabled, error, makeRequest } = useApiRequest();
|
||||||
|
const form = useTemplateRef<HTMLFormElement>("form");
|
||||||
|
|
||||||
|
const day = ref<number>(448);
|
||||||
|
const feed = ref(true);
|
||||||
|
|
||||||
|
function submit() {
|
||||||
|
const data = new URLSearchParams();
|
||||||
|
if (typeof day.value === "number") data.append("day", day.value.toFixed());
|
||||||
|
data.append("feed", String(feed.value));
|
||||||
|
void makeRequest("api/catfishing", data);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<form ref="form" @submit.prevent="submit">
|
||||||
|
<h2>catfishing</h2>
|
||||||
|
|
||||||
|
<label class="wide">
|
||||||
|
Day:
|
||||||
|
<input v-model="day" type="number" min="1" :disabled />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="wide">
|
||||||
|
<label><input v-model="feed" type="checkbox" :disabled /> Feed</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button :disabled>Print</button>
|
||||||
|
<CError :message="error" />
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wide {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import CDocumentBanner from "./CDocumentBanner.vue";
|
import CDocumentBanner from "./CDocumentBanner.vue";
|
||||||
import CDocumentCalendar from "./CDocumentCalendar.vue";
|
import CDocumentCalendar from "./CDocumentCalendar.vue";
|
||||||
|
import CDocumentsCatfishing from "./CDocumentCatfishing.vue";
|
||||||
import CDocumentCells from "./CDocumentCells.vue";
|
import CDocumentCells from "./CDocumentCells.vue";
|
||||||
import CDocumentChat from "./CDocumentChat.vue";
|
import CDocumentChat from "./CDocumentChat.vue";
|
||||||
import CDocumentEgg from "./CDocumentEgg.vue";
|
import CDocumentEgg from "./CDocumentEgg.vue";
|
||||||
|
|
@ -14,6 +15,7 @@ import CDocumentXkcd from "./CDocumentXkcd.vue";
|
||||||
const mode = ref<
|
const mode = ref<
|
||||||
| "banner"
|
| "banner"
|
||||||
| "calendar"
|
| "calendar"
|
||||||
|
| "catfishing"
|
||||||
| "cells"
|
| "cells"
|
||||||
| "chat"
|
| "chat"
|
||||||
| "egg"
|
| "egg"
|
||||||
|
|
@ -30,6 +32,7 @@ const mode = ref<
|
||||||
<button v-if="mode" class="close" @click="mode = undefined">X</button>
|
<button v-if="mode" class="close" @click="mode = undefined">X</button>
|
||||||
<CDocumentBanner v-if="mode === 'banner'" />
|
<CDocumentBanner v-if="mode === 'banner'" />
|
||||||
<CDocumentCalendar v-if="mode === 'calendar'" />
|
<CDocumentCalendar v-if="mode === 'calendar'" />
|
||||||
|
<CDocumentsCatfishing v-if="mode === 'catfishing'" />
|
||||||
<CDocumentCells v-if="mode === 'cells'" />
|
<CDocumentCells v-if="mode === 'cells'" />
|
||||||
<CDocumentChat v-if="mode === 'chat'" />
|
<CDocumentChat v-if="mode === 'chat'" />
|
||||||
<CDocumentEgg v-if="mode === 'egg'" />
|
<CDocumentEgg v-if="mode === 'egg'" />
|
||||||
|
|
@ -44,6 +47,7 @@ const mode = ref<
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<button @click="mode = 'banner'">Banner</button>
|
<button @click="mode = 'banner'">Banner</button>
|
||||||
<button @click="mode = 'calendar'">Calendar</button>
|
<button @click="mode = 'calendar'">Calendar</button>
|
||||||
|
<button @click="mode = 'catfishing'">Catfishing</button>
|
||||||
<button @click="mode = 'cells'">Cellular Automaton</button>
|
<button @click="mode = 'cells'">Cellular Automaton</button>
|
||||||
<button @click="mode = 'chat'">Chat Message</button>
|
<button @click="mode = 'chat'">Chat Message</button>
|
||||||
<button @click="mode = 'egg'">Easter Egg</button>
|
<button @click="mode = 'egg'">Easter Egg</button>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ pub mod sunrise;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
pub mod tictactoe;
|
pub mod tictactoe;
|
||||||
pub mod xkcd;
|
pub mod xkcd;
|
||||||
|
pub mod catfishing;
|
||||||
|
|
||||||
fn typst_with_lib() -> Typst {
|
fn typst_with_lib() -> Typst {
|
||||||
Typst::new().with_file("/lib/main.typ", include_str!("documents/lib/main.typ"))
|
Typst::new().with_file("/lib/main.typ", include_str!("documents/lib/main.typ"))
|
||||||
|
|
|
||||||
223
showbits-thermal-printer/src/documents/catfishing/data.json
Normal file
223
showbits-thermal-printer/src/documents/catfishing/data.json
Normal file
|
|
@ -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
|
||||||
|
}
|
||||||
1
showbits-thermal-printer/src/documents/catfishing/lib
Symbolic link
1
showbits-thermal-printer/src/documents/catfishing/lib
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../lib
|
||||||
19
showbits-thermal-printer/src/documents/catfishing/main.typ
Normal file
19
showbits-thermal-printer/src/documents/catfishing/main.typ
Normal file
|
|
@ -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
|
||||||
|
}
|
||||||
55
showbits-thermal-printer/src/documents/catfishing/mod.rs
Normal file
55
showbits-thermal-printer/src/documents/catfishing/mod.rs
Normal file
|
|
@ -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<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Data {
|
||||||
|
day: u32,
|
||||||
|
articles: Vec<ArticleInfo>,
|
||||||
|
feed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct FormData {
|
||||||
|
pub day: u32,
|
||||||
|
pub feed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn post(server: State<Server>, Form(form): Form<FormData>) -> somehow::Result<Response> {
|
||||||
|
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::<Vec<ArticleInfo>>()
|
||||||
|
.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())
|
||||||
|
}
|
||||||
|
|
@ -45,6 +45,7 @@ pub async fn run(
|
||||||
// API
|
// API
|
||||||
.route("/api/banner", post(documents::banner::post))
|
.route("/api/banner", post(documents::banner::post))
|
||||||
.route("/api/calendar", post(documents::calendar::post))
|
.route("/api/calendar", post(documents::calendar::post))
|
||||||
|
.route("/api/catfishing", post(documents::catfishing::post))
|
||||||
.route("/api/cells", post(documents::cells::post))
|
.route("/api/cells", post(documents::cells::post))
|
||||||
.route("/api/chat", post(documents::chat::post))
|
.route("/api/chat", post(documents::chat::post))
|
||||||
.route("/api/egg", post(documents::egg::post))
|
.route("/api/egg", post(documents::egg::post))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue