aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/mp
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-02-19 22:39:09 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2026-02-19 22:39:09 +0100
commit9c6cb50906b5b504e9a4afd0259d9384562cd43d (patch)
tree6e08052818674d7d7c752bb09cd9768d8fbd1429 /pkgs/by-name/mp
parentpkgs/mpdpopmd: Make the {positive,neutral,negative} chances configurable (diff)
downloadnixos-config-9c6cb50906b5b504e9a4afd0259d9384562cd43d.zip
pkgs/mpdpopmd: Also consider the `last_played` sticker when calculating weights
Diffstat (limited to '')
-rw-r--r--pkgs/by-name/mp/mpdpopm/src/dj/algorithms.rs48
1 files changed, 43 insertions, 5 deletions
diff --git a/pkgs/by-name/mp/mpdpopm/src/dj/algorithms.rs b/pkgs/by-name/mp/mpdpopm/src/dj/algorithms.rs
index fcb7a88d..c002f055 100644
--- a/pkgs/by-name/mp/mpdpopm/src/dj/algorithms.rs
+++ b/pkgs/by-name/mp/mpdpopm/src/dj/algorithms.rs
@@ -1,7 +1,10 @@
-use std::collections::HashSet;
+use std::{
+ collections::HashSet,
+ time::{Duration, SystemTime},
+};
use anyhow::{Context, Result};
-use rand::{Rng, distr, seq::SliceRandom};
+use rand::{Rng, distr};
use tracing::info;
use crate::{clients::Client, storage};
@@ -149,15 +152,50 @@ impl Discovery {
/// dislikes to a lower number.
/// Currently, only the rating, skip count and play count are considered. Similarity scores,
/// fetched from e.g. last.fm should be included in the future.
- async fn weight_track(client: &mut Client, track: &str) -> Result<i64> {
+ pub async fn weight_track(client: &mut Client, track: &str) -> Result<i64> {
+ let last_played_delta = {
+ let last_played = storage::last_played::get(client, track).await?.unwrap_or(0);
+ let now = SystemTime::now()
+ .duration_since(SystemTime::UNIX_EPOCH)
+ .expect("to be before")
+ .as_secs();
+
+ let played_seconds_ago = now - last_played;
+
+ const HOUR: u64 = Duration::from_hours(1).as_secs();
+ const DAY: u64 = Duration::from_hours(24).as_secs();
+ const MONTH: u64 = Duration::from_hours(24 * 30).as_secs();
+
+ match played_seconds_ago {
+ ..HOUR => {
+ // it was played in the last hour already
+ -3
+ }
+ HOUR..DAY => {
+ // it was not played in the last hour, but in the last day
+ -2
+ }
+ DAY..MONTH => {
+ // it was not played in the last day, but in the last month
+ -1
+ }
+ MONTH.. => {
+ // it was not played in a month
+ 1
+ }
+ }
+ };
+
let rating = i32::from(storage::rating::get(client, track).await?.unwrap_or(0));
let play_count = i32::try_from(storage::play_count::get(client, track).await?.unwrap_or(0))
.context("`play_count` too big")?;
let skip_count = i32::try_from(storage::skip_count::get(client, track).await?.unwrap_or(0))
.context("`skip_count` too big")?;
- let output: f64 =
- 1.0 * f64::from(rating) + 0.3 * f64::from(play_count) + -0.6 * f64::from(skip_count);
+ let output: f64 = 1.0 * f64::from(rating)
+ + 0.3 * f64::from(play_count)
+ + -0.6 * f64::from(skip_count)
+ + 0.65 * f64::from(last_played_delta);
let weight = output.round() as i64;