Add batch default flow and downloads
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import io
|
||||
import json
|
||||
import mimetypes
|
||||
import threading
|
||||
import traceback
|
||||
import zipfile
|
||||
from http import HTTPStatus
|
||||
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||
from itertools import count
|
||||
@@ -112,16 +114,71 @@ def _run_post_job(log, payload: dict[str, Any]) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
def _run_default_batch_job(log, payload: dict[str, Any]) -> dict[str, Any]:
|
||||
requested = payload.get("images") or [item["name"] for item in pipeline.list_images()]
|
||||
skip_existing = bool(payload.get("skip_existing", True))
|
||||
completed = []
|
||||
failed = []
|
||||
|
||||
for filename in requested:
|
||||
try:
|
||||
log(f"[默认流程] {filename}: Baidu_API -> 自动 S/V")
|
||||
baidu_output = pipeline.dehaze_result_path(filename, "Baidu_API")
|
||||
if skip_existing and baidu_output.exists():
|
||||
log(f"[Baidu_API] 已存在,跳过: {pipeline.relpath(baidu_output)}")
|
||||
else:
|
||||
baidu_output = pipeline.run_dehaze_method(filename, "Baidu_API", {}, log)
|
||||
|
||||
auto_output = pipeline.post_result_path(filename, "Baidu_API", "auto_sv", {})
|
||||
if skip_existing and auto_output.exists():
|
||||
log(f"[自动 S/V] 已存在,跳过: {pipeline.relpath(auto_output)}")
|
||||
else:
|
||||
outputs = pipeline.run_postprocessors_for_source(
|
||||
filename,
|
||||
"Baidu_API",
|
||||
["auto_sv"],
|
||||
params={"auto_sv": {}},
|
||||
reference_filename=filename,
|
||||
log=log,
|
||||
)
|
||||
auto_output = outputs[-1]
|
||||
|
||||
completed.append(
|
||||
{
|
||||
"image": filename,
|
||||
"baidu": pipeline.relpath(baidu_output),
|
||||
"auto_sv": pipeline.relpath(auto_output),
|
||||
}
|
||||
)
|
||||
except Exception as exc:
|
||||
failed.append({"image": filename, "error": str(exc)})
|
||||
log(f"[默认流程] {filename} 失败: {exc}")
|
||||
|
||||
return {
|
||||
"completed": completed,
|
||||
"failed": failed,
|
||||
"results": {item["image"]: pipeline.get_results(item["image"]) for item in completed},
|
||||
}
|
||||
|
||||
|
||||
class DehazeRequestHandler(BaseHTTPRequestHandler):
|
||||
server_version = "DehazeWeb/1.0"
|
||||
|
||||
def log_message(self, fmt: str, *args) -> None:
|
||||
print("[%s] %s" % (self.log_date_time_string(), fmt % args))
|
||||
|
||||
def _send(self, status: int, body: bytes, content_type: str = "application/json; charset=utf-8") -> None:
|
||||
self.send_response(status)
|
||||
def _send(
|
||||
self,
|
||||
status: int,
|
||||
body: bytes,
|
||||
content_type: str = "application/json; charset=utf-8",
|
||||
headers: dict[str, str] | None = None,
|
||||
) -> None:
|
||||
self.send_response(int(status))
|
||||
self.send_header("Content-Type", content_type)
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
for key, value in (headers or {}).items():
|
||||
self.send_header(key, value)
|
||||
self.end_headers()
|
||||
self.wfile.write(body)
|
||||
|
||||
@@ -179,6 +236,8 @@ class DehazeRequestHandler(BaseHTTPRequestHandler):
|
||||
elif path == "/api/results":
|
||||
filename = query.get("image", [""])[0]
|
||||
self._send_json(pipeline.get_results(filename))
|
||||
elif path == "/api/download":
|
||||
self._serve_download(query)
|
||||
elif path == "/api/job":
|
||||
job_id = query.get("id", [""])[0]
|
||||
with JOB_LOCK:
|
||||
@@ -200,6 +259,9 @@ class DehazeRequestHandler(BaseHTTPRequestHandler):
|
||||
if parsed.path == "/api/run":
|
||||
job = _new_job("dehaze", _run_dehaze_job, payload)
|
||||
self._send_json({"job": job})
|
||||
elif parsed.path == "/api/run-default":
|
||||
job = _new_job("default_batch", _run_default_batch_job, payload)
|
||||
self._send_json({"job": job})
|
||||
elif parsed.path == "/api/postprocess":
|
||||
job = _new_job("postprocess", _run_post_job, payload)
|
||||
self._send_json({"job": job})
|
||||
@@ -230,6 +292,35 @@ class DehazeRequestHandler(BaseHTTPRequestHandler):
|
||||
content_type = mimetypes.guess_type(target.name)[0] or "application/octet-stream"
|
||||
self._send(HTTPStatus.OK, target.read_bytes(), content_type)
|
||||
|
||||
def _serve_download(self, query: dict[str, list[str]]) -> None:
|
||||
scope = query.get("scope", ["all"])[0]
|
||||
if scope == "current":
|
||||
filename = query.get("image", [""])[0]
|
||||
if not filename:
|
||||
self._send_error_json(HTTPStatus.BAD_REQUEST, "missing image")
|
||||
return
|
||||
items = pipeline.collect_download_items([filename])
|
||||
archive_name = f"dehaze_{pipeline.image_id(filename)}.zip"
|
||||
else:
|
||||
items = pipeline.collect_download_items()
|
||||
archive_name = "dehaze_results_all.zip"
|
||||
|
||||
if not items:
|
||||
self._send_error_json(HTTPStatus.NOT_FOUND, "no downloadable files")
|
||||
return
|
||||
|
||||
buffer = io.BytesIO()
|
||||
with zipfile.ZipFile(buffer, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
||||
for path, inner_name in items:
|
||||
archive.write(path, inner_name)
|
||||
|
||||
self._send(
|
||||
HTTPStatus.OK,
|
||||
buffer.getvalue(),
|
||||
"application/zip",
|
||||
headers={"Content-Disposition": f'attachment; filename="{archive_name}"'},
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="Local dehaze web console")
|
||||
|
||||
Reference in New Issue
Block a user