import datetime as dt
import html
import json
import os
from collections import defaultdict
times = defaultdict(list)
path_to_files = "/Users/axel/repos/literature-clock/docs/times"
TEMPLATE = """/// DO NOT MODIFY
/// THIS FILE IS GENERATED BY RUNNING ./script.py FROM REPO ROOT
use anyhow::{{bail, Context, Result}};
use rand::seq::SliceRandom;
pub struct Minute<'a> {{
pub title: &'a str,
pub author: &'a str,
pub start: &'a str,
pub time: &'a str,
pub end: &'a str,
}}
{minutes}
pub fn get_minute<'a>(time: &str, sfw: bool) -> Result<&'a Minute> {{
let options = match (time, sfw) {{
{matches}
(_, _) => bail!("Couldn't match timestamp!"),
}};
let quote = options.choose(&mut rand::thread_rng()).context("Unable to choose a random quote")?;
Ok(quote)
}}
"""
REPLACES = [
('"', '\\"'),
("<br>", "\\n"),
("<br/>", "\\n"),
("<br />", "\\n"),
("\\n ", "\\n"),
]
def prep(section: str) -> str:
value = html.unescape(section)
for from_str, to_str in REPLACES:
value = value.replace(from_str, to_str)
return value
malformed_timestamps = []
for json_file in sorted(os.listdir(path_to_files)):
with open(os.path.join(path_to_files, json_file), "r") as f:
timestamp = json_file.split(".")[0].replace("_", ":")
for d in sorted(json.load(f), key=lambda q: q["title"]):
times[timestamp].append(
{
"start": prep(d["quote_first"]),
"time": prep(d["quote_time_case"]),
"end": prep(d["quote_last"]),
"title": prep(d["title"]),
"author": prep(d["author"]),
"sfw": d["sfw"] == "yes",
}
)
minutes = []
matches = []
def get_next_ts(ts: str) -> str:
dummy_dt = dt.datetime.fromisoformat(f"2000-01-01T{ts}") + dt.timedelta(minutes=1)
return dummy_dt.strftime("%H:%M")
matches_pre_process = []
for timestamp, quotes in times.items():
var_names = []
sfw_var_names = []
for idx, quote in enumerate(quotes):
var_name = f"QUOTE_{timestamp.replace(':', '_')}_{idx}"
var_names.append(f"&{var_name}")
if quote["sfw"]:
sfw_var_names.append(f"&{var_name}")
minutes.append(
f"static {var_name}: Minute = Minute"
"{"
f"title: \"{quote['title']}\", "
f"author: \"{quote['author']}\", "
f"start: \"{quote['start']}\", "
f"time: \"{quote['time']}\", "
f"end: \"{quote['end']}\""
"};",
)
timestamps = [timestamp]
timestamp = get_next_ts(timestamp)
while timestamp not in times:
timestamps.append(timestamp)
timestamp = get_next_ts(timestamp)
joined_timestamps = '" | "'.join(timestamps)
if len(var_names) == len(sfw_var_names):
joined_varnames = ", ".join(var_names)
matches_pre_process.append((joined_timestamps, "_", joined_varnames))
elif len(sfw_var_names) == 0:
previous_joined_timestamps, sfw, varnames = matches_pre_process.pop()
if sfw == "true":
previous_joined_timestamps += '" | "' + joined_timestamps
matches_pre_process.append((previous_joined_timestamps, sfw, varnames))
elif sfw == "_":
matches_pre_process.append((previous_joined_timestamps, "false", varnames))
previous_joined_timestamps += '" | "' + joined_timestamps
matches_pre_process.append((previous_joined_timestamps, "true", varnames))
pass
else:
raise Exception("Last preprocessed was nsfw??")
joined_varnames = ", ".join(var_names)
matches_pre_process.append((joined_timestamps, "false", joined_varnames))
else:
joined_varnames = ", ".join(var_names)
matches_pre_process.append((joined_timestamps, "false", joined_varnames))
joined_sfw_varnames = ", ".join(sfw_var_names)
matches_pre_process.append((joined_timestamps, "true", joined_sfw_varnames))
for (joined_timestamps, sfw, varnames) in matches_pre_process:
matches.append(f' ("{joined_timestamps}", {sfw}) => vec![{varnames}],')
with open("./src/minute.rs", "w") as f:
f.write(TEMPLATE.format(minutes="\n".join(minutes), matches="\n".join(matches)))