List every photo's open Enhance jobs for a jobs manager
GET /enhance/jobs without a path now answers the jobs manager (FVR #99): every photo's queued / running / unavailable jobs, plus ready / failed / expired ones touched in the last 3 days, newest first, discarded and approved hidden, at most 100. DB only; the poller keeps rows current. An optional status=a,b filter applies to both forms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f121457c43
commit
37a2386458
5 files changed
+156
-8
No files matched your search
+36
-8
@@ -347,12 +347,20 @@ pub async fn get_job(
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct JobsQuery {
|
||||
pub path: String,
|
||||
/// A photo (original or version): that photo's jobs. Omitted: every
|
||||
/// photo's open jobs, for the jobs manager.
|
||||
pub path: Option<String>,
|
||||
pub library: Option<String>,
|
||||
/// Comma-separated statuses to keep (e.g. `queued,running,ready`);
|
||||
/// omitted = all. Applies to both forms.
|
||||
pub status: Option<String>,
|
||||
}
|
||||
|
||||
/// A photo's recent jobs, newest first, so the viewer can pick up an enhance
|
||||
/// in progress after reopening. Discarded jobs are not listed.
|
||||
/// With `path`: a photo's recent jobs, newest first, so the viewer can pick up
|
||||
/// an enhance in progress after reopening. Without: the jobs manager's list,
|
||||
/// every photo's queued / running / unavailable jobs plus ready / failed /
|
||||
/// expired ones from the last few days. Discarded and approved-and-done jobs
|
||||
/// are not listed. DB only.
|
||||
#[get("/enhance/jobs")]
|
||||
pub async fn list_jobs(
|
||||
_: Claims,
|
||||
@@ -361,13 +369,33 @@ pub async fn list_jobs(
|
||||
app_state: web::Data<AppState>,
|
||||
exif_dao: ExifData,
|
||||
) -> impl Responder {
|
||||
let file = match resolve_file(&app_state, &exif_dao, &q.path, q.library.as_deref()) {
|
||||
Ok(f) => f,
|
||||
Err(r) => return r,
|
||||
let jobs = match q.path.as_deref() {
|
||||
Some(path) => {
|
||||
let file = match resolve_file(&app_state, &exif_dao, path, q.library.as_deref()) {
|
||||
Ok(f) => f,
|
||||
Err(r) => return r,
|
||||
};
|
||||
svc.jobs_for_hash(&file.hash)
|
||||
}
|
||||
None => svc.open_jobs(),
|
||||
};
|
||||
match svc.jobs_for_hash(&file.hash) {
|
||||
let wanted: Option<Vec<&str>> = q.status.as_deref().map(|s| {
|
||||
s.split(',')
|
||||
.map(str::trim)
|
||||
.filter(|s| !s.is_empty())
|
||||
.collect()
|
||||
});
|
||||
match jobs {
|
||||
Ok(jobs) => {
|
||||
let views: Vec<JobView> = jobs.iter().map(job_view).collect();
|
||||
let views: Vec<JobView> = jobs
|
||||
.iter()
|
||||
.filter(|j| {
|
||||
wanted
|
||||
.as_ref()
|
||||
.is_none_or(|w| w.contains(&j.status.as_str()))
|
||||
})
|
||||
.map(job_view)
|
||||
.collect();
|
||||
HttpResponse::Ok().json(json!({ "jobs": views }))
|
||||
}
|
||||
Err(e) => error_response(&e),
|
||||
|
||||
Reference in new issue
Block a user