Compare commits
No commits in common. "1228c7cb70062efcce72a98d8b45b5561988853c" and "2bfdac25a71648c0fd8ded952a0f496de41f73e7" have entirely different histories.
1228c7cb70
...
2bfdac25a7
|
|
@ -619,7 +619,18 @@ impl NowPlaying {
|
||||||
/// if the binary is renamed or wrapped.
|
/// if the binary is renamed or wrapped.
|
||||||
#[cfg(feature = "notifications")]
|
#[cfg(feature = "notifications")]
|
||||||
fn notify_now_playing(track: &Track) {
|
fn notify_now_playing(track: &Track) {
|
||||||
let body = notification_body(track);
|
let body = if let Some(ref album) = track.album {
|
||||||
|
format!(
|
||||||
|
"{} by {}\n\n{} ({})",
|
||||||
|
track.title,
|
||||||
|
track.artist,
|
||||||
|
album.title,
|
||||||
|
// FIXME: get out year and format differently if it's missing
|
||||||
|
album.release_date()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!("{} by {}", track.title, track.artist)
|
||||||
|
};
|
||||||
if let Err(err) = Notification::new()
|
if let Err(err) = Notification::new()
|
||||||
.appname("crabidy")
|
.appname("crabidy")
|
||||||
.summary("Now playing")
|
.summary("Now playing")
|
||||||
|
|
@ -630,41 +641,6 @@ fn notify_now_playing(track: &Track) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The notification body: the track, and on its own line the album with its
|
|
||||||
/// release year. Most providers leave `release_date` unset (it is an optional
|
|
||||||
/// proto field, so absent reads as ""), which is why the parentheses belong to
|
|
||||||
/// the year and not to the album line — otherwise a dateless album shows up as
|
|
||||||
/// "Album ()".
|
|
||||||
#[cfg(feature = "notifications")]
|
|
||||||
fn notification_body(track: &Track) -> String {
|
|
||||||
let Some(album) = &track.album else {
|
|
||||||
return format!("{} by {}", track.title, track.artist);
|
|
||||||
};
|
|
||||||
let released = match release_year(album.release_date()) {
|
|
||||||
Some(year) => format!(" ({year})"),
|
|
||||||
None => String::new(),
|
|
||||||
};
|
|
||||||
format!(
|
|
||||||
"{} by {}\n\n{}{released}",
|
|
||||||
track.title, track.artist, album.title
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The year in a provider's `release_date`, for a notification that has one
|
|
||||||
/// line to spend on the album.
|
|
||||||
///
|
|
||||||
/// The strings are not all ISO 8601 — each provider passes through whatever
|
|
||||||
/// its API or (for `fsdy`) the sidecar TOML said — so this reads the leading
|
|
||||||
/// four digits of a `YYYY`/`YYYY-MM-DD`/`YYYY/MM/DD` date and gives up on
|
|
||||||
/// anything else rather than guessing. An unparseable date is dropped, not
|
|
||||||
/// shown raw: it is metadata noise, and a notification is not the place to
|
|
||||||
/// debug it.
|
|
||||||
#[cfg(feature = "notifications")]
|
|
||||||
fn release_year(release_date: &str) -> Option<&str> {
|
|
||||||
let year = release_date.trim().get(..4)?;
|
|
||||||
year.chars().all(|c| c.is_ascii_digit()).then_some(year)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Built without the `notifications` feature: nothing to show
|
/// Built without the `notifications` feature: nothing to show
|
||||||
/// (architecture/build-features.md D1).
|
/// (architecture/build-features.md D1).
|
||||||
#[cfg(not(feature = "notifications"))]
|
#[cfg(not(feature = "notifications"))]
|
||||||
|
|
@ -703,70 +679,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The notification body for a track on `album`, which carries
|
|
||||||
/// `release_date`.
|
|
||||||
#[cfg(feature = "notifications")]
|
|
||||||
fn body_for(release_date: Option<&str>) -> String {
|
|
||||||
let mut track = now_playing(0, 0).track.expect("track");
|
|
||||||
track.album = Some(crabidy_core::proto::crabidy::Album {
|
|
||||||
title: "album".to_string(),
|
|
||||||
release_date: release_date.map(str::to_string),
|
|
||||||
});
|
|
||||||
notification_body(&track)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A full date is reduced to its year; a bare year is already one.
|
|
||||||
#[cfg(feature = "notifications")]
|
|
||||||
#[test]
|
|
||||||
fn notification_shows_the_release_year_when_there_is_one() {
|
|
||||||
assert_eq!(
|
|
||||||
body_for(Some("1977-10-28")),
|
|
||||||
"title by artist\n\nalbum (1977)"
|
|
||||||
);
|
|
||||||
assert_eq!(body_for(Some("1977")), "title by artist\n\nalbum (1977)");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// No date must mean no parentheses, whether the provider left the field
|
|
||||||
/// unset or sent it empty.
|
|
||||||
#[cfg(feature = "notifications")]
|
|
||||||
#[test]
|
|
||||||
fn notification_omits_empty_parentheses() {
|
|
||||||
assert_eq!(body_for(None), "title by artist\n\nalbum");
|
|
||||||
assert_eq!(body_for(Some("")), "title by artist\n\nalbum");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Providers hand through whatever their API said, so a date that is not
|
|
||||||
/// year-first is dropped rather than shown raw or half-parsed. Nothing
|
|
||||||
/// here may panic — `get(..4)` has to survive a short string and a
|
|
||||||
/// multi-byte boundary.
|
|
||||||
#[cfg(feature = "notifications")]
|
|
||||||
#[test]
|
|
||||||
fn an_unparseable_release_date_is_left_out() {
|
|
||||||
for date in ["Oct 1977", "77", "-", "жизнь", "12/05/1977", "197"] {
|
|
||||||
assert_eq!(
|
|
||||||
body_for(Some(date)),
|
|
||||||
"title by artist\n\nalbum",
|
|
||||||
"date {date:?} should not reach the notification"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The year is taken from the front, whatever separator follows it.
|
|
||||||
#[cfg(feature = "notifications")]
|
|
||||||
#[test]
|
|
||||||
fn the_year_is_read_from_the_front_of_the_date() {
|
|
||||||
assert_eq!(release_year(" 1977-10-28 "), Some("1977"));
|
|
||||||
assert_eq!(release_year("1977/10/28"), Some("1977"));
|
|
||||||
assert_eq!(release_year("19771028"), Some("1977"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "notifications")]
|
|
||||||
#[test]
|
|
||||||
fn notification_without_an_album_is_just_the_track() {
|
|
||||||
let track = now_playing(0, 0).track.expect("track");
|
|
||||||
assert_eq!(notification_body(&track), "title by artist");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// One flat color, no markers: the glyph tests are about the bars'
|
/// One flat color, no markers: the glyph tests are about the bars'
|
||||||
/// geometry, so they pin the paint down and let the color tests own it.
|
/// geometry, so they pin the paint down and let the color tests own it.
|
||||||
fn flat() -> SpectrumStyle {
|
fn flat() -> SpectrumStyle {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue