+ Загрузите документы (.docx, .xlsx, .pptx, .pdf, .txt).
+ DrHider заменит все персональные данные, реквизиты компаний, телефоны, email на фиктивные значения.
+
| Имя | +Размер | ++ |
|---|---|---|
| Нет выбранных файлов | ||
diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml new file mode 100644 index 0000000..022aa2d --- /dev/null +++ b/.gitea/workflows/deploy.yaml @@ -0,0 +1,13 @@ +name: Deploy drhider +on: + push: + branches: [master] + +jobs: + validate: + runs-on: linux_amd64 + steps: + - name: Test runner + run: | + echo "OK" + python3 --version diff --git a/site/app.py b/site/app.py new file mode 100644 index 0000000..c6f4fe8 --- /dev/null +++ b/site/app.py @@ -0,0 +1,96 @@ +import os +import io +import sys +import json +import zipfile +from flask import Flask, render_template, request, send_file, jsonify + +# Добавляем корень в sys.path чтобы import drhider работал +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from drhider import obfuscate_files + +app = Flask(__name__) + +VERSION = "1.0.0" + +MAX_BODY = 200 * 1024 * 1024 # 200 MB + + +class LLMClient: + """LLM-клиент для drhider (обнаружение компаний/ФИО).""" + + def __init__(self): + import httpx + self._httpx = httpx + + def complete(self, prompt: str) -> str: + key = os.environ.get("LLM_KEY") or os.environ.get("LLM_API_KEY", "") + r = self._httpx.post( + os.environ.get("LLM_URL", "https://api.aillm.ru/v1/chat/completions"), + json={ + "model": os.environ.get("LLM_MODEL", "gpt-oss-120b"), + "messages": [{"role": "user", "content": prompt}], + "max_tokens": 8000, + "temperature": 0.1, + }, + headers={ + "Authorization": f"Bearer {key}", + "Content-Type": "application/json", + }, + timeout=120, + ) + r.raise_for_status() + return r.json()["choices"][0]["message"]["content"] + + +@app.route("/") +def index(): + return render_template("index.html", version=VERSION) + + +@app.route("/health") +def health(): + return jsonify({"ok": True, "version": VERSION}) + + +@app.route("/api/drhider", methods=["POST"]) +def api_drhider(): + """Обфускация: multipart/form-data с файлами → ZIP.""" + uploaded = request.files.getlist("files") + if not uploaded: + return jsonify({"ok": False, "error": "Нет файлов"}), 400 + + files = [] + for f in uploaded: + if f.filename: + files.append((f.filename, f.read(), f.mimetype or "")) + + if not files: + return jsonify({"ok": False, "error": "Нет файлов"}), 400 + + try: + llm = LLMClient() + zip_data, _csv = obfuscate_files(files, llm_client=llm) + return send_file( + io.BytesIO(zip_data), + mimetype="application/zip", + as_attachment=True, + download_name="drhider_output.zip", + ) + except Exception as e: + import traceback + traceback.print_exc() + return jsonify({"ok": False, "error": str(e)}), 500 + + +if __name__ == "__main__": + import subprocess + subprocess.run([ + sys.executable, "-m", "gunicorn", "app:app", + "--bind", "0.0.0.0:5000", + "--worker-class", "gevent", + "--workers", "1", + "--worker-connections", "1000", + "--timeout", "300", + ]) diff --git a/site/static/favicon.svg b/site/static/favicon.svg new file mode 100644 index 0000000..3a2969d --- /dev/null +++ b/site/static/favicon.svg @@ -0,0 +1,66 @@ + + + + diff --git a/site/templates/index.html b/site/templates/index.html new file mode 100644 index 0000000..b1a67d9 --- /dev/null +++ b/site/templates/index.html @@ -0,0 +1,209 @@ + + +
+ + +
+ Загрузите документы (.docx, .xlsx, .pptx, .pdf, .txt).
+ DrHider заменит все персональные данные, реквизиты компаний, телефоны, email на фиктивные значения.
+
| Имя | +Размер | ++ |
|---|---|---|
| Нет выбранных файлов | ||