restructure and add stgb
All checks were successful
CI/CD Pipeline / test (push) Successful in 31s

This commit is contained in:
philipp 2024-02-04 16:09:59 +01:00
parent 5131b39a65
commit 57905899d7
7 changed files with 124 additions and 86 deletions

View File

@ -9,6 +9,13 @@ use std::{
use crate::{overview, par};
use self::responsible::{
contains, contains_at_start, contains_without_unter, starts_with_letter, starts_with_number,
starts_with_roman_number, starts_with_uppercaseletter,
};
mod responsible;
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub(crate) struct Law {
name: String, //ABGB, UrhG
@ -102,50 +109,6 @@ impl From<ClassifierInstance> for HeadingContent {
}
}
pub(crate) fn contains_without_unter(classifier_name: &str, instance_name: &str) -> bool {
instance_name
.to_lowercase()
.contains(&classifier_name.to_lowercase())
&& !instance_name.to_lowercase().contains("unter")
}
pub(crate) fn contains(classifier_name: &str, instance_name: &str) -> bool {
instance_name
.to_lowercase()
.contains(&classifier_name.to_lowercase())
}
fn starts_with_roman_number(_: &str, s: &str) -> bool {
// Define the prefixes for Roman numerals.
let roman_prefixes = [
"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV",
"XV", "XVI", "XVII", "XVIII", "XIX", "XX",
];
// Check if the string starts with one of the Roman numeral prefixes followed by a period.
roman_prefixes
.iter()
.any(|&prefix| s.starts_with(&(prefix.to_string() + ".")))
}
fn contains_at_start(_classifier_name: &str, instance_name: &str) -> bool {
!instance_name.is_empty() && instance_name.starts_with('@')
}
fn starts_with_number(_classifier_name: &str, instance_name: &str) -> bool {
matches!(instance_name.trim().as_bytes().first(), Some(c) if c.is_ascii_digit())
}
fn starts_with_letter(_classifier_name: &str, instance_name: &str) -> bool {
instance_name.starts_with(|c: char| c.is_ascii_lowercase())
&& (instance_name.chars().nth(1) == Some('.') || instance_name.chars().nth(1) == Some(')'))
}
fn starts_with_uppercaseletter(_classifier_name: &str, instance_name: &str) -> bool {
instance_name.starts_with(|c: char| c.is_ascii_uppercase())
&& (instance_name.chars().nth(1) == Some('.') || instance_name.chars().nth(1) == Some(')'))
}
/// Is used to generate a law struct. It's organized mainly by classifier.
#[derive(Debug)]
pub(crate) struct LawBuilder {
@ -259,6 +222,11 @@ impl LawBuilder {
classifiers.push(Classifier::new("Hauptstück", Arc::new(&contains)).root());
classifiers.push(Classifier::new("Abschnitt", Arc::new(&contains)));
} else if name == "StGB" {
law_id = Some(10002296);
classifiers.push(Classifier::new("Teil", Arc::new(&contains)).root());
classifiers.push(Classifier::new("Abschnitt", Arc::new(&contains)));
}
let mut builder = Self {

43
src/law/responsible.rs Normal file
View File

@ -0,0 +1,43 @@
pub(crate) fn contains_without_unter(classifier_name: &str, instance_name: &str) -> bool {
instance_name
.to_lowercase()
.contains(&classifier_name.to_lowercase())
&& !instance_name.to_lowercase().contains("unter")
}
pub(crate) fn contains(classifier_name: &str, instance_name: &str) -> bool {
instance_name
.to_lowercase()
.contains(&classifier_name.to_lowercase())
}
pub(crate) fn starts_with_roman_number(_: &str, s: &str) -> bool {
// Define the prefixes for Roman numerals.
let roman_prefixes = [
"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV",
"XV", "XVI", "XVII", "XVIII", "XIX", "XX",
];
// Check if the string starts with one of the Roman numeral prefixes followed by a period.
roman_prefixes
.iter()
.any(|&prefix| s.starts_with(&(prefix.to_string() + ".")))
}
pub(crate) fn contains_at_start(_classifier_name: &str, instance_name: &str) -> bool {
!instance_name.is_empty() && instance_name.starts_with('@')
}
pub(crate) fn starts_with_number(_classifier_name: &str, instance_name: &str) -> bool {
matches!(instance_name.trim().as_bytes().first(), Some(c) if c.is_ascii_digit())
}
pub(crate) fn starts_with_letter(_classifier_name: &str, instance_name: &str) -> bool {
instance_name.starts_with(|c: char| c.is_ascii_lowercase())
&& (instance_name.chars().nth(1) == Some('.') || instance_name.chars().nth(1) == Some(')'))
}
pub(crate) fn starts_with_uppercaseletter(_classifier_name: &str, instance_name: &str) -> bool {
instance_name.starts_with(|c: char| c.is_ascii_uppercase())
&& (instance_name.chars().nth(1) == Some('.') || instance_name.chars().nth(1) == Some(')'))
}

View File

@ -1,48 +1,13 @@
use std::io;
use law::LawBuilder;
mod law;
mod overview;
mod par;
#[derive(Debug)]
pub struct Error {
msg: String,
}
impl From<ureq::Error> for Error {
fn from(value: ureq::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}
impl From<io::Error> for Error {
fn from(value: io::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}
impl From<serde_json::Error> for Error {
fn from(value: serde_json::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}
impl From<roxmltree::Error> for Error {
fn from(value: roxmltree::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}
mod misc;
fn main() {
env_logger::init();
let law = LawBuilder::new("KSchG");
let law = LawBuilder::new("StGB");
law.to_md();
}

35
src/misc.rs Normal file
View File

@ -0,0 +1,35 @@
use std::io;
#[derive(Debug)]
pub struct Error {
msg: String,
}
impl From<ureq::Error> for Error {
fn from(value: ureq::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}
impl From<io::Error> for Error {
fn from(value: io::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}
impl From<serde_json::Error> for Error {
fn from(value: serde_json::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}
impl From<roxmltree::Error> for Error {
fn from(value: roxmltree::Error) -> Self {
Self {
msg: value.to_string(),
}
}
}

View File

@ -5,7 +5,7 @@ use log::info;
use serde::Deserialize;
use time::{format_description, OffsetDateTime};
use crate::{overview::parser::OgdSearchResult, Error};
use crate::{misc::Error, overview::parser::OgdSearchResult};
/// Returns the current date in YYYY-MM-DD format. Needed for RIS API query to get current version of the overview.
fn current_date() -> String {

View File

@ -2,7 +2,7 @@ mod parser;
use log::{debug, info};
use crate::{law::LawBuilder, par::parser::Risdok, Error};
use crate::{law::LawBuilder, misc::Error, par::parser::Risdok};
fn fetch_page(url: &str) -> Result<String, Error> {
Ok(ureq::get(url).call()?.into_string()?)
@ -23,6 +23,33 @@ pub(crate) fn parse_from_str(xml: &str, builder: &mut LawBuilder) -> Result<bool
r#"<absatz typ="abs" ct="text" halign="j">(2) Einer Rundfunksendung steht es gleich, wenn ein Werk von einer im In- oder im Ausland gelegenen Stelle aus der Öffentlichkeit im Inland, ähnlich wie durch Rundfunk, aber mit Hilfe von Leitungen wahrnehmbar gemacht wird.</absatz>"#,
);
let xml = xml.replace(
// in § 17 (2)
r#"<absatz typ="abs" ct="text" halign="j">(3) Die Verjährungsfrist beträgt</absatz><absatz typ="erltext" ct="text" halign="j">zwanzig Jahre,</absatz><liste><schluss typ="e1" ct="text">wenn die Handlung zwar nicht mit lebenslanger Freiheitsstrafe, aber mit mehr als zehnjähriger Freiheitsstrafe bedroht ist;</schluss></liste><absatz typ="erltext" ct="text" halign="j">zehn Jahre,</absatz><liste><schluss typ="e1" ct="text">wenn die Handlung mit mehr als fünfjähriger, aber höchstens zehnjähriger Freiheitsstrafe bedroht ist;</schluss></liste><absatz typ="erltext" ct="text" halign="j">fünf Jahre,</absatz><liste><schluss typ="e1" ct="text">wenn die Handlung mit mehr als einjähriger, aber höchstens fünfjähriger Freiheitsstrafe bedroht ist;</schluss></liste><absatz typ="erltext" ct="text" halign="j">drei Jahre,</absatz><liste><schluss typ="e1" ct="text">wenn die Handlung mit mehr als sechsmonatiger, aber höchstens einjähriger Freiheitsstrafe bedroht ist;</schluss></liste><absatz typ="erltext" ct="text" halign="j">ein Jahr,</absatz><liste><schluss typ="e1" ct="text">wenn die Handlung mit nicht mehr als sechsmonatiger Freiheitsstrafe oder nur mit Geldstrafe bedroht ist.</schluss></liste>"#,
r#"<absatz typ="abs" ct="text" halign="j">(3) Die Verjährungsfrist beträgt zwanzig Jahre, wenn die Handlung zwar nicht mit lebenslanger Freiheitsstrafe, aber mit mehr als zehnjähriger Freiheitsstrafe bedroht ist; zehn Jahre, wenn die Handlung mit mehr als fünfjähriger, aber höchstens zehnjähriger Freiheitsstrafe bedroht ist; fünf Jahre, wenn die Handlung mit mehr als einjähriger, aber höchstens fünfjähriger Freiheitsstrafe bedroht ist; drei Jahre, wenn die Handlung mit mehr als sechsmonatiger, aber höchstens einjähriger Freiheitsstrafe bedroht ist; ein Jahr, wenn die Handlung mit nicht mehr als sechsmonatiger Freiheitsstrafe oder nur mit Geldstrafe bedroht ist.</absatz>"#,
);
let xml = xml.replace(
r#"<absatz typ="abs" ct="text" halign="j">(3) Die Frist beträgt</absatz><absatz typ="erltext" ct="text" halign="j">fünfzehn Jahre,</absatz><liste><schlussteil ebene="0.5" art="normal" ct="text">wenn auf Freiheitsstrafe von mehr als einem Jahr, aber nicht mehr als zehn Jahren erkannt worden ist;</schlussteil></liste><absatz typ="erltext" ct="text" halign="j">zehn Jahre,</absatz><liste><schlussteil ebene="0.5" art="normal" ct="text">wenn auf Freiheitsstrafe von mehr als drei Monaten, aber nicht mehr als einem Jahr oder auf eine Geldstrafe unter Festsetzung einer Ersatzfreiheitsstrafe von mehr als drei Monaten erkannt worden ist;</schlussteil></liste><absatz typ="erltext" ct="text" halign="j">fünf Jahre</absatz><liste><schlussteil ebene="0.5" art="normal" ct="text">in allen übrigen Fällen.</schlussteil></liste>"#,
r#"<absatz typ="abs" ct="text" halign="j">(3) Die Frist beträgt fünfzehn Jahre, wenn auf Freiheitsstrafe von mehr als einem Jahr, aber nicht mehr als zehn Jahren erkannt worden ist; zehn Jahre, wenn auf Freiheitsstrafe von mehr als drei Monaten, aber nicht mehr als einem Jahr oder auf eine Geldstrafe unter Festsetzung einer Ersatzfreiheitsstrafe von mehr als drei Monaten erkannt worden ist; fünf Jahre in allen übrigen Fällen.</absatz>"#,
);
let xml = xml.replace(
r#"<ueberschrift typ="g2" ct="text" halign="c">Erster Abschnitt</ueberschrift>"#,
r#"<ueberschrift typ="g1" ct="text" halign="c">Erster Abschnitt</ueberschrift>"#,
); // StGB
let xml = xml.replace(r#"<abstand ct="text" halign="l" />"#, r#""#); // StGB...
let xml = xml.replace(
r#"<ueberschrift typ="g1min" ct="text" halign="c">Strafbare Handlungen gegen Leib und Leben</ueberschrift>"#,
r#"<ueberschrift typ="g2" ct="text" halign="c">Strafbare Handlungen gegen Leib und Leben</ueberschrift>"#,
); // StGB
let xml = xml.replace(
r#"<ueberschrift typ="g1min" ct="text" halign="c">Allgemeine Bestimmungen</ueberschrift>"#,
r#"<ueberschrift typ="g2" ct="text" halign="c">Allgemeine Bestimmungen</ueberschrift>"#,
); // StGB
let xml = xml.replace(
r#"<ueberschrift typ="para" ct="text" halign="c">1. Verwertungsrechte.</ueberschrift>"#,
r#"<ueberschrift typ="g1" ct="text" halign="c">1. Verwertungsrechte.</ueberschrift>"#,

View File

@ -2,7 +2,7 @@ use roxmltree::Node;
use crate::{
law::{Content, LawBuilder},
Error,
misc::Error,
};
#[derive(Debug, PartialEq)]
@ -489,11 +489,11 @@ impl Absatz {
n.tag_name().name() == "absatz"
}
pub(crate) fn test_with_typ(n: &Node, typ: &str) -> bool {
n.tag_name().name() == "absatz" && n.attribute("typ") == Some(typ)
Self::test(n) && n.attribute("typ") == Some(typ)
}
pub(crate) fn parse(n: Node) -> Self {
assert!(n.tag_name().name() == "absatz");
assert!(Self::test(&n));
if let Some(text) = n.text() {
Self {