aboutsummaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/mp
diff options
context:
space:
mode:
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;