Compare commits
1 Commits
5eee31fe91
...
cb63619610
| Author | SHA1 | Date | |
|---|---|---|---|
| cb63619610 |
+36
-1
@@ -60,11 +60,15 @@ impl fmt::Display for LibrarySummary {
|
||||
}
|
||||
|
||||
/// Add an artist to the watchlist by expanding into individual track wanted items.
|
||||
///
|
||||
/// `allowed_secondary_types` filters release groups by secondary type (e.g., Compilation, Live).
|
||||
/// An empty slice means studio releases only.
|
||||
pub async fn add_artist(
|
||||
conn: &DatabaseConnection,
|
||||
name: Option<&str>,
|
||||
musicbrainz_id: Option<&str>,
|
||||
provider: &impl MetadataProvider,
|
||||
allowed_secondary_types: &[String],
|
||||
user_id: Option<i32>,
|
||||
) -> WatchResult<AddSummary> {
|
||||
let (resolved_name, resolved_mbid) =
|
||||
@@ -91,14 +95,31 @@ pub async fn add_artist(
|
||||
|
||||
tracing::info!(name = %resolved_name, mbid = %artist_mbid, "fetching discography (release groups)");
|
||||
|
||||
let release_groups = provider
|
||||
let all_release_groups = provider
|
||||
.get_artist_release_groups(&artist_mbid)
|
||||
.await
|
||||
.map_err(|e| WatchError::Other(format!("failed to fetch release groups: {e}")))?;
|
||||
|
||||
// Only include release groups where this artist is the primary credit,
|
||||
// filtered by allowed secondary types (same as the artist detail page)
|
||||
let release_groups: Vec<_> = all_release_groups
|
||||
.into_iter()
|
||||
.filter(|rg| !rg.featured)
|
||||
.filter(|rg| {
|
||||
if rg.secondary_types.is_empty() {
|
||||
true
|
||||
} else {
|
||||
rg.secondary_types
|
||||
.iter()
|
||||
.all(|st| allowed_secondary_types.contains(st))
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
tracing::info!(count = release_groups.len(), "found release groups");
|
||||
|
||||
let mut summary = AddSummary::default();
|
||||
let mut seen_mbids: std::collections::HashSet<String> = std::collections::HashSet::new();
|
||||
|
||||
for rg in &release_groups {
|
||||
// Resolve a concrete release MBID from the release group
|
||||
@@ -128,6 +149,9 @@ pub async fn add_artist(
|
||||
};
|
||||
|
||||
for track in &tracks {
|
||||
if !seen_mbids.insert(track.recording_mbid.clone()) {
|
||||
continue; // Already processed this recording in another release group
|
||||
}
|
||||
match add_track_inner(
|
||||
conn,
|
||||
&resolved_name,
|
||||
@@ -277,6 +301,17 @@ async fn add_track_inner(
|
||||
artist_mbid: Option<&str>,
|
||||
user_id: Option<i32>,
|
||||
) -> WatchResult<bool> {
|
||||
// Skip if a wanted_item with this recording MBID already exists
|
||||
if let Some(mbid) = recording_mbid {
|
||||
if queries::wanted::find_by_mbid(conn, mbid)
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
tracing::debug!(title = title, mbid = mbid, "already in watchlist, skipping");
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
let artist = queries::artists::upsert(conn, artist_name, artist_mbid).await?;
|
||||
let is_owned = matching::track_is_owned(conn, artist_name, title).await?;
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
name.as_deref(),
|
||||
mbid.as_deref(),
|
||||
&mb_client,
|
||||
&[], // CLI: studio releases only (default)
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -204,7 +204,7 @@ async fn test_add_artist_expands_to_tracks() {
|
||||
let db = test_db().await;
|
||||
let provider = MockProvider;
|
||||
|
||||
let summary = add_artist(db.conn(), Some("Test Artist"), None, &provider, None)
|
||||
let summary = add_artist(db.conn(), Some("Test Artist"), None, &provider, &[], None)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(summary.tracks_added, 2);
|
||||
|
||||
Reference in New Issue
Block a user