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" crossterm = "0.26"
anyhow = "1.0" anyhow = "1.0"
untis = "0.3.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}, widgets::{Block, Borders, Paragraph},
Terminal, Terminal,
}; };
use untis_rs::Client; use reqwest::blocking::Client;
use scraper::{Html};
struct App { struct App {
current_date: NaiveDate, current_date: NaiveDate,
timetable: Vec<untis_rs::models::Period>, timetable: Vec<untis::Lesson>,
} }
impl App { impl App {
@@ -33,25 +34,29 @@ impl App {
fn fetch_timetable(&mut self) -> Result<()> { fn fetch_timetable(&mut self) -> Result<()> {
dotenv().ok(); dotenv().ok();
let username = env::var("UNTIS_USERNAME").context("UNTIS_USERNAME not set")?; let username = env::var("UNTIS_USERNAME").context("UNTIS_USERNAME not set")?;
let password = env::var("UNTIS_PASSWORD").context("UNTIS_PASSWORD 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 server = env::var("UNTIS_SERVER").context("UNTIS_SERVER not set")?;
let mut client = Client::new(&username, &password, &school, &server); // Find school
client.login()?; 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) // Get start and end of the current week (Monday to Friday)
let start = self let start = self.current_date;
.current_date
.pred_opt()
.unwrap()
.week(chrono::Weekday::Mon)
.first_day();
let end = start + Duration::days(4); 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(()) Ok(())
} }
@@ -64,18 +69,24 @@ impl App {
} }
fn get_week_range(&self) -> (NaiveDate, NaiveDate) { fn get_week_range(&self) -> (NaiveDate, NaiveDate) {
let start = self let start = self.current_date;
.current_date
.pred_opt()
.unwrap()
.week(chrono::Weekday::Mon)
.first_day();
let end = start + Duration::days(4); let end = start + Duration::days(4);
(start, end) (start, end)
} }
} }
fn main() -> Result<()> { 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 // Setup terminal
enable_raw_mode()?; enable_raw_mode()?;
let mut stdout = io::stdout(); 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]); f.render_widget(title_paragraph, chunks[0]);
// Timetable content // 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 { for lesson in &app.timetable {
let weekday = period.start_time.weekday().num_days_from_monday(); let date = lesson.date.to_chrono();
let weekday = date.weekday().num_days_from_monday();
if weekday < 5 { 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)); .style(Style::default().fg(Color::White));
let mut day_content = Vec::new(); let mut day_content = Vec::new();
for period in &periods_by_day[i] { for lesson in &lessons_by_day[i] {
let start = period.start_time.format("%H:%M").to_string(); let start = lesson.start_time.format("%H:%M").to_string();
let end = period.end_time.format("%H:%M").to_string(); let end = lesson.end_time.format("%H:%M").to_string();
let subject = period let subject = lesson.subjects.iter().map(|s| s.name.as_str()).collect::<Vec<_>>().join(", ");
.subjects let teacher = lesson.teachers.iter().map(|t| t.name.as_str()).collect::<Vec<_>>().join(", ");
.first() let room = lesson.rooms.iter().map(|r| r.name.as_str()).collect::<Vec<_>>().join(", ");
.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();
let period_text = Spans::from(vec![ let period_text = Spans::from(vec![
Span::styled( Span::styled(