"""Upload service — accept file, store to DB, parse.""" import uuid, base64, json, io, cgi from db import documents, contracts, supplements from .parse import parse_file def handle_upload(rfile, content_type, content_length): """Parse multipart upload, store in DB, return result dict.""" body = rfile.read(content_length) environ = { "REQUEST_METHOD": "POST", "CONTENT_TYPE": content_type, "CONTENT_LENGTH": str(content_length), } fs = cgi.FieldStorage(fp=io.BytesIO(body), environ=environ, keep_blank_values=True) filename = None file_data = None contract_id = "" if "files" in fs: item = fs["files"] if isinstance(item, list): item = item[0] filename = item.filename file_data = item.file.read() if hasattr(item, "file") else item.value if isinstance(file_data, str): file_data = file_data.encode("utf-8") if "contract_id" in fs: contract_id = fs.getfirst("contract_id", "") batch_id = fs.getfirst("batch_id", None) if "batch_id" in fs else None if not filename or not file_data: return {"ok": False, "error": "no file in request"} mime = _mime_for(filename) b64 = base64.b64encode(file_data).decode() if contract_id: supplements.delete_by_document(contract_id, filename) doc = documents.insert(filename, mime, b64, batch_id=batch_id) if not contract_id: from datetime import datetime now = datetime.now() c = contracts.insert(f"б/н {now.strftime('%Y%m%d')}-{now.strftime('%H%M')}") contract_id = c["id"] supp_type = "initial" else: supp_type = "additional" supplements.insert(contract_id, doc["id"], supp_type) parsed = parse_file(filename, file_data) if parsed and parsed.get("status") == "parsed": documents.set_parsed(doc["id"], parsed["elements"]) elif parsed and parsed.get("status") == "error": documents.set_error(doc["id"], parsed.get("error", "parse failed")) return { "ok": True, "doc_id": doc["id"], "contract_id": contract_id, "filename": filename, "size": len(file_data), "parsed": parsed, } def _mime_for(filename): ext = filename.rsplit(".", 1)[-1].lower() if "." in filename else "" mime_map = { "pdf": "application/pdf", "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "doc": "application/msword", "zip": "application/zip", } return mime_map.get(ext, "application/octet-stream")