diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-02-19 22:39:09 +0100 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-02-19 22:39:09 +0100 |
| commit | 9c6cb50906b5b504e9a4afd0259d9384562cd43d (patch) | |
| tree | 6e08052818674d7d7c752bb09cd9768d8fbd1429 | |
| parent | pkgs/mpdpopmd: Make the {positive,neutral,negative} chances configurable (diff) | |
| download | nixos-config-9c6cb50906b5b504e9a4afd0259d9384562cd43d.zip | |
pkgs/mpdpopmd: Also consider the `last_played` sticker when calculating weights
| -rw-r--r-- | pkgs/by-name/mp/mpdpopm/src/dj/algorithms.rs | 48 |
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; |
