aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/mp/mpdpopm/src/playcounts.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--pkgs/by-name/mp/mpdpopm/src/playcounts.rs62
1 files changed, 47 insertions, 15 deletions
diff --git a/pkgs/by-name/mp/mpdpopm/src/playcounts.rs b/pkgs/by-name/mp/mpdpopm/src/playcounts.rs
index 7d646b4c..eac71948 100644
--- a/pkgs/by-name/mp/mpdpopm/src/playcounts.rs
+++ b/pkgs/by-name/mp/mpdpopm/src/playcounts.rs
@@ -26,7 +26,7 @@
//!
use crate::clients::{Client, PlayerStatus};
-use crate::storage::{last_played, play_count, skipped};
+use crate::storage::{last_played, play_count, skip_count};
use anyhow::{Context, Error, Result, anyhow};
use tracing::{debug, info};
@@ -71,13 +71,16 @@ impl PlayState {
/// Poll the server-- update our status; maybe increment the current track's play count; the
/// caller must arrange to have this method invoked periodically to keep our state fresh
- pub async fn update(&mut self, client: &mut Client) -> Result<()> {
+ ///
+ /// Returns whether a song finished between the last call and this one.
+ /// That can be used to add a new song to the queue.
+ pub async fn update(&mut self, client: &mut Client) -> Result<bool> {
let new_stat = client
.status()
.await
.context("Failed to get client status")?;
- match (&self.last_server_stat, &new_stat) {
+ let previous_song_finished = match (&self.last_server_stat, &new_stat) {
(PlayerStatus::Play(last), PlayerStatus::Play(curr))
| (PlayerStatus::Pause(last), PlayerStatus::Play(curr))
| (PlayerStatus::Play(last), PlayerStatus::Pause(curr))
@@ -93,33 +96,59 @@ impl PlayState {
}
self.have_incr_play_count = false;
+
+ // We are now playing something else, as such the previous one must have
+ // finished or was skipped.
+ true
} else if last.elapsed > curr.elapsed
&& self.have_incr_play_count
&& curr.elapsed / curr.duration <= 0.1
{
debug!("Re-play-- resetting PC incremented flag.");
self.have_incr_play_count = false;
+
+ // We are still playing the same song, just skipped at the start again.
+ // This means that we don't need a new one.
+ false
+ } else {
+ // We are still playing the same song, so nothing changed
+ false
}
}
(PlayerStatus::Stopped, PlayerStatus::Play(_))
- | (PlayerStatus::Stopped, PlayerStatus::Pause(_))
- | (PlayerStatus::Pause(_), PlayerStatus::Stopped)
+ | (PlayerStatus::Stopped, PlayerStatus::Pause(_)) => {
+ self.have_incr_play_count = false;
+
+ // We didn't play anything before and now we play something. This means that we
+ // obviously have something to play and thus don't need to add another song.
+ false
+ }
+ (PlayerStatus::Pause(_), PlayerStatus::Stopped)
| (PlayerStatus::Play(_), PlayerStatus::Stopped) => {
self.have_incr_play_count = false;
+
+ // We played a song before and now we stopped, maybe because we ran out of songs to
+ // play. So we need to add another one.
+ true
}
- (PlayerStatus::Stopped, PlayerStatus::Stopped) => (),
- }
+ (PlayerStatus::Stopped, PlayerStatus::Stopped) => {
+ // We did not play before and we are still not playing, as such nothing really
+ // changed.
+ false
+ }
+ };
match &new_stat {
PlayerStatus::Play(curr) => {
let pct = curr.played_pct();
debug!("Updating status: {:.3}% complete.", 100.0 * pct);
+
if !self.have_incr_play_count && pct >= self.played_thresh {
info!(
- "Increment play count for '{}' (songid: {}) at {} played.",
+ "Increment play count for '{}' (songid: {}) at {:.2}% played.",
curr.file.display(),
curr.songid,
- curr.elapsed / curr.duration
+ (curr.elapsed / curr.duration) * 100.0
);
let file = curr.file.to_str().ok_or_else(|| {
@@ -143,6 +172,9 @@ impl PlayState {
play_count::set(client, file, curr_pc + 1).await?;
} else if self.last_song_was_skipped {
+ // TODO(@bpeetz): This should also record _when_ the skip was (e.g. a
+ // skip at 80% is not as important as one at 2%) <2026-09-05>
+
self.last_song_was_skipped = false;
let last = self
.last_server_stat
@@ -150,25 +182,25 @@ impl PlayState {
.expect("To exist, as it was skipped");
info!(
- "Marking '{}' (songid: {}) as skipped at {}.",
+ "Marking '{}' (songid: {}) as skipped at {:.2}%.",
last.file.display(),
last.songid,
- last.elapsed / last.duration
+ (last.elapsed / last.duration) * 100.0
);
let file = last.file.to_str().ok_or_else(|| {
anyhow!("Failed to parse path as utf8: `{}`", last.file.display())
})?;
- let skip_count = skipped::get(client, file).await?.unwrap_or_default();
- skipped::set(client, file, skip_count + 1).await?;
+ let skip_count = skip_count::get(client, file).await?.unwrap_or_default();
+ skip_count::set(client, file, skip_count + 1).await?;
}
}
PlayerStatus::Pause(_) | PlayerStatus::Stopped => (),
};
self.last_server_stat = new_stat;
- Ok(()) // No need to update the DB
+ Ok(previous_song_finished)
}
}
@@ -308,6 +340,6 @@ OK
assert!(check);
ps.update(&mut cli).await.unwrap();
- ps.update(&mut cli).await.unwrap()
+ ps.update(&mut cli).await.unwrap();
}
}