Парсинг данных из LMS Odin по REST API в PostgreSQL с веб-интерфейсом, админкой и выгрузкой работ студентов через headless-браузер (Playwright).
git clone https://github.com/Zhidkov-Nikita/OdinWorker.git && cd OdinWorker
python3 -m venv venv
source venv/bin/activate # Linux
# venv\Scripts\activate # Windows
pip install -r requirements.txt
cp .env.example .env # отредактировать — указать токены
playwright install chromium # только для выгрузки работ
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver| Переменная | Обязательна | Назначение |
|---|---|---|
ODIN_BEARER_TOKEN |
для API | Bearer-токен для REST-запросов к Odin |
ODIN_AUTHORIZATIONSTORE |
для браузера | JSON с jwtToken для авторизации в SPA |
Один из двух токенов обязателен для выгрузки работ (Playwright), для парсинга
структуры достаточно ODIN_BEARER_TOKEN.
Стартовая страница доступна после входа в админку (/admin/).
Левая панель — формы запуска:
- Парсинг структуры — указывается один или несколько ID университетов
через пробел (по умолчанию
1). - Выгрузка работ — указывается ID активности и ID группы.
- Извлечение заданий из .pptx — парсит презентации, извлекает текст с последнего слайда.
- Выставление оценок — загружает CSV-файл (studentId, markValue) и отправляет оценки через REST API.
Правая панель — консоль: все логи выполнения команды выводятся в реальном
времени через StreamingHttpResponse.
- Зайти в
/admin/parser/university/ - Открыть свой университет —
idвиден в заголовке строки таблицы.
- Зайти в
/admin/parser/cohort/, открыть нужный поток. - Внизу отобразятся inline-группы —
idв первой колонке. - Либо сразу
/admin/parser/group/— таблица со всеми группами.
- Зайти в
/admin/parser/activity/. - Колонка
id— это ID активности, он же первый аргумент командdownload_activity_worksиset_marks_from_csv.
Сквозная навигация: от университета можно провалиться в дивизионы → программы → потоки → группы и дисциплины через inline-таблицы в админке.
python manage.py parse_odin_structure <university_id>Обходит иерархию:
University → Division → EducationalProgram → Cohort → Group → Discipline → Activity
python manage.py download_activity_works <activity_id> <group_id>Что делает:
- Открывает страницу активности в Chromium (headless).
- Прокручивает виртуальный список Quasar до стабилизации
scrollHeight. - Кликает по каждому студенту, ищет кнопку скачивания (SVG-иконка).
- Скачивает файл, вычисляет SHA-256, сохраняет в БД путь до файла.
- Ищет лекцию с таким же именем в том же потоке — скачивает презентации
через REST API (
Activity/Contents).
Условие повторного скачивания: если файл с таким хэшем уже есть — пропускается (кэширование по SHA-256). Если студент не прикрепил работу — пропускается.
python manage.py extract_pptx_tasksЧто делает:
- Берёт все записи
LecturePresentationиз БД. - Парсит
.pptxкак zip-архив (стандартная библиотекаzipfile+re). - Извлекает текст из тегов
<a:t>последнего слайда. - Сохраняет текст в поле
task.
python manage.py set_marks_from_csv <activity_id> <csv_path>CSV-файл — два столбца: studentId, markValue. Что делает:
- Читает строки из CSV.
- Для каждой строки отправляет POST-запрос на
/api/Mark/SetMarkForTask. - Логирует HTTP-ответ для каждого студента.
Формат CSV:
studentId,markValue
12345,85
12346,90
Файлы сохраняются в директорию:
media/solutions/<sha256>.ext
В базе данных (таблица StudentWork) хранятся:
student_id— ID студентаactivity— FK на активностьfile_hash— SHA-256local_path— путь к файлуsolution_url— полная ссылка на страницу решенияparsed_at— дата загрузки
Файлы сохраняются в директорию:
media/lections/<sha256>.ext
В базе данных (таблица LecturePresentation) хранятся:
activity— FK на активностьfile_path— URL из APIlocal_path— путь к файлу на дискеfile_hash— SHA-256task— текст задания с последнего слайда .pptxparsed_at— дата загрузки
| Модель | Поля | Связь |
|---|---|---|
| University | id, name, city_name, library_id | — |
| Division | id, name, short_name, type_of_string | FK → University |
| EducationalProgram | id, name, short_name, degree | FK → Division |
| Cohort | id, name, title, start/end_education_date | FK → EducationalProgram |
| Group | id, title, students_number | FK → Cohort |
| Discipline | id, name | FK → Cohort |
| Activity | id, name, type, type_id, start/end_date, duration | FK → Discipline |
| Student | id, first_name, last_name, middle_name | FK → Group |
| StudentWork | student_id, activity, file_hash, local_path, solution_url, parsed_at | — |
| LecturePresentation | activity, file_path, local_path, file_hash, task, parsed_at | FK → Activity |
Для выгрузки работ требуется установить Chromium:
playwright install chromiumdocker compose up --buildСервер будет доступен на http://localhost:8000. База данных PostgreSQL
и директория media/ (скачанные файлы) сохраняются в Docker volumes.