Metadata-Version: 2.4
Name: djops
Version: 1.7.1
Summary: DJ automation toolkit + CLI
Author: DJOps Team
License-Expression: MIT
Keywords: dj,music,automation,playlist,metadata
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: End Users/Desktop
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Sound/Audio
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mutagen<2.0,>=1.47.0
Requires-Dist: typer<1.0,>=0.12.0
Requires-Dist: rich<14.0,>=13.7.0
Requires-Dist: PyYAML<7.0,>=6.0.1
Requires-Dist: pydantic<3.0,>=2.7.0
Requires-Dist: defusedxml<1.0,>=0.7.1
Provides-Extra: analysis
Requires-Dist: librosa>=0.10.0; extra == "analysis"
Requires-Dist: essentia-tensorflow>=2.1b6.dev0; extra == "analysis"
Requires-Dist: numpy>=1.24.0; extra == "analysis"
Requires-Dist: scipy>=1.10.0; extra == "analysis"
Requires-Dist: audioop-lts>=0.2.1; python_version >= "3.13" and extra == "analysis"
Requires-Dist: standard-aifc>=3.13.0; python_version >= "3.13" and extra == "analysis"
Requires-Dist: standard-sunau>=3.13.0; python_version >= "3.13" and extra == "analysis"
Provides-Extra: fingerprinting
Requires-Dist: pyacoustid>=1.2.0; extra == "fingerprinting"
Provides-Extra: tracing
Requires-Dist: opentelemetry-api>=1.20.0; extra == "tracing"
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == "tracing"
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == "tracing"
Provides-Extra: cloud
Requires-Dist: boto3>=1.28.0; extra == "cloud"
Provides-Extra: ml
Requires-Dist: scikit-learn>=1.3.0; extra == "ml"
Requires-Dist: numpy>=1.24.0; extra == "ml"
Requires-Dist: scipy>=1.10.0; extra == "ml"
Provides-Extra: security
Requires-Dist: cryptography<48.0,>=41.0.0; extra == "security"
Provides-Extra: api
Requires-Dist: fastapi>=0.111.0; extra == "api"
Requires-Dist: uvicorn[standard]>=0.30.0; extra == "api"
Requires-Dist: python-jose[cryptography]>=3.3.0; extra == "api"
Requires-Dist: slowapi>=0.1.9; extra == "api"
Provides-Extra: dev
Requires-Dist: ruff>=0.7.0; extra == "dev"
Requires-Dist: black>=24.4.2; extra == "dev"
Requires-Dist: mypy>=1.10.0; extra == "dev"
Requires-Dist: types-PyYAML; extra == "dev"
Requires-Dist: types-python-jose; extra == "dev"
Requires-Dist: pytest>=8.2.0; extra == "dev"
Requires-Dist: pytest-cov>=6.0.0; extra == "dev"
Requires-Dist: pytest-mock>=3.12.0; extra == "dev"
Requires-Dist: pytest-xdist>=3.5.0; extra == "dev"
Requires-Dist: robotframework>=7.0.0; extra == "dev"
Requires-Dist: robotframework-requests>=0.9.0; extra == "dev"
Requires-Dist: pre-commit>=4.0.1; extra == "dev"
Requires-Dist: mkdocs>=1.6.0; extra == "dev"
Requires-Dist: mkdocs-material>=9.5.0; extra == "dev"
Requires-Dist: mkdocs-static-i18n>=1.2.0; extra == "dev"
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == "dev"
Requires-Dist: mkdocs-gen-files>=0.5.0; extra == "dev"
Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == "dev"
Requires-Dist: bandit[toml]>=1.7.0; extra == "dev"
Requires-Dist: safety>=2.0.0; extra == "dev"
Requires-Dist: pip-audit>=2.6.0; extra == "dev"
Requires-Dist: allure-pytest>=2.13.0; extra == "dev"
Requires-Dist: allure-robotframework>=2.13.0; extra == "dev"
Requires-Dist: pytest-bdd>=7.0.0; extra == "dev"
Requires-Dist: pytest-timeout>=2.2.0; extra == "dev"
Provides-Extra: test
Requires-Dist: pytest>=8.2.0; extra == "test"
Requires-Dist: pytest-cov>=6.0.0; extra == "test"
Requires-Dist: pytest-mock>=3.12.0; extra == "test"
Dynamic: license-file

# 🎧 DJOps

[![CI](https://github.com/mrbernardi/djOps/actions/workflows/ci.yml/badge.svg)](https://github.com/mrbernardi/djOps/actions/workflows/ci.yml)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![PyPI](https://img.shields.io/pypi/v/djops?color=blue)](https://pypi.org/project/djops/)
[![Codecov](https://codecov.io/gh/mrbernardi/djOps/branch/main/graph/badge.svg)](https://codecov.io/gh/mrbernardi/djOps)
[![Status](https://img.shields.io/badge/status-production%20ready-success)](TEST_STATUS_REPORT.md)

## 🛠️ Technologies

[![Python](https://img.shields.io/badge/Python-3.10+-3776AB?style=flat&logo=python&logoColor=white)](https://python.org)
[![Pydantic](https://img.shields.io/badge/Validation-Pydantic-E92063?style=flat&logo=pydantic&logoColor=white)](https://pydantic.dev)
[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?style=flat&logo=docker&logoColor=white)](https://docker.com)
[![Typer](https://img.shields.io/badge/CLI-Typer-009639?style=flat&logo=fastapi&logoColor=white)](https://typer.tiangolo.com)
[![Rich](https://img.shields.io/badge/UI-Rich-FF6B6B?style=flat&logo=python&logoColor=white)](https://rich.readthedocs.io)
[![pytest](https://img.shields.io/badge/Testing-pytest-0A9EDC?style=flat&logo=pytest&logoColor=white)](https://pytest.org)
[![Ruff](https://img.shields.io/badge/Code%20Quality-Ruff-FCC21B?style=flat&logo=ruff&logoColor=black)](https://docs.astral.sh/ruff)
[![MyPy](https://img.shields.io/badge/Type%20Check-MyPy-2A5ADA?style=flat&logo=python&logoColor=white)](https://mypy.readthedocs.io)

**DJOps** is a modern DevOps-inspired framework for DJs who need automation,
organization and professional workflows for music libraries.

## ✨ Features

### Core Features

- 🎵 **Playlist Management** - Type-safe playlists with Pydantic validation
- 📤 **Export/Import** - Rekordbox, VirtualDJ, Serato, Traktor, Engine DJ, Ableton Live, djay Pro (bidirectional)
- 🏷️ **DJ Metadata** - Complete Track model (BPM, key, energy, cue points, rating)
- 📁 **Library Organization** - Professional DJ folder structure
- 🔍 **Smart Path Resolution** - Automatic resolution of moved/renamed music files
- 💾 **Atomic Operations** - Corruption-proof file saves
- 🔒 **Security** - Path traversal protection, input sanitization
- 🖥️ **Rich CLI** - Beautiful `djops` interface with tables and colors
- 🧠 **Knowledge Graphs** - Mixing theory, dance styles, genre taxonomy with CRUD management
- ⚙️ **Custom Workflows** - User-defined YAML/JSON workflow automation

### Production Ready ✅

- ✅ **Exception Hierarchy** - Clear error messages for users and developers
- ✅ **Type Safety** - 100% type annotations, zero Pylance warnings
- ✅ **Atomic File Ops** - Safe writes with temp + atomic rename
- ✅ **Input Validation** - Runtime validation with Pydantic
- ✅ **Security Layer** - Protection against common attacks

### Phase 01 (Complete ✅)

- ✅ **BPM Detection** - Automatic tempo analysis with librosa + dry-run mode
- ✅ **Key Detection** - Musical key identification with Essentia + dry-run mode
- ✅ **Exception Hierarchy** - Clear error messages for users and developers
- ✅ **Type Safety** - 100% type annotations, zero Pylance warnings
- ✅ **Atomic File Ops** - Safe writes with temp + atomic rename
- ✅ **Input Validation** - Runtime validation with Pydantic
- ✅ **Security Layer** - Protection against common attacks

### Audio Analysis

- ✅ **BPM Detection** - Automatic tempo analysis with librosa + dry-run mode
- ✅ **Key Detection** - Musical key identification with Essentia + dry-run mode
- ✅ **Audio Analysis** - Waveform generation and beat grid
- ✅ **Audio Quality** - LUFS loudness, peak detection, dynamic range, bitrate validation, artwork check
- ✅ **Volume Normalization** - ReplayGain tag writing with configurable target LUFS
- ✅ **Dependency Management** - Easy setup for analysis libraries

### Export & Import

- ✅ **Rekordbox** - XML format with bidirectional import/export
- ✅ **VirtualDJ** - XML format with bidirectional import/export (98% coverage)
- ✅ **Serato** - Binary .crate format with bidirectional import/export (90% coverage)
- ✅ **Traktor** - NML XML format with bidirectional import/export (86% coverage)
- ✅ **Engine DJ** - SQLite database with bidirectional import/export (83% coverage)
- ✅ **Ableton Live** - Gzipped XML (.als) export with AudioClip arrangement
- ✅ **djay Pro** - SQLite database with bidirectional import/export for mobile sync
- ✅ **Path Translation** - Cross-platform path conversion for all formats
- ✅ **Smart Path Resolution** - Automatic resolution of moved/renamed files

### Playlist Features

- ✅ **Smart Playlist Generation** - Harmonic mixing with Camelot Wheel
- ✅ **Playlist Analysis** - Quality scoring and transition analysis
- ✅ **Advanced Filtering** - Multi-criteria playlist filtering
- ✅ **Playlist Templates** - Pre-configured templates (warmup, peak, cooldown, balanced)
- ✅ **Play History** - Persistent play count and last played tracking
- ✅ **Smart Auto-Update** - Re-apply smart configs against current library state

### DJ Software Config Management

- ✅ **Config Export/Import** - Export/import DJ software configs to normalized JSON
- ✅ **Cross-Software Migration** - Migrate configs between VirtualDJ, Rekordbox, Serato, Traktor
- ✅ **Backup & Restore** - Timestamped zip backups with one-click restore
- ✅ **Config Diff** - Compare two DJ software configurations side by side

### Generic Exports

- ✅ **M3U/M3U8** - Universal playlist format
- ✅ **CSV** - Spreadsheet format
- ✅ **JSON** - Structured data format
- ✅ **Excel** - Microsoft Excel format

## Quick Start

```bash
# Install with analysis dependencies

pip install -e ".[analysis]"

# Create DJ library structure

djops library setup /path/to/dj_music

# Detect BPM from audio file

djops analysis bpm song.mp3

# Detect musical key

djops analysis key song.mp3

# Batch BPM detection with tag writing

djops analysis bpm /path/to/music --batch --write

# Preview before writing (dry-run)

djops analysis bpm /path/to/music --batch --write --dry-run

# Batch key detection with compatible keys

djops analysis key /path/to/music --batch --show-compatible --write

# Create a playlist from folder

djops playlist load /path/to/music --output my_playlist.json

# Show playlist contents

djops playlist show my_playlist.json

# Verify playlist integrity (check for missing files)

djops playlist verify my_playlist.json

# Auto-fix broken paths in playlist

djops playlist update-paths my_playlist.json --scan-folders /music1 /music2

# Interactive missing file resolution

djops playlist fix-missing my_playlist.json

# Export playlist to VirtualDJ with auto-resolution

djops export virtualdj my_playlist.json --auto-resolve-paths --scan-folders /music1 /music2

# Export playlist to Rekordbox with auto-resolution

djops export rekordbox my_playlist.json --auto-resolve-paths --scan-folders /music1 /music2

# Configure default scan folders (one-time setup)

djops config set-scan-folders --folder /music1 --folder /music2

# Export with path translation (Linux to Windows)

djops export rekordbox playlist.json --replace-path "/home/user/music:D:/Music"

# Advanced playlist analysis

djops analysis playlist full my_set.json
djops analysis playlist energy my_set.json
djops analysis playlist harmony my_set.json

# Cue point management

djops cuepoint list my_playlist.json
djops cuepoint template my_playlist.json --template intro-outro
```

## DJ Library Structure

DJOps creates a professional DJ folder structure:

```text
dj_music/
├── 00_staging/              # New downloads before tagging
├── 01_masters/              # Fully tagged, final library
│   ├── brazilian/           # Brazilian music styles
│   │   ├── samba/
│   │   ├── forro/
│   │   ├── bolero/
│   │   ├── sertanejo/
│   │   └── zouk/
│   ├── latin/               # Latin music styles
│   │   ├── salsa/
│   │   ├── bachata/
│   │   └── merengue/
│   └── international/       # International styles
│       ├── kizomba/
│       ├── tango/
│       └── swing/
├── 02_edits/                # Custom edits, remixes, mashups
└── 03_sets/                 # Saved sets, warmups, event sets
```

## Filename Convention

DJOps uses a standardized naming convention:

```text
artist_title_style_bpm_key_version.mp3
```

**Example:**

```text
Carlos_Vives_La_Tierra_Del_Olvido_salsa_98_Am_original.mp3
```

## Commands

### Playlist Operations

```bash
djops playlist create "My Mix"           # Create empty playlist
djops playlist load /music --output mix.json  # Load from folder
djops playlist show mix.json             # Display playlist
```

### Smart Playlists

```bash
djops playlist smart filter in.json out.json --bpm-min 120 --bpm-max 140
djops playlist smart sort in.json out.json --by bpm --by energy_level
djops playlist smart apply in.json config.json out.json
djops playlist smart update config.json /music out.json  # Auto-update from library
```

### Play History

```bash
djops playlist history record my_set.json          # Record plays for all tracks
djops playlist history record my_set.json --track 3 # Record play for track #3
djops playlist history record my_set.json --context "Club XYZ Friday" # With venue context
djops playlist history show my_set.json             # Show play stats per track
djops playlist history show                         # Show global play summary
```

### Core Deck

```bash
djops playlist core create library.json              # Create core deck (top 200 tracks)
djops playlist core create library.json --max-tracks 100 --min-rating 4
djops playlist core update library.json              # Refresh from latest plays/ratings
djops playlist core show                             # Display core deck
```

### Library Operations

```bash
djops library setup /dj_music           # Create folder structure
djops library scan /music               # Scan library
djops library stats /music              # Library statistics
djops library validate /music           # Validate filenames
djops library rename song.mp3           # Rename to DJ convention
djops library move song.mp3             # Move to genre folder
djops library organize /music           # Auto-organize files
djops library clean /music --duplicates # Find duplicates
djops library clean /music --broken     # Find broken files
djops library clean /music --duplicates --prefer-lossless  # Keep FLAC over MP3
djops library clean /music --broken --quarantine /bad_files # Move broken to quarantine
djops library ingest /staging /masters --write  # Ingest with auto-analysis
djops library backup /music --output /backup    # Incremental local backup
djops library backup /music --cloud s3://bucket # Cloud backup
djops library export-prepared set.json -o /usb -f rekordbox  # Gig-ready export
```

### Metadata Management

```bash
djops metadata read song.mp3             # Display all tags
djops metadata read song.mp3 --json      # Output as JSON
djops metadata write song.mp3 --json '{"bpm": 128, "key": "8A"}'
djops metadata batch-update /music --json updates.json --recursive
djops metadata export /music --format csv --output library.csv
```

### Audio Quality Analysis

```bash
djops analysis quality check song.mp3              # Single file quality report
djops analysis quality check song.mp3 --json       # JSON output
djops analysis quality check /music --batch         # Batch quality report
djops analysis quality check /music --batch --min-bitrate 256

# Volume normalization
djops analysis normalize check song.mp3              # Measure LUFS
djops analysis normalize check song.mp3 --write      # Write ReplayGain tags
djops analysis normalize check /music --batch --write # Batch normalize
djops analysis normalize check /music --batch --write --target-lufs -16

# Waveform analysis
djops analysis waveform analyze song.mp3             # Generate waveform + beat grid
djops analysis waveform analyze song.mp3 -o wf.json  # Save to JSON
```

### Auto Detection (Energy, Mood, Cue Points)

```bash
# Auto-detect energy level and mood from audio
djops analysis energy song.mp3           # Returns energy 1-5 + mood
djops analysis mood song.mp3             # Returns mood classification

# Auto-detect cue points (intro/drop/outro)
djops analysis cues song.mp3             # Detect structural cue points

# Stem separation (requires demucs)
djops analysis stems song.mp3 -o stems/  # Separate vocals/drums/bass/other
```

### Venue & Event Tracking

```bash
djops venue add "Club XYZ" --city "São Paulo" --capacity 500 --genre house
djops venue list                         # List all venues
djops venue gig "Club XYZ" --date 2026-04-03 --set friday_set --tracks 25
djops venue history "Club XYZ"           # Show gig history
djops venue history                      # Show all gigs
```

### Playlist Sync (Round-Trip)

```bash
# Sync between DJ software formats
djops playlist sync rekordbox library.xml virtualdj output.xml
djops playlist sync serato crate.crate traktor output.nml
```

### Set Building & Analysis

```bash
djops set analyze my_set.json            # Full set analysis
djops set energy my_set.json             # Energy flow analysis
djops set harmony my_set.json            # Harmonic mixing analysis
djops set create tracks.json --duration 60 --profile warmup
djops set optimize my_set.json           # Optimization suggestions
```

### Workflow Automation

```bash
djops workflow list                      # List available workflows
djops workflow run batch-bpm /music      # Batch BPM detection
djops workflow run batch-key /music      # Batch key detection
djops workflow run cleanup /music --dry-run  # Library cleanup
djops workflow run organize /music --dry-run # Auto-organize by genre
djops workflow run prepare-set set.json --duration 60 --profile peak
djops workflow run my-workflow.yaml /music   # Run custom workflow
djops workflow validate my-workflow.yaml     # Validate custom workflow
djops workflow status /music             # Library health report
```

### Knowledge Graph

```bash
djops knowledge version                  # Graph stats
djops knowledge validate                 # Integrity check
djops knowledge mixing query --from-key 8A  # Compatible keys
djops knowledge mixing path --from-key 8A --to-key 11B  # Key path
djops knowledge dance info salsa         # Dance style info
djops knowledge genre tree               # Genre taxonomy
djops knowledge manage health            # Full health report
djops knowledge manage fix               # Auto-fix issues
djops knowledge manage export -o graph.json  # Export graph
djops knowledge manage import graph.json     # Rebuild from JSON
djops knowledge manage add-genre --name cumbia --display Cumbia
djops knowledge manage reset --yes       # Reset to defaults
djops knowledge serve                    # Interactive graph visualization
djops knowledge serve --build-only       # Generate static site only
```

### Export & Import

```bash
djops export rekordbox playlist.json -o library.xml
djops export virtualdj playlist.json -o playlist.xml
djops export serato playlist.json -o playlist.crate
djops export traktor playlist.json -o collection.nml
djops export enginedj playlist.json -o engine.db
djops export ableton playlist.json -o set.als
djops export djay playlist.json -o library.djaydb
djops export m3u playlist.json -o playlist.m3u
djops export csv playlist.json -o library.csv
djops export json playlist.json -o library.json
djops export excel playlist.json -o library.xlsx
djops import rekordbox library.xml
djops import virtualdj playlist.xml
djops import serato playlist.crate
djops import traktor collection.nml
djops import enginedj engine.db
```

### Cue Point Management

```bash
djops cuepoint list my_playlist.json
djops cuepoint copy source.json target.json
djops cuepoint template my_playlist.json --template intro-outro
djops cuepoint clear my_playlist.json
```

### DJ Software Config Management

```bash
djops config djsoftware export virtualdj           # Export VirtualDJ config to JSON
djops config djsoftware export rekordbox -o rb.json # Export Rekordbox config
djops config djsoftware import virtualdj config.json # View imported config
djops config djsoftware migrate source.json --to rekordbox -o migrated.json
djops config djsoftware backup virtualdj            # Zip backup of config dir
djops config djsoftware restore backup.zip          # Restore from backup
djops config djsoftware diff config1.json config2.json  # Compare two configs
```

### Testing & Reports

```bash
djops test pytest                    # Run pytest with all reports
djops test robot                     # Run Robot Framework acceptance tests
djops test bdd                       # Run BDD/Gherkin scenarios
djops test all                       # Run everything (pytest + Robot)
djops test clean                     # Clean all report directories
djops test serve                     # Serve reports dashboard at http://localhost:8083
djops test serve --build-only        # Generate dashboard HTML only
```

## Development Setup

### Prerequisites

- Python 3.10+
- Git
- Docker (Docker Desktop or native Docker in WSL2)
- VS Code with Dev Containers extension

### DevContainer (Recommended)

The easiest way to get started:

```bash
# Clone repository

git clone <repository-url>
cd djOps

# Open in VS Code - DevContainer will auto-setup

code .
```

The DevContainer automatically:

- Detects your user ID/permissions for any workstation
- Sets up Python environment with all dependencies
- Configures development tools and extensions
- Starts Docker documentation server at <http://localhost:8081> or <http://localhost/djops/>
- Works on Linux, Windows WSL2, and macOS

**Manual Documentation Server** (if auto-start fails):

- Use VS Code Command Palette: `Tasks: Run Task` → `Start Documentation Server`

**For Windows WSL2**: See [DevContainer WSL2 Setup](docs/developer/guide/wsl2-setup.md)

### Script Options

All setup scripts support dry-run and help options:

```bash
# Preview what setup will do

./scripts/dev/setup-dev.sh --dry-run

# Generate documentation and restart Docker server

./scripts/docs/generate-docs.sh --deploy

# Show help for any script

./scripts/dev/setup-dev.sh --help
./scripts/docs/generate-docs.sh --help
./.devcontainer/devcontainer-setup-dev.sh --help
```

### Local Development

```bash
# Clone repository

git clone <repository-url>
cd djOps

# Create virtual environment

python -m venv .venv
source .venv/bin/activate  # Linux/Mac
# or .venv\Scripts\activate  # Windows

# Install development dependencies

pip install -e ".[dev]"

# Install pre-commit hooks

pre-commit install

# Run tests

pytest tests/

# Run code quality checks

ruff check src/ tests/
mypy src/
```

### Multi-Environment Testing

```bash
# Test across Python versions

tox

# Run specific environment

tox -e py312
tox -e lint
tox -e type-check
```

## Documentation

📚 **[Complete Documentation](docs/index.md)** - Full project documentation index

📋 **[Requirements & Roadmap](docs/project/requirements/README.md)** - Detailed requirements and development roadmap

✅ **[Development TODO List](docs/project/requirements/TODO.md)** - Prioritized roadmap with 200+ items, timelines, and goals

🔮 **[Next Phases (15–19)](docs/project/requirements/requirements-next-phases.md)** - PyPI publishing, CI/CD hardening, streaming integrations, plugin marketplace, AI/ML analysis

🏗️ **[Architecture](docs/developer/architecture/README.md)** - System architecture and design decisions

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run tests: `make test`
5. Submit a pull request

## License

MIT License - see [LICENSE](LICENSE) file.
