shit ; fuck this

This commit is contained in:
2025-07-03 20:08:07 +02:00
parent d09800adc8
commit b8d189dec6
3 changed files with 43 additions and 83 deletions

View File

@@ -10,3 +10,5 @@ tui = "0.19"
crossterm = "0.26"
anyhow = "1.0"
untis = "0.3.0"
reqwest = { version = "0.12", features = ["blocking", "cookies", "rustls-tls"] }
scraper = "0.18"

View File

@@ -1,42 +0,0 @@
/// Code straight copied from the docs.
/// Should work.
use dotenvy::dotenv;
use std::env;
fn main() -> Result<(), untis::Error> {
// Get the school by its id.
let school = untis::schools::get_by_id(&42)?;
// Log in with your credentials. The school's details are filled in automatically.
let result = school.client_login(
&env::var("UNTIS_USERNAME")?,
&env::var("UNTIS_PASSWORD")? // avoid password in plaintext cause its fucking stupid as fuck. use env instead cuase securrrrre.
);
let mut client: untis::Client;
// Match the result to handle specific error cases.
match result {
Ok(v) => client = v,
Err(untis::Error::Rpc(err)) => {
if err.code == untis::jsonrpc::ErrorCode::InvalidCredentials.as_isize() {
println!("Invalid credentials");
}
return Err(untis::Error::Rpc(err));
}
Err(err) => return Err(err)?,
};
let date = chrono::Local::now().date_naive() + chrono::Duration::weeks(2);
// Get the client's own timetable until 2 weeks from now.
let timetable = client.own_timetable_until(&date.into())?;
for lesson in timetable {
println!("{:?}", lesson);
}
Ok(())
} // fn main

View File

@@ -15,11 +15,12 @@ use tui::{
widgets::{Block, Borders, Paragraph},
Terminal,
};
use untis_rs::Client;
use reqwest::blocking::Client;
use scraper::{Html};
struct App {
current_date: NaiveDate,
timetable: Vec<untis_rs::models::Period>,
timetable: Vec<untis::Lesson>,
}
impl App {
@@ -33,25 +34,29 @@ impl App {
fn fetch_timetable(&mut self) -> Result<()> {
dotenv().ok();
let username = env::var("UNTIS_USERNAME").context("UNTIS_USERNAME not set")?;
let password = env::var("UNTIS_PASSWORD").context("UNTIS_PASSWORD not set")?;
let school = env::var("UNTIS_SCHOOL").context("UNTIS_SCHOOL not set")?;
let school_name = env::var("UNTIS_SCHOOL").context("UNTIS_SCHOOL not set")?;
let server = env::var("UNTIS_SERVER").context("UNTIS_SERVER not set")?;
let mut client = Client::new(&username, &password, &school, &server);
client.login()?;
// Find school
let schools = untis::schools::search(&school_name)
.map_err(|e| anyhow::anyhow!(e.to_string()))?;
let school = schools.iter().find(|s| s.server == server)
.ok_or_else(|| anyhow::anyhow!("School not found on specified server"))?;
// Login
let mut client = school.client_login(&username, &password)
.map_err(|e| anyhow::anyhow!(e.to_string()))?;
// Get start and end of the current week (Monday to Friday)
let start = self
.current_date
.pred_opt()
.unwrap()
.week(chrono::Weekday::Mon)
.first_day();
let start = self.current_date;
let end = start + Duration::days(4);
let end_untis: untis::Date = end.into();
self.timetable = client.get_timetable(start, end)?;
// Fetch timetable for current user (up to Friday)
self.timetable = client.own_timetable_until(&end_untis)
.map_err(|e| anyhow::anyhow!(e.to_string()))?;
Ok(())
}
@@ -64,18 +69,24 @@ impl App {
}
fn get_week_range(&self) -> (NaiveDate, NaiveDate) {
let start = self
.current_date
.pred_opt()
.unwrap()
.week(chrono::Weekday::Mon)
.first_day();
let start = self.current_date;
let end = start + Duration::days(4);
(start, end)
}
}
fn main() -> Result<()> {
// URL of the public timetable page
let url = "https://thalia.webuntis.com/WebUntis/?school=gym_hartberg#/basic/timetablePublic";
let client = Client::builder().build()?;
let html = client.get(url).send()?.text()?;
// Parse the HTML
let document = Html::parse_document(&html);
// For now, just print the raw HTML so we can inspect the structure
println!("{}", document.root_element().html());
// Setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
@@ -158,12 +169,13 @@ fn ui<B: tui::backend::Backend>(f: &mut tui::Frame<B>, app: &App) {
f.render_widget(title_paragraph, chunks[0]);
// Timetable content
let mut periods_by_day: Vec<Vec<&untis_rs::models::Period>> = vec![vec![]; 5]; // Monday to Friday
let mut lessons_by_day: Vec<Vec<&untis::Lesson>> = vec![vec![]; 5]; // Monday to Friday
for period in &app.timetable {
let weekday = period.start_time.weekday().num_days_from_monday();
for lesson in &app.timetable {
let date = lesson.date.to_chrono();
let weekday = date.weekday().num_days_from_monday();
if weekday < 5 {
periods_by_day[weekday as usize].push(period);
lessons_by_day[weekday as usize].push(lesson);
}
}
@@ -189,24 +201,12 @@ fn ui<B: tui::backend::Backend>(f: &mut tui::Frame<B>, app: &App) {
.style(Style::default().fg(Color::White));
let mut day_content = Vec::new();
for period in &periods_by_day[i] {
let start = period.start_time.format("%H:%M").to_string();
let end = period.end_time.format("%H:%M").to_string();
let subject = period
.subjects
.first()
.map(|s| s.name.clone())
.unwrap_or_default();
let teacher = period
.teachers
.first()
.map(|t| t.name.clone())
.unwrap_or_default();
let room = period
.rooms
.first()
.map(|r| r.name.clone())
.unwrap_or_default();
for lesson in &lessons_by_day[i] {
let start = lesson.start_time.format("%H:%M").to_string();
let end = lesson.end_time.format("%H:%M").to_string();
let subject = lesson.subjects.iter().map(|s| s.name.as_str()).collect::<Vec<_>>().join(", ");
let teacher = lesson.teachers.iter().map(|t| t.name.as_str()).collect::<Vec<_>>().join(", ");
let room = lesson.rooms.iter().map(|r| r.name.as_str()).collect::<Vec<_>>().join(", ");
let period_text = Spans::from(vec![
Span::styled(