lr2-oxytabler 0.9.1

Table manager for Lunatic Rave 2
use crate::{
    build_reqwest, changelog, fetch, open_db, output::OutputFolder, save_db, table::Table,
    time::UnixEpochTs,
};
use anyhow::Result;
use std::{collections::HashMap, path::Path};

const TABLE_UPDATE_INTERVAL: UnixEpochTs = UnixEpochTs(60 * 60 * 12);

pub fn run(db: &Path, outputs: &[OutputFolder], write_tags: bool) -> Result<()> {
    let (mut db, mut tables) = open_db(db, outputs)?;
    let mut fallback_song_titles = HashMap::<String, String>::new();
    let now = UnixEpochTs::now();
    let client = build_reqwest()?;
    let runtime = tokio::runtime::Runtime::new()?;
    let tasks = tables
        .iter()
        .filter(|t| t.wants_updating(now, TABLE_UPDATE_INTERVAL))
        .map(fetch::TableLocator::new_for_table)
        .collect::<Vec<_>>();
    log::info!("[1/3] fetching {} tables...", tasks.len());
    let pb = indicatif::ProgressBar::new(tasks.len().try_into()?)
        .with_style(indicatif::ProgressStyle::default_bar());
    let updates = runtime.block_on(futures::future::join_all(tasks.into_iter().map(
        |locator| {
            let client = client.clone();
            let pb = pb.clone();
            async move {
                let out = fetch::fetch_table(client, locator.web_url().clone()).await;
                pb.inc(1);
                (out, locator)
            }
        },
    )));
    pb.finish_and_clear();
    log::info!("[2/3] applying updates...");
    for update in updates {
        match update {
            (Ok((answer, new_song_titles)), locator) => {
                fallback_song_titles.extend(new_song_titles);
                Table::apply_update(
                    &changelog::SongNameAccessor::new(&db, &fallback_song_titles),
                    &mut tables,
                    answer,
                    &locator,
                    now,
                )?;
            }
            (Err(e), locator) => {
                log::warn!("table {locator}: fetch error: {e}");
                log::debug!("full error: {e:?}");
            }
        }
    }
    log::info!("[3/3] saving...");
    save_db(&mut db, outputs, &mut tables, write_tags)?;
    log::info!("all done!");
    Ok(())
}