diff --git a/.venv/bin/python b/.venv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/.venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/.venv/bin/python3 b/.venv/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/.venv/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/.venv/bin/python3.12 b/.venv/bin/python3.12 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/.venv/bin/python3.12 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/.venv/lib64 b/.venv/lib64 new file mode 120000 index 0000000..7951405 --- /dev/null +++ b/.venv/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/.venv/pyvenv.cfg b/.venv/pyvenv.cfg new file mode 100644 index 0000000..9376090 --- /dev/null +++ b/.venv/pyvenv.cfg @@ -0,0 +1,5 @@ +home = /usr/bin +include-system-site-packages = false +version = 3.12.3 +executable = /usr/bin/python3.12 +command = /usr/bin/python3 -m venv /home/naeel/nubes/drhider/.venv diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c9ebf2d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python-envs.defaultEnvManager": "ms-python.python:system" +} \ No newline at end of file diff --git a/0144-03-2023_отчет об оценке.pdf b/0144-03-2023_отчет об оценке.pdf new file mode 100755 index 0000000..178d48a Binary files /dev/null and b/0144-03-2023_отчет об оценке.pdf differ diff --git a/History/2026-08-19-process-names-api.md b/History/2026-08-19-process-names-api.md deleted file mode 100644 index 88c69e7..0000000 --- a/History/2026-08-19-process-names-api.md +++ /dev/null @@ -1,57 +0,0 @@ -# v0.0.45 — тестовый API process_names (обфускация по именам файлов) — 2026-08-19 - -**Дата:** 2026-08-19 -**Версия:** 0.0.44 → 0.0.45 - ---- - -## Суть - -Тестовый endpoint для curl: обфускация файлов по ИМЕНАМ из локальной папки -сервера (не таскать файлы каждый раз). - -## Использование - -```bash -# На сервере задана папка TEST_INPUT_DIR (env), в ней лежат входные файлы. -curl -X POST https://drhider.../api/process_names \ - -H "Content-Type: application/json" \ - -d '{"files": ["0144-03-2023_отчет об оценке.pdf", "test.pdf"]}' \ - -o result.zip -``` - -Ответ: ZIP с обфусцированными .md + mapping.csv. - -## Поведение (по требованию) - -- **Если `TEST_INPUT_DIR` не задан ИЛИ невалиден (не директория) — endpoint - возвращает 404** (как будто API нет). -- Имена файлов — только **basename** (защита от path traversal). -- Файл читается из `TEST_INPUT_DIR/`; если нет → 404. - -## Изменения - -### `site/routes/api_bp.py` -- `import os` добавлен. -- Глобальные `TEST_INPUT_DIR = os.environ.get("TEST_INPUT_DIR", "").strip()` - и `_TEST_API_ENABLED = bool(TEST_INPUT_DIR) and os.path.isdir(TEST_INPUT_DIR)`. -- Endpoint `POST /api/process_names`: - - 404 если `_TEST_API_ENABLED` false; - - читает JSON `{"files": [...]}`; - - basename + проверка файла в TEST_INPUT_DIR; - - `obfuscate_files(all_files, llm_client=LLMClient())`; - - возврат ZIP (`send_file`). - -### `site/app.py` -- `VERSION = "0.0.45"`. - -## Проверка -- Без `TEST_INPUT_DIR` → 404. -- С валидной папкой → 200, ZIP `['t.md', 'mapping.csv']`. -- Path traversal (`../../etc/passwd`) → 404 «файл не найден». -- Невалидная папка → 404. -- `py_compile` — OK. - -## Примечание -- Endpoint тестовый. На проде включать только при необходимости (задать TEST_INPUT_DIR). -- В тесте локально LLM недоступен (нет ключа) — «LLM NER failed» ожидаемо; на проде ключ есть. diff --git a/site/app.py b/site/app.py index 775ea7a..8523028 100644 --- a/site/app.py +++ b/site/app.py @@ -20,7 +20,7 @@ if _sys_path_root not in sys.path: sys.path.insert(0, _sys_path_root) # Версия приложения (меняется при изменениях) -VERSION = "0.0.45" +VERSION = "0.0.46" def create_app(): diff --git a/site/routes/api_bp.py b/site/routes/api_bp.py index 0e79148..fa3198c 100644 --- a/site/routes/api_bp.py +++ b/site/routes/api_bp.py @@ -7,13 +7,9 @@ Five endpoints: - POST /api/process/ — process all session files -> {status:"done"} (legacy) - GET /api/download/ — download ZIP (with timestamp name) - GET /api/csv/ — download CSV separately - -Тестовый (только при TEST_INPUT_DIR): -- POST /api/process_names — обфускация файлов по именам из TEST_INPUT_DIR """ import io -import os import json import queue import threading @@ -28,10 +24,6 @@ from session import (create_session, add_file, get_files, store_result, api_bp = Blueprint("api", __name__, url_prefix="/api") -# Тестовый API «по именам» доступен ТОЛЬКО если задана валидная папка TEST_INPUT_DIR. -TEST_INPUT_DIR = os.environ.get("TEST_INPUT_DIR", "").strip() -_TEST_API_ENABLED = bool(TEST_INPUT_DIR) and os.path.isdir(TEST_INPUT_DIR) - def _disconnect_exceptions(): """Исключения, означающие отключение клиента SSE.""" @@ -65,56 +57,6 @@ def upload(): return jsonify({"ok": True, "session": sid, "count": file_count(sid)}) -@api_bp.route("/process_names", methods=["POST"]) -def process_names(): - """Тестовый API: обфускация файлов ПО ИМЕНАМ из TEST_INPUT_DIR. - - Удобно для тестирования curl'ом (не таскать файлы заново). - - Доступен ТОЛЬКО если задан и валиден TEST_INPUT_DIR (env). - Иначе endpoint возвращает 404 — как будто API нет. - - Запрос: {"files": ["имя1.pdf", "имя2.pdf"]} (только имена, без путей) - Ответ: ZIP с обфусцированными .md + mapping.csv. - """ - if not _TEST_API_ENABLED: - return jsonify({"ok": False, "error": "Not found"}), 404 - - data = request.get_json(silent=True) or {} - names = data.get("files") or [] - if not isinstance(names, list) or not names: - return jsonify({"ok": False, "error": "files: список имён файлов"}), 400 - - all_files = [] - for name in names: - # Только basename — защита от path traversal - base = os.path.basename(str(name)) - if not base: - continue - path = os.path.join(TEST_INPUT_DIR, base) - if not os.path.isfile(path): - return jsonify({"ok": False, "error": f"файл не найден: {base}"}), 404 - with open(path, "rb") as fh: - all_files.append((base, fh.read(), "")) - - if not all_files: - return jsonify({"ok": False, "error": "нет файлов"}), 400 - - try: - llm = LLMClient() - zip_data, csv_str = obfuscate_files(all_files, llm_client=llm) - except Exception as e: - traceback.print_exc() - return jsonify({"ok": False, "error": str(e)}), 500 - - return send_file( - io.BytesIO(zip_data), - mimetype="application/zip", - as_attachment=True, - download_name="drhider_test.zip", - ) - - @api_bp.route("/process_stream/", methods=["GET"]) def process_stream(sid): """SSE: process all session files, streaming per-file progress.