v0.38.0: several imported songs are identified as one batch

No identify dialog pops up mid-download any more: songs are looked up
quietly as they land and reviewed together once the last one is in, as
rows in the app's columns. Songs that are one album get the album-wide
fields once, unified, plus a cover from the album-art search. Ticked
rows apply as one undo step; unticked ones get the ordinary dialog
after. Popups wait for LinTunes to be the app in front.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-09 01:42:13 -07:00
co-authored by Claude Opus 5.5
parent 581be8d732
commit f899794068
9 changed files with 1150 additions and 8 deletions
+19
View File
@@ -378,6 +378,25 @@ persistence) → GUI (Qt widgets that read the manager and connect to its signal
track number into the mp3 **before** emitting `downloaded`, so the
import files it under the right artist and Identify ranks by that artist.
If the embed page changes shape, `parse_embed` raises `SpotifyError`.
**Several songs are identified as one batch** (Round 77,
`identify_batch.py` + `gui/identify_batch_dialog.py`): an import of more
than one song never pops a dialog mid-download. `IdentifyCollector` looks
each up quietly as it lands, and only after `finished`/`failed` *and* the
last lookup does one review window open, with all the songs as rows in the
app's columns. `find_common_album` makes it "one album" when every song
naming an album can be on the same one (its own tags vote too, which is
what carries a Spotify album through AcoustID's compilations). Then the
album-wide fields are unified to the most common value, shown once above
the table, and the cover comes from the same `AlbumArtFetcher` search.
Ticked rows go through `LibraryManager.edit_many_track_fields` as **one**
undo step. Unticked rows get the ordinary `IdentifyDialog` afterwards,
from the lookups already made. **No popup may land on top of another
app**: `MainWindow._when_app_active` shows it at once only while LinTunes
is the active application, and otherwise asks for attention
(`QApplication.alert`) and waits for `applicationStateChanged`. A window
test that downloads several songs must stub `_show_batch_review` and
cancel `_url_batch` on teardown, or a late lookup opens a modal dialog
in the next test.
- **`lintunes/mpris.py`** — registers `org.mpris.MediaPlayer2.lintunes` over D-Bus
so the desktop's media keys / now-playing popup control playback. Spacebar and