Want to contribute? Fork me on Codeberg.org!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

74 lines
3.3 KiB

use clap::Parser;
use derive_more::From;
use scraper::{Html, Selector};
use colored::Colorize;
#[derive(Default, Parser)]
#[clap(author, version, about)]
struct Arguments {
#[clap(help = "Plume Labs location ID. For example, https://air.plumelabs.com/air-quality-in-XXX")]
location: String,
#[clap(short, long, help = "Display raw Air Quality Index")]
raw: bool,
#[clap(short, long, help = "Display AccuWeather Air Quality Index description")]
description: bool,
}
#[derive(From, Debug)]
enum Error {
ReqwestError(reqwest::Error),
HttpError,
InvalidResponse,
}
fn main() -> Result<(), Error> {
let arguments = Arguments::parse();
let response = reqwest::blocking::get(format!("https://air.plumelabs.com/air-quality-in-{}", arguments.location))?;
if !response.status().is_success() {
return Err(Error::HttpError);
}
let content = response.text_with_charset("utf-8")?;
let document = Html::parse_document(&content);
let selector = Selector::parse("span[data-role=\"current-pi\"]").unwrap();
let aqi = match match document.select(&selector).next() {
Some(element) => element,
None => return Err(Error::InvalidResponse),
}.inner_html().trim().parse::<f32>() {
Ok(aqi) => aqi,
Err(_) => return Err(Error::InvalidResponse),
} as u32;
if arguments.raw {
println!("{}", aqi);
return Ok(());
}
println!("{} {}",
match aqi {
250.. => "Dangerous".purple(),
150.. => "Very Unhealthy".purple(),
100.. => "Unhealthy".magenta(),
50.. => "Poor".red(),
20.. => "Fair".yellow(),
0.. => "Excellent".green(),
}.bold(),
match aqi {
// 250.. => (no appropriate terminal color) // Dangerous 250+
150.. => aqi.to_string().purple(), // Very Unhealthy 150-249
100.. => aqi.to_string().magenta(), // Unhealthy 100-149
50.. => aqi.to_string().red(), // Poor 50-99
20.. => aqi.to_string().yellow(), // Fair 20-49
0.. => aqi.to_string().green(), // Excellent 0-19
}.bold()
);
if arguments.description {
println!("{}", match aqi {
250.. => "Any exposure to the air, even for a few minutes, can lead to serious health effects on everybody. Avoid outdoor activities.",
150.. => "Health effects will be immediately felt by sensitive groups and should avoid outdoor activity. Healthy individuals are likely to experience difficulty breathing and throat irritation; consider staying indoors and rescheduling outdoor activities.",
100.. => "Health effects can be immediately felt by sensitive groups. Healthy individuals may experience difficulty breathing and throat irritation with prolonged exposure. Limit outdoor activity.",
50.. => "The air has reached a high level of pollution and is unhealthy for sensitive groups. Reduce time spent outside if you are feeling symptoms such as difficulty breathing or throat irritation.",
20.. => "The air quality is generally acceptable for most individuals. However, sensitive groups may experience minor to moderate symptoms from long-term exposure.",
0.. => "The air quality is ideal for most individuals; enjoy your normal outdoor activities.",
});
}
return Ok(());
}