Continue work
This commit is contained in:
parent
bc2e1d0f40
commit
0fe422f609
|
@ -78,6 +78,19 @@ version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
"time",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -239,7 +252,7 @@ checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -559,6 +572,25 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
@ -929,6 +961,17 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
|
@ -1099,6 +1142,12 @@ version = "0.9.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.68"
|
version = "0.2.68"
|
||||||
|
@ -1171,6 +1220,7 @@ checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
||||||
name = "weatherstat"
|
name = "weatherstat"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
|
|
@ -5,6 +5,7 @@ authors = ["Rob Watson <rfwatson@users.noreply.github.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
chrono = "0.4"
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
futures-util = "0.3.6"
|
futures-util = "0.3.6"
|
||||||
reqwest = { version = "0.10.8", features = ["json"] }
|
reqwest = { version = "0.10.8", features = ["json"] }
|
||||||
|
|
99
src/main.rs
99
src/main.rs
|
@ -2,18 +2,20 @@ mod config;
|
||||||
mod slack;
|
mod slack;
|
||||||
mod weather;
|
mod weather;
|
||||||
|
|
||||||
|
use chrono::Timelike;
|
||||||
use config::ConfigUser;
|
use config::ConfigUser;
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use slack::SlackUser;
|
use slack::SlackUser;
|
||||||
use tokio::prelude::*;
|
use tokio::prelude::*;
|
||||||
|
use weather::WeatherSummary;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
let config = config::get_config().unwrap();
|
let config = config::get_config().unwrap();
|
||||||
println!("Got config: {:?}", config);
|
println!("Got config: {:?}", &config);
|
||||||
|
|
||||||
let slack_users = slack::list_users().await.unwrap();
|
let slack_users = slack::list_users().await.unwrap();
|
||||||
println!("Got {} users: {:?}", slack_users.len(), slack_users);
|
println!("Got {} users: {:?}", slack_users.len(), slack_users);
|
||||||
|
@ -37,13 +39,102 @@ async fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_user_status(config_user: &ConfigUser, slack_user: &SlackUser) -> Result<(), String> {
|
async fn set_user_status(config_user: &ConfigUser, slack_user: &SlackUser) -> Result<(), String> {
|
||||||
|
let offset = chrono::offset::FixedOffset::east(slack_user.tz_offset);
|
||||||
|
let now = chrono::offset::Utc::now().with_timezone(&offset);
|
||||||
|
let is_pm = now.hour() < 6 || now.hour() >= 18;
|
||||||
let sum = weather::get_summary(&config_user.location).await?;
|
let sum = weather::get_summary(&config_user.location).await?;
|
||||||
|
|
||||||
let status = format!("{} {}\u{00b0}C", sum.name, sum.temp_max);
|
match &sum {
|
||||||
let emoji = format!(":{}:", sum.emoji);
|
WeatherSummary::Thunderstorm(_, _)
|
||||||
|
| WeatherSummary::Clouds(_, _)
|
||||||
|
| WeatherSummary::Snow(_, _)
|
||||||
|
| WeatherSummary::Rain(_, _)
|
||||||
|
| WeatherSummary::Drizzle(_, _)
|
||||||
|
| WeatherSummary::Clear(_, _)
|
||||||
|
| WeatherSummary::Atmospheric(_, _) => {
|
||||||
|
let status = status_text(&sum, is_pm);
|
||||||
|
let emoji = format!(":{}:", &emoji(&sum, is_pm));
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Set status for user {} to: {} {:?}",
|
"Set status for user {} to: {} {:?}",
|
||||||
&slack_user.id, &emoji, &status
|
&slack_user.id, &emoji, &status
|
||||||
);
|
);
|
||||||
Ok(slack::set_status(&slack_user.id, &status, &emoji, 0).await?)
|
let res = slack::set_status(&slack_user.id, &status, &emoji, 0).await?;
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn status_text(sum: &WeatherSummary, is_pm: bool) -> String {
|
||||||
|
match sum {
|
||||||
|
WeatherSummary::Thunderstorm(temp_min, temp_max) => {
|
||||||
|
if is_pm {
|
||||||
|
format!("Thunderstorm, min {}\u{00b0}C", temp_min)
|
||||||
|
} else {
|
||||||
|
format!("Thunderstorm, max {}\u{00b0}C", temp_max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WeatherSummary::Clouds(temp_min, temp_max) => {
|
||||||
|
if is_pm {
|
||||||
|
format!("Cloudy, min {}\u{00b0}C", temp_min)
|
||||||
|
} else {
|
||||||
|
format!("Cloudy, max {}\u{00b0}C", temp_max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WeatherSummary::Snow(temp_min, temp_max) => {
|
||||||
|
if is_pm {
|
||||||
|
format!("Snow, min {}\u{00b0}C", temp_min)
|
||||||
|
} else {
|
||||||
|
format!("Snow, max {}\u{00b0}C", temp_max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WeatherSummary::Rain(temp_min, temp_max) => {
|
||||||
|
if is_pm {
|
||||||
|
format!("Rain, min {}\u{00b0}C", temp_min)
|
||||||
|
} else {
|
||||||
|
format!("Rain, max {}\u{00b0}C", temp_max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WeatherSummary::Drizzle(temp_min, temp_max) => {
|
||||||
|
if is_pm {
|
||||||
|
format!("Drizzle, min {}\u{00b0}C", temp_min)
|
||||||
|
} else {
|
||||||
|
format!("Drizzle, max {}\u{00b0}C", temp_max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WeatherSummary::Clear(temp_min, temp_max) => {
|
||||||
|
if is_pm {
|
||||||
|
format!("Clear, min {}\u{00b0}C", temp_min)
|
||||||
|
} else {
|
||||||
|
format!("Sunny, max {}\u{00b0}C", temp_max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WeatherSummary::Atmospheric(temp_min, temp_max) => {
|
||||||
|
if is_pm {
|
||||||
|
format!("Foggy, min {}\u{00b0}C", temp_min)
|
||||||
|
} else {
|
||||||
|
format!("Foggy, max {}\u{00b0}C", temp_max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emoji(sum: &WeatherSummary, is_pm: bool) -> String {
|
||||||
|
let emoji = match sum {
|
||||||
|
WeatherSummary::Thunderstorm(_, _) => "thunder_cloud_and_rain",
|
||||||
|
WeatherSummary::Clouds(_, _) => "cloud",
|
||||||
|
WeatherSummary::Snow(_, _) => "snow_cloud",
|
||||||
|
WeatherSummary::Rain(_, _) => "rain_cloud",
|
||||||
|
WeatherSummary::Drizzle(_, _) => "rain_cloud",
|
||||||
|
WeatherSummary::Clear(_, _) => {
|
||||||
|
if is_pm {
|
||||||
|
"crescent_moon"
|
||||||
|
} else {
|
||||||
|
"sunny"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WeatherSummary::Atmospheric(_, _) => "foggy",
|
||||||
|
};
|
||||||
|
|
||||||
|
emoji.to_string()
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ pub async fn set_status(
|
||||||
value: None,
|
value: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Returns invalid_user unless the Slack app was installed by a team admin
|
||||||
|
// AND the Slack account is on a paid plan. :cry:
|
||||||
slack_api::users_profile::set(&client, &api_key, &set_req)
|
slack_api::users_profile::set(&client, &api_key, &set_req)
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
|
@ -25,77 +25,30 @@ struct APIResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WeatherSummary {
|
pub enum WeatherSummary {
|
||||||
pub name: String,
|
Thunderstorm(i32, i32),
|
||||||
pub emoji: String,
|
Clouds(i32, i32),
|
||||||
pub temp: i32,
|
Snow(i32, i32),
|
||||||
pub temp_min: i32,
|
Rain(i32, i32),
|
||||||
pub temp_max: i32,
|
Drizzle(i32, i32),
|
||||||
|
Clear(i32, i32),
|
||||||
|
Atmospheric(i32, i32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<APIResponse> for WeatherSummary {
|
impl From<APIResponse> for WeatherSummary {
|
||||||
fn from(resp: APIResponse) -> Self {
|
fn from(resp: APIResponse) -> Self {
|
||||||
let temp = resp.main.temp as i32;
|
|
||||||
let temp_min = resp.main.temp_min as i32;
|
let temp_min = resp.main.temp_min as i32;
|
||||||
let temp_max = resp.main.temp_max as i32;
|
let temp_max = resp.main.temp_max as i32;
|
||||||
|
|
||||||
match resp.weather[0].main.as_ref() {
|
match resp.weather[0].main.as_ref() {
|
||||||
"Thunderstorm" => Self {
|
"Thunderstorm" => Self::Thunderstorm(temp_min, temp_max),
|
||||||
name: "Thunderstorm".to_string(),
|
"Clouds" => Self::Clouds(temp_min, temp_max),
|
||||||
emoji: "thunder_cloud_and_rain".to_string(),
|
"Snow" => Self::Snow(temp_min, temp_max),
|
||||||
temp,
|
"Rain" => Self::Rain(temp_min, temp_max),
|
||||||
temp_min,
|
"Drizzle" => Self::Drizzle(temp_min, temp_max),
|
||||||
temp_max,
|
"Clear" => Self::Clear(temp_min, temp_max),
|
||||||
},
|
"Atmosphere" => Self::Atmospheric(temp_min, temp_max),
|
||||||
"Clouds" => Self {
|
_ => panic!("unrecognized weather type"),
|
||||||
name: "Cloudy".to_string(),
|
|
||||||
emoji: "cloud".to_string(),
|
|
||||||
temp,
|
|
||||||
temp_min,
|
|
||||||
temp_max,
|
|
||||||
},
|
|
||||||
"Snow" => Self {
|
|
||||||
name: "Snow".to_string(),
|
|
||||||
emoji: "snow_cloud".to_string(),
|
|
||||||
temp,
|
|
||||||
temp_min,
|
|
||||||
temp_max,
|
|
||||||
},
|
|
||||||
"Rain" => Self {
|
|
||||||
name: "Rain".to_string(),
|
|
||||||
emoji: "rain_cloud".to_string(),
|
|
||||||
temp,
|
|
||||||
temp_min,
|
|
||||||
temp_max,
|
|
||||||
},
|
|
||||||
"Drizzle" => Self {
|
|
||||||
name: "Drizzle".to_string(),
|
|
||||||
emoji: "rain_cloud".to_string(),
|
|
||||||
temp,
|
|
||||||
temp_min,
|
|
||||||
temp_max,
|
|
||||||
},
|
|
||||||
"Clear" => Self {
|
|
||||||
name: "Clear".to_string(),
|
|
||||||
emoji: "sunny".to_string(),
|
|
||||||
temp,
|
|
||||||
temp_min,
|
|
||||||
temp_max,
|
|
||||||
},
|
|
||||||
"Atmosphere" => Self {
|
|
||||||
name: "Atmospheric".to_string(),
|
|
||||||
emoji: "foggy".to_string(),
|
|
||||||
temp,
|
|
||||||
temp_min,
|
|
||||||
temp_max,
|
|
||||||
},
|
|
||||||
_ => Self {
|
|
||||||
name: "Unknown".to_string(),
|
|
||||||
emoji: "cloud".to_string(),
|
|
||||||
temp,
|
|
||||||
temp_min,
|
|
||||||
temp_max,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,14 +61,19 @@ pub async fn get_summary(loc: &str) -> Result<WeatherSummary, String> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let resp = reqwest::get(&url).map_err(|e| e.to_string()).await?;
|
let resp = reqwest::get(&url).map_err(|e| e.to_string()).await?;
|
||||||
|
|
||||||
|
//println!("{}", resp.text().map_err(|e| e.to_string()).await?);
|
||||||
|
|
||||||
if !resp.status().is_success() {
|
if !resp.status().is_success() {
|
||||||
return Err(format!("Weather API response: {}", resp.status()).into());
|
return Err(format!("Weather API response: {}", resp.status()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = resp
|
let api_response = resp
|
||||||
.json::<APIResponse>()
|
.json::<APIResponse>()
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(body.into())
|
println!("Got API resp: {:?}", api_response);
|
||||||
|
|
||||||
|
Ok(api_response.into())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue