mirror of
https://github.com/Lumither/nocturne.git
synced 2026-10-17 10:26:21 +00:00
feat(blog) add force refresh
This commit is contained in:
3 files changed
+57
-12
No files matched your search
@@ -2,10 +2,11 @@ use std::{env, fs};
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use axum::extract::State;
|
use axum::extract::{Query, State};
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use futures::{stream, StreamExt};
|
use futures::{stream, StreamExt};
|
||||||
|
use serde::Deserialize;
|
||||||
use serde_json::{json, Map, Value};
|
use serde_json::{json, Map, Value};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use sqlx::{PgPool, query};
|
use sqlx::{PgPool, query};
|
||||||
@@ -16,9 +17,18 @@ use crate::api::post::errors::refresh::PostIdxError;
|
|||||||
use crate::api::post::utils::{build_post_idx, post};
|
use crate::api::post::utils::{build_post_idx, post};
|
||||||
use crate::model::blog::{POST_BASE_MODEL, POST_HASH_MODEL, POST_META_MODEL, TAG_MODEL};
|
use crate::model::blog::{POST_BASE_MODEL, POST_HASH_MODEL, POST_META_MODEL, TAG_MODEL};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Params {
|
||||||
|
/// refresh level
|
||||||
|
level: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn refresh(
|
pub async fn refresh(
|
||||||
State(db_connection): State<PgPool>,
|
State(db_connection): State<PgPool>,
|
||||||
|
Query(params): Query<Params>,
|
||||||
) -> Result<StatusCode, (StatusCode, Json<Value>)> {
|
) -> Result<StatusCode, (StatusCode, Json<Value>)> {
|
||||||
|
let is_force_refresh = params.level.unwrap_or("".to_string()) == "force";
|
||||||
|
|
||||||
// search post
|
// search post
|
||||||
let data_repo_dir = match env::var("GIT_WORK_DIR") {
|
let data_repo_dir = match env::var("GIT_WORK_DIR") {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
@@ -33,6 +43,22 @@ pub async fn refresh(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if is_force_refresh {
|
||||||
|
if let Err(e) = query("DROP TABLE hash, meta, post, tag;")
|
||||||
|
.execute(&db_connection)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
error!(
|
||||||
|
"DB query error when deleting table: `hash`, `meta`, `post`, `tag`: {}",
|
||||||
|
e.to_string()
|
||||||
|
);
|
||||||
|
return Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Json::from(json!(("error", e.to_string()))),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// generate post idx
|
// generate post idx
|
||||||
let md_path = search_md(Path::new(&data_repo_dir));
|
let md_path = search_md(Path::new(&data_repo_dir));
|
||||||
|
|
||||||
@@ -81,19 +107,30 @@ pub async fn refresh(
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let stream = stream::iter(post_list_with_hash).for_each_concurrent(None, |(post, hash)| {
|
let res: Vec<_> = stream::iter(post_list_with_hash)
|
||||||
|
.map(|(post, hash)| {
|
||||||
let db_clone = db_connection.clone();
|
let db_clone = db_connection.clone();
|
||||||
async move {
|
async move { build_post_idx(&db_clone, post, hash).await }
|
||||||
if let Err(e) = build_post_idx(&db_clone, post, hash).await {
|
})
|
||||||
error!("{}", e.to_string());
|
.buffer_unordered(usize::MAX)
|
||||||
}
|
.collect()
|
||||||
}
|
.await;
|
||||||
});
|
|
||||||
|
|
||||||
stream.await;
|
let errs: Vec<_> = res
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|res| res.err())
|
||||||
|
.map(|e| e.to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if !errs.is_empty() {
|
||||||
|
Err((
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
Json::from(json!({"error": errs})),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
Ok(StatusCode::OK)
|
Ok(StatusCode::OK)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Search a dir, return a list of markdown files
|
/// Search a dir, return a list of markdown files
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -214,6 +214,8 @@ INSERT INTO Hash (post_id, hash) VALUES ($1, $2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn meta(db_connection: &PgPool, post_id: Uuid, meta: &Value) -> Result<(), PostIdxError> {
|
pub async fn meta(db_connection: &PgPool, post_id: Uuid, meta: &Value) -> Result<(), PostIdxError> {
|
||||||
|
let mut err_trails = 5;
|
||||||
|
loop {
|
||||||
if let Err(e) = query(
|
if let Err(e) = query(
|
||||||
format!(
|
format!(
|
||||||
r"
|
r"
|
||||||
@@ -264,13 +266,19 @@ $$ LANGUAGE plpgsql;
|
|||||||
)
|
)
|
||||||
.execute(db_connection)
|
.execute(db_connection)
|
||||||
.await {
|
.await {
|
||||||
Err(PostIdxError::DBWriteFailure {
|
if err_trails >= 0 {
|
||||||
|
err_trails -= 1;
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return Err(PostIdxError::DBWriteFailure {
|
||||||
data_desc: "post meta data".to_string(),
|
data_desc: "post meta data".to_string(),
|
||||||
db_table: "Meta".to_string(),
|
db_table: "Meta".to_string(),
|
||||||
id: post_id.to_string(),
|
id: post_id.to_string(),
|
||||||
err_msg: e.to_string(),
|
err_msg: e.to_string(),
|
||||||
})
|
})
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
return Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ pub fn from_path(path: &str) -> Result<Map<String, Value>, Box<dyn Error>> {
|
|||||||
.arg("--format=%cI")
|
.arg("--format=%cI")
|
||||||
.arg("--")
|
.arg("--")
|
||||||
.current_dir(env::var("GIT_WORK_DIR")?)
|
.current_dir(env::var("GIT_WORK_DIR")?)
|
||||||
.arg(&path)
|
.arg(path)
|
||||||
.output()
|
.output()
|
||||||
{
|
{
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
|
|||||||
Reference in new issue
Block a user