Avoid fetching covers via MPD if it definitely does not have them
This commit is contained in:
25
src/db.rs
25
src/db.rs
@@ -869,6 +869,31 @@ pub fn albums_without_cover(conn: &Connection) -> Result<Vec<UncachedAlbum>> {
|
|||||||
rows.collect()
|
rows.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like [`albums_without_cover`] but restricted to albums where at least one
|
||||||
|
/// scrobble came from MPD (`source = 'MPD'`).
|
||||||
|
///
|
||||||
|
/// There is no point asking MPD for a cover art of an album that was scrobbled
|
||||||
|
/// entirely via an MPRIS player (e.g. Qobuz, Spotify) — MPD almost certainly
|
||||||
|
/// does not have that file on disk. This query avoids those wasted round-trips.
|
||||||
|
pub fn albums_without_cover_from_mpd(conn: &Connection) -> Result<Vec<UncachedAlbum>> {
|
||||||
|
let mut stmt = conn.prepare(
|
||||||
|
"SELECT DISTINCT s.artist, s.album
|
||||||
|
FROM scrobbles s
|
||||||
|
LEFT JOIN album_cache c ON s.artist = c.artist AND s.album = c.album
|
||||||
|
WHERE s.album != ''
|
||||||
|
AND s.source = 'MPD'
|
||||||
|
AND (c.id IS NULL OR c.cover_url IS NULL)
|
||||||
|
ORDER BY s.artist, s.album",
|
||||||
|
)?;
|
||||||
|
let rows = stmt.query_map([], |row| {
|
||||||
|
Ok(UncachedAlbum {
|
||||||
|
artist: row.get(0)?,
|
||||||
|
album: row.get(1)?,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
rows.collect()
|
||||||
|
}
|
||||||
|
|
||||||
/// Cached album metadata returned by [`album_cache_meta`].
|
/// Cached album metadata returned by [`album_cache_meta`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AlbumCacheMeta {
|
pub struct AlbumCacheMeta {
|
||||||
|
|||||||
15
src/mpd.rs
15
src/mpd.rs
@@ -942,9 +942,10 @@ fn try_extract_cover(
|
|||||||
/// one; if it finds nothing, the local cover is preserved (see
|
/// one; if it finds nothing, the local cover is preserved (see
|
||||||
/// `db::upsert_album_cache` for the `COALESCE` logic).
|
/// `db::upsert_album_cache` for the `COALESCE` logic).
|
||||||
pub fn run_mpd_cover_enrich(config: &MpdConfig, conn: &Connection) {
|
pub fn run_mpd_cover_enrich(config: &MpdConfig, conn: &Connection) {
|
||||||
// Fetch covers for every scrobbled album that still has no cover_url.
|
// Only consider albums where at least one scrobble came from MPD — albums
|
||||||
// Used by the standalone `enrich` command where the scope is the whole DB.
|
// scrobbled exclusively via MPRIS players (Qobuz, Spotify, etc.) are
|
||||||
let albums = match db::albums_without_cover(conn) {
|
// unlikely to be present in MPD's music database.
|
||||||
|
let albums = match db::albums_without_cover_from_mpd(conn) {
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("[error] Failed to query albums without cover: {}", e);
|
eprintln!("[error] Failed to query albums without cover: {}", e);
|
||||||
@@ -971,10 +972,10 @@ pub fn run_mpd_cover_enrich_targeted(
|
|||||||
conn: &Connection,
|
conn: &Connection,
|
||||||
needed: &std::collections::HashSet<(String, String)>,
|
needed: &std::collections::HashSet<(String, String)>,
|
||||||
) {
|
) {
|
||||||
// Start from albums that genuinely have no cover yet, then narrow to the
|
// Start from albums that have no cover AND were scrobbled via MPD — albums
|
||||||
// set the caller cares about. This avoids redundant MPD round-trips for
|
// from MPRIS-only players are excluded because MPD won't have those files.
|
||||||
// albums that already have art.
|
// Then narrow further to the set the caller cares about.
|
||||||
let albums = match db::albums_without_cover(conn) {
|
let albums = match db::albums_without_cover_from_mpd(conn) {
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("[error] Failed to query albums without cover: {}", e);
|
eprintln!("[error] Failed to query albums without cover: {}", e);
|
||||||
|
|||||||
Reference in New Issue
Block a user