Formatting
This commit is contained in:
@@ -9,6 +9,6 @@ pub mod matching;
|
||||
|
||||
pub use error::{WatchError, WatchResult};
|
||||
pub use library::{
|
||||
AddSummary, LibrarySummary, WatchListEntry, add_album, add_artist, add_track,
|
||||
library_summary, list_items, remove_item,
|
||||
AddSummary, LibrarySummary, WatchListEntry, add_album, add_artist, add_track, library_summary,
|
||||
list_items, remove_item,
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ impl fmt::Display for LibrarySummary {
|
||||
writeln!(f, " Wanted: {}", self.wanted)?;
|
||||
writeln!(f, " Available: {}", self.available)?;
|
||||
writeln!(f, " Downloaded: {}", self.downloaded)?;
|
||||
write!(f, " Owned: {}", self.owned)
|
||||
write!(f, " Owned: {}", self.owned)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,11 +84,12 @@ pub async fn add_artist(
|
||||
.search_artist(&resolved_name, 1)
|
||||
.await
|
||||
.map_err(|e| WatchError::Other(format!("artist search failed: {e}")))?;
|
||||
results
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|a| a.mbid)
|
||||
.ok_or_else(|| WatchError::Other(format!("artist '{}' not found on MusicBrainz", resolved_name)))?
|
||||
results.into_iter().next().map(|a| a.mbid).ok_or_else(|| {
|
||||
WatchError::Other(format!(
|
||||
"artist '{}' not found on MusicBrainz",
|
||||
resolved_name
|
||||
))
|
||||
})?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -117,7 +118,14 @@ pub async fn add_artist(
|
||||
};
|
||||
|
||||
for track in &tracks {
|
||||
match add_track_inner(conn, &resolved_name, &track.title, Some(&track.recording_mbid)).await {
|
||||
match add_track_inner(
|
||||
conn,
|
||||
&resolved_name,
|
||||
&track.title,
|
||||
Some(&track.recording_mbid),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(true) => summary.tracks_added += 1,
|
||||
Ok(false) => summary.tracks_already_owned += 1,
|
||||
Err(e) => {
|
||||
@@ -153,11 +161,12 @@ pub async fn add_album(
|
||||
.search_release(&resolved_artist, &resolved_album)
|
||||
.await
|
||||
.map_err(|e| WatchError::Other(format!("album search failed: {e}")))?;
|
||||
results
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|r| r.mbid)
|
||||
.ok_or_else(|| WatchError::Other(format!("album '{}' not found on MusicBrainz", resolved_album)))?
|
||||
results.into_iter().next().map(|r| r.mbid).ok_or_else(|| {
|
||||
WatchError::Other(format!(
|
||||
"album '{}' not found on MusicBrainz",
|
||||
resolved_album
|
||||
))
|
||||
})?
|
||||
}
|
||||
};
|
||||
|
||||
@@ -171,7 +180,14 @@ pub async fn add_album(
|
||||
let mut summary = AddSummary::default();
|
||||
|
||||
for track in &tracks {
|
||||
match add_track_inner(conn, &resolved_artist, &track.title, Some(&track.recording_mbid)).await {
|
||||
match add_track_inner(
|
||||
conn,
|
||||
&resolved_artist,
|
||||
&track.title,
|
||||
Some(&track.recording_mbid),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(true) => summary.tracks_added += 1,
|
||||
Ok(false) => summary.tracks_already_owned += 1,
|
||||
Err(e) => {
|
||||
@@ -269,9 +285,8 @@ async fn resolve_artist_info(
|
||||
return Ok((n.to_string(), mbid.map(String::from)));
|
||||
}
|
||||
|
||||
let mbid = mbid.ok_or_else(|| {
|
||||
WatchError::Other("either a name or --mbid is required".into())
|
||||
})?;
|
||||
let mbid =
|
||||
mbid.ok_or_else(|| WatchError::Other("either a name or --mbid is required".into()))?;
|
||||
|
||||
// Search for artist by MBID to get the name
|
||||
let results = provider
|
||||
@@ -282,7 +297,10 @@ async fn resolve_artist_info(
|
||||
if let Some(artist) = results.into_iter().next() {
|
||||
Ok((artist.name, Some(mbid.to_string())))
|
||||
} else {
|
||||
Ok((format!("Artist [{}]", &mbid[..8.min(mbid.len())]), Some(mbid.to_string())))
|
||||
Ok((
|
||||
format!("Artist [{}]", &mbid[..8.min(mbid.len())]),
|
||||
Some(mbid.to_string()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +315,11 @@ async fn resolve_album_info(
|
||||
album_name.filter(|s| !s.is_empty()),
|
||||
artist_name.filter(|s| !s.is_empty()),
|
||||
) {
|
||||
return Ok((album.to_string(), artist.to_string(), mbid.map(String::from)));
|
||||
return Ok((
|
||||
album.to_string(),
|
||||
artist.to_string(),
|
||||
mbid.map(String::from),
|
||||
));
|
||||
}
|
||||
|
||||
let mbid = mbid.ok_or_else(|| {
|
||||
@@ -317,7 +339,9 @@ async fn resolve_album_info(
|
||||
.unwrap_or_else(|| release.artist.clone());
|
||||
Ok((album, artist, Some(mbid.to_string())))
|
||||
} else {
|
||||
Err(WatchError::Other(format!("no release found for MBID {mbid}")))
|
||||
Err(WatchError::Other(format!(
|
||||
"no release found for MBID {mbid}"
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,9 +359,8 @@ async fn resolve_track_info(
|
||||
return Ok((t.to_string(), a.to_string(), mbid.map(String::from)));
|
||||
}
|
||||
|
||||
let mbid = mbid.ok_or_else(|| {
|
||||
WatchError::Other("either artist+title or --mbid is required".into())
|
||||
})?;
|
||||
let mbid =
|
||||
mbid.ok_or_else(|| WatchError::Other("either artist+title or --mbid is required".into()))?;
|
||||
|
||||
let details = provider
|
||||
.get_recording(mbid)
|
||||
@@ -345,8 +368,14 @@ async fn resolve_track_info(
|
||||
.map_err(|e| WatchError::Other(format!("MusicBrainz lookup failed: {e}")))?;
|
||||
|
||||
Ok((
|
||||
title.filter(|s| !s.is_empty()).map(String::from).unwrap_or(details.title),
|
||||
artist_name.filter(|s| !s.is_empty()).map(String::from).unwrap_or(details.artist),
|
||||
title
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(String::from)
|
||||
.unwrap_or(details.title),
|
||||
artist_name
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(String::from)
|
||||
.unwrap_or(details.artist),
|
||||
Some(mbid.to_string()),
|
||||
))
|
||||
}
|
||||
|
||||
29
src/main.rs
29
src/main.rs
@@ -96,7 +96,9 @@ fn parse_status(s: &str) -> anyhow::Result<WantedStatus> {
|
||||
"available" => Ok(WantedStatus::Available),
|
||||
"downloaded" => Ok(WantedStatus::Downloaded),
|
||||
"owned" => Ok(WantedStatus::Owned),
|
||||
_ => anyhow::bail!("unknown status: {s} (expected wanted, available, downloaded, or owned)"),
|
||||
_ => {
|
||||
anyhow::bail!("unknown status: {s} (expected wanted, available, downloaded, or owned)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,16 +130,15 @@ async fn main() -> anyhow::Result<()> {
|
||||
if name.is_none() && mbid.is_none() {
|
||||
anyhow::bail!("provide either a name or --mbid");
|
||||
}
|
||||
let summary = add_artist(
|
||||
db.conn(),
|
||||
name.as_deref(),
|
||||
mbid.as_deref(),
|
||||
&mb_client,
|
||||
)
|
||||
.await?;
|
||||
let summary =
|
||||
add_artist(db.conn(), name.as_deref(), mbid.as_deref(), &mb_client).await?;
|
||||
println!("Artist watch: {summary}");
|
||||
}
|
||||
AddCommand::Album { artist, album, mbid } => {
|
||||
AddCommand::Album {
|
||||
artist,
|
||||
album,
|
||||
mbid,
|
||||
} => {
|
||||
if artist.is_none() && album.is_none() && mbid.is_none() {
|
||||
anyhow::bail!("provide artist+album names or --mbid");
|
||||
}
|
||||
@@ -151,7 +152,11 @@ async fn main() -> anyhow::Result<()> {
|
||||
.await?;
|
||||
println!("Album watch: {summary}");
|
||||
}
|
||||
AddCommand::Track { artist, title, mbid } => {
|
||||
AddCommand::Track {
|
||||
artist,
|
||||
title,
|
||||
mbid,
|
||||
} => {
|
||||
if artist.is_none() && title.is_none() && mbid.is_none() {
|
||||
anyhow::bail!("provide artist+title or --mbid");
|
||||
}
|
||||
@@ -180,8 +185,8 @@ async fn main() -> anyhow::Result<()> {
|
||||
println!("Watchlist is empty.");
|
||||
} else {
|
||||
println!(
|
||||
"{:<5} {:<8} {:<12} {:<30} {}",
|
||||
"ID", "TYPE", "STATUS", "NAME", "ARTIST"
|
||||
"{:<5} {:<8} {:<12} {:<30} ARTIST",
|
||||
"ID", "TYPE", "STATUS", "NAME"
|
||||
);
|
||||
for e in &entries {
|
||||
println!(
|
||||
|
||||
@@ -7,7 +7,11 @@ use crate::error::WatchResult;
|
||||
|
||||
/// Normalize a string for fuzzy comparison: NFC unicode, lowercase, trim.
|
||||
pub fn normalize(s: &str) -> String {
|
||||
s.nfc().collect::<String>().to_lowercase().trim().to_string()
|
||||
s.nfc()
|
||||
.collect::<String>()
|
||||
.to_lowercase()
|
||||
.trim()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
/// Check if an artist is "owned" — i.e., any tracks by this artist exist in the indexed library.
|
||||
@@ -52,7 +56,9 @@ pub async fn album_is_owned(
|
||||
let norm_album = normalize(album_name);
|
||||
|
||||
// Try exact lookup
|
||||
if let Some(album) = queries::albums::find_by_name_and_artist(conn, album_name, artist_name).await? {
|
||||
if let Some(album) =
|
||||
queries::albums::find_by_name_and_artist(conn, album_name, artist_name).await?
|
||||
{
|
||||
let tracks = queries::tracks::get_by_album(conn, album.id).await?;
|
||||
if !tracks.is_empty() {
|
||||
return Ok(true);
|
||||
|
||||
Reference in New Issue
Block a user