Initial commit

This commit is contained in:
Vegard Berg 2023-01-24 06:35:55 +01:00
commit 25b64a6ca0
4 changed files with 1148 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1008
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

19
Cargo.toml Normal file
View File

@ -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"

120
src/main.rs Normal file
View File

@ -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>,
}