Added set sail button and much nicer artist enrichment

This commit is contained in:
Connor Johnstone
2026-03-18 14:54:52 -04:00
parent 8b16859526
commit ff41233a96
8 changed files with 251 additions and 13 deletions

View File

@@ -144,7 +144,7 @@ async fn get_artist(
/// Fetch (or retrieve from cache) the tracklist for a release group.
/// Cache key: `artist_rg_tracks:{release_group_id}`
async fn get_cached_album_tracks(
state: &web::Data<AppState>,
state: &AppState,
rg_id: &str,
first_release_id: Option<&str>,
ttl_seconds: i64,
@@ -241,9 +241,19 @@ async fn get_artist_full(
) -> Result<HttpResponse, ApiError> {
let id_or_mbid = path.into_inner();
let quick_mode = query.quick;
let result = enrich_artist(&state, &id_or_mbid, quick_mode).await?;
Ok(HttpResponse::Ok().json(result))
}
/// Enrich an artist's data: fetch release groups, track lists, compute totals.
/// Can be called from HTTP handlers or background tasks.
pub async fn enrich_artist(
state: &AppState,
id_or_mbid: &str,
quick_mode: bool,
) -> Result<serde_json::Value, ApiError> {
// Resolve artist: local ID or MBID
let (artist, id, mbid) = if let Ok(local_id) = id_or_mbid.parse::<i32>() {
let (artist, id, mbid) = if let Ok(local_id) = id_or_mbid.parse() {
let artist = queries::artists::get_by_id(state.db.conn(), local_id).await?;
let mbid = match &artist.musicbrainz_id {
Some(m) => m.clone(),
@@ -256,7 +266,7 @@ async fn get_artist_full(
};
(artist, Some(local_id), mbid)
} else {
let mbid = id_or_mbid;
let mbid = id_or_mbid.to_string();
// Direct MBID lookup — first check local DB, then MusicBrainz
let local = {
@@ -489,7 +499,7 @@ async fn get_artist_full(
}
}
Ok(HttpResponse::Ok().json(serde_json::json!({
Ok(serde_json::json!({
"artist": artist,
"albums": albums,
"artist_status": artist_status,
@@ -497,7 +507,30 @@ async fn get_artist_full(
"total_watched_tracks": total_artist_watched,
"total_owned_tracks": total_artist_owned,
"enriched": !skip_track_fetch,
})))
}))
}
/// Enrich all watched artists in the background, updating their cached totals.
pub async fn enrich_all_watched_artists(state: &AppState) -> Result<u32, ApiError> {
let all_wanted = queries::wanted::list(state.db.conn(), None).await?;
// Collect unique artist IDs that have any wanted items
let mut artist_ids: Vec<i32> = all_wanted
.iter()
.filter_map(|w| w.artist_id)
.collect();
artist_ids.sort();
artist_ids.dedup();
let mut count = 0u32;
for artist_id in &artist_ids {
match enrich_artist(state, &artist_id.to_string(), false).await {
Ok(_) => count += 1,
Err(e) => tracing::warn!(artist_id = artist_id, error = %e, "failed to enrich artist"),
}
}
Ok(count)
}
async fn add_artist(
@@ -514,6 +547,16 @@ async fn add_artist(
&state.mb_client,
)
.await?;
// Enrich the newly watched artist in the background so library totals are populated
if let Some(ref mbid) = body.mbid {
let state = state.clone();
let mbid = mbid.clone();
tokio::spawn(async move {
let _ = enrich_artist(&state, &mbid, false).await;
});
}
Ok(HttpResponse::Ok().json(serde_json::json!({
"tracks_added": summary.tracks_added,
"tracks_already_owned": summary.tracks_already_owned,