diff --git a/deploy/convert_server.py b/deploy/convert_server.py index ef62ecc..b7791a4 100755 --- a/deploy/convert_server.py +++ b/deploy/convert_server.py @@ -60,6 +60,8 @@ class Handler(BaseHTTPRequestHandler): def do_POST(self): if self.path == "/llm-ops": self._handle_llm_ops() + elif self.path == "/unzip-upload": + self._handle_unzip_upload() else: self._handle_doc_convert() @@ -275,6 +277,57 @@ class Handler(BaseHTTPRequestHandler): self.end_headers() self.wfile.write(json.dumps({"error": str(e)}, ensure_ascii=False).encode()) + def _handle_unzip_upload(self): + """Распаковать ZIP и загрузить каждый файл в Lucee. Только файлы из корня архива.""" + import zipfile, io + length = int(self.headers.get("Content-Length", 0)) + data = self.rfile.read(length) + + results = [] + try: + with zipfile.ZipFile(io.BytesIO(data)) as zf: + for name in zf.namelist(): + # Только файлы из корня (без папок), пропускаем директории + if name.endswith('/') or '/' in name: + continue + content = zf.read(name) + ext = name.rsplit('.', 1)[-1].lower() if '.' in name else '' + if ext not in ('docx', 'doc', 'pdf'): + continue + + # Загрузить в Lucee + resp = httpx.post( + f"{LUCEE_URL}/upload.cfm", + data={"filename": name, "data": content}, + timeout=30 + ) + if resp.status_code == 200: + rj = resp.json() + if rj.get("OK"): + results.append({ + "filename": name, + "doc_id": rj.get("DOC_ID", ""), + "contract_id": rj.get("CONTRACT_ID", ""), + "size": len(content), + }) + else: + results.append({"filename": name, "error": rj.get("ERROR", "upload failed")}) + else: + results.append({"filename": name, "error": f"HTTP {resp.status_code}"}) + + except zipfile.BadZipFile: + self.send_error(400, "not a valid ZIP file") + return + except Exception as e: + self.send_error(500, str(e)) + return + + self.send_response(200) + self.send_header("Content-Type", "application/json; charset=utf-8") + self.send_header("Access-Control-Allow-Origin", "*") + self.end_headers() + self.wfile.write(json.dumps({"ok": True, "files": results}, ensure_ascii=False).encode()) + def _handle_doc_convert(self): length = int(self.headers.get("Content-Length", 0)) data = self.rfile.read(length) diff --git a/deploy/nginx-contracts.conf b/deploy/nginx-contracts.conf index 93199d3..99291b1 100644 --- a/deploy/nginx-contracts.conf +++ b/deploy/nginx-contracts.conf @@ -43,6 +43,15 @@ server { add_header Access-Control-Allow-Methods "GET, OPTIONS" always; } + location /unzip-upload { + add_header Access-Control-Allow-Origin "*"; + add_header Access-Control-Allow-Methods "POST, OPTIONS"; + add_header Access-Control-Allow-Headers "*"; + if ($request_method = OPTIONS) { return 200; } + proxy_pass http://127.0.0.1:8766; + client_max_body_size 100m; + } + listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/contracts.kube5s.ru/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/contracts.kube5s.ru/privkey.pem; # managed by Certbot diff --git a/index.cfm b/index.cfm index 4d9bb8b..5791e9d 100644 --- a/index.cfm +++ b/index.cfm @@ -75,7 +75,7 @@