2023-08-07 23:06:00 +00:00
|
|
|
/*
|
2023-07-28 18:42:25 +00:00
|
|
|
#[macro_use]
|
|
|
|
extern crate serde_derive;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate lazy_static;
|
2023-08-07 23:06:00 +00:00
|
|
|
*/
|
2023-07-28 18:42:25 +00:00
|
|
|
|
2023-08-08 02:35:43 +00:00
|
|
|
use chrono::{Datelike, Duration, NaiveTime};
|
2023-08-07 23:06:00 +00:00
|
|
|
use glib::Object;
|
2023-08-08 02:35:43 +00:00
|
|
|
use gtk::{prelude::*, subclass::prelude::*, Orientation};
|
|
|
|
use ifc::IFC;
|
|
|
|
use std::{cell::RefCell, f64::consts::PI, ops::Deref, rc::Rc};
|
2023-08-07 23:06:00 +00:00
|
|
|
|
|
|
|
/*
|
2023-07-28 18:42:25 +00:00
|
|
|
use geo_types::{Latitude, Longitude};
|
2023-08-08 02:35:43 +00:00
|
|
|
*/
|
2023-07-28 18:42:25 +00:00
|
|
|
|
|
|
|
mod soluna_client;
|
2023-08-08 02:35:43 +00:00
|
|
|
use soluna_client::{LunarPhase, SunMoon};
|
2023-07-28 18:42:25 +00:00
|
|
|
|
2023-08-08 02:35:43 +00:00
|
|
|
/*
|
2023-07-28 18:42:25 +00:00
|
|
|
mod solstices;
|
2023-08-07 23:06:00 +00:00
|
|
|
use solstices::EVENTS;
|
|
|
|
*/
|
2023-07-28 18:42:25 +00:00
|
|
|
|
2023-08-03 04:31:04 +00:00
|
|
|
/*
|
2023-07-28 18:42:25 +00:00
|
|
|
const EO_TEXT: &'static str = "
|
|
|
|
day = {$day ->
|
|
|
|
*[Sunday] Dimanĉo
|
|
|
|
[Monday] Lundo
|
|
|
|
[Tuesday] Mardo
|
|
|
|
[Wednesday] Merkredo
|
|
|
|
[Thursday] Ĵaŭdo
|
|
|
|
[Friday] Vendredo
|
|
|
|
[Saturday] Sabato
|
|
|
|
[LeapDay] Leap Day
|
|
|
|
[YearDay] Year Day
|
|
|
|
}
|
|
|
|
month = {$month ->
|
|
|
|
*[January] Januaro
|
|
|
|
[February] Februaro
|
|
|
|
[March] Marto
|
|
|
|
[April] Aprilo
|
|
|
|
[May] Mayo
|
|
|
|
[June] Junio
|
|
|
|
[Sol] Solo
|
|
|
|
[July] Julio
|
|
|
|
[August] Aŭgusto
|
|
|
|
[September] Septembro
|
|
|
|
[October] Oktobro
|
|
|
|
[November] Novembro
|
|
|
|
[December] Decembro
|
|
|
|
}
|
|
|
|
spring_equinox = Printempa Ekvinokso
|
|
|
|
summer_solstice = Somera Solstico
|
|
|
|
autumn_equinox = Aŭtuna Ekvinokso
|
|
|
|
winter_solstice = Vintra Solstico
|
|
|
|
";
|
|
|
|
|
2023-08-07 19:14:14 +00:00
|
|
|
fn date(fluent: Arc<fluent_ergonomics::FluentErgo>, today: ifc::IFC) -> impl Render {
|
2023-07-28 18:42:25 +00:00
|
|
|
let mut day_args = FluentArgs::new();
|
|
|
|
day_args.set(
|
|
|
|
"day",
|
|
|
|
FluentValue::String(Cow::Owned(String::from(today.weekday_ifc()))),
|
|
|
|
);
|
|
|
|
let tago = fluent.tr("tago", Some(&day_args)).unwrap();
|
|
|
|
|
|
|
|
let mut month_args = FluentArgs::new();
|
|
|
|
month_args.set(
|
|
|
|
"month",
|
|
|
|
FluentValue::String(Cow::Owned(String::from(today.month_ifc()))),
|
|
|
|
);
|
|
|
|
let monato = fluent.tr("month", Some(&month_args)).unwrap();
|
|
|
|
|
|
|
|
owned_html! {p : format!("{}, {} {}, {}", tago, monato, today.day(), today.year());}
|
|
|
|
}
|
2023-08-03 04:31:04 +00:00
|
|
|
*/
|
2023-07-28 18:42:25 +00:00
|
|
|
|
2023-08-03 04:31:04 +00:00
|
|
|
/*
|
|
|
|
fn soluna_desegno<Tz: TimeZone>(sun_moon: SunMoon<Tz>) -> impl Render {
|
2023-07-28 18:42:25 +00:00
|
|
|
owned_html! {
|
|
|
|
table {
|
|
|
|
tr {
|
|
|
|
th : "Sunleviĝo";
|
|
|
|
th : "Sunfalo";
|
|
|
|
th : "Lunleviĝo";
|
|
|
|
th : "Lunfalo";
|
|
|
|
}
|
|
|
|
tr {
|
2023-08-03 04:31:04 +00:00
|
|
|
td : format!("{}", sun_moon.sunrise.format("%H:%M"));
|
|
|
|
td : format!("{}", sun_moon.sunset.format("%H:%M"));
|
|
|
|
td : sun_moon.moonrise.map(|v| format!("{}", v.format("%H:%M"))).unwrap_or("".to_string());
|
|
|
|
td : sun_moon.moonset.map(|v| format!("{}", v.format("%H:%M"))).unwrap_or("".to_string());
|
|
|
|
td : format!("{:?}", sun_moon.moon_phase);
|
2023-07-28 18:42:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-08-03 04:31:04 +00:00
|
|
|
*/
|
2023-07-28 18:42:25 +00:00
|
|
|
|
2023-08-03 04:31:04 +00:00
|
|
|
/*
|
2023-07-28 18:42:25 +00:00
|
|
|
fn astronomia_eventa_desegno(
|
|
|
|
fluent: Arc<fluent_ergonomics::FluentErgo>,
|
|
|
|
event: Option<Event>,
|
|
|
|
) -> impl Render {
|
|
|
|
let s = match event {
|
|
|
|
None => "".to_owned(),
|
|
|
|
Some(event) => {
|
|
|
|
let eventa_str = match event {
|
2023-08-03 04:31:04 +00:00
|
|
|
Event::SpringEquinox(_) => fluent.tr("spring_equinox", None),
|
|
|
|
Event::SummerSolstice(_) => fluent.tr("summer_solstice", None),
|
|
|
|
Event::AutumnEquinox(_) => fluent.tr("autumn_equinox", None),
|
|
|
|
Event::WinterSolstice(_) => fluent.tr("winter_solstice", None),
|
2023-07-28 18:42:25 +00:00
|
|
|
}
|
|
|
|
.unwrap();
|
|
|
|
format!("{} {}", eventa_str, event.date().format("%Y-%m-%d"))
|
|
|
|
}
|
|
|
|
};
|
|
|
|
owned_html! {
|
|
|
|
div : s.clone();
|
|
|
|
}
|
|
|
|
}
|
2023-08-03 04:31:04 +00:00
|
|
|
*/
|
2023-07-28 18:42:25 +00:00
|
|
|
|
2023-08-03 02:44:10 +00:00
|
|
|
/*
|
2023-07-28 18:42:25 +00:00
|
|
|
fn page_template(
|
|
|
|
fluent: Arc<fluent_ergonomics::FluentErgo>,
|
2023-08-07 19:14:14 +00:00
|
|
|
today: ifc::IFC,
|
2023-07-28 18:42:25 +00:00
|
|
|
sun_moon: SunMoon,
|
|
|
|
event: Option<solstices::Event>,
|
|
|
|
) -> String {
|
|
|
|
format!(
|
|
|
|
"{}",
|
|
|
|
html! {
|
|
|
|
: doctype::HTML;
|
|
|
|
html {
|
|
|
|
head {
|
|
|
|
title: "Superrigardo";
|
|
|
|
}
|
|
|
|
body {
|
|
|
|
h1(id="heading", class="title") : date(fluent.clone(), today);
|
|
|
|
div : soluna_desegno(sun_moon.clone());
|
|
|
|
div : astronomia_eventa_desegno(fluent.clone(), event);
|
|
|
|
// div : cirklo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn page(
|
|
|
|
fluent: Arc<fluent_ergonomics::FluentErgo>,
|
|
|
|
solar_client: Arc<SolunaClient>,
|
|
|
|
latitude: Latitude,
|
|
|
|
longitude: Longitude,
|
|
|
|
) -> Result<Html<String>, Rejection> {
|
|
|
|
let now = Utc::now();
|
2023-08-07 19:14:14 +00:00
|
|
|
let d = ifc::IFC::from(now.with_timezone(&New_York).date());
|
2023-07-28 18:42:25 +00:00
|
|
|
let sun_moon = solar_client
|
|
|
|
.request(latitude, longitude, now.with_timezone(&New_York).date())
|
|
|
|
.await;
|
|
|
|
let next_event = EVENTS.next_event(now);
|
|
|
|
Ok(warp::reply::html(page_template(
|
|
|
|
fluent, d, sun_moon, next_event,
|
|
|
|
)))
|
|
|
|
}
|
2023-08-03 02:44:10 +00:00
|
|
|
*/
|
2023-07-28 18:42:25 +00:00
|
|
|
|
2023-08-07 23:06:00 +00:00
|
|
|
#[derive(Default)]
|
|
|
|
pub struct DatePrivate {}
|
|
|
|
|
|
|
|
#[glib::object_subclass]
|
|
|
|
impl ObjectSubclass for DatePrivate {
|
|
|
|
const NAME: &'static str = "Date";
|
|
|
|
type Type = Date;
|
|
|
|
type ParentType = gtk::Box;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ObjectImpl for DatePrivate {}
|
|
|
|
impl WidgetImpl for DatePrivate {}
|
|
|
|
impl BoxImpl for DatePrivate {}
|
|
|
|
|
|
|
|
glib::wrapper! {
|
|
|
|
pub struct Date(ObjectSubclass<DatePrivate>) @extends gtk::Box, gtk::Widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Date {
|
|
|
|
fn new() -> Self {
|
|
|
|
let s: Self = Object::builder().build();
|
|
|
|
|
2023-08-08 02:35:43 +00:00
|
|
|
let dt = IFC::from(chrono::Local::now().date_naive().with_year(12023).unwrap());
|
2023-08-07 23:06:00 +00:00
|
|
|
s.append(>k::Label::new(Some(
|
|
|
|
format!(
|
|
|
|
"{:?}, {:?} {}, {}",
|
|
|
|
dt.weekday(),
|
|
|
|
dt.month(),
|
|
|
|
dt.day(),
|
|
|
|
dt.year()
|
|
|
|
)
|
|
|
|
.as_ref(),
|
|
|
|
)));
|
|
|
|
s
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-08 02:35:43 +00:00
|
|
|
#[derive(Default)]
|
2023-08-08 03:53:42 +00:00
|
|
|
pub struct ClockPrivate {
|
2023-08-08 02:35:43 +00:00
|
|
|
info: Rc<RefCell<Option<SunMoon>>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[glib::object_subclass]
|
2023-08-08 03:53:42 +00:00
|
|
|
impl ObjectSubclass for ClockPrivate {
|
|
|
|
const NAME: &'static str = "Clock";
|
|
|
|
type Type = Clock;
|
2023-08-08 02:35:43 +00:00
|
|
|
type ParentType = gtk::DrawingArea;
|
|
|
|
}
|
|
|
|
|
2023-08-08 03:53:42 +00:00
|
|
|
impl ObjectImpl for ClockPrivate {}
|
|
|
|
impl WidgetImpl for ClockPrivate {}
|
|
|
|
impl DrawingAreaImpl for ClockPrivate {}
|
2023-08-08 02:35:43 +00:00
|
|
|
|
|
|
|
glib::wrapper! {
|
2023-08-08 03:53:42 +00:00
|
|
|
pub struct Clock(ObjectSubclass<ClockPrivate>) @extends gtk::DrawingArea, gtk::Widget;
|
2023-08-08 02:35:43 +00:00
|
|
|
}
|
|
|
|
|
2023-08-08 03:53:42 +00:00
|
|
|
impl Clock {
|
2023-08-08 02:35:43 +00:00
|
|
|
pub fn new(sun_moon_info: SunMoon) -> Self {
|
|
|
|
let s: Self = Object::builder().build();
|
|
|
|
s.set_width_request(500);
|
|
|
|
s.set_height_request(500);
|
|
|
|
|
|
|
|
*s.imp().info.borrow_mut() = Some(sun_moon_info);
|
|
|
|
s.set_draw_func({
|
|
|
|
let s = s.clone();
|
|
|
|
move |_, context, width, height| {
|
|
|
|
let info = s.imp().info.borrow();
|
|
|
|
|
|
|
|
// context.set_source_rgb(240., 240., 240.);
|
|
|
|
context.set_source_rgb(0., 0., 0.);
|
|
|
|
let _ = context.paint();
|
|
|
|
|
|
|
|
context.set_line_width(5.);
|
|
|
|
context.set_source_rgb(0.7, 0., 0.9);
|
|
|
|
context.arc(width as f64 / 2., height as f64 / 2., 200., 0., PI * 2.);
|
|
|
|
let _ = context.stroke();
|
|
|
|
|
2023-08-08 03:53:42 +00:00
|
|
|
(0..24).for_each(|hour| {
|
|
|
|
context.translate(width as f64 / 2., height as f64 / 2.);
|
|
|
|
context.rotate(PI / 12. * hour as f64);
|
|
|
|
context.move_to(210., 0.);
|
|
|
|
context.line_to(230., 0.);
|
|
|
|
context.identity_matrix();
|
|
|
|
let _ = context.stroke();
|
|
|
|
});
|
|
|
|
|
2023-08-08 02:35:43 +00:00
|
|
|
if let Some(info) = info.deref() {
|
|
|
|
context.move_to(width as f64 / 2., height as f64 / 2.);
|
|
|
|
let full_day = Duration::days(1).num_seconds() as f64;
|
|
|
|
let sunrise = info.sunrise - NaiveTime::from_hms_opt(0, 0, 0).unwrap();
|
|
|
|
let sunset = info.sunset - NaiveTime::from_hms_opt(0, 0, 0).unwrap();
|
|
|
|
|
|
|
|
let start = (PI * 2.) * sunset.num_seconds() as f64 / full_day - (PI / 2.);
|
|
|
|
let end = (PI * 2.) * sunrise.num_seconds() as f64 / full_day - (PI / 2.);
|
|
|
|
|
|
|
|
context.set_source_rgb(0., 0.7, 0.9);
|
|
|
|
context.arc(width as f64 / 2., height as f64 / 2., 200., start, end);
|
|
|
|
let _ = context.fill();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
s
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-07 23:06:00 +00:00
|
|
|
pub fn main() {
|
|
|
|
/*
|
|
|
|
let runtime = Arc::new(
|
|
|
|
tokio::runtime::Builder::new_multi_thread()
|
|
|
|
.enable_all()
|
|
|
|
.build()
|
|
|
|
.unwrap(),
|
|
|
|
);
|
|
|
|
*/
|
|
|
|
let app = gtk::Application::builder()
|
|
|
|
.application_id("com.luminescent-dreams.dashboard")
|
|
|
|
.build();
|
|
|
|
|
|
|
|
app.connect_activate(
|
|
|
|
// let runtime = runtime.clone();
|
|
|
|
|app| {
|
|
|
|
let window = gtk::ApplicationWindow::new(app);
|
|
|
|
window.present();
|
|
|
|
|
2023-08-08 02:35:43 +00:00
|
|
|
let layout = gtk::Box::builder()
|
|
|
|
.orientation(Orientation::Vertical)
|
|
|
|
.build();
|
2023-08-07 23:06:00 +00:00
|
|
|
let date = Date::new();
|
2023-08-08 03:53:42 +00:00
|
|
|
let day = Clock::new(SunMoon {
|
2023-08-08 02:35:43 +00:00
|
|
|
sunrise: NaiveTime::from_hms_opt(6, 0, 0).unwrap(),
|
|
|
|
sunset: NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
|
|
|
|
moonrise: NaiveTime::from_hms_opt(15, 0, 0),
|
|
|
|
moonset: NaiveTime::from_hms_opt(5, 0, 0),
|
|
|
|
moon_phase: LunarPhase::WaningCrescent,
|
|
|
|
});
|
|
|
|
layout.append(&date);
|
|
|
|
layout.append(&day);
|
|
|
|
window.set_child(Some(&layout));
|
2023-08-07 23:06:00 +00:00
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
app.run();
|
|
|
|
|
|
|
|
/*
|
2023-08-03 04:31:04 +00:00
|
|
|
let now = Local::now();
|
2023-08-07 19:14:14 +00:00
|
|
|
let ifc = ifc::IFC::from(now.date_naive().with_year(12023).unwrap());
|
2023-08-03 04:31:04 +00:00
|
|
|
let next_event = EVENTS.next_event(now.with_timezone(&Utc)).unwrap();
|
2023-07-28 18:42:25 +00:00
|
|
|
|
2023-08-03 04:31:04 +00:00
|
|
|
println!(
|
|
|
|
"{:?}, {:?} {}, {}",
|
|
|
|
ifc.weekday(),
|
|
|
|
ifc.month(),
|
|
|
|
ifc.day(),
|
|
|
|
ifc.year()
|
|
|
|
);
|
|
|
|
|
|
|
|
println!("{:?}", next_event);
|
|
|
|
|
|
|
|
let latitude = Latitude::from(41.78);
|
|
|
|
let longitude = Longitude::from(-71.41);
|
|
|
|
let soluna_client = SolunaClient::new();
|
|
|
|
let sun_moon = soluna_client
|
|
|
|
.request(latitude, longitude, Local::now())
|
2023-07-28 18:42:25 +00:00
|
|
|
.await;
|
2023-08-03 04:31:04 +00:00
|
|
|
|
|
|
|
println!(
|
|
|
|
"Solar Transit: {} -> {}",
|
|
|
|
sun_moon.sunrise.format("%H:%M").to_string(),
|
|
|
|
sun_moon.sunset.format("%H:%M").to_string()
|
|
|
|
);
|
|
|
|
println!(
|
|
|
|
"Lunar Transit: {} -> {} [{:?}]",
|
|
|
|
sun_moon
|
|
|
|
.moonrise
|
|
|
|
.map(|time| time.format("%H:%M").to_string())
|
|
|
|
.unwrap_or(" -- ".to_owned()),
|
|
|
|
sun_moon
|
|
|
|
.moonset
|
|
|
|
.map(|time| time.format("%H:%M").to_string())
|
|
|
|
.unwrap_or(" -- ".to_owned()),
|
|
|
|
sun_moon.moon_phase
|
|
|
|
);
|
2023-08-07 23:06:00 +00:00
|
|
|
*/
|
2023-07-28 18:42:25 +00:00
|
|
|
}
|