Skip to content

Development Guide

This guide covers how to set up a development environment and contribute to Video Vault.

Development Setup

Requirements

  • Python 3.12 or 3.13
  • uv package manager
  • Git

Clone the Repository

git clone <repository-url>
cd video-vault

Install Dependencies

# Install all dependencies including dev dependencies
uv sync

Run in Development Mode

# Run the application
uv run video-vault

# Or run directly with Python
uv run python -m video_vault.main

Project Structure

video-vault/
├── video_vault/           # Main package
│   ├── main.py           # Application entry point
│   └── src/              # Source code
│       ├── core/         # Core business logic
│       │   ├── downloads.py    # Download functionality
│       │   ├── security.py     # Encryption/keyring
│       │   ├── ffmpeg.py       # FFmpeg integration
│       │   └── consts.py       # Constants
│       ├── db/           # Database layer
│       │   ├── models.py       # Django models
│       │   ├── setup.py        # Django configuration
│       │   └── migrations/     # Database migrations
│       └── ui/           # User interface
│           ├── stylesheet.py   # Global styles
│           ├── windows/        # Main window
│           └── pages/          # UI pages
│               ├── downloads.py      # Downloads page
│               ├── add_downloads.py  # Browser page
│               └── player.py         # Player page
├── tests/                # Test suite
├── docs/                 # Documentation
└── pyproject.toml        # Project configuration

Key Technologies

UI Framework

  • PySide6: Qt for Python - provides the UI framework
  • winipyside: Custom framework built on PySide6 for page-based navigation

Video Processing

  • yt-dlp: Downloads videos from various platforms
  • FFmpeg: Video format conversion (bundled via imageio-ffmpeg)

Database

  • Django ORM: Database abstraction layer
  • SQLite: Local database storage
  • winidjango: Custom Django utilities

Security

  • cryptography: AES-GCM encryption
  • keyring: Secure key storage in system keyring

Development Tasks

Running Tests

# Run all tests
uv run pytest

# Run specific test file
uv run pytest tests/test_video_vault/test_main.py

# Run with coverage
uv run pytest --cov=video_vault

Code Quality

# Run linter
uv run ruff check .

# Auto-fix linting issues
uv run ruff check --fix .

# Run type checker
uv run mypy .

# Run security checks
uv run bandit -r video_vault/

Database Migrations

When you modify models in video_vault/src/db/models.py:

# Create new migration
uv run python video_vault/src/db/make_migrations.py

# Migrations are automatically applied on app startup

Pre-commit Hooks

# Install pre-commit hooks
uv run pre-commit install

# Run hooks manually
uv run pre-commit run --all-files

Architecture Overview

Application Flow

  1. Startup (main.py):
  2. Initialize Django and database
  3. Create Qt application
  4. Apply global stylesheet
  5. Show main window

  6. Main Window (ui/windows/main.py):

  7. Discovers all page classes
  8. Sets up page navigation
  9. Shows Downloads page by default

  10. Page Lifecycle:

  11. pre_setup(): Initialize UI components
  12. setup(): Configure layout and widgets
  13. post_setup(): Final setup and connections

Download Workflow

  1. User clicks download button in browser page
  2. DownloadWorker thread spawns
  3. yt-dlp downloads video to temp directory
  4. FFmpeg converts to MP4 format
  5. Video is encrypted with AES-GCM
  6. Encrypted file saved to media directory
  7. Database record created
  8. UI updated with new video

Encryption Flow

  1. Key Management:
  2. Key stored in system keyring
  3. Retrieved via get_or_create_app_aes_gcm()
  4. Same key used for all videos

  5. Encryption (during download):

  6. Read unencrypted video data
  7. Encrypt with EncryptedPyQFile.encrypt_data_static()
  8. Save encrypted data to disk

  9. Decryption (during playback):

  10. EncryptedPyQFile QIODevice wraps encrypted file
  11. Decrypts data on-the-fly as player reads
  12. No unencrypted data written to disk

Contributing

Code Style

  • Follow PEP 8 guidelines
  • Use Google-style docstrings
  • Type hints required for all functions
  • Maximum line length: 88 characters (Ruff default)

Commit Messages

Use conventional commit format:

feat: add new feature
fix: fix bug
docs: update documentation
test: add tests
refactor: refactor code

Pull Request Process

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests and linting
  5. Submit a pull request

Building for Distribution

Create Executable

# Build with PyInstaller
uv run pyinstaller video_vault.spec

The executable will be in the dist/ directory.

Troubleshooting Development Issues

Qt/PySide6 Issues

If you encounter Qt-related errors:

# Reinstall PySide6
uv pip install --force-reinstall PySide6

Database Issues

If database migrations fail:

# Delete database and start fresh
rm -rf ~/.local/share/VideoVault/db/

Import Errors

Ensure you're running commands with uv run to use the correct virtual environment.