#![feature(proc_macro_hygiene, decl_macro)] #![recursion_limit="1024"] use std::sync::Mutex; #[macro_use] extern crate rocket; use rocket::{State, response::content}; use typed_html::{html, text, dom::DOMTree}; use diesel::{Connection, pg::PgConnection, prelude::*}; use chrono::{offset::Local, NaiveDate}; use libticker::{ config::{Config, CalendarOptions}, schema::{self, events::dsl::events}, model::{Calendar, Event}, ics::{Object, Timestamp, GetValue}, }; fn fix_url(s: &str) -> std::borrow::Cow { if s.starts_with("http:") || s.starts_with("https:") { s.into() } else { format!("http://{}", s).into() } } struct DayEvents<'e> { date: NaiveDate, events: &'e [Event], } /// assumes pre-sorted input fn group_by_day(es: &[Event]) -> Vec { let mut results = vec![]; let mut prev_date = None; let mut date_start = 0; for (i, event) in es.iter().enumerate() { if prev_date.is_some() && prev_date != Some(event.dtstart.date()) { if i > date_start { results.push(DayEvents { date: prev_date.unwrap().clone(), events: &es[date_start..i], }); date_start = i; } } prev_date = Some(event.dtstart.date()); } results } #[get("/")] fn index(db: State>) -> content::Html { let db = db.lock().unwrap(); let today = Local::today().naive_local().and_hms(0, 0, 0); let es = events .filter(schema::events::dtstart.ge(&today)) .order_by(schema::events::dtstart.asc()) .then_order_by(schema::events::dtend.desc()) .load::(&*db) .unwrap(); let days = group_by_day(&es); let doc: DOMTree = html!( "Ticker"

"Ticker"

{ days.iter().map(|day| html!(
{ day.events.iter().map(|e| html!(
{ match &e.url { None => html!(

{ text!("{}", &e.summary) }

), Some(url) => html!(

{ text!("{}", &e.summary) }

), } }

{ text!("{}", &e.dtstart) }

{ e.location.as_ref().map(|location| html!(

{ text!("{}", location) }

)) }
)) }
)) } ); content::Html(doc.to_string()) } fn main() { let config = Config::read_yaml_file("config.yaml"); let db = PgConnection::establish(&config.db_url) .expect("DB"); rocket::ignite() .manage(Mutex::new(db)) .mount("/", routes![ index, ]) .launch(); }