README/weather

This commit is contained in:
Cadey Ratio 2020-04-08 18:19:44 -04:00
parent 83c5a8ccbd
commit ac0ea18145
4 changed files with 121 additions and 0 deletions

27
README.md Normal file
View File

@ -0,0 +1,27 @@
# lo mi cabytcini
ni'o ni'o ti cu me lo mi cabytcini be lo mi cankyralju me'e la zo DWM.
## gaftercu'a
.i sfaile fa zoi .py. $HOME/.config/cabytcini/gaftercu'a.toml .py. lo gaftercu'a
be ko'a .i le formato cu:
```toml
front_url = "https://whatever.omg/path"
weather_url = "https://omg.weather/darksky"
```
.i lo zo `front_url` cu eilga terbe'i lo jadycau uensni fi'o benji zo HTTP
.i lo zo `weather_url` cu eilga terbe'i lo zo JSON fi'o benji zo HTTP
## pilno
.i ko ci'erse'a fi'o zoi .ko.
```console
$ nix-env -if ./cabytcini.nix
```
.ko.

View File

@ -1,5 +1,6 @@
mod config;
mod front;
mod weather;
mod xsetroot;
use chrono::prelude::*;
@ -14,6 +15,14 @@ use std::{
};
use xsetroot::XSetRoot;
// Name your user agent after your app?
pub static APP_USER_AGENT: &str = concat!(
env!("CARGO_PKG_NAME"),
"/",
env!("CARGO_PKG_VERSION"),
" +https://tulpa.dev/cadey/cabytcini",
);
pub(crate) type MTState = Arc<Mutex<State>>;
fn handle_client(stream: UnixStream, st: MTState) {
@ -62,6 +71,13 @@ fn main() -> std::io::Result<()> {
thread::spawn(move || front::update(mtst, cfg));
}
// start weather thread
{
let mtst = mtst.clone();
let cfg = cfg.clone();
thread::spawn(move || weather::update(mtst, cfg));
}
let _ = std::fs::remove_file("/home/cadey/tmp/cabytcini.sock")?;
let listener = UnixListener::bind("/home/cadey/tmp/cabytcini.sock")?;
for stream in listener.incoming() {
@ -83,6 +99,7 @@ fn main() -> std::io::Result<()> {
pub(crate) struct State {
msg: String,
front: String,
weather: Option<weather::Root>,
}
impl fmt::Display for State {
@ -96,6 +113,7 @@ impl State {
State {
msg: "".to_string(),
front: "".to_string(),
weather: None,
}
}
@ -113,6 +131,17 @@ impl State {
msg.push_str(format!("{} | ", self.front).as_str());
}
match &self.weather {
Some(datni) => msg.push_str(format!(
"{} {} / {} {} | ",
datni.currently.temperature,
datni.currently.summary,
datni.daily.data[0].temperature_high,
datni.daily.data[0].temperature_low
).as_str()),
None => {}
};
msg.push_str(format!("{}", now).as_str());
xsr.render(msg);

65
src/weather.rs Normal file
View File

@ -0,0 +1,65 @@
use crate::{config::Config, MTState};
use reqwest::blocking::*;
use serde::{Deserialize, Serialize};
use std::{thread, time};
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Root {
pub currently: Currently,
pub daily: Daily,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Currently {
pub time: i64,
pub summary: String,
pub temperature: f64,
pub apparent_temperature: f64,
pub humidity: f64,
pub icon: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Daily {
pub summary: String,
pub icon: String,
pub data: Vec<Daum>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Daum {
pub time: i64,
pub icon: String,
pub temperature_high: f64,
pub temperature_low: f64,
}
const UPDATE_FREQUENCY: u64 = 15 * 60; // 15 minutes
fn get(cfg: &Config) -> reqwest::Result<Root> {
let client = Client::builder().user_agent(crate::APP_USER_AGENT).build()?;
let now: Root = client.get(&cfg.weather_url).send()?.json()?;
Ok(now)
}
pub(crate) fn update(st: MTState, cfg: Config) {
loop {
match get(&cfg) {
Ok(datni) => {
let mut data = st.lock().unwrap();
data.weather = Some(datni);
}
Err(why) => {
log::error!("error getting weather from {}: {:?}", &cfg.weather_url, why);
}
}
let amt = time::Duration::new(UPDATE_FREQUENCY, 0);
thread::sleep(amt);
}
}