lr2-oxytabler 0.10.2

Table manager for Lunatic Rave 2
Documentation
use anyhow::Result;
use lr2_oxytabler::{
    build_reqwest, changelog, fetch, open_db, output::OutputFolder, save_db, table::Table,
    time::UnixEpochTs,
};
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 now = UnixEpochTs::now();
    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 updates = {
        let client = build_reqwest()?;
        let pb = indicatif::ProgressBar::new(tasks.len().try_into()?)
            .with_style(indicatif::ProgressStyle::default_bar());
        let out = tokio::runtime::Runtime::new()?.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();
        out
    };
    log::info!("[2/3] applying updates...");
    {
        let mut fallback_song_titles = HashMap::<String, String>::new();
        for update in updates {
            match update {
                (Ok((answer, new_song_titles)), locator) => {
                    fallback_song_titles.extend(new_song_titles);
                    Table::apply_update(
                        &[
                            &changelog::DbSongNameAccessor { db: &db },
                            &changelog::FallbackSongNameAccessor {
                                fallback: &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(())
}