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;
|
||||
|
||||
pub mod calendar;
|
||||
pub mod cells;
|
||||
pub mod egg;
|
||||
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 calendar;
|
||||
mod chat_message;
|
||||
mod new_typst;
|
||||
mod photo;
|
||||
|
|
@ -12,9 +11,8 @@ use tokio::sync::mpsc;
|
|||
use crate::persistent_printer::PersistentPrinter;
|
||||
|
||||
pub use self::{
|
||||
backlog::BacklogDrawing, calendar::CalendarDrawing, chat_message::ChatMessageDrawing,
|
||||
new_typst::NewTypstDrawing, photo::PhotoDrawing, tictactoe::TicTacToeDrawing,
|
||||
typst::TypstDrawing,
|
||||
backlog::BacklogDrawing, chat_message::ChatMessageDrawing, new_typst::NewTypstDrawing,
|
||||
photo::PhotoDrawing, tictactoe::TicTacToeDrawing, typst::TypstDrawing,
|
||||
};
|
||||
|
||||
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::{
|
||||
documents,
|
||||
drawer::{
|
||||
CalendarDrawing, ChatMessageDrawing, Command, PhotoDrawing, TicTacToeDrawing, TypstDrawing,
|
||||
},
|
||||
drawer::{ChatMessageDrawing, Command, PhotoDrawing, TicTacToeDrawing, TypstDrawing},
|
||||
};
|
||||
|
||||
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<()> {
|
||||
let app = Router::new()
|
||||
.route("/calendar", post(post_calendar))
|
||||
.route(
|
||||
"/calendar",
|
||||
post(documents::calendar::post).fallback(get_static_file),
|
||||
)
|
||||
.route(
|
||||
"/cells",
|
||||
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(())
|
||||
}
|
||||
|
||||
// /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
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue