Compare commits
1 Commits
| 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.
|
/// 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(
|
pub async fn add_artist(
|
||||||
conn: &DatabaseConnection,
|
conn: &DatabaseConnection,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
musicbrainz_id: Option<&str>,
|
musicbrainz_id: Option<&str>,
|
||||||
provider: &impl MetadataProvider,
|
provider: &impl MetadataProvider,
|
||||||
|
allowed_secondary_types: &[String],
|
||||||
user_id: Option<i32>,
|
user_id: Option<i32>,
|
||||||
) -> WatchResult<AddSummary> {
|
) -> WatchResult<AddSummary> {
|
||||||
let (resolved_name, resolved_mbid) =
|
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)");
|
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)
|
.get_artist_release_groups(&artist_mbid)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| WatchError::Other(format!("failed to fetch release groups: {e}")))?;
|
.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");
|
tracing::info!(count = release_groups.len(), "found release groups");
|
||||||
|
|
||||||
let mut summary = AddSummary::default();
|
let mut summary = AddSummary::default();
|
||||||
|
let mut seen_mbids: std::collections::HashSet<String> = std::collections::HashSet::new();
|
||||||
|
|
||||||
for rg in &release_groups {
|
for rg in &release_groups {
|
||||||
// Resolve a concrete release MBID from the release group
|
// Resolve a concrete release MBID from the release group
|
||||||
@@ -128,6 +149,9 @@ pub async fn add_artist(
|
|||||||
};
|
};
|
||||||
|
|
||||||
for track in &tracks {
|
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(
|
match add_track_inner(
|
||||||
conn,
|
conn,
|
||||||
&resolved_name,
|
&resolved_name,
|
||||||
@@ -277,6 +301,17 @@ async fn add_track_inner(
|
|||||||
artist_mbid: Option<&str>,
|
artist_mbid: Option<&str>,
|
||||||
user_id: Option<i32>,
|
user_id: Option<i32>,
|
||||||
) -> WatchResult<bool> {
|
) -> 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 artist = queries::artists::upsert(conn, artist_name, artist_mbid).await?;
|
||||||
let is_owned = matching::track_is_owned(conn, artist_name, title).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(),
|
name.as_deref(),
|
||||||
mbid.as_deref(),
|
mbid.as_deref(),
|
||||||
&mb_client,
|
&mb_client,
|
||||||
|
&[], // CLI: studio releases only (default)
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ async fn test_add_artist_expands_to_tracks() {
|
|||||||
let db = test_db().await;
|
let db = test_db().await;
|
||||||
let provider = MockProvider;
|
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
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(summary.tracks_added, 2);
|
assert_eq!(summary.tracks_added, 2);
|
||||||
|
|||||||
Reference in New Issue
Block a user