fix: more on progress in tasks
This commit is contained in:
@@ -12,11 +12,24 @@ pub struct ReindexReport {
|
||||
pub media_indexed: usize,
|
||||
}
|
||||
|
||||
/// Per-item progress callback: (current_item, total_items, item_description).
|
||||
pub type ItemProgressFn = Box<dyn Fn(usize, usize, &str) + Send>;
|
||||
|
||||
/// Drop and rebuild the entire FTS index for all posts and media in a project.
|
||||
pub fn reindex_all(
|
||||
conn: &Connection,
|
||||
project_id: &str,
|
||||
main_language: &str,
|
||||
) -> EngineResult<ReindexReport> {
|
||||
reindex_all_with_progress(conn, project_id, main_language, None)
|
||||
}
|
||||
|
||||
/// Like `reindex_all` but with optional per-item progress.
|
||||
pub fn reindex_all_with_progress(
|
||||
conn: &Connection,
|
||||
project_id: &str,
|
||||
main_language: &str,
|
||||
on_item: Option<ItemProgressFn>,
|
||||
) -> EngineResult<ReindexReport> {
|
||||
// Wipe existing FTS content
|
||||
conn.execute("DELETE FROM posts_fts", [])?;
|
||||
@@ -25,8 +38,16 @@ pub fn reindex_all(
|
||||
// Reindex all posts
|
||||
let posts = post_q::list_posts_by_project(conn, project_id)?;
|
||||
|
||||
// Reindex all media
|
||||
let media_items = media_q::list_media_by_project(conn, project_id)?;
|
||||
|
||||
let total = posts.len() + media_items.len();
|
||||
|
||||
let mut posts_indexed = 0;
|
||||
for post in &posts {
|
||||
for (i, post) in posts.iter().enumerate() {
|
||||
if let Some(ref cb) = on_item {
|
||||
cb(i + 1, total, &post.title);
|
||||
}
|
||||
let translations = post_translation::list_post_translations_by_post(conn, &post.id)?;
|
||||
|
||||
let trans_pairs: Vec<(String, String)> = translations
|
||||
@@ -58,11 +79,12 @@ pub fn reindex_all(
|
||||
posts_indexed += 1;
|
||||
}
|
||||
|
||||
// Reindex all media
|
||||
let media_items = media_q::list_media_by_project(conn, project_id)?;
|
||||
|
||||
let offset = posts.len();
|
||||
let mut media_indexed = 0;
|
||||
for m in &media_items {
|
||||
for (i, m) in media_items.iter().enumerate() {
|
||||
if let Some(ref cb) = on_item {
|
||||
cb(offset + i + 1, total, &m.original_name);
|
||||
}
|
||||
let translations = media_translation::list_media_translations_by_media(conn, &m.id)?;
|
||||
|
||||
let trans_pairs: Vec<(String, String)> = translations
|
||||
|
||||
@@ -50,11 +50,24 @@ pub struct TranslationValidationReport {
|
||||
pub checked_fs_files: usize,
|
||||
}
|
||||
|
||||
/// Per-item progress callback: (current_item, total_items, item_description).
|
||||
pub type ItemProgressFn = Box<dyn Fn(usize, usize, &str) + Send>;
|
||||
|
||||
/// Validate all translations in a project against consistency rules.
|
||||
pub fn validate_translations(
|
||||
conn: &Connection,
|
||||
data_dir: &Path,
|
||||
project_id: &str,
|
||||
) -> EngineResult<TranslationValidationReport> {
|
||||
validate_translations_with_progress(conn, data_dir, project_id, None)
|
||||
}
|
||||
|
||||
/// Like `validate_translations` but with optional per-item progress.
|
||||
pub fn validate_translations_with_progress(
|
||||
conn: &Connection,
|
||||
data_dir: &Path,
|
||||
project_id: &str,
|
||||
on_item: Option<ItemProgressFn>,
|
||||
) -> EngineResult<TranslationValidationReport> {
|
||||
let posts = post_q::list_posts_by_project(conn, project_id)?;
|
||||
|
||||
@@ -64,8 +77,12 @@ pub fn validate_translations(
|
||||
// Phase 1: database validation
|
||||
let mut db_issues = Vec::new();
|
||||
let mut checked_db_rows = 0usize;
|
||||
let post_count = posts.len();
|
||||
|
||||
for post in &posts {
|
||||
for (i, post) in posts.iter().enumerate() {
|
||||
if let Some(ref cb) = on_item {
|
||||
cb(i + 1, post_count, &post.title);
|
||||
}
|
||||
let translations = post_translation::list_post_translations_by_post(conn, &post.id)?;
|
||||
|
||||
for t in &translations {
|
||||
@@ -113,19 +130,26 @@ pub fn validate_translations(
|
||||
|
||||
let posts_dir = data_dir.join("posts");
|
||||
if posts_dir.exists() {
|
||||
for entry in walkdir::WalkDir::new(&posts_dir)
|
||||
// Collect translation files first so we know the total
|
||||
let translation_files: Vec<_> = walkdir::WalkDir::new(&posts_dir)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| e.file_type().is_file())
|
||||
{
|
||||
let path = entry.path();
|
||||
let Some(ext) = path.extension() else { continue };
|
||||
if ext != "md" { continue; }
|
||||
.filter(|e| e.path().extension().is_some_and(|ext| ext == "md"))
|
||||
.filter(|e| {
|
||||
let stem = e.path().file_stem().and_then(|s| s.to_str()).unwrap_or("");
|
||||
is_translation_stem(stem)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Check if this is a translation file (has language code before .md)
|
||||
let fs_total = translation_files.len();
|
||||
|
||||
for (i, entry) in translation_files.iter().enumerate() {
|
||||
let path = entry.path();
|
||||
let stem = path.file_stem().and_then(|s| s.to_str()).unwrap_or("");
|
||||
if !is_translation_stem(stem) {
|
||||
continue;
|
||||
|
||||
if let Some(ref cb) = on_item {
|
||||
cb(i + 1, fs_total, stem);
|
||||
}
|
||||
|
||||
checked_fs_files += 1;
|
||||
|
||||
@@ -498,9 +498,15 @@ impl BdsApp {
|
||||
.ok()
|
||||
.and_then(|m| m.main_language)
|
||||
.unwrap_or_else(|| "en".to_string());
|
||||
tm.report_progress(tid, Some(0.10), Some("Reindexing...".into()));
|
||||
let report = engine::search::reindex_all(db.conn(), &project_id, &main_lang)
|
||||
.map_err(|e| e.to_string())?;
|
||||
let tm2 = Arc::clone(&tm);
|
||||
let on_item: engine::search::ItemProgressFn = Box::new(move |current, total, name| {
|
||||
let pct = if total > 0 { current as f32 / total as f32 } else { 1.0 };
|
||||
let msg = format!("Indexing: {current}/{total} \u{2014} {name}");
|
||||
tm2.report_progress(tid, Some(pct), Some(msg));
|
||||
});
|
||||
let report = engine::search::reindex_all_with_progress(
|
||||
db.conn(), &project_id, &main_lang, Some(on_item),
|
||||
).map_err(|e| e.to_string())?;
|
||||
Ok(format!("posts={}, media={}", report.posts_indexed, report.media_indexed))
|
||||
},
|
||||
)
|
||||
@@ -510,9 +516,10 @@ impl BdsApp {
|
||||
"engine.calendarStarted",
|
||||
|db_path, project_id, data_dir, tm, tid| {
|
||||
let db = Database::open(&db_path).map_err(|e| e.to_string())?;
|
||||
tm.report_progress(tid, Some(0.10), Some("Generating calendar JSON...".into()));
|
||||
tm.report_progress(tid, Some(0.20), Some("Loading posts...".into()));
|
||||
engine::calendar::regenerate_calendar(db.conn(), &data_dir, &project_id)
|
||||
.map_err(|e| e.to_string())?;
|
||||
tm.report_progress(tid, Some(0.90), Some("Writing calendar JSON...".into()));
|
||||
Ok("done".to_string())
|
||||
},
|
||||
)
|
||||
@@ -523,9 +530,14 @@ impl BdsApp {
|
||||
"engine.validateTranslationsStarted",
|
||||
|db_path, project_id, data_dir, tm, tid| {
|
||||
let db = Database::open(&db_path).map_err(|e| e.to_string())?;
|
||||
tm.report_progress(tid, Some(0.10), Some("Checking translations...".into()));
|
||||
let report = engine::validate_translations::validate_translations(
|
||||
db.conn(), &data_dir, &project_id,
|
||||
let tm2 = Arc::clone(&tm);
|
||||
let on_item: engine::validate_translations::ItemProgressFn = Box::new(move |current, total, name| {
|
||||
let pct = if total > 0 { current as f32 / total as f32 } else { 1.0 };
|
||||
let msg = format!("Checking: {current}/{total} \u{2014} {name}");
|
||||
tm2.report_progress(tid, Some(pct), Some(msg));
|
||||
});
|
||||
let report = engine::validate_translations::validate_translations_with_progress(
|
||||
db.conn(), &data_dir, &project_id, Some(on_item),
|
||||
).map_err(|e| e.to_string())?;
|
||||
Ok(format!("db_issues={}, fs_issues={}", report.db_issues.len(), report.fs_issues.len()))
|
||||
},
|
||||
@@ -536,9 +548,10 @@ impl BdsApp {
|
||||
"engine.generateSiteStarted",
|
||||
|db_path, project_id, data_dir, tm, tid| {
|
||||
let db = Database::open(&db_path).map_err(|e| e.to_string())?;
|
||||
tm.report_progress(tid, Some(0.10), Some("Generating calendar...".into()));
|
||||
tm.report_progress(tid, Some(0.20), Some("Generating calendar...".into()));
|
||||
engine::calendar::regenerate_calendar(db.conn(), &data_dir, &project_id)
|
||||
.map_err(|e| e.to_string())?;
|
||||
tm.report_progress(tid, Some(0.90), Some("Calendar written".into()));
|
||||
Ok("done".to_string())
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user