use cache by default, add clear-cache argument
Some checks failed
CI/CD Pipeline / test (push) Failing after 1m30s

This commit is contained in:
2024-02-15 09:24:30 +01:00
parent c511e5a4d8
commit ddb2ebe5b7
6 changed files with 134 additions and 41 deletions

View File

@ -1,5 +1,5 @@
use clap::{command, Parser};
use risp::law::Law;
use risp::{law::Law, misc::clear_cache};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
@ -7,12 +7,22 @@ struct Args {
/// Path to the config of a law text
#[arg(short, long)]
config: String,
/// Clears the cache (downloaded laws + paragraphs)
clear_cache: bool,
}
fn main() {
env_logger::init();
let args = Args::parse();
if args.clear_cache {
if let Err(e) = clear_cache() {
println!("Failed to clear cache: {e:?}");
}
}
let law = Law::from_config(&args.config).unwrap();
law.to_md();

View File

@ -1,11 +1,11 @@
use std::io;
use std::{fs, io, path::Path};
use time::{format_description, OffsetDateTime};
#[derive(Debug)]
#[allow(dead_code)]
pub struct Error {
msg: String,
pub(crate) msg: String,
}
impl Error {
@ -57,3 +57,40 @@ pub(crate) fn current_date() -> String {
let format = format_description::parse("[year]-[month]-[day]").unwrap(); //unwrap okay, supplied format is fine
local_date.format(&format).expect("Failed to format date")
}
#[cfg(not(test))]
pub(crate) fn get_cache_dir() -> Result<String, Error> {
let cache_dir = directories::BaseDirs::new().ok_or(Error {
msg: "directories crate could not find basedirs.".into(),
})?;
let cache_dir = cache_dir.cache_dir();
Ok(format!("{}/risp/", cache_dir.to_str().unwrap()))
}
#[cfg(test)]
pub(crate) fn get_cache_dir() -> Result<String, Error> {
Ok("./data/cache/".into())
}
pub fn clear_cache() -> Result<(), Error> {
Ok(delete_all_in_dir(Path::new(&get_cache_dir()?))?)
}
fn delete_all_in_dir<P: AsRef<Path>>(dir_path: P) -> std::io::Result<()> {
let entries = fs::read_dir(dir_path)?;
for entry in entries {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
delete_all_in_dir(&path)?;
fs::remove_dir(&path)?;
} else {
// If it's a file, delete it
fs::remove_file(&path)?;
}
}
Ok(())
}

View File

@ -2,10 +2,12 @@
mod ris_structure;
use std::path::Path;
use log::info;
use serde::Deserialize;
use crate::misc::{current_date, Error};
use crate::misc::{current_date, get_cache_dir, Error};
use ris_structure::OgdSearchResult;
@ -82,30 +84,10 @@ fn parse_from_str(content: &str, skip_first: bool) -> Result<(bool, Vec<String>)
Ok((true, ret))
}
#[cfg(not(test))]
/// Fetches the json content of the given overview (`law_id`) from the RIS API.
///
/// # Errors
/// Fails if `ureq` can't create a connection, probably because there's no internet connection? (Or RIS is not online.)
fn fetch_page(overview_id: usize, page: usize) -> Result<String, Error> {
Ok(
ureq::post("https://data.bka.gv.at/ris/api/v2.6/Bundesrecht")
.send_form(&[
("Applikation", "BrKons"),
("Gesetzesnummer", &format!("{overview_id}")),
("DokumenteProSeite", "OneHundred"),
("Seitennummer", &format!("{page}")),
("Fassung.FassungVom", &current_date()),
])?
.into_string()?,
)
}
#[cfg(test)]
fn fetch_page(overview_id: usize, page: usize) -> Result<String, Error> {
use std::fs;
let expected_filename = format!("./data/cache/law-{overview_id}-{page}");
let expected_filename = format!("{}law-{overview_id}-{page}", get_cache_dir()?);
match fs::read_to_string(&expected_filename) {
Ok(data) => Ok(data),
@ -120,6 +102,11 @@ fn fetch_page(overview_id: usize, page: usize) -> Result<String, Error> {
("Fassung.FassungVom", &current_date()),
])?
.into_string()?;
let path = Path::new(&expected_filename);
if let Some(parent) = path.parent() {
// Try to create the directory (and any necessary parent directories)
fs::create_dir_all(parent).expect("Unable to create directory");
}
fs::write(expected_filename, &data).expect("Unable to write file");
Ok(data)
}

View File

@ -1,9 +1,18 @@
//! Deals with getting all paragraphs for a given law text
mod parser;
use std::{
fs,
hash::{DefaultHasher, Hash, Hasher},
path::Path,
};
use log::info;
use crate::{law::LawBuilder, misc::Error};
use crate::{
law::LawBuilder,
misc::{get_cache_dir, Error},
};
use self::parser::Risdok;
@ -57,30 +66,23 @@ impl Parser {
}
}
#[cfg(not(test))]
fn fetch(url: &str) -> Result<String, Error> {
Ok(ureq::get(url).call()?.into_string()?)
}
#[cfg(test)]
fn fetch(url: &str) -> Result<String, Error> {
use std::{
collections::hash_map::DefaultHasher,
fs,
hash::{Hash, Hasher},
};
let mut hasher = DefaultHasher::new();
url.hash(&mut hasher);
let hash = format!("{:x}", hasher.finish());
let expected_filename = format!("./data/cache/par-{hash}");
let expected_filename = format!("{}par-{hash}", get_cache_dir()?);
match fs::read_to_string(&expected_filename) {
Ok(data) => Ok(data),
Err(_) => {
info!("Not finding url {url} in the cache, downloading...");
let data = ureq::get(url).call()?.into_string()?;
let path = Path::new(&expected_filename);
if let Some(parent) = path.parent() {
// Try to create the directory (and any necessary parent directories)
fs::create_dir_all(parent).expect("Unable to create directory");
}
fs::write(expected_filename, &data).expect("Unable to write file");
Ok(data)
}