No description
  • Python 95.4%
  • Shell 3%
  • Makefile 0.8%
  • Dockerfile 0.8%
Find a file
2026-07-24 14:14:33 +03:00
agents Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
common Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
config Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
deploy/ubuntu Исправлена ошибка незапускаемых скриптов из-за неправильно установленных прав 2026-07-23 16:06:54 +03:00
secrets Первая версия, созданная ChatGPT для переноса кода с Windows на Linux 2026-07-22 18:04:26 +03:00
tests Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
.dockerignore Первая версия, созданная ChatGPT для переноса кода с Windows на Linux 2026-07-22 18:04:26 +03:00
.env.example - Разделена установка агентов и компонентов, необходимых для WhisperX - для ситуаций, когда Whisper используется либо на этом же сервере, либо на другом; 2026-07-23 14:08:19 +03:00
.gitattributes Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
.gitignore Первая версия, созданная ChatGPT для переноса кода с Windows на Linux 2026-07-22 18:04:26 +03:00
docker-compose.gpu.yml - Разделена установка агентов и компонентов, необходимых для WhisperX - для ситуаций, когда Whisper используется либо на этом же сервере, либо на другом; 2026-07-23 14:08:19 +03:00
docker-compose.yml - Разделена установка агентов и компонентов, необходимых для WhisperX - для ситуаций, когда Whisper используется либо на этом же сервере, либо на другом; 2026-07-23 14:08:19 +03:00
Dockerfile Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
Makefile Исправлена ошибка незапускаемых скриптов из-за неправильно установленных прав 2026-07-23 16:06:54 +03:00
MIGRATION_NOTES.md Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
README.md Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
requirements.txt Первая версия, созданная ChatGPT для переноса кода с Windows на Linux 2026-07-22 18:04:26 +03:00
run.py Первая версия, созданная ChatGPT для переноса кода с Windows на Linux 2026-07-22 18:04:26 +03:00
SHA256SUMS Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00
summary.py Исправлена логика обработки: теперь первичной всегда считается информация о наличии конкретного файла в Nextcloud, а не сохранённый статус в БД. 2026-07-24 14:14:33 +03:00

Автоматическая обработка записей из Nextcloud — Linux/Docker

Комплект переносит конвейер с Windows на Linux, устраняет вызовы .bat и не требует локального зеркала больших каталогов Nextcloud.

Архитектура хранения

Данные разделены на две категории.

Большие каталоги записей

Аудио, видео, Zoom VTT, расшифровки и резюме встреч обрабатываются через WebDAV:

  1. scheduler_agent рекурсивно выполняет PROPFIND только для каталогов из nextcloud.roots и записывает в SQLite метаданные файлов.
  2. transcriber_agent скачивает по GET одну выбранную запись во временный каталог workdir/whisperx/<meeting_id>.
  3. WhisperX создаёт локальные временные артефакты.
  4. Готовые *-parsed.txt и *-whisperx.srt загружаются обратно в исходную папку через PUT. SRT содержит временные интервалы и технические метки говорящих; он нужен, если Zoom VTT появится позднее.
  5. Если рядом есть Zoom VTT, enricher_agent скачивает *-parsed.txt, Zoom VTT и *-whisperx.srt, создаёт *-enriched.txt и загружает его через PUT.
  6. analyzer_agent читает parsed/enriched-текст через WebDAV, вызывает локальную LLM и загружает *-resume.txt в ту же удалённую папку.
  7. Временные локальные копии медиа и промежуточных файлов удаляются после успешного шага; долговечное состояние обработки остаётся в Nextcloud.

На диске сервера постоянно не хранится архив записей. Требуемое место определяется размером одновременно обрабатываемой записи, кэшем моделей и техническими артефактами.

Небольшая папка Automation

nextcloudcmd используется только для папки, например /Automation:

