aboutsummaryrefslogtreecommitdiffstats
path: root/src/dsb/html.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dsb/html.rs')
-rw-r--r--src/dsb/html.rs333
1 files changed, 324 insertions, 9 deletions
diff --git a/src/dsb/html.rs b/src/dsb/html.rs
index 51e8580..670ce07 100644
--- a/src/dsb/html.rs
+++ b/src/dsb/html.rs
@@ -1,10 +1,12 @@
+use std::convert::TryFrom;
+
+use super::DSB;
use crate::types::*;
use crate::Error;
-use super::DSB;
//use html5ever::rcdom::{Handle, Node, NodeData};
-use markup5ever_rcdom::{Handle, Node, NodeData};
use html5ever::tendril::Tendril;
+use markup5ever_rcdom::{Handle, Node, NodeData};
pub(crate) fn parse(handle: &Handle) -> Result<Vec<DSB>, Error> {
let mut dsb_ret = Vec::new();
@@ -19,13 +21,20 @@ pub(crate) fn parse(handle: &Handle) -> Result<Vec<DSB>, Error> {
if name.local.to_string() == "body" {
let mut found_head = false;
for w in v.children.borrow().iter() {
- if let NodeData::Element { ref name, ref attrs, .. } = w.data {
+ if let NodeData::Element {
+ ref name,
+ ref attrs,
+ ..
+ } = w.data
+ {
let name: &html5ever::QualName = name;
let attrs = &attrs.borrow();
- println!("name: {}", name.local.to_string());
+ println!("name: {:?}", name);
if name.local.to_string() == "table" {
for attrs in attrs.iter() {
- if attrs.name.local.to_string() == "class" && attrs.value.to_string() == "mon_head" {
+ if attrs.name.local.to_string() == "class"
+ && attrs.value.to_string() == "mon_head"
+ {
dsb_ret.push(new_mon_head(w)?);
found_head = true;
}
@@ -46,11 +55,317 @@ pub(crate) fn parse(handle: &Handle) -> Result<Vec<DSB>, Error> {
Ok(dsb_ret)
}
-fn new_mon_head(handle: &Handle) -> Result<DSB, Error> {
+fn new_mon_head(node: &Node) -> Result<DSB, Error> {
+ //let mut ret = DSB::default();
+ let node: &Node = &node.children.borrow()[1];
+ let node: &Node = &node.children.borrow()[0];
+ let node: &Node = &node.children.borrow()[5];
+ let node: &Node = &node.children.borrow()[1];
+ let school: &Node = &node.children.borrow()[0];
+
+ let school = if let NodeData::Text { ref contents } = school.data {
+ contents.borrow().to_string()
+ } else {
+ "error".to_string()
+ };
+
+ let year: &Node = &node.children.borrow()[4];
+ let year = if let NodeData::Text { ref contents } = year.data {
+ let year = &contents.borrow();
+ let year: Vec<&str> = year.split(" ").collect();
+ if let Some(year) = year.last() {
+ year.to_string()
+ } else {
+ "1970/70".to_string()
+ }
+ } else {
+ "1970/70".to_string()
+ };
+
+ let date: &Node = &node.children.borrow()[6];
+
+ let valid_from = if let NodeData::Text { ref contents } = date.data {
+ let date = contents.borrow();
+ let date: Vec<&str> = date.split(" ").collect();
+
+ date.get(2)
+ .map(|v| chrono::NaiveDate::parse_from_str(v, "%d.%m.%Y").ok())
+ .flatten() // FIXME: discover which element to get
+ } else {
+ None
+ }
+ .unwrap_or(chrono::NaiveDate::from_ymd(1970, 1, 1));
+
+ let date: &Node = &node.children.borrow()[8];
+
+ let updated_at = if let NodeData::Text { ref contents } = date.data {
+ let date = contents.borrow();
+ let date: Vec<&str> = date.split(" ").collect();
+
+ date.get(date.len() - 2..date.len())
+ .map(|v| {
+ chrono::NaiveDateTime::parse_from_str(
+ &format!("{} {}", v[0], v[1]),
+ "%d.%m.%Y %k:%M",
+ )
+ .ok()
+ })
+ .flatten()
+ } else {
+ None
+ }
+ .unwrap_or(chrono::NaiveDateTime::from_timestamp(0, 0));
+
+ Ok(DSB {
+ school,
+ year,
+ valid_from,
+ updated_at,
+ date: chrono::NaiveDate::from_ymd(1970, 1, 1),
+ week: Week::A, // TODO: ??
+ free_lessons: None,
+ missing_teachers: Vec::new(),
+ blocked_rooms: Vec::new(),
+ affected_classes: Vec::new(),
+ entries: Vec::new(),
+ })
+}
+
+fn parse_mon_title(dsb: &mut DSB, info: &str) -> Result<(), Error> {
+ dsb.week = Week::try_from(info.as_bytes()[info.len() - 1] as char)?;
+ let strs = info.split_ascii_whitespace().collect::<Vec<&str>>();
+ dsb.date = chrono::NaiveDate::parse_from_str(strs[0], "%d.%m.%Y")?;
+ Ok(())
+}
+
+fn parse_info_table(dsb: &mut DSB, node: &Node) -> Result<(), Error> {
+ let node = &node.children.borrow()[1];
+
+ for v in node.children.borrow().iter() {
+ if v.children.borrow().len() != 2 {
+ continue;
+ }
+ let infoType: &Node = &v.children.borrow()[0];
+ let infoType: &Node = &infoType.children.borrow()[0];
+ let infoString = if let NodeData::Text { ref contents } = infoType.data {
+ contents.borrow().trim().to_string()
+ } else {
+ String::new()
+ };
+
+ let content: &Node = &v.children.borrow()[1];
+ let content: &Node = &content.children.borrow()[0];
+ let contentString = if let NodeData::Text { ref contents } = content.data {
+ contents.borrow().trim().to_string()
+ } else {
+ String::new()
+ };
+
+ if infoString.to_lowercase() == "abwesende lehrer" {
+ let contentString: Vec<&str> = contentString.split(", ").collect();
+ for v in contentString.iter() {
+ let v: &str = v.trim();
+ let v: Vec<&str> = v.split(" ").collect();
+ if v.len() != 1 {
+ eprintln!(
+ "Error: DSB: unimplemented: td.info.{{Abwesende Lehrer}}.len {{{}}} {:?}",
+ v.len(),
+ v
+ );
+ }
+ dsb.missing_teachers.push(Teacher {
+ name: v[0].to_string(),
+ });
+ }
+ } else if infoString.to_lowercase() == "betroffene klassen" {
+ let contentString: Vec<&str> = contentString.split(", ").collect();
+ for v in contentString.iter() {
+ let v: &str = v.trim();
+ dsb.affected_classes.push(Class {
+ name: v.to_string(),
+ });
+ }
+ } else {
+ log::warn!(
+ "Error: DSB: unimplemented: td.info.{{{}}} {{{}}}",
+ infoString,
+ contentString
+ );
+ }
+ }
- todo!()
+ Ok(())
}
-fn parse_center(handle: &Handle, dsb: &mut DSB) -> Result<(), Error> {
- todo!()
+fn parse_center(node: &Node, dsb: &mut DSB) -> Result<(), Error> {
+ if node.children.borrow().len() < 2 {
+ return Ok(()); // TODO: ??
+ }
+ let mon_title: &Node = &node.children.borrow()[1];
+ let mon_title: &Node = &mon_title.children.borrow()[0];
+ if let NodeData::Text { ref contents } = mon_title.data {
+ let contents = &contents.borrow();
+ parse_mon_title(dsb, contents)?;
+ } else {
+ return Err(crate::err_dsb_parse!("Expected Text element"));
+ }
+
+ let info: &Node = &node.children.borrow()[3];
+ parse_info_table(dsb, info)?;
+
+ let rows: &Node = &node.children.borrow()[5];
+ let rows: &Node = &rows.children.borrow()[1];
+ let rows: &Node = &rows.children.borrow()[1];
+
+ let mut old_row = None;
+ for v in rows.children.borrow().iter() {
+ if v.children.borrow().len() == 8 {
+ let class = &v.children.borrow()[0];
+ let class = &class.children.borrow()[0];
+ let mut new = false;
+ let mut name = String::new();
+ if let NodeData::Text { ref contents } = class.data {
+ let contents = contents.borrow();
+ if contents.contains("Klasse") {
+ continue;
+ }
+ if contents.to_string().as_str() != " " {
+ if let Some(v) = old_row.take() {
+ dsb.entries.push(v);
+ }
+ name = contents.to_string();
+ new = true;
+ println!("name: {}", name);
+ }
+ }
+ if new {
+ let hour = &v.children.borrow()[1];
+ let hour = &hour.children.borrow()[0];
+ let hour = &hour.children.borrow()[0];
+ let hour = if let NodeData::Text { ref contents } = hour.data {
+ Ok(Hour::try_from(contents.borrow().to_string().as_str())?)
+ } else {
+ Err(crate::err_dsb_parse!("Expected hour tag"))
+ }?;
+
+ let sub = &v.children.borrow()[2];
+ let sub = &sub.children.borrow()[0];
+ let sub = &sub.children.borrow()[0];
+ let sub = if let NodeData::Text { ref contents } = sub.data {
+ if contents.borrow().contains("---") {
+ None
+ } else {
+ Some(Teacher {
+ name: contents.borrow().to_string(),
+ })
+ }
+ } else {
+ None
+ };
+
+ let ncourse = &v.children.borrow()[3];
+ let ncourse = &ncourse.children.borrow()[0];
+ let ncourse = if let NodeData::Text { ref contents } = ncourse.data {
+ if contents.borrow().contains("---") {
+ None
+ } else {
+ // TODO: sec2 deciding
+ Some(Course::Sec1(contents.borrow().to_string()))
+ }
+ } else {
+ None
+ };
+
+ let ocourse = &v.children.borrow()[4];
+ let ocourse = &ocourse.children.borrow()[0];
+ let ocourse = if let NodeData::Text { ref contents } = ocourse.data {
+ if contents.borrow().contains("---") {
+ None
+ } else {
+ // TODO: sec2 deciding
+ Some(Course::Sec1(contents.borrow().to_string()))
+ }
+ } else {
+ None
+ }; //.ok_or_else(|| Err(crate::err_dsb_parse!("wanted a old course")))?;
+ let ocourse: Result<Course, Error> =
+ ocourse.ok_or_else(|| crate::err_dsb_parse!("wanted an old course"));
+ let ocourse = ocourse?;
+
+ let message: &Node = &v.children.borrow()[5];
+ let message: &Node = &message.children.borrow()[0];
+ let message = if let NodeData::Text { ref contents } = message.data {
+ Some(contents.borrow().trim().trim_matches('-').to_string())
+ } else {
+ None
+ };
+ let kind: &Node = &v.children.borrow()[6];
+ let kind: &Node = &kind.children.borrow()[0];
+ let kind = if let NodeData::Text { ref contents } = kind.data {
+ let kind = &contents.borrow();
+ let kind: &str = kind.trim().trim_matches('-');
+ Some(Kind::from(kind))
+ } else {
+ None
+ }
+ .ok_or_else(|| crate::err_dsb_parse!("expected course"))?;
+ let room: &Node = &v.children.borrow()[7];
+ let room: &Node = &room.children.borrow()[0];
+ let room = room
+ .children
+ .borrow()
+ .get(0)
+ .map(|v| {
+ if let NodeData::Text { ref contents } = v.data {
+ let room = &contents.borrow();
+ let room: &str = room.trim().trim_matches('-');
+ Some(Room::try_from(room).ok()).flatten() // TODO: better error handling
+ } else {
+ None
+ }
+ })
+ .flatten();
+ let dsb_entry = DsbEntry {
+ name,
+ new_course: ncourse,
+ old_course: ocourse,
+ hour,
+ new_teacher: sub,
+ message,
+ kind,
+ room,
+ };
+ old_row = Some(dsb_entry);
+ } else {
+ if let Some(ref mut entry) = old_row {
+ /*let message: &Node = &v.children.borrow()[5];
+ let message: &Node = &message.children.borrow()[0];
+ if let NodeData::Text { ref contents } = message.data {
+ let message: String = escape_default(&contents.borrow())
+ .trim()
+ .trim_matches('-')
+ .to_string();
+ entrie.message = entrie.message.clone() + &message;
+ }*/
+ let message: &Node = &v.children.borrow()[5];
+ let message: &Node = &message.children.borrow()[0];
+ if let NodeData::Text { ref contents } = message.data {
+ let message = &contents.borrow();
+ let message = message.trim().trim_matches('-');
+ if entry.message.is_some() {
+ let entry_message = entry.message.as_mut().unwrap();
+ entry_message.push_str(message);
+ //entry.message.as_ref().map(|v| {v.push_str(message); v});
+ } else {
+ entry.message = Some(message.to_string());
+ }
+ }
+ } else {
+ eprintln!("not an empty row exists");
+ }
+ }
+ }
+ }
+
+ Ok(())
}