tildes-statistics/source/cli/run.rs

174 lines
4.5 KiB
Rust

//! All logic for running the CLI.
use {
async_std::fs::{copy, create_dir_all},
clap::Parser,
color_eyre::Result,
sea_orm_migration::MigratorTrait,
tracing::info,
};
use crate::{
assets::write_assets,
charts::UserCountChart,
cli::{
Cli, MainSubcommands, MigrateSubcommands, SnapshotSubcommands,
WebSubcommands,
},
group_data::GroupDataModel,
migrations::Migrator,
scss::generate_css,
snapshots::SnapshotModel,
templates::{GroupTemplate, HomeTemplate},
utilities::{create_db, today},
};
/// Run the CLI.
pub async fn run() -> Result<()> {
let cli = Cli::parse();
let db = create_db(cli.sql_logging).await?;
if !cli.no_migrate {
Migrator::up(&db, None).await?;
}
match cli.command {
MainSubcommands::Migrate {
command: migrate_command,
} => match migrate_command {
MigrateSubcommands::Down { amount } => {
Migrator::down(&db, Some(amount)).await?;
}
MigrateSubcommands::Status => {
Migrator::status(&db).await?;
}
MigrateSubcommands::Up { amount } => {
Migrator::up(&db, Some(amount)).await?;
}
},
MainSubcommands::Snapshot {
command: snapshot_command,
} => match snapshot_command {
SnapshotSubcommands::Create { force } => {
SnapshotModel::create(&db, force).await?;
}
SnapshotSubcommands::List {} => {
for snapshot in SnapshotModel::get_all(&db).await? {
info!("Snapshot {snapshot:?}")
}
}
SnapshotSubcommands::Show { date, id } => {
let date = date.unwrap_or_else(today);
let snapshot = match id {
Some(id) => SnapshotModel::get_by_id(&db, id).await,
None => SnapshotModel::get_by_date(&db, date).await,
}?;
let snapshot = match (snapshot, id) {
(None, Some(id)) => {
info!("No snapshot exists for id {id}");
return Ok(());
}
(None, None) => {
info!("No snapshot exists for date {date}");
return Ok(());
}
(Some(snapshot), _) => snapshot,
};
info!("Snapshot {snapshot:?}");
for group in GroupDataModel::get_all_by_snapshot(&db, &snapshot).await?
{
info!(
id = group.id,
name = group.name,
subscribers = group.subscribers,
);
}
}
},
MainSubcommands::Web {
command: web_command,
} => match web_command {
WebSubcommands::Build { output } => {
let (groups, user_count_group) =
if let Some(snapshot) = SnapshotModel::get_most_recent(&db).await? {
(
GroupDataModel::get_all_by_snapshot(&db, &snapshot).await?,
GroupDataModel::get_tildes_official_data(&db, &snapshot).await?,
)
} else {
(vec![], None)
};
create_dir_all(&output).await?;
for group in &groups {
let chart = UserCountChart {
groups: GroupDataModel::get_n_most_recent(&db, 31, &group.name)
.await?,
};
chart
.render(&output, &group.name, true, true, "charts")
.await?;
chart
.render(&output, &group.name, true, false, "charts-untruncated")
.await?;
{
let total_chart = UserCountChart {
groups: GroupDataModel::get_all(&db, &group.name).await?,
};
total_chart
.render(&output, &group.name, false, true, "charts-total")
.await?;
total_chart
.render(
&output,
&group.name,
false,
false,
"charts-total-untruncated",
)
.await?;
}
GroupTemplate::new(group.description.clone(), &group.name)
.await
.render_to_file(&output)
.await?;
}
HomeTemplate::new(
groups,
user_count_group.as_ref().map(|group| group.subscribers),
)
.await
.render_to_file(&output)
.await?;
generate_css(&output).await?;
write_assets(&output).await?;
if let Some(group) = user_count_group {
for dir in ["charts", "charts-untruncated"] {
let from_path =
output.join(&format!("{}/user-count/{}.svg", dir, &group.name));
let to_path = output.join(format!("{}/main-user-count.svg", dir));
copy(from_path, to_path).await?;
}
}
}
},
}
Ok(())
}