Automation/
├── config.yaml
├── prompts/
│   ├── *.txt
│   └── clients/*.txt
└── summaries/

Она содержит общую конфигурацию, промпты, клиентские контексты и сводные отчёты. Код запрещает запуск nextcloudcmd без явного списка заданий и отказывается синхронизировать корень /.

Что заменено

Windows-реализация Linux-реализация
run.bat run.py / agents.pipeline_agent
summary.bat summary.py
WhisperX.bat common/whisperx_runner.py
summarize_transcript.bat и AskGPT.py common/llm.py, OpenAI-совместимый API llama.cpp
полный локальный доступ к каталогам записей выборочные PROPFIND, GET и PUT через WebDAV
секреты в общем YAML Docker secrets или root-owned файлы

Состав конвейера

nextcloudcmd: синхронизация /Automation
        ↓
WebDAV scheduler: метаданные выбранных remote roots
        ↓
classifier_agent
        ↓
GET одной записи → WhisperX → PUT parsed + whisperx.srt
        ↓
GET parsed + VTT + whisperx.srt → обогащение → PUT enriched
        ↓
GET текста → llama.cpp → PUT resume
        ↓
повторный WebDAV scan

Правило определения состояния

SQLite является локальным индексом и журналом, но не источником истины. Каждый цикл начинается со сканирования Nextcloud, а стадии определяют работу по наличию удалённых артефактов:

Стадия Обязательные входы Выход Условие запуска
Транскрибация медиа *-parsed.txt, *-whisperx.srt parsed отсутствует; либо VTT появился позднее, enriched отсутствует и нет whisperx SRT
Обогащение parsed, Zoom VTT, whisperx SRT *-enriched.txt все входы есть, enriched отсутствует
Анализ встречи enriched; либо parsed при отсутствии VTT *-resume.txt/*.md вход готов, resume отсутствует
Сводный анализ remote resume-файлы файл в /Automation/summaries ожидаемый сводный файл отсутствует после синхронизации

Если выходной файл удалён в Nextcloud, следующий полный scan очистит соответствующее поле SQLite и стадия создаст файл снова. Существующие выходы не перезаписываются: загрузка выполняется условным PUT с If-None-Match: *. Исключение — явно заданные параметры --force/--force-analysis.

classifier_agent не создаёт файл в Nextcloud: он детерминированно восстанавливает служебные атрибуты встречи из удалённого пути и общей конфигурации, поэтому его безопасно запускать при каждом цикле.

Конфигурация

Общая конфигурация команды

Шаблон: config/shared.example.yaml.

Общий файл находится в /Automation/config.yaml и содержит:

  • удалённые корни записей nextcloud.roots;
  • тип и клиента для каждого корня;
  • правила классификации;
  • порядок предпочтения форматов медиа;
  • маршруты промптов;
  • параметры сканирования, не содержащие секретов.

Пути к промптам разрешаются относительно каталога общего config.yaml.

Локальная конфигурация сервера

Создайте config/server.yaml из config/server.example.yaml. Файл не должен попадать в Git или общую папку Nextcloud.

Ключевые параметры:

shared_config_path: /data/automation/config.yaml

runtime:
  nextcloud:
    webdav_url: https://cloud.example.org/remote.php/dav/files/{username}
    username_file: /run/secrets/nextcloud_username
    password_file: /run/secrets/nextcloud_password

  nextcloud_sync:
    server_url: https://cloud.example.org
    jobs:
      - remote_path: /Automation
        local_path: /data/automation

webdav_url — полный DAV-корень пользователя. {username} заменяется значением из защищённого secret-файла.

nextcloud_sync.server_url — обычный адрес сервера Nextcloud без /remote.php/dav/....

Секреты

Создайте файлы:

secrets/nextcloud_username
secrets/nextcloud_password
secrets/huggingface_token
secrets/llama_api_key

Пример:

mkdir -p secrets
printf '%s' 'nextcloud-user' > secrets/nextcloud_username
printf '%s' 'NEXTCLOUD-APP-PASSWORD' > secrets/nextcloud_password
printf '%s' 'hf_...' > secrets/huggingface_token
printf '%s' 'no-key' > secrets/llama_api_key
chmod 700 secrets
chmod 600 secrets/*

Для незащищённого llama-server можно использовать значение no-key.

Для диаризации токен Hugging Face должен иметь доступ к используемой модели pyannote; принятие условий модели выполняется в учётной записи Hugging Face заранее.

Требования к серверу

  • Linux x86-64;
  • Docker Engine и Docker Compose plugin;
  • драйвер NVIDIA на Docker-хосте;
  • NVIDIA Container Toolkit на Docker-хосте, если WhisperX использует локальный GPU;
  • доступ из контейнера к Nextcloud и серверу llama.cpp;
  • свободное место минимум для крупнейшей одновременно обрабатываемой записи, кэша моделей и временных артефактов.

Подготовка Docker-хоста для локального WhisperX на NVIDIA

CUDA-библиотеки внутри образа не устанавливают host-side NVIDIA Container Toolkit. Команда nvidia-ctk и настройка Docker runtime должны находиться на самом Ubuntu-сервере. После клонирования репозитория выполните один раз:

make bootstrap-gpu

Скрипт deploy/ubuntu/install-nvidia-container-toolkit.sh идемпотентен: он проверяет работу драйвера через nvidia-smi, подключает официальный репозиторий NVIDIA, устанавливает Toolkit, запускает nvidia-ctk runtime configure --runtime=docker, перезапускает Docker и обновляет CDI-описания, если соответствующий systemd-сервис доступен. Скрипт намеренно не устанавливает драйвер NVIDIA.

Базовый docker-compose.yml не требует GPU. Локальный GPU подключается только через docker-compose.gpu.yml, поэтому синхронизация и административные команды работают даже на CPU-only сервере.

Развёртывание

sudo mkdir -p /opt/nextcloud_processing
sudo chown "$USER":"$USER" /opt/nextcloud_processing

git clone https://git.greesha.ru/modeus_tools/nextcloud_processing \
  /opt/nextcloud_processing
cd /opt/nextcloud_processing

cp config/server.example.yaml config/server.yaml
cp .env.example .env
mkdir -p data/{automation,work,database,models} secrets

Запишите UID/GID владельца файлов в .env:

id -u
id -g

До первого запуска создайте в Nextcloud /Automation и разместите там:

  • config/shared.example.yaml под именем config.yaml;
  • файлы промптов в prompts/;
  • клиентские контексты в prompts/clients/.

Затем отредактируйте config/server.yaml и создайте secret-файлы.

Первичная проверка

Сначала проверьте только синхронизацию небольшой папки:

make build
make sync

В data/automation должен появиться config.yaml и папка prompts.

Проверьте WebDAV-сканирование без WhisperX:

make scan

Сканирование читает только метаданные и не скачивает содержимое медиа.

Запуск

Однократный полный проход:

make run-once-gpu

Фоновый режим:

make up-gpu
make logs

Фильтр по клиенту и дате:

docker compose -f docker-compose.yml -f docker-compose.gpu.yml \
  run --rm processor --config /config/server.yaml --once \
  --client 'УрФУ' --from_date 2026-07-01

Сводное резюме нескольких встреч:

docker compose run --rm --entrypoint python3 processor \
  summary.py --config /config/server.yaml \
  --client 'УрФУ' --from_date 2026-07-01

Сводный файл записывается в /data/automation/summaries, после чего summary.py синхронизирует /Automation.

Настройка llama.cpp

runtime:
  llm:
    base_url: http://llama-server.internal:8080/v1
    model: local-model
    api_key_file: /run/secrets/llama_api_key
    timeout: 900
    temperature: 0.1
    max_tokens: 8192

Клиент вызывает POST /v1/chat/completions. localhost внутри контейнера означает сам контейнер, поэтому для отдельного сервера LLM укажите адрес, доступный из Docker-сети.

Диагностика

CUDA:

docker compose -f docker-compose.yml -f docker-compose.gpu.yml \
  run --rm --entrypoint python3 processor -c \
  "import torch; print(torch.cuda.is_available(), torch.version.cuda)"

WhisperX:

docker compose -f docker-compose.yml -f docker-compose.gpu.yml \
  run --rm --entrypoint python3 processor -c \
  "import whisperx; print('WhisperX imported')"

Тесты без GPU и реального Nextcloud:

python3 -m unittest discover -s tests -v

Журнал операций хранится в SQLite data/database/nextcloud_media.sqlite3, таблица operations.

Персистентные данные

  • data/automation — только небольшая синхронизируемая папка Automation;
  • data/database — SQLite и история операций;
  • data/work — временные загрузки, локальные копии артефактов, полные промпты и технические результаты;
  • data/models — кэш Hugging Face и Torch.

Каталога с локальным зеркалом записей нет.

Очистка временных файлов

При успешной обработке:

  • исходное медиа удаляется после загрузки недостающих remote-артефактов;
  • локальные JSON, parsed и SRT WhisperX удаляются;
  • долговечный *-whisperx.srt остаётся рядом с записью в Nextcloud;
  • после обогащения локально скачанные VTT/parsed/SRT удаляются.

Для диагностики можно задать:

runtime:
  transcribe:
    keep_source_copy: true
    keep_artifacts: true
  enrich:
    keep_artifacts: true

Эти параметры существенно увеличивают использование диска.

CPU-режим

Для диагностического запуска без NVIDIA не требуется редактировать Compose-файлы:

  1. запускайте команды через базовый docker-compose.yml (make run-once или make up);
  2. задайте device: cpu и compute_type: int8;
  3. уменьшите batch_size.

Для локальной NVIDIA используйте make run-once-gpu или make up-gpu.

Для регулярной обработки длинных записей CPU-режим обычно непрактичен.