Initial commit
This commit is contained in:
commit
25b64a6ca0
|
@ -0,0 +1 @@
|
||||||
|
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "n58-kantine"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.68"
|
||||||
|
chrono = "0.4.23"
|
||||||
|
clap = { version = "4.1.2", features = ["derive"] }
|
||||||
|
dirs = "4.0.0"
|
||||||
|
html-escape = "0.2.13"
|
||||||
|
owo-colors = { version = "3.5.0", features = ["supports-colors"] }
|
||||||
|
serde = { version = "1.0.152", features = ["derive"] }
|
||||||
|
serde_json = "1.0.91"
|
||||||
|
strum = { version = "0.24.1", features = ["derive"] }
|
||||||
|
tl = { version = "0.7.7", features = ["simd"] }
|
||||||
|
ureq = "2.6.2"
|
|
@ -0,0 +1,120 @@
|
||||||
|
use std::string::ToString;
|
||||||
|
|
||||||
|
use clap::{Parser, ValueEnum};
|
||||||
|
use chrono::Datelike;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[command(author, version, about, long_about = None)]
|
||||||
|
struct Cli {
|
||||||
|
/// Show the soup menu instead of the normal menu.
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub soup: bool,
|
||||||
|
|
||||||
|
/// Display output as JSON.
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub json: bool,
|
||||||
|
|
||||||
|
/// Colorise output. No effect when --json is set.
|
||||||
|
#[arg(short, long, default_value_t = ColoriseOutput::Auto)]
|
||||||
|
pub color: ColoriseOutput
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(strum::Display, Debug, ValueEnum, Clone, Copy)]
|
||||||
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
pub enum ColoriseOutput {
|
||||||
|
Auto,
|
||||||
|
True,
|
||||||
|
False,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> anyhow::Result<()>{
|
||||||
|
let _args = Cli::parse();
|
||||||
|
|
||||||
|
let resp = ureq::get("http://kantinemeny.azurewebsites.net/ukesmeny?lokasjon=toro@albatross-as.no&dato=")
|
||||||
|
.call()?;
|
||||||
|
|
||||||
|
let body = resp.into_string()?;
|
||||||
|
|
||||||
|
let items = body.html_string_to_vec()?;
|
||||||
|
|
||||||
|
for item in items {
|
||||||
|
println!("{} - {}", item.title.unwrap_or("".to_string()), item.additional.unwrap_or("".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let now = chrono::offset::Local::now();
|
||||||
|
println!("{}", now.date_naive().weekday().number_from_monday());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
trait DeocdeHTMLEnts {
|
||||||
|
fn decode_html_ents(&self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeocdeHTMLEnts for String {
|
||||||
|
fn decode_html_ents(&self) -> Self {
|
||||||
|
let mut s = String::new();
|
||||||
|
html_escape::decode_html_entities_to_string(self, &mut s);
|
||||||
|
s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HTMLStringToVec {
|
||||||
|
fn html_string_to_vec(&self) -> anyhow::Result<Vec<MenuItem>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_item(p: &tl::Parser, tag: &tl::HTMLTag) -> Option<String> {
|
||||||
|
Some(
|
||||||
|
tag
|
||||||
|
.query_selector(p, ".dagsrett")?
|
||||||
|
.last()?
|
||||||
|
.get(p)?
|
||||||
|
.as_tag()?
|
||||||
|
.inner_text(p).to_string()
|
||||||
|
.decode_html_ents()
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_item_additional(p: &tl::Parser, tag: &tl::HTMLTag) -> Option<String> {
|
||||||
|
Some(
|
||||||
|
tag
|
||||||
|
.query_selector(p, ".dagsrettgarnityr")?
|
||||||
|
.last()?
|
||||||
|
.get(p)?
|
||||||
|
.as_tag()?.inner_text(p).to_string()
|
||||||
|
.decode_html_ents()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HTMLStringToVec for String {
|
||||||
|
fn html_string_to_vec(&self) -> anyhow::Result<Vec<MenuItem>> {
|
||||||
|
let dom = tl::parse(self, tl::ParserOptions::default())?;
|
||||||
|
let p = dom.parser();
|
||||||
|
|
||||||
|
let nodes: Vec<&tl::Node> = Vec::from_iter(dom.query_selector(".dagsinfo").unwrap().filter_map(|x| x.get(p)));
|
||||||
|
|
||||||
|
let items = nodes.into_iter().map(|i| {
|
||||||
|
let tag = i.as_tag().unwrap();
|
||||||
|
let text = get_item(p, tag);
|
||||||
|
|
||||||
|
let additional = get_item_additional(p, tag);
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
title: text,
|
||||||
|
additional: additional,
|
||||||
|
}
|
||||||
|
}).collect::<Vec<MenuItem>>();
|
||||||
|
|
||||||
|
Ok(items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct MenuItem {
|
||||||
|
pub title: Option<String>,
|
||||||
|
pub additional: Option<String>,
|
||||||
|
}
|
Loading…
Reference in New Issue