Compare commits

...

16 Commits

Author SHA1 Message Date
Cadey Ratio 858949745e updates
Signed-off-by: Christine Dodrill <me@christine.website>
2021-06-09 09:39:52 -04:00
Cadey Ratio 398cd96934 omg colors
Signed-off-by: Christine Dodrill <me@christine.website>
2021-01-30 10:34:31 -05:00
Cadey Ratio 8501c8b61d giga oops
Signed-off-by: Christine Dodrill <me@christine.website>
2021-01-30 10:21:13 -05:00
Cadey Ratio 50d62d1283 oops
Signed-off-by: Christine Dodrill <me@christine.website>
2021-01-30 10:18:30 -05:00
Cadey Ratio ae305313eb pilno lahoi sway
Signed-off-by: Christine Dodrill <me@christine.website>
2021-01-30 10:11:30 -05:00
Cadey Ratio 6095468e76 Update '.drone.yml'
continuous-integration/drone/push Build is passing Details
2020-11-06 14:31:16 +00:00
Cadey Ratio e92842da33 Update 'default.nix'
continuous-integration/drone/push Build is failing Details
2020-11-06 14:30:48 +00:00
Cadey Ratio 364efb280c really disable openssl
continuous-integration/drone/push Build is passing Details
2020-10-28 08:38:29 -04:00
Cadey Ratio 6e3d49beb2 rustls
continuous-integration/drone/push Build is passing Details
2020-10-28 08:19:45 -04:00
Cadey Ratio 3cb50f1c35 0.3.0
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is passing Details
2020-10-28 08:12:29 -04:00
Cadey Ratio 19dd028c07 remove x11 crate 2020-10-28 08:12:08 -04:00
Cadey Ratio c78fb3dcb5 more slow
continuous-integration/drone/push Build is passing Details
2020-08-25 16:06:15 -04:00
Cadey Ratio 310c018d0c fix lag 2020-08-25 16:04:46 -04:00
Cadey Ratio 3de2d10f90 v0.2.1
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2020-04-10 07:20:26 -04:00
Cadey Ratio 722a99c8d9 use anyhow all over
continuous-integration/drone/push Build is failing Details
2020-04-10 07:18:51 -04:00
Cadey Ratio b4d3cfe960 use anyhow 2020-04-10 07:12:09 -04:00
14 changed files with 474 additions and 960 deletions

View File

@ -2,6 +2,6 @@ kind: pipeline
name: zbasu name: zbasu
steps: steps:
- commands: - commands:
- "nix-build ./cabytcini.nix" - "nix-build"
image: "monacoremo/nix:2020-04-05-05f09348-circleci" image: "monacoremo/nix:2020-04-05-05f09348-circleci"
name: zbasu le sampla name: zbasu le sampla

5
CHANGELOG.md Normal file
View File

@ -0,0 +1,5 @@
# Changelog
## 0.3.0
- Rewrite using async rust

920
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cabytcini" name = "cabytcini"
version = "0.2.0" version = "0.3.0"
authors = ["Christine Dodrill <me@christine.website>"] authors = ["Christine Dodrill <me@christine.website>"]
edition = "2018" edition = "2018"
license = "MIT" license = "MIT"
@ -8,18 +8,12 @@ license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
anyhow = "1.0"
chrono = "0.4" chrono = "0.4"
log = "0.4"
env_logger = "0.7" env_logger = "0.7"
serde = { version = "1", features = [ "derive" ] } log = "0.4"
serde_json = "1" serde_json = "1"
serde = { version = "1", features = [ "derive" ] }
toml = "0.5" toml = "0.5"
xdg = "2.2" xdg = "2.2"
ureq = { version = "2", features = ["json", "charset"] }
[dependencies.reqwest]
version = "0.10"
features = [ "blocking", "json" ]
[dependencies.x11]
features = ["xlib"]
version = "2.18.2"

View File

