Add command for writing cell edits over time
This commit is contained in:
47
src/commands/dump_cell_edit_counts_over_time.rs
Normal file
47
src/commands/dump_cell_edit_counts_over_time.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
use crate::models::cell::{self, CellFileEditCount};
|
||||
use anyhow::Result;
|
||||
use chrono::{Duration, NaiveDateTime};
|
||||
use std::collections::HashMap;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tracing::{debug, info};
|
||||
|
||||
pub async fn dump_cell_edit_counts_over_time(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
start_date: NaiveDateTime,
|
||||
end_date: NaiveDateTime,
|
||||
path: &str,
|
||||
) -> Result<()> {
|
||||
let mut current_date = start_date;
|
||||
while current_date <= end_date {
|
||||
let next_date = current_date + Duration::weeks(1);
|
||||
let mut cell_file_edit_counts = HashMap::new();
|
||||
let counts =
|
||||
cell::count_file_edits_in_time_range(pool, "Skyrim.esm", 1, current_date, next_date)
|
||||
.await?;
|
||||
for x in -77..75 {
|
||||
for y in -50..44 {
|
||||
let count: Option<&CellFileEditCount> = counts.iter().find(|c| c.x.unwrap() == x && c.y.unwrap() == y);
|
||||
let count = count.map(|c| c.count).unwrap_or(Some(0)).unwrap();
|
||||
debug!(x = x, y = y, count = count, "read cell edit count");
|
||||
cell_file_edit_counts.insert(format!("{},{}", x, y), count);
|
||||
}
|
||||
}
|
||||
|
||||
let file_name = format!(
|
||||
"{}/cell_edits_{}.json",
|
||||
path,
|
||||
current_date.format("%Y-%m-%d")
|
||||
);
|
||||
info!(
|
||||
"writing {} cell edit counts to {}",
|
||||
cell_file_edit_counts.values().sum::<i64>(),
|
||||
file_name
|
||||
);
|
||||
let mut file = File::create(&file_name).await?;
|
||||
file.write_all(serde_json::to_string(&cell_file_edit_counts)?.as_bytes()).await?;
|
||||
|
||||
current_date = next_date;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -2,6 +2,7 @@ pub mod backfills;
|
||||
pub mod download_tiles;
|
||||
pub mod dump_cell_data;
|
||||
pub mod dump_cell_edit_counts;
|
||||
pub mod dump_cell_edit_counts_over_time;
|
||||
pub mod dump_file_data;
|
||||
pub mod dump_games;
|
||||
pub mod dump_mod_cell_counts;
|
||||
@@ -13,6 +14,7 @@ pub mod update;
|
||||
pub use download_tiles::download_tiles;
|
||||
pub use dump_cell_data::dump_cell_data;
|
||||
pub use dump_cell_edit_counts::dump_cell_edit_counts;
|
||||
pub use dump_cell_edit_counts_over_time::dump_cell_edit_counts_over_time;
|
||||
pub use dump_file_data::dump_file_data;
|
||||
pub use dump_games::dump_games;
|
||||
pub use dump_mod_cell_counts::dump_mod_cell_counts;
|
||||
|
||||
19
src/main.rs
19
src/main.rs
@@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use argh::FromArgs;
|
||||
use chrono::NaiveDateTime;
|
||||
use chrono::{NaiveDateTime, NaiveDate, Utc};
|
||||
use dotenv::dotenv;
|
||||
use sqlx::postgres::PgPoolOptions;
|
||||
use std::env;
|
||||
@@ -15,8 +15,8 @@ mod plugin_processor;
|
||||
use commands::{
|
||||
backfills::backfill_is_base_game, backfills::backfill_is_translation,
|
||||
backfills::deduplicate_interior_cells, download_tiles, dump_cell_data, dump_cell_edit_counts,
|
||||
dump_file_data, dump_games, dump_mod_cell_counts, dump_mod_data, dump_mod_search_index,
|
||||
dump_plugin_data, update,
|
||||
dump_cell_edit_counts_over_time, dump_file_data, dump_games, dump_mod_cell_counts,
|
||||
dump_mod_data, dump_mod_search_index, dump_plugin_data, update,
|
||||
};
|
||||
|
||||
#[derive(FromArgs)]
|
||||
@@ -42,6 +42,10 @@ struct Args {
|
||||
#[argh(option, short = 'e')]
|
||||
dump_edits: Option<String>,
|
||||
|
||||
/// file to output the cell mod edit counts over time as json
|
||||
#[argh(option, short = 'E')]
|
||||
dump_edits_over_time: Option<String>,
|
||||
|
||||
/// folder to output all cell data as json files
|
||||
#[argh(option, short = 'c')]
|
||||
cell_data: Option<String>,
|
||||
@@ -107,6 +111,15 @@ pub async fn main() -> Result<()> {
|
||||
if let Some(path) = args.dump_edits {
|
||||
return dump_cell_edit_counts(&pool, &path).await;
|
||||
}
|
||||
if let Some(path) = args.dump_edits_over_time {
|
||||
return dump_cell_edit_counts_over_time(
|
||||
&pool,
|
||||
NaiveDate::from_ymd_opt(2011, 11, 11).unwrap().and_hms_opt(0, 0, 0).unwrap(),
|
||||
Utc::now().naive_utc(),
|
||||
&path,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
if let Some(dir) = args.cell_data {
|
||||
return dump_cell_data(&pool, &dir).await;
|
||||
}
|
||||
|
||||
@@ -150,6 +150,43 @@ pub async fn count_mod_edits(
|
||||
.context("Failed to count mod edits on cell")
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, FromRow)]
|
||||
pub struct CellFileEditCount {
|
||||
pub x: Option<i32>,
|
||||
pub y: Option<i32>,
|
||||
pub count: Option<i64>,
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(pool))]
|
||||
pub async fn count_file_edits_in_time_range(
|
||||
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||
master: &str,
|
||||
world_id: i32,
|
||||
start_date: NaiveDateTime,
|
||||
end_date: NaiveDateTime,
|
||||
) -> Result<Vec<CellFileEditCount>> {
|
||||
sqlx::query_as!(
|
||||
CellFileEditCount,
|
||||
"SELECT cells.x, cells.y, COUNT(DISTINCT files.id)
|
||||
FROM cells
|
||||
JOIN plugin_cells on cells.id = cell_id
|
||||
JOIN plugins ON plugins.id = plugin_id
|
||||
JOIN files ON files.id = plugins.file_id
|
||||
WHERE master = $1 AND world_id = $2
|
||||
AND cells.x IS NOT NULL and cells.y IS NOT NULL
|
||||
AND files.uploaded_at BETWEEN $3 AND $4
|
||||
GROUP BY cells.x, cells.y
|
||||
",
|
||||
master,
|
||||
world_id,
|
||||
start_date,
|
||||
end_date,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await
|
||||
.context("Failed to count file-based mod edits on cell")
|
||||
}
|
||||
|
||||
/// Returns cell properties plus a list of mods that edit the cell
|
||||
#[instrument(level = "debug", skip(pool))]
|
||||
pub async fn get_cell_data(
|
||||
|
||||
Reference in New Issue
Block a user