Typstify /calendar endpoint
This commit is contained in:
parent
42f0885b43
commit
5f2dcf81d3
8 changed files with 93 additions and 126 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
use showbits_typst::Typst;
|
use showbits_typst::Typst;
|
||||||
|
|
||||||
|
pub mod calendar;
|
||||||
pub mod cells;
|
pub mod cells;
|
||||||
pub mod egg;
|
pub mod egg;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"year": 2025,
|
||||||
|
"month": 3,
|
||||||
|
"feed": false
|
||||||
|
}
|
||||||
1
showbits-thermal-printer/src/documents/calendar/lib
Symbolic link
1
showbits-thermal-printer/src/documents/calendar/lib
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../lib
|
||||||
36
showbits-thermal-printer/src/documents/calendar/main.typ
Normal file
36
showbits-thermal-printer/src/documents/calendar/main.typ
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#import "@preview/oxifmt:0.2.1": strfmt
|
||||||
|
#import "lib/main.typ" as lib;
|
||||||
|
#show: it => lib.init(it)
|
||||||
|
|
||||||
|
#let data = json("data.json")
|
||||||
|
#let date = datetime(year: data.year, month: data.month, day: 1)
|
||||||
|
|
||||||
|
#let month_length = 32 - (date + duration(days: 31)).day()
|
||||||
|
|
||||||
|
#let head(name) = text(size: 32pt, name)
|
||||||
|
#let empty = box()
|
||||||
|
#let day(n) = box(
|
||||||
|
width: 100%,
|
||||||
|
height: 100%,
|
||||||
|
stroke: 2pt + black,
|
||||||
|
strfmt("{:02}", n),
|
||||||
|
)
|
||||||
|
|
||||||
|
#align(center + horizon)[
|
||||||
|
#set par(spacing: 8pt)
|
||||||
|
|
||||||
|
Ankreuzkalender #strfmt("{:04}-{:02}", date.year(), date.month())
|
||||||
|
|
||||||
|
#grid(
|
||||||
|
columns: (50pt,) * 7,
|
||||||
|
rows: 50pt,
|
||||||
|
gutter: 4pt,
|
||||||
|
head[Mo], head[Di], head[Mi], head[Do], head[Fr], head[Sa], head[So],
|
||||||
|
..for _ in range(date.weekday() - 1) { (empty,) },
|
||||||
|
..for i in range(month_length) { (day(i + 1),) },
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
#if data.feed {
|
||||||
|
lib.feed
|
||||||
|
}
|
||||||
43
showbits-thermal-printer/src/documents/calendar/mod.rs
Normal file
43
showbits-thermal-printer/src/documents/calendar/mod.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
use axum::{Form, extract::State};
|
||||||
|
use jiff::Zoned;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
drawer::{Command, NewTypstDrawing},
|
||||||
|
server::{Server, somehow},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Data {
|
||||||
|
year: i16,
|
||||||
|
month: i8,
|
||||||
|
feed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct FormData {
|
||||||
|
pub year: Option<i16>,
|
||||||
|
pub month: Option<i8>,
|
||||||
|
pub feed: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn post(server: State<Server>, Form(form): Form<FormData>) -> somehow::Result<()> {
|
||||||
|
let date = Zoned::now().date();
|
||||||
|
|
||||||
|
let data = Data {
|
||||||
|
year: form.year.unwrap_or(date.year()),
|
||||||
|
month: form.month.unwrap_or(date.month()),
|
||||||
|
feed: form.feed.unwrap_or(true),
|
||||||
|
};
|
||||||
|
|
||||||
|
let typst = super::typst_with_lib()
|
||||||
|
.with_json("/data.json", &data)
|
||||||
|
.with_main_file(include_str!("main.typ"));
|
||||||
|
|
||||||
|
let _ = server
|
||||||
|
.tx
|
||||||
|
.send(Command::draw(NewTypstDrawing::new(typst)))
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
mod backlog;
|
mod backlog;
|
||||||
mod calendar;
|
|
||||||
mod chat_message;
|
mod chat_message;
|
||||||
mod new_typst;
|
mod new_typst;
|
||||||
mod photo;
|
mod photo;
|
||||||
|
|
@ -12,9 +11,8 @@ use tokio::sync::mpsc;
|
||||||
use crate::persistent_printer::PersistentPrinter;
|
use crate::persistent_printer::PersistentPrinter;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
backlog::BacklogDrawing, calendar::CalendarDrawing, chat_message::ChatMessageDrawing,
|
backlog::BacklogDrawing, chat_message::ChatMessageDrawing, new_typst::NewTypstDrawing,
|
||||||
new_typst::NewTypstDrawing, photo::PhotoDrawing, tictactoe::TicTacToeDrawing,
|
photo::PhotoDrawing, tictactoe::TicTacToeDrawing, typst::TypstDrawing,
|
||||||
typst::TypstDrawing,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FEED: f32 = 96.0;
|
pub const FEED: f32 = 96.0;
|
||||||
|
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
use jiff::civil;
|
|
||||||
use showbits_common::{
|
|
||||||
Node, Tree, WidgetExt,
|
|
||||||
color::{BLACK, WHITE},
|
|
||||||
widgets::{Block, Text},
|
|
||||||
};
|
|
||||||
use taffy::{
|
|
||||||
AlignContent, AlignItems, Display, FlexDirection,
|
|
||||||
style_helpers::{length, percent, repeat},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::persistent_printer::PersistentPrinter;
|
|
||||||
|
|
||||||
use super::{Context, Drawing, FEED};
|
|
||||||
|
|
||||||
pub struct CalendarDrawing {
|
|
||||||
pub year: i16,
|
|
||||||
pub month: i8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drawing for CalendarDrawing {
|
|
||||||
fn draw(&self, printer: &mut PersistentPrinter, ctx: &mut Context) -> anyhow::Result<()> {
|
|
||||||
let mut date = civil::Date::new(self.year, self.month, 1)?;
|
|
||||||
|
|
||||||
let mut tree = Tree::<Context>::new(WHITE);
|
|
||||||
|
|
||||||
let mut grid = Node::empty()
|
|
||||||
.with_display(Display::Grid)
|
|
||||||
.with_grid_template_columns(vec![repeat(7, vec![length(50.0)])])
|
|
||||||
.with_grid_auto_rows(vec![length(50.0)])
|
|
||||||
.with_gap(length(2.0));
|
|
||||||
|
|
||||||
for weekday in ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"] {
|
|
||||||
let text = Text::new()
|
|
||||||
.with_metrics(Text::default_metrics().scale(2.0))
|
|
||||||
.and_plain(weekday)
|
|
||||||
.widget(&mut ctx.font_stuff)
|
|
||||||
.node()
|
|
||||||
.with_justify_self(Some(AlignItems::Center))
|
|
||||||
.with_align_self(Some(AlignItems::Center))
|
|
||||||
.register(&mut tree)?;
|
|
||||||
|
|
||||||
grid = grid.and_child(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
let placeholders = date.weekday().to_monday_zero_offset();
|
|
||||||
for _ in 0..placeholders {
|
|
||||||
let empty = Node::empty().register(&mut tree)?;
|
|
||||||
grid = grid.and_child(empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let day = Text::new()
|
|
||||||
.and_plain(date.day().to_string())
|
|
||||||
.widget(&mut ctx.font_stuff)
|
|
||||||
.node()
|
|
||||||
.register(&mut tree)?;
|
|
||||||
|
|
||||||
let block = Block::new()
|
|
||||||
.with_border(BLACK)
|
|
||||||
.node()
|
|
||||||
.with_border(length(2.0))
|
|
||||||
.with_display(Display::Flex)
|
|
||||||
.with_justify_content(Some(AlignContent::Center))
|
|
||||||
.with_align_items(Some(AlignItems::Center))
|
|
||||||
.and_child(day)
|
|
||||||
.register(&mut tree)?;
|
|
||||||
|
|
||||||
grid = grid.and_child(block);
|
|
||||||
|
|
||||||
let next_day = date.tomorrow()?;
|
|
||||||
if date.month() != next_day.month() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
date = next_day;
|
|
||||||
}
|
|
||||||
|
|
||||||
let title = Text::new()
|
|
||||||
.and_plain(format!(
|
|
||||||
"Ankreuzkalender {:04}-{:02}",
|
|
||||||
self.year, self.month
|
|
||||||
))
|
|
||||||
.widget(&mut ctx.font_stuff)
|
|
||||||
.node()
|
|
||||||
.register(&mut tree)?;
|
|
||||||
|
|
||||||
let root = Node::empty()
|
|
||||||
.with_size_width(percent(1.0))
|
|
||||||
.with_padding_bottom(length(FEED))
|
|
||||||
.with_display(Display::Flex)
|
|
||||||
.with_flex_direction(FlexDirection::Column)
|
|
||||||
.with_align_items(Some(AlignItems::Center))
|
|
||||||
.and_child(title)
|
|
||||||
.and_child(grid.register(&mut tree)?)
|
|
||||||
.register(&mut tree)?;
|
|
||||||
|
|
||||||
printer.print_tree(&mut tree, ctx, root)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,9 +14,7 @@ use tokio::{net::TcpListener, sync::mpsc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
documents,
|
documents,
|
||||||
drawer::{
|
drawer::{ChatMessageDrawing, Command, PhotoDrawing, TicTacToeDrawing, TypstDrawing},
|
||||||
CalendarDrawing, ChatMessageDrawing, Command, PhotoDrawing, TicTacToeDrawing, TypstDrawing,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::{r#static::get_static_file, statuscode::status_code};
|
use self::{r#static::get_static_file, statuscode::status_code};
|
||||||
|
|
@ -28,7 +26,10 @@ pub struct Server {
|
||||||
|
|
||||||
pub async fn run(tx: mpsc::Sender<Command>, addr: String) -> anyhow::Result<()> {
|
pub async fn run(tx: mpsc::Sender<Command>, addr: String) -> anyhow::Result<()> {
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/calendar", post(post_calendar))
|
.route(
|
||||||
|
"/calendar",
|
||||||
|
post(documents::calendar::post).fallback(get_static_file),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
"/cells",
|
"/cells",
|
||||||
post(documents::cells::post).fallback(get_static_file),
|
post(documents::cells::post).fallback(get_static_file),
|
||||||
|
|
@ -55,24 +56,6 @@ pub async fn run(tx: mpsc::Sender<Command>, addr: String) -> anyhow::Result<()>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// /calendar
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct PostCalendarForm {
|
|
||||||
year: i16,
|
|
||||||
month: i8,
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn post_calendar(server: State<Server>, request: Form<PostCalendarForm>) {
|
|
||||||
let _ = server
|
|
||||||
.tx
|
|
||||||
.send(Command::draw(CalendarDrawing {
|
|
||||||
year: request.0.year,
|
|
||||||
month: request.0.month,
|
|
||||||
}))
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
// /chat_message
|
// /chat_message
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue