ticker-serve: group_by_day()

This commit is contained in:
Astro 2019-10-26 02:19:33 +02:00
parent 72349760eb
commit a3e5ca2af3
1 changed files with 57 additions and 26 deletions

View File

@ -1,13 +1,12 @@
#![feature(proc_macro_hygiene, decl_macro)] #![feature(proc_macro_hygiene, decl_macro)]
#![recursion_limit="512"] #![recursion_limit="1024"]
use std::fs::read_to_string;
use std::sync::Mutex; use std::sync::Mutex;
#[macro_use] extern crate rocket; #[macro_use] extern crate rocket;
use rocket::{State, response::content}; use rocket::{State, response::content};
use typed_html::{html, text, dom::DOMTree}; use typed_html::{html, text, dom::DOMTree};
use diesel::{Connection, pg::PgConnection, prelude::*}; use diesel::{Connection, pg::PgConnection, prelude::*};
use chrono::offset::Local; use chrono::{offset::Local, NaiveDate};
use libticker::{ use libticker::{
config::{Config, CalendarOptions}, config::{Config, CalendarOptions},
@ -24,6 +23,33 @@ fn fix_url(s: &str) -> std::borrow::Cow<str> {
} }
} }
struct DayEvents<'e> {
date: NaiveDate,
events: &'e [Event],
}
/// assumes pre-sorted input
fn group_by_day(es: &[Event]) -> Vec<DayEvents> {
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("/")] #[get("/")]
fn index(db: State<Mutex<PgConnection>>) -> content::Html<String> { fn index(db: State<Mutex<PgConnection>>) -> content::Html<String> {
let db = db.lock().unwrap(); let db = db.lock().unwrap();
@ -34,7 +60,8 @@ fn index(db: State<Mutex<PgConnection>>) -> content::Html<String> {
.then_order_by(schema::events::dtend.desc()) .then_order_by(schema::events::dtend.desc())
.load::<Event>(&*db) .load::<Event>(&*db)
.unwrap(); .unwrap();
let days = group_by_day(&es);
let doc: DOMTree<String> = html!( let doc: DOMTree<String> = html!(
<html> <html>
<head> <head>
@ -43,29 +70,33 @@ fn index(db: State<Mutex<PgConnection>>) -> content::Html<String> {
<body> <body>
<h1>"Ticker"</h1> <h1>"Ticker"</h1>
{ es.iter().map(|e| html!( { days.iter().map(|day| html!(<div>
<article class="event"> <nav><h2>{ text!("{}", &day.date) }</h2></nav>
{ match &e.url {
None => html!(
<h2>{ text!("{}", &e.summary) }</h2>
),
Some(url) => html!(
<h2>
<a href={ fix_url(url) }>
{ text!("{}", &e.summary) }
</a>
</h2>
),
} }
<p class="dtstart">{ text!("{}", &e.dtstart) }</p> { day.events.iter().map(|e| html!(
{ e.location.as_ref().map(|location| html!( <article class="event">
<p> { match &e.url {
{ text!("{}", location) } None => html!(
</p> <h3>{ text!("{}", &e.summary) }</h3>
)) } ),
</article> Some(url) => html!(
)) } <h3>
<a href={ fix_url(url) }>
{ text!("{}", &e.summary) }
</a>
</h3>
),
} }
<p class="dtstart">{ text!("{}", &e.dtstart) }</p>
{ e.location.as_ref().map(|location| html!(
<p>
{ text!("{}", location) }
</p>
)) }
</article>
)) }
</div>)) }
</body> </body>
</html> </html>
); );