feat: update tag and timeline share panel copy for clarity and conciseness
Some checks failed
docker-images / resolve-build-targets (push) Successful in 7s
ui-regression / playwright-regression (push) Failing after 13m4s
docker-images / build-and-push (admin) (push) Successful in 1m17s
docker-images / build-and-push (backend) (push) Successful in 28m13s
docker-images / build-and-push (frontend) (push) Successful in 47s
docker-images / submit-indexnow (push) Successful in 13s
Some checks failed
docker-images / resolve-build-targets (push) Successful in 7s
ui-regression / playwright-regression (push) Failing after 13m4s
docker-images / build-and-push (admin) (push) Successful in 1m17s
docker-images / build-and-push (backend) (push) Successful in 28m13s
docker-images / build-and-push (frontend) (push) Successful in 47s
docker-images / submit-indexnow (push) Successful in 13s
style: enhance global CSS for better responsiveness of terminal chips and navigation pills test: remove inline subscription test and add maintenance mode access code test feat: implement media library picker dialog for selecting images from the media library feat: add media URL controls for uploading and managing media assets feat: add migration for music_enabled and maintenance_mode settings in site settings feat: implement maintenance mode functionality with access control feat: create maintenance page with access code input and error handling chore: add TypeScript declaration for QR code module
This commit is contained in:
@@ -1,14 +1,11 @@
|
||||
use chrono::Utc;
|
||||
use loco_rs::{
|
||||
bgworker::BackgroundWorker,
|
||||
prelude::*,
|
||||
};
|
||||
use loco_rs::{bgworker::BackgroundWorker, prelude::*};
|
||||
use sea_orm::{
|
||||
ActiveModelTrait, ColumnTrait, Condition, EntityTrait, IntoActiveModel, Order,
|
||||
PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, Set,
|
||||
ActiveModelTrait, ColumnTrait, Condition, EntityTrait, IntoActiveModel, Order, PaginatorTrait,
|
||||
QueryFilter, QueryOrder, QuerySelect, Set,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Value};
|
||||
use serde_json::{Value, json};
|
||||
|
||||
use crate::{
|
||||
models::_entities::{notification_deliveries, worker_jobs},
|
||||
@@ -213,7 +210,10 @@ fn can_cancel_status(status: &str, cancel_requested: bool) -> bool {
|
||||
}
|
||||
|
||||
fn can_retry_status(status: &str) -> bool {
|
||||
matches!(status, JOB_STATUS_FAILED | JOB_STATUS_CANCELLED | JOB_STATUS_SUCCEEDED)
|
||||
matches!(
|
||||
status,
|
||||
JOB_STATUS_FAILED | JOB_STATUS_CANCELLED | JOB_STATUS_SUCCEEDED
|
||||
)
|
||||
}
|
||||
|
||||
fn to_job_record(item: worker_jobs::Model) -> WorkerJobRecord {
|
||||
@@ -256,15 +256,17 @@ fn catalog_entries() -> Vec<WorkerCatalogEntry> {
|
||||
(TASK_SEND_MONTHLY_DIGEST, JOB_KIND_TASK, true, true),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|(worker_name, job_kind, supports_cancel, supports_retry)| WorkerCatalogEntry {
|
||||
worker_name: worker_name.to_string(),
|
||||
job_kind: job_kind.to_string(),
|
||||
label: label_for(worker_name),
|
||||
description: description_for(worker_name),
|
||||
queue_name: queue_name_for(worker_name),
|
||||
supports_cancel,
|
||||
supports_retry,
|
||||
})
|
||||
.map(
|
||||
|(worker_name, job_kind, supports_cancel, supports_retry)| WorkerCatalogEntry {
|
||||
worker_name: worker_name.to_string(),
|
||||
job_kind: job_kind.to_string(),
|
||||
label: label_for(worker_name),
|
||||
description: description_for(worker_name),
|
||||
queue_name: queue_name_for(worker_name),
|
||||
supports_cancel,
|
||||
supports_retry,
|
||||
},
|
||||
)
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -311,7 +313,10 @@ async fn dispatch_download(args_ctx: AppContext, args: DownloadWorkerArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
async fn dispatch_notification_delivery(args_ctx: AppContext, args: NotificationDeliveryWorkerArgs) {
|
||||
async fn dispatch_notification_delivery(
|
||||
args_ctx: AppContext,
|
||||
args: NotificationDeliveryWorkerArgs,
|
||||
) {
|
||||
let worker = NotificationDeliveryWorker::build(&args_ctx);
|
||||
if let Err(error) = worker.perform(args).await {
|
||||
tracing::warn!("notification delivery worker execution failed: {error}");
|
||||
@@ -326,7 +331,9 @@ async fn enqueue_download_worker(ctx: &AppContext, args: DownloadWorkerArgs) ->
|
||||
Ok(())
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::warn!("download worker queue unavailable, falling back to local task: {error}");
|
||||
tracing::warn!(
|
||||
"download worker queue unavailable, falling back to local task: {error}"
|
||||
);
|
||||
tokio::spawn(dispatch_download(ctx.clone(), args));
|
||||
Ok(())
|
||||
}
|
||||
@@ -344,7 +351,9 @@ async fn enqueue_notification_worker(
|
||||
Ok(())
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::warn!("notification worker queue unavailable, falling back to local task: {error}");
|
||||
tracing::warn!(
|
||||
"notification worker queue unavailable, falling back to local task: {error}"
|
||||
);
|
||||
tokio::spawn(dispatch_notification_delivery(ctx.clone(), args));
|
||||
Ok(())
|
||||
}
|
||||
@@ -442,17 +451,19 @@ pub async fn get_overview(ctx: &AppContext) -> Result<WorkerOverview> {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let entry = grouped.entry(item.worker_name.clone()).or_insert_with(|| WorkerStats {
|
||||
worker_name: item.worker_name.clone(),
|
||||
job_kind: item.job_kind.clone(),
|
||||
label: label_for(&item.worker_name),
|
||||
queued: 0,
|
||||
running: 0,
|
||||
succeeded: 0,
|
||||
failed: 0,
|
||||
cancelled: 0,
|
||||
last_job_at: None,
|
||||
});
|
||||
let entry = grouped
|
||||
.entry(item.worker_name.clone())
|
||||
.or_insert_with(|| WorkerStats {
|
||||
worker_name: item.worker_name.clone(),
|
||||
job_kind: item.job_kind.clone(),
|
||||
label: label_for(&item.worker_name),
|
||||
queued: 0,
|
||||
running: 0,
|
||||
succeeded: 0,
|
||||
failed: 0,
|
||||
cancelled: 0,
|
||||
last_job_at: None,
|
||||
});
|
||||
|
||||
match item.status.as_str() {
|
||||
JOB_STATUS_QUEUED => entry.queued += 1,
|
||||
@@ -473,18 +484,35 @@ pub async fn get_overview(ctx: &AppContext) -> Result<WorkerOverview> {
|
||||
}
|
||||
|
||||
pub async fn list_jobs(ctx: &AppContext, query: WorkerJobListQuery) -> Result<WorkerJobListResult> {
|
||||
let mut db_query = worker_jobs::Entity::find().order_by(worker_jobs::Column::CreatedAt, Order::Desc);
|
||||
let mut db_query =
|
||||
worker_jobs::Entity::find().order_by(worker_jobs::Column::CreatedAt, Order::Desc);
|
||||
|
||||
if let Some(status) = query.status.map(|value| value.trim().to_string()).filter(|value| !value.is_empty()) {
|
||||
if let Some(status) = query
|
||||
.status
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
{
|
||||
db_query = db_query.filter(worker_jobs::Column::Status.eq(status));
|
||||
}
|
||||
if let Some(job_kind) = query.job_kind.map(|value| value.trim().to_string()).filter(|value| !value.is_empty()) {
|
||||
if let Some(job_kind) = query
|
||||
.job_kind
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
{
|
||||
db_query = db_query.filter(worker_jobs::Column::JobKind.eq(job_kind));
|
||||
}
|
||||
if let Some(worker_name) = query.worker_name.map(|value| value.trim().to_string()).filter(|value| !value.is_empty()) {
|
||||
if let Some(worker_name) = query
|
||||
.worker_name
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
{
|
||||
db_query = db_query.filter(worker_jobs::Column::WorkerName.eq(worker_name));
|
||||
}
|
||||
if let Some(search) = query.search.map(|value| value.trim().to_string()).filter(|value| !value.is_empty()) {
|
||||
if let Some(search) = query
|
||||
.search
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
{
|
||||
db_query = db_query.filter(
|
||||
Condition::any()
|
||||
.add(worker_jobs::Column::WorkerName.contains(search.clone()))
|
||||
@@ -830,6 +858,9 @@ pub async fn retry_job(
|
||||
)
|
||||
.await
|
||||
}
|
||||
_ => Err(Error::BadRequest(format!("不支持重试任务:{}", item.worker_name))),
|
||||
_ => Err(Error::BadRequest(format!(
|
||||
"不支持重试任务:{}",
|
||||
item.worker_name
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user