@ -5,10 +5,10 @@
"homepage": "", "homepage": "",
"owner": "nmattia", "owner": "nmattia",
"repo": "naersk", "repo": "naersk",
"rev": "1dd63230066a93c61ab7a66934eb0aae3f1a3613", "rev": "e8061169e1495871b56be97c5c51d310fae01374",
"sha256": "1xn8m62ypg13jh4zf101qmfa6gy8cl923fgwvk9c33m573h3k154", "sha256": "0683bdn7nvd63ziy09vm43iwpis4fdsj2hyk14hksz7igwrsy2g3",
"type": "tarball", "type": "tarball",
"url": "https://github.com/nmattia/naersk/archive/1dd63230066a93c61ab7a66934eb0aae3f1a3613.tar.gz", "url": "https://github.com/nmattia/naersk/archive/e8061169e1495871b56be97c5c51d310fae01374.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"niv": { "niv": {
@ -17,22 +17,22 @@
"homepage": "https://github.com/nmattia/niv", "homepage": "https://github.com/nmattia/niv",
"owner": "nmattia", "owner": "nmattia",
"repo": "niv", "repo": "niv",
"rev": "f73bf8d584148677b01859677a63191c31911eae", "rev": "527494090f7075ed5e3aa15ef7093846e5e25d52",
"sha256": "0jlmrx633jvqrqlyhlzpvdrnim128gc81q5psz2lpp2af8p8q9qs", "sha256": "1hahf0i0iix1iyzaaq5a7rbgyfm3xjcfl69lm1b5mas1p8vdimih",
"type": "tarball", "type": "tarball",
"url": "https://github.com/nmattia/niv/archive/f73bf8d584148677b01859677a63191c31911eae.tar.gz", "url": "https://github.com/nmattia/niv/archive/527494090f7075ed5e3aa15ef7093846e5e25d52.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
}, },
"nixpkgs": { "nixpkgs": {
"branch": "nixos-20.03", "branch": "nixpkgs-unstable",
"description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to", "description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to",
"homepage": "https://github.com/NixOS/nixpkgs", "homepage": "https://github.com/NixOS/nixpkgs",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs-channels", "repo": "nixpkgs-channels",
"rev": "0bb35152be895abfd1fc743b42f1c4e56ae71906", "rev": "502845c3e31ef3de0e424f3fcb09217df2ce6df6",
"sha256": "0mydmhr1fm5l0p668wx5wlk3six7k3n56sz41fv0h9zms0lqszf9", "sha256": "0fcqpsy6y7dgn0y0wgpa56gsg0b0p8avlpjrd79fp4mp9bl18nda",
"type": "tarball", "type": "tarball",
"url": "https://github.com/NixOS/nixpkgs-channels/archive/0bb35152be895abfd1fc743b42f1c4e56ae71906.tar.gz", "url": "https://github.com/NixOS/nixpkgs-channels/archive/502845c3e31ef3de0e424f3fcb09217df2ce6df6.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
} }
} }

View File

@ -6,52 +6,63 @@ let
# The fetchers. fetch_<type> fetches specs of type <type>. # The fetchers. fetch_<type> fetches specs of type <type>.
# #
fetch_file = pkgs: spec: fetch_file = pkgs: name: spec:
if spec.builtin or true then let
builtins_fetchurl { inherit (spec) url sha256; } name' = sanitizeName name + "-src";
else in
pkgs.fetchurl { inherit (spec) url sha256; }; if spec.builtin or true then
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
else
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
fetch_tarball = pkgs: spec: fetch_tarball = pkgs: name: spec:
if spec.builtin or true then let
builtins_fetchTarball { inherit (spec) url sha256; } name' = sanitizeName name + "-src";
else in
pkgs.fetchzip { inherit (spec) url sha256; }; if spec.builtin or true then
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
else
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
fetch_git = spec: fetch_git = name: spec:
builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; }; let
ref =
if spec ? ref then spec.ref else
if spec ? branch then "refs/heads/${spec.branch}" else
if spec ? tag then "refs/tags/${spec.tag}" else
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
in
builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; };
fetch_builtin-tarball = spec: fetch_local = spec: spec.path;
builtins.trace
''
WARNING:
The niv type "builtin-tarball" will soon be deprecated. You should
instead use `builtin = true`.
$ niv modify <package> -a type=tarball -a builtin=true fetch_builtin-tarball = name: throw
'' ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
builtins_fetchTarball { inherit (spec) url sha256; }; $ niv modify ${name} -a type=tarball -a builtin=true'';
fetch_builtin-url = spec: fetch_builtin-url = name: throw
builtins.trace ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
'' $ niv modify ${name} -a type=file -a builtin=true'';
WARNING:
The niv type "builtin-url" will soon be deprecated. You should
instead use `builtin = true`.
$ niv modify <package> -a type=file -a builtin=true
''
(builtins_fetchurl { inherit (spec) url sha256; });
# #
# Various helpers # Various helpers
# #
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
sanitizeName = name:
(
concatMapStrings (s: if builtins.isList s then "-" else s)
(
builtins.split "[^[:alnum:]+._?=-]+"
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
)
);
# The set of packages used when specs are fetched using non-builtins. # The set of packages used when specs are fetched using non-builtins.
mkPkgs = sources: mkPkgs = sources: system:
let let
sourcesNixpkgs = sourcesNixpkgs =
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {}; import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
hasThisAsNixpkgsPath = <nixpkgs> == ./.; hasThisAsNixpkgsPath = <nixpkgs> == ./.;
in in
@ -71,14 +82,27 @@ let
if ! builtins.hasAttr "type" spec then if ! builtins.hasAttr "type" spec then
abort "ERROR: niv spec ${name} does not have a 'type' attribute" abort "ERROR: niv spec ${name} does not have a 'type' attribute"
else if spec.type == "file" then fetch_file pkgs spec else if spec.type == "file" then fetch_file pkgs name spec
else if spec.type == "tarball" then fetch_tarball pkgs spec else if spec.type == "tarball" then fetch_tarball pkgs name spec
else if spec.type == "git" then fetch_git spec else if spec.type == "git" then fetch_git name spec
else if spec.type == "builtin-tarball" then fetch_builtin-tarball spec else if spec.type == "local" then fetch_local spec
else if spec.type == "builtin-url" then fetch_builtin-url spec else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
else if spec.type == "builtin-url" then fetch_builtin-url name
else else
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
# If the environment variable NIV_OVERRIDE_${name} is set, then use
# the path directly as opposed to the fetched source.
replace = name: drv:
let
saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
in
if ersatz == "" then drv else
# this turns the string into an actual Nix path (for both absolute and
# relative paths)
if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
# Ports of functions for older nix versions # Ports of functions for older nix versions
# a Nix version of mapAttrs if the built-in doesn't exist # a Nix version of mapAttrs if the built-in doesn't exist
@ -87,23 +111,37 @@ let
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
); );
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
concatMapStrings = f: list: concatStrings (map f list);
concatStrings = builtins.concatStringsSep "";
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
optionalAttrs = cond: as: if cond then as else {};
# fetchTarball version that is compatible between all the versions of Nix # fetchTarball version that is compatible between all the versions of Nix
builtins_fetchTarball = { url, sha256 }@attrs: builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
let let
inherit (builtins) lessThan nixVersion fetchTarball; inherit (builtins) lessThan nixVersion fetchTarball;
in in
if lessThan nixVersion "1.12" then if lessThan nixVersion "1.12" then
fetchTarball { inherit url; } fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else else
fetchTarball attrs; fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix # fetchurl version that is compatible between all the versions of Nix
builtins_fetchurl = { url, sha256 }@attrs: builtins_fetchurl = { url, name ? null, sha256 }@attrs:
let let
inherit (builtins) lessThan nixVersion fetchurl; inherit (builtins) lessThan nixVersion fetchurl;
in in
if lessThan nixVersion "1.12" then if lessThan nixVersion "1.12" then
fetchurl { inherit url; } fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
else else
fetchurl attrs; fetchurl attrs;
@ -115,14 +153,15 @@ let
then abort then abort
"The values in sources.json should not have an 'outPath' attribute" "The values in sources.json should not have an 'outPath' attribute"
else else
spec // { outPath = fetch config.pkgs name spec; } spec // { outPath = replace name (fetch config.pkgs name spec); }
) config.sources; ) config.sources;
# The "config" used by the fetchers # The "config" used by the fetchers
mkConfig = mkConfig =
{ sourcesFile ? ./sources.json { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
, sources ? builtins.fromJSON (builtins.readFile sourcesFile) , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
, pkgs ? mkPkgs sources , system ? builtins.currentSystem
, pkgs ? mkPkgs sources system
}: rec { }: rec {
# The sources, i.e. the attribute set of spec name to spec # The sources, i.e. the attribute set of spec name to spec
inherit sources; inherit sources;
@ -130,5 +169,6 @@ let
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
inherit pkgs; inherit pkgs;
}; };
in in
mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }

77
src/bin/cabytcinysuhei.rs Normal file
View File

@ -0,0 +1,77 @@
use anyhow::Result;
use cabytcini::*;
use chrono::prelude::*;
use std::{
sync::{Arc, Mutex},
thread, time,
};
const UPDATE_FREQUENCY: u64 = 15000;
fn main() -> Result<()> {
env_logger::init();
println!(r#"{{ "version": 1 }}"#);
println!("[[]");
let st: State = State::init();
let mtst = Arc::new(Mutex::new(st));
let cfg = config::load()?;
// start front thread
{
let mtst = mtst.clone();
let cfg = cfg.clone();
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));
}
thread::sleep(time::Duration::from_millis(750));
loop {
{
let data = mtst.lock().unwrap();
let mut blocks: Vec<Block> = vec![Block {
full_text: data.front.clone(),
color: match data.front.as_str() {
"Cadey" => Some("#F86AF3".to_string()),
"Nicole" => Some("#C79DD7".to_string()),
"Jessie" => Some("#97871A".to_string()),
"Ashe" => Some("#458588".to_string()),
"Sephie" => Some("#D79921".to_string()),
"Mai" => Some("#D65D0E".to_string()),
_ => None,
},
}];
if let Some(datni) = &data.weather {
blocks.push(Block {
full_text: format!(
"{} {} / {} {}",
datni.currently.temperature,
datni.currently.summary,
datni.daily.data[0].temperature_high,
datni.daily.data[0].temperature_low
),
color: None,
})
}
blocks.push(Block {
full_text: Local::now().format("%H:%M M%m %-d %a").to_string(),
color: None,
});
println!(",{}", serde_json::to_string(&blocks)?);
}
let so_often = time::Duration::from_millis(UPDATE_FREQUENCY);
thread::sleep(so_often);
}
}

View File

@ -1,29 +1,26 @@
use anyhow::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
fs::File, fs::File,
io::{Read, Result, Write}, io::{Read, Write},
}; };
use xdg::*; use xdg::*;
#[derive(Deserialize, Serialize, Debug, Clone)] #[derive(Deserialize, Serialize, Debug, Clone)]
pub(crate) struct Config { pub struct Config {
pub(crate) front_url: String, pub(crate) front_url: String,
pub(crate) weather_url: String, pub(crate) weather_url: String,
} }
pub(crate) fn load() -> Result<Config> { pub fn load() -> Result<Config> {
let xdg_dirs = let xdg_dirs =
BaseDirectories::with_prefix("cabytcini").expect("pu djica lo nu finti lei datnyveiste"); BaseDirectories::with_prefix("cabytcini").expect("pu djica lo nu finti lei datnyveiste");
let config_path = xdg_dirs let config_path = xdg_dirs.place_config_file("gaftercu'a.toml")?;
.place_config_file("gaftercu'a.toml")
.expect("pu djica lo nu le datnyveiste be lo gaftercu'a zvati");
match File::open(&config_path) { match File::open(&config_path) {
Ok(mut fin) => { Ok(mut fin) => {
let mut datni = String::new(); let mut datni = String::new();
fin.read_to_string(&mut datni) fin.read_to_string(&mut datni)?;
.expect("pu djica lo nu tcidu le sfaile"); let cfg: Config = toml::from_str(datni.as_str())?;
let cfg: Config =
toml::from_str(datni.as_str()).expect("pu djica lo nu jimpe lo sfaile");
Ok(cfg) Ok(cfg)
} }

View File

@ -4,12 +4,15 @@ use std::{thread, time};
const FIVE_MINUTES: u64 = 60 * 5; const FIVE_MINUTES: u64 = 60 * 5;
pub(crate) fn update(st: MTState, cfg: Config) { pub fn update(st: MTState, cfg: Config) {
loop { loop {
match reqwest::blocking::get(&cfg.front_url) { match ureq::get(&cfg.front_url)
.set("User-Agent", crate::APP_USER_AGENT)
.call()
{
Ok(who) => { Ok(who) => {
let mut data = st.lock().unwrap(); let mut data = st.lock().unwrap();
let who = who.text().unwrap().trim().to_string(); let who = who.into_string().unwrap().trim().to_string();
if who != data.front { if who != data.front {
data.front = who; data.front = who;
info!("new front: {}", data.front); info!("new front: {}", data.front);

90
src/lib.rs Normal file
View File

@ -0,0 +1,90 @@
#[macro_use]
extern crate log;
use chrono::prelude::*;
use serde::Serialize;
use std::{
fmt,
sync::{Arc, Mutex},
};
use xsetroot::XSetRoot;
pub mod config;
pub mod front;
pub mod weather;
pub mod xsetroot;
pub static APP_USER_AGENT: &str = concat!(
env!("CARGO_PKG_NAME"),
"/",
env!("CARGO_PKG_VERSION"),
" +https://tulpa.dev/cadey/cabytcini",
);
pub type MTState = Arc<Mutex<State>>;
pub struct State {
pub msg: String,
pub front: String,
pub weather: Option<weather::Root>,
}
#[derive(Serialize, Default)]
pub struct Block {
pub full_text: String,
pub color: Option<String>,
}
impl fmt::Display for State {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.msg)
}
}
impl State {
pub fn init() -> State {
State {
msg: "".to_string(),
front: "".to_string(),
weather: None,
}
}
pub fn to_string(&self) -> String {
let now = Local::now().format("%H:%M M%m %-d %a");
let mut msg = String::new();
if self.msg != "" {
msg.push_str(format!("{} | ", self.msg).as_str());
}
if self.front != "" {
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());
msg
}
pub fn xsetroot(&self) {
let xsr = XSetRoot::init().expect("xsetroot to initialize");
if let Err(why) = xsr.render(self.to_string()) {
error!("error setting root window title: {:?}", why);
}
}
}

View File

@ -1,29 +1,16 @@
mod config; use anyhow::Result;
mod front;
mod weather;
mod xsetroot;
use chrono::prelude::*;
use log::*; use log::*;
use std::{ use std::{
fmt,
io::{prelude::*, BufReader}, io::{prelude::*, BufReader},
net::Shutdown, net::Shutdown,
os::unix::net::{UnixListener, UnixStream}, os::unix::net::{UnixListener, UnixStream},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
thread, time, thread, time,
}; };
use xsetroot::XSetRoot;
// Name your user agent after your app? use cabytcini::*;
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>>; pub type MTState = Arc<Mutex<State>>;
fn handle_client(stream: UnixStream, st: MTState) { fn handle_client(stream: UnixStream, st: MTState) {
let mut rdr = BufReader::new(&stream); let mut rdr = BufReader::new(&stream);
@ -37,7 +24,7 @@ fn handle_client(stream: UnixStream, st: MTState) {
stream.shutdown(Shutdown::Both).expect("socket to close"); stream.shutdown(Shutdown::Both).expect("socket to close");
} }
const UPDATE_FREQUENCY: u64 = 250; const UPDATE_FREQUENCY: u64 = 15000;
fn update_every_so_often(st: MTState) { fn update_every_so_often(st: MTState) {
loop { loop {
@ -46,14 +33,14 @@ fn update_every_so_often(st: MTState) {
{ {
let data = st.lock().unwrap(); let data = st.lock().unwrap();
data.show(); data.xsetroot();
} }
} }
} }
fn main() -> std::io::Result<()> { fn main() -> Result<()> {
let st: State = State::init(); let st: State = State::init();
st.show(); st.xsetroot();
let mtst = Arc::new(Mutex::new(st)); let mtst = Arc::new(Mutex::new(st));
env_logger::init(); env_logger::init();
let cfg = config::load()?; let cfg = config::load()?;
@ -87,63 +74,10 @@ fn main() -> std::io::Result<()> {
thread::spawn(move || handle_client(stream, mtst)); thread::spawn(move || handle_client(stream, mtst));
} }
Err(err) => { Err(err) => {
error!("unix listener error: {:?}", err); return Err(err.into());
break;
} }
} }
} }
Ok(()) Ok(())
} }
pub(crate) struct State {
msg: String,
front: String,
weather: Option<weather::Root>,
}
impl fmt::Display for State {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.msg)
}
}
impl State {
fn init() -> State {
State {
msg: "".to_string(),
front: "".to_string(),
weather: None,
}
}
pub(crate) fn show(&self) {
let now = Local::now().format("%H:%M M%m %-d %a");
let xsr = XSetRoot::init();
let mut msg = String::new();
if self.msg != "" {
msg.push_str(format!("{} | ", self.msg).as_str());
}
if self.front != "" {
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);
}
}

View File

@ -1,5 +1,5 @@
use crate::{config::Config, MTState}; use crate::{config::Config, MTState};
use reqwest::blocking::*; use anyhow::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{thread, time}; use std::{thread, time};
@ -40,14 +40,16 @@ pub struct Daum {
const UPDATE_FREQUENCY: u64 = 15 * 60; // 15 minutes const UPDATE_FREQUENCY: u64 = 15 * 60; // 15 minutes
fn get(cfg: &Config) -> reqwest::Result<Root> { fn get(cfg: &Config) -> Result<Root> {
let client = Client::builder().user_agent(crate::APP_USER_AGENT).build()?; let now: Root = ureq::get(&cfg.weather_url)
let now: Root = client.get(&cfg.weather_url).send()?.json()?; .set("User-Agent", crate::APP_USER_AGENT)
.call()?
.into_json()?;
Ok(now) Ok(now)
} }
pub(crate) fn update(st: MTState, cfg: Config) { pub fn update(st: MTState, cfg: Config) {
loop { loop {
match get(&cfg) { match get(&cfg) {
Ok(datni) => { Ok(datni) => {

View File

@ -1,53 +1,17 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use std::ffi::CString; use anyhow::Result;
use std::os::raw::c_char; use std::process::Command;
use std::ptr;
use x11::xlib;
pub(crate) struct XSetRoot { pub struct XSetRoot;
display: *mut xlib::Display,
root_window: xlib::Window,
}
impl XSetRoot { impl XSetRoot {
pub(crate) fn init() -> Self { pub fn init() -> Result<Self> {
unsafe { Ok(Self {})
let display = xlib::XOpenDisplay(ptr::null());
if display.is_null() {
panic!("cannot open display");
}
let screen = xlib::XDefaultScreen(display);
let root_window = xlib::XRootWindow(display, screen);
Self {
display,
root_window,
}
}
} }
pub(crate) fn render(&self, text: String) { pub fn render(&self, text: String) -> Result<()> {
let status_c = CString::new(text).expect("status text could not be converted to CString"); Command::new("xsetroot").arg("-name").arg(text).output()?;
Ok(())
unsafe {
xlib::XStoreName(
self.display,
self.root_window,
status_c.as_ptr() as *mut c_char,
);
xlib::XFlush(self.display);
}
}
}
impl Drop for XSetRoot {
fn drop(&mut self) {
unsafe {
xlib::XCloseDisplay(self.display);
}
} }
} }