use anyhow::Context as _;
use csv;
use regex::Regex;
use serde::Serialize;
use crate::{
contexts::ItemsInContextExt, export::Exporter, srt::Subtitle,
time::seconds_to_hhmmss_sss, Result,
};
fn episode_prefix(file_stem: &str) -> String {
let re = Regex::new(r"[0-9][-_.0-9]+$").unwrap();
re.captures(file_stem)
.map(|c| {
let ep = c.get(0).unwrap().as_str();
format!("{} ", ep.replace("-", ".").replace("_", "."))
})
.unwrap_or_else(|| "".to_owned())
}
#[test]
fn test_episode_prefix() {
assert_eq!("01.02 ", episode_prefix("series_01_02"));
assert_eq!("", episode_prefix("film"));
}
#[derive(Debug, Serialize)]
struct AnkiNote {
sound: String,
time: String,
source: String,
image: String,
foreign_curr: Option<String>,
native_curr: Option<String>,
foreign_prev: Option<String>,
native_prev: Option<String>,
foreign_next: Option<String>,
native_next: Option<String>,
}
pub fn export_csv(exporter: &mut Exporter) -> Result<()> {
let foreign_lang = exporter.foreign().language;
let prefix = episode_prefix(exporter.file_stem());
let mut buffer = Vec::<u8>::new();
{
let mut wtr = csv::Writer::from_writer(&mut buffer);
let aligned: Vec<(Option<Subtitle>, Option<Subtitle>)> = exporter
.align()
.iter()
.filter(|&&(ref f, _)| f.is_some())
.cloned()
.collect();
for ctx in aligned.items_in_context() {
let foreign = ctx.map(|&(ref f, _)| f).flatten();
let native = ctx.map(|&(_, ref n)| n).flatten();
if let Some(curr) = foreign.curr {
let period = curr.period.grow(1.5, 1.5);
let image_path = exporter.schedule_image_export(period.midpoint());
let audio_path = exporter.schedule_audio_export(foreign_lang, period);
let sort_key =
format!("{}{}", &prefix, &seconds_to_hhmmss_sss(period.begin()));
let note = AnkiNote {
sound: format!("[sound:{}]", &audio_path),
time: sort_key,
source: exporter.title().to_owned(),
image: format!("<img src=\"{}\" />", &image_path),
foreign_curr: foreign.curr.map(|s| s.plain_text()),
native_curr: native.curr.map(|s| s.plain_text()),
foreign_prev: foreign.prev.map(|s| s.plain_text()),
native_prev: native.prev.map(|s| s.plain_text()),
foreign_next: foreign.next.map(|s| s.plain_text()),
native_next: native.next.map(|s| s.plain_text()),
};
wtr.serialize(¬e).context("error serializing to RAM")?;
}
}
}
exporter.export_data_file("cards.csv", &buffer)?;
exporter.finish_exports()?;
Ok(())
}