Sync your music library to a classic iPod from a modern Mac
Project description
clickwheel
A CLI for syncing a music library to a classic iPod from a modern Mac — no iTunes required.
Handles the full workflow: scan and clean up your library's metadata, interactively pick what goes on the iPod, and sync with a progress bar.
Install
pipx install clickwheel
To use clickwheel fix (metadata cleanup, album art, genre tagging):
pipx inject clickwheel 'clickwheel[fix]'
Quick Start
Create a config file pointing to your music library:
mkdir -p ~/.clickwheel
cat > ~/.clickwheel/config.yaml << 'EOF'
music_dir: /path/to/your/music
EOF
Then run clickwheel scan to index your library and clickwheel select to start picking music for your iPod.
Commands like select, edit, diff, and sync automatically check for library changes before running. To skip this, pass --no-scan.
Commands
| Command | Description |
|---|---|
clickwheel scan |
Index your music library and report on metadata quality |
clickwheel fix |
Clean up metadata, fetch album art, fill genres via beets |
clickwheel select |
Interactive picker — browse by artist/album/genre |
clickwheel playlist |
List saved playlists or show details for one |
clickwheel edit |
Add or remove artists from a playlist (interactive or via --add/--remove) |
clickwheel delete |
Delete a saved playlist |
clickwheel diff |
Preview what would be added or removed on the iPod |
clickwheel sync |
Push your playlist to the iPod |
clickwheel ls |
Show what's on the iPod |
clickwheel eject |
Safely unmount the iPod |
clickwheel scrobble |
Submit recent iPod listens to Last.fm |
Configuration
clickwheel reads from ~/.clickwheel/config.yaml:
music_dir: /Volumes/Music/Library
ipod_capacity_gb: 64 # defaults to 64
auto_scan: true # auto-check for library changes (default: true)
auto_scan_staleness_minutes: 30 # how often to re-check (default: 30)
lastfm_api_key: your_key # last.fm/api/account/create
lastfm_api_secret: your_secret
lastfm_username: your_username
Environment variables (MUSIC_DIR, AUTO_SCAN, etc.) override the config file.
Metadata cleanup (fix)
clickwheel fix uses beets to fetch album art, fill genres, and clean up tags. Install the extras first:
# If installed with pipx:
pipx inject clickwheel 'clickwheel[fix]'
# If installed with pip:
pip install 'clickwheel[fix]'
On first run, clickwheel generates a beets config at ~/.clickwheel/beets/config.yaml. You can edit it to customize sources, matching thresholds, etc. The config is set up to never move or rename your files.
Fix a single artist/album folder:
clickwheel fix "Artist - Album Name"
Or fix the entire library:
clickwheel fix
Last.fm scrobbling
To submit your iPod listens to Last.fm, add your API credentials to the config (get them at last.fm/api/account/create):
lastfm_api_key: your_key
lastfm_api_secret: your_secret
lastfm_username: your_username
Then authorize clickwheel with your Last.fm account (one-time):
clickwheel scrobble --auth
After that, submit listens any time your iPod is connected:
clickwheel scrobble
Scrobbles are cached locally so duplicates are never submitted, even if you run it multiple times.
Requirements
- macOS (iPod sync depends on macOS disk utilities)
- Python 3.11+
- iPod Classic with stock firmware, connected via USB
- FLAC files are excluded from sync (stock firmware limitation)
Contributing
See CONTRIBUTING.md for dev setup, testing, and commit conventions.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file clickwheel-0.4.0.tar.gz.
File metadata
- Download URL: clickwheel-0.4.0.tar.gz
- Upload date:
- Size: 547.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
574f1c0668cebd0aa369e879df75f8e11483a59200b471d12f5bb308ca59032e
|
|
| MD5 |
d06fa441918c87d102c5989314bfb4ac
|
|
| BLAKE2b-256 |
d715900305fe805e4e89619406402292ab9dd1d5d35455531cdc508c334029e3
|
Provenance
The following attestation bundles were made for clickwheel-0.4.0.tar.gz:
Publisher:
publish.yml on pdugan20/clickwheel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
clickwheel-0.4.0.tar.gz -
Subject digest:
574f1c0668cebd0aa369e879df75f8e11483a59200b471d12f5bb308ca59032e - Sigstore transparency entry: 1111151717
- Sigstore integration time:
-
Permalink:
pdugan20/clickwheel@666c3fa94bc95d006a6bdb6f41c41ba84efcd776 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/pdugan20
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@666c3fa94bc95d006a6bdb6f41c41ba84efcd776 -
Trigger Event:
push
-
Statement type:
File details
Details for the file clickwheel-0.4.0-py3-none-any.whl.
File metadata
- Download URL: clickwheel-0.4.0-py3-none-any.whl
- Upload date:
- Size: 550.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e43936ef877f095539ccf9c764f741398706590642128a1d7dbd07b60d30c40
|
|
| MD5 |
6f138f0e8e0b0083f57abe6b3e03fdcd
|
|
| BLAKE2b-256 |
0ca985a69407546a4fc5fa1a77b01797394b4ff843f5d89f4ece159d861730fc
|
Provenance
The following attestation bundles were made for clickwheel-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on pdugan20/clickwheel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
clickwheel-0.4.0-py3-none-any.whl -
Subject digest:
9e43936ef877f095539ccf9c764f741398706590642128a1d7dbd07b60d30c40 - Sigstore transparency entry: 1111151720
- Sigstore integration time:
-
Permalink:
pdugan20/clickwheel@666c3fa94bc95d006a6bdb6f41c41ba84efcd776 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/pdugan20
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@666c3fa94bc95d006a6bdb6f41c41ba84efcd776 -
Trigger Event:
push
-
Statement type: