add chapter "how it is made" to mensa-upb-cli project
This commit is contained in:
parent
49a6d9eaac
commit
3e852e551b
|
@ -46,3 +46,67 @@ It works by parsing the command-line arguments with [clap](https://crates.io/cra
|
|||
```bash
|
||||
mensa-upb-cli -p student
|
||||
```
|
||||
|
||||
## How it is made
|
||||
|
||||
My university has multiple cafeterias and a website with the menu of each one. I did not like checking multiple pages when choosing what and where to eat.
|
||||
|
||||
Therefore I decided to build an application that would make this process easier. My solution had 4 steps:
|
||||
|
||||
1. Read the user input
|
||||
2. Fetch the data
|
||||
3. Filter the data based on user input
|
||||
4. Output the data in a readable way
|
||||
|
||||
### 1. Reading user input
|
||||
|
||||
For reading the cli arguments, I choose [clap](https://crates.io/crates/clap) which is a popular library and very easy to use by deriving the traits.
|
||||
|
||||
```rust
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct Cli {
|
||||
/// Choose the mensa
|
||||
#[arg(short, long, value_enum, default_values_t = [Mensa::Forum, Mensa::Academica])]
|
||||
mensa: Vec<Mensa>,
|
||||
/// Choose the price level
|
||||
#[arg(short, long)]
|
||||
price_level: Option<PriceLevel>,
|
||||
/// Choose how many days in the future to fetch
|
||||
#[arg(short, long)]
|
||||
days_ahead: Option<u64>,
|
||||
/// Filter by extras
|
||||
#[arg(short, long)]
|
||||
extras: Vec<String>,
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Fetch the data
|
||||
|
||||
Because there is no API for our cafeteria, I had to scrape the website. The tools I used are [reqwest](https://crates.io/crates/reqwest) for fetching the html and [scraper](https://crates.io/crates/scraper) for extracting the required information from the html.
|
||||
|
||||
### 3. Filter the data based on user input
|
||||
|
||||
Filtering is done at multiple places:
|
||||
|
||||
- only fetch and parse the pages of the cafeterias requested and the day selected
|
||||
- filter which price level to show (student, employee, guest)
|
||||
- filter which meals match the selected extra (vegetarian, vegan)
|
||||
|
||||
### 4. Output the data in a readable way
|
||||
|
||||
For readability, I choose to display the meals in a table. Also I wanted to group the meals by categorie (main dishes, side dishes and desserts). A nice library I found for printing tables to the terminal is [comfy-table](https://crates.io/crates/comfy-table). It allows customizing the borders and alignment of each cell.
|
||||
|
||||
```rust
|
||||
let mut desserts_row = Row::new();
|
||||
desserts_row.add_cell(
|
||||
Cell::from("Desserts")
|
||||
.set_alignment(CellAlignment::Center)
|
||||
.add_attribute(comfy_table::Attribute::Underlined)
|
||||
.add_attribute(comfy_table::Attribute::OverLined),
|
||||
);
|
||||
```
|
||||
|
||||
## Source Code
|
||||
|
||||
If you want to take a look at the source code, it is available on my [GitHub](https://github.com/moritz-hoelting/mensa-upb-cli). You could even try to adapt the web requesting and scraping to the cafeteria you go to.
|
||||
|
|
Loading…
Reference in New Issue