Metadata-Version: 2.4
Name: track-id
Version: 0.2.0
Summary: CLI for downloading, searching, and enriching MP3 metadata via Soulseek, Bandcamp, MusicBrainz, and Discogs
Project-URL: Homepage, https://github.com/vtasca/track-id
Project-URL: Repository, https://github.com/vtasca/track-id
Project-URL: Issues, https://github.com/vtasca/track-id/issues
Author: track-id contributors
License: MIT License
        
        Copyright (c) 2026 track-id contributors
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: bandcamp,cli,discogs,id3,metadata,mp3,music,musicbrainz
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
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
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Requires-Dist: aioslsk>=1.5.0
Requires-Dist: mutagen>=1.47.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: requests>=2.32.4
Requires-Dist: rich>=13.0.0
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
Requires-Dist: typer>=0.16.0
Requires-Dist: urllib3<2.0.0
Description-Content-Type: text/markdown

# track-id
[![Package Validation](https://github.com/vtasca/track-id/actions/workflows/package-validation.yml/badge.svg)](https://github.com/vtasca/track-id/actions/workflows/package-validation.yml) [![Publish PyPI](https://github.com/vtasca/track-id/actions/workflows/publish-pypi.yml/badge.svg)](https://github.com/vtasca/track-id/actions/workflows/publish-pypi.yml) [![PyPI version](https://img.shields.io/pypi/v/track-id.svg)](https://pypi.org/project/track-id/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/vtasca/track-id/blob/main/LICENSE)

A Python CLI tool for music metadata enrichment, search, and download. Searches and downloads tracks from Soulseek, displays MP3 file info, and enriches MP3 files with metadata from Bandcamp, MusicBrainz, and Discogs.

## Features

- **Download**: Search Soulseek for a track and download the best match, with automatic metadata enrichment
- **Search**: Search for tracks across Bandcamp, MusicBrainz, and Discogs
- **Info**: Display detailed information about an MP3 file including all ID3 tags
- **Enrich**: Automatically populate an MP3 file's metadata (artist, album, genre, label, styles, track number, artwork, etc.) from Bandcamp, MusicBrainz, and Discogs

## Installation

### Using uv

Install from PyPI as a tool:
```bash
uv tool install track-id
track-id --version
track-id search "Chaos In The CBD"
```

### Using pip

Install from PyPI with pip:
```bash
pip install track-id
track-id --version
track-id search "Chaos In The CBD"
track-id info "path/to/your/file.mp3"
track-id enrich "path/to/your/file.mp3"
```

### Clone and install locally

Mainly for development purposes:
```bash
# Clone the repository
git clone https://github.com/vtasca/track-id
cd track-id

# Install dependencies
uv sync
```

## Usage

### Download a track from Soulseek

Searches the Soulseek network, ranks candidates by bitrate and filename match, downloads the best result, and automatically enriches the file with metadata from Bandcamp, MusicBrainz, and Discogs:

```bash
track-id download "Aphex Twin - Windowlicker"
track-id download "Burial - Archangel" --output-dir ~/Music
track-id download "DJ Krush - Ha Doh" --min-bitrate 320 --timeout 20
```

Files are saved to `downloads/` by default. Credentials are required — set them once:

```bash
# Option 1: .env file in the project root (copy from .env.example)
cp .env.example .env  # then fill in your username and password

# Option 2: environment variables
export SOULSEEK_USERNAME=your_username
export SOULSEEK_PASSWORD=your_password

# Option 3: ~/.config/track-id/config.toml
# [soulseek]
# username = "your_username"
# password = "your_password"
```

A free Soulseek account can be created at [slsknet.org](https://www.slsknet.org/news/node/1).

Available options:

| Flag | Default | Description |
|---|---|---|
| `--output-dir` / `-o` | `downloads/` | Directory to save the file |
| `--min-bitrate` | `192` | Minimum acceptable bitrate in kbps |
| `--timeout` / `-T` | `10.0` | Seconds to collect search results |
| `--attempts` | `5` | Max download attempts before giving up |
| `--no-enrich` | — | Skip metadata enrichment after download |

### Search for tracks

Search across Bandcamp, MusicBrainz, and Discogs simultaneously:

```bash
track-id search "Chaos In The CBD"
track-id search "Burial - Archangel" --top 5
```

The `--top` / `-t` flag controls how many results are shown per source (default: 3).

### Display MP3 file information

```bash
track-id info "path/to/your/file.mp3"
```

### Enrich an MP3 file with metadata

Queries Bandcamp, MusicBrainz, and Discogs for a matching track and writes the retrieved metadata directly into the file's ID3 tags:

```bash
track-id enrich "path/to/your/file.mp3"
```

The file must have either existing `Artist` and `Title` ID3 tags, or an `Artist - Title` filename so the tool knows what to search for. All three sources are tried and their results merged — existing tags are never overwritten.

Tags populated across sources include: `Title`, `Artist`, `Album Artist`, `Album`, `Year`, `Track Number`, `Genre`, `Publisher/Label`, `Style` (Discogs community tags), `Artwork`, and a `Discogs URL` reference.

## Development

### Setting up the development environment

```bash
uv sync --dev
```

### Running tests

```bash
# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=track_id --cov-report=term-missing

# Run a specific file
uv run pytest tests/test_data_sources.py -v
```

## Project Structure

```
track-id/
├── track_id/
│   ├── track_id.py           # CLI commands (Typer app)
│   ├── unified_api.py        # Orchestrates search/enrich across all sources
│   ├── data_sources.py       # Abstract base class + registry
│   ├── bandcamp_api.py       # Bandcamp data source
│   ├── musicbrainz_api.py    # MusicBrainz data source
│   ├── discogs_api.py        # Discogs data source
│   ├── enrichment_handlers.py# Shared enrichment logic
│   ├── soulseek_downloader.py# Soulseek download via aioslsk
│   ├── config.py             # Credential loading (.env / env vars / config file)
│   ├── mp3_utils.py          # MP3File class — ID3 read/write, filename parsing
│   ├── display.py            # Rich console output
│   ├── id3_tags.py           # Canonical ID3 tag name mapping
│   └── __init__.py
├── tests/
│   ├── conftest.py
│   ├── test_data_sources.py
│   ├── test_bandcamp_api.py
│   ├── test_musicbrainz_api.py
│   ├── test_discogs_api.py
│   ├── test_soulseek_downloader.py
│   ├── test_config.py
│   ├── test_artwork.py
│   ├── test_id3_tags.py
│   ├── test_track_id.py
│   └── test_integration.py
├── .env.example              # Credential template
├── pyproject.toml
└── README.md
```

## Contributing

1. Write tests for new features
2. Ensure all tests pass
3. Follow the existing code style
4. Update documentation as needed
