Document three ways to get the dependencies since Debian's system pip is locked down (PEP 668 externally-managed-environment): pip, apt (no pip), or a venv, with the note that `python3 -m lintunes.main` runs the app without pip or the `lintunes` command at all. Make the second-machine steps install-agnostic and add the app screenshot. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
151 lines
5.8 KiB
Markdown
151 lines
5.8 KiB
Markdown
# LinTunes
|
||
|
||

|
||
|
||
an mp3 library manager and player for linux. Absolutely no guarantees, if it wrecks your itunes library or wipes your
|
||
harddrive that's on you (maybe just have your LLM of choice review the
|
||
software for bugs and vulns?).
|
||
|
||
## Features
|
||
|
||
- can import an iTunes 12 (untested on other versions) library, including
|
||
smart playlists (auto-updating, editable, marked with a ❧)
|
||
- runs on several machines off one Syncthing-synced library (see below)
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
## How it works
|
||
|
||
- Your music files are never moved or rewritten (except when you edit tags).
|
||
- The library lives as **plain JSON files** (`library.json` + one file per
|
||
playlist) in a directory you choose — designed to be synced with
|
||
[Syncthing](https://syncthing.net); sync conflicts are merged automatically
|
||
on startup (play counts take the max, edits take the newest, playlists
|
||
take the union).
|
||
- Playback via Qt Multimedia/FFmpeg (mp3, m4a, flac). Media keys work
|
||
through MPRIS. Scrobbling to last.fm is optional (Edit → Preferences).
|
||
|
||
|
||
## Why
|
||
|
||
I have been a mac user for ~34 years. I gave up daily driving mac os in 2020. I figured Apple
|
||
|
||
but my music library
|
||
even some tracks I got from napster all the way back in 2000 (I have since
|
||
paid for!!)
|
||
|
||
|
||
## Installing
|
||
|
||
LinTunes needs four Python packages — **PyQt6** (with its QtMultimedia module),
|
||
**mutagen**, **numpy**, **requests** — plus the **FFmpeg codecs** for Qt
|
||
Multimedia so audio actually plays. Nothing compiles; get the deps whichever way
|
||
fits your distro:
|
||
|
||
- **pip** — simplest where your distro allows it; also puts a `lintunes` command
|
||
in `~/.local/bin`:
|
||
```sh
|
||
pip install -e .
|
||
```
|
||
- **Debian/Ubuntu** — system pip is locked down (the `externally-managed-environment`
|
||
/ PEP 668 error), so install the deps from apt and skip pip entirely:
|
||
```sh
|
||
sudo apt install python3-pyqt6 python3-pyqt6.qtmultimedia \
|
||
python3-mutagen python3-numpy python3-requests
|
||
```
|
||
(If `python3-pyqt6.qtmultimedia` isn't found, `apt search python3-pyqt6` and
|
||
grab the multimedia one.) There's no `lintunes` command this way — run it with
|
||
`python3 -m lintunes.main`.
|
||
- **venv** — isolated:
|
||
```sh
|
||
python3 -m venv .venv && .venv/bin/pip install -e .
|
||
```
|
||
Run with `.venv/bin/lintunes`. One caveat: the dock launcher (see *App icon*)
|
||
uses the *system* python, which can't see a venv's packages — so for the icon
|
||
to work, edit the installed `lintunes.desktop`'s `Exec=` line to the absolute
|
||
venv path (`…/lintunes/.venv/bin/lintunes %F`).
|
||
|
||
**You never strictly need pip or the `lintunes` command.** As long as those four
|
||
deps import, `python3 -m lintunes.main` from the checkout runs the app — which is
|
||
exactly what the desktop launcher does. The FFmpeg codecs come from
|
||
`qt6-qtmultimedia` built with ffmpeg (Fedora: RPM Fusion; Debian/Ubuntu: pulled in
|
||
by `python3-pyqt6.qtmultimedia`). Without them the UI runs but tracks won't play.
|
||
|
||
## Running it
|
||
|
||
```sh
|
||
# one-time import from iTunes (XML: File ▸ Library ▸ Export Library in iTunes 12.x)
|
||
python3 -m lintunes.main --import-xml "iTunes Library.xml" \
|
||
--music-root "/path/to/iTunes Media" \
|
||
--data-dir /path/to/library-data --save-config
|
||
python3 -m lintunes.main # run the app (uses the saved config)
|
||
```
|
||
|
||
(Installed with pip? Type `lintunes` instead of `python3 -m lintunes.main`.)
|
||
|
||
LinTunes looks best with **Century Gothic** installed (`~/.local/share/fonts/`);
|
||
if it's missing, you'll be asked to pick a font on first run.
|
||
|
||
The desktop launcher runs LinTunes with no `--data-dir`, so it always uses
|
||
whatever is saved in `~/.config/lintunes/config.json` — point that config wherever
|
||
you want and the dock icon follows.
|
||
|
||
## Running on a second machine (Syncthing)
|
||
|
||
Keep the data dir (which holds `library.json`, the playlists, and
|
||
`preferences.json`) **inside** your Syncthing-shared music folder, so the music
|
||
and the library travel together. Track paths are stored *relative to the data
|
||
dir*, so the library resolves correctly no matter where each machine mounts the
|
||
shared folder — you never edit anything inside the library to move it.
|
||
|
||
`~/.config/lintunes/config.json` is **per-machine** (it is *not* synced), so on a
|
||
new machine you just tell LinTunes where the synced folder landed:
|
||
|
||
```sh
|
||
# 1. get the code, then install the deps (see "Installing" above: pip / apt / venv)
|
||
git clone ssh://git@git.autonomic.zone:2222/trav/lintunes.git
|
||
cd lintunes
|
||
|
||
# 2. let Syncthing finish replicating the music folder, then point the config at
|
||
# THIS machine's paths and launch — no re-import, the data is already synced:
|
||
python3 -m lintunes.main --data-dir "/path/to/synced/music/lintunes" \
|
||
--music-root "/path/to/synced/music/iTunes Media" \
|
||
--save-config
|
||
|
||
# 3. install the launcher + icon, then pin it (see "App icon" below)
|
||
bash packaging/install-desktop.sh
|
||
```
|
||
|
||
(Step 2 just writes `data_dir` + `music_root` into `~/.config/lintunes/config.json`
|
||
— you can also create that file by hand. After it's saved, every launch, including
|
||
the dock icon, uses the synced library automatically.)
|
||
|
||
## Keys
|
||
|
||
Space play/pause · ←/→ previous/next · Ctrl+B column browser ·
|
||
Ctrl+I get info · Ctrl+, preferences · Ctrl+C/Ctrl+X/Ctrl+V copy/cut/paste tracks ·
|
||
double-click sidebar art for a big art window
|
||
|
||
## App icon
|
||
|
||
`packaging/install-desktop.sh` installs the launcher entry and icon for your
|
||
user (lets you pin LinTunes to the GNOME dash). The icon is just a file —
|
||
replace `packaging/lintunes.png` (256×256 PNG) and re-run the script to use
|
||
your own. GNOME caches icons, so if the old one lingers, log out and back in.
|
||
|
||
Unpinning from the dash does **not** uninstall LinTunes — it's still in the
|
||
GNOME app grid (open Activities and search "LinTunes"). Right-click it there →
|
||
**Pin to Dash** to get it back.
|
||
|
||
## Development
|
||
|
||
```sh
|
||
python3 -m pytest tests/
|
||
```
|
||
|
||
`spec.md` is the original design brief; `tasks*.md` track what's built.
|