blob: f1628959f9b2ddbbc74193c1558f43d9be074798 [file] [log] [blame]
Matthias Andreas Benkard178f9912024-08-30 18:44:51 +02001{-# LANGUAGE UndecidableInstances #-}
2
3module Mulkup.Ranking (rankBupItems) where
4
5import qualified Data.List.NonEmpty as NonEmpty
6import qualified Data.Set as Set
7import Data.Time
8import Mulkup.Bupstash
9import Mulkup.Config
10import Mulkup.Prelude
11import Optics
12
13rankBupItems :: TierConfigs -> [BupItem] -> (Set Text, Set Text)
14rankBupItems tierConfigs currentItems =
15 (keepIds, rmIds)
16 where
17 tiers =
18 [ (utctHour . bupItemUTCTime, #hourly),
19 (utctJulianDay . bupItemUTCTime, #daily),
20 (utctWeek . bupItemUTCTime, #weekly),
21 (utctMonth . bupItemUTCTime, #monthly)
22 ]
23
24 keepIds =
25 Set.unions $
26 map
27 ( \(discriminator, cfgLens) ->
28 let tierCfg = tierConfigs ^. cfgLens
29 in tierKeepIds discriminator (tierCfg ^. #keep) currentItems
30 )
31 tiers
32
33 currentIds = Set.fromList (map (^. #id) currentItems)
34 rmIds = Set.difference currentIds keepIds
35
36tierKeepIds :: (BupItem -> Integer) -> Natural -> [BupItem] -> Set Text
37tierKeepIds discriminator keep items =
38 fromList $
39 take (fromIntegral keep) $
40 map (^. #id) $
41 reverse $
42 sortWith bupItemUTCTime $
43 map (head . NonEmpty.sortWith bupItemUTCTime) $
44 elems
45 (groupBy discriminator items :: HashMap Integer (NonEmpty BupItem))
46
47utctHour :: UTCTime -> Integer
48utctHour (UTCTime (ModifiedJulianDay julianDay) tdiff) = (julianDay * 24) + (diffTimeToPicoseconds tdiff `div` (10 ^ (12 :: Integer)) `div` 3600)
49
50utctJulianDay :: UTCTime -> Integer
51utctJulianDay (UTCTime (ModifiedJulianDay julianDay) _) = julianDay
52
53utctWeek :: UTCTime -> Integer
54utctWeek (UTCTime day _) =
55 julianDay + fromIntegral (dayOfWeekDiff (dayOfWeek day) Sunday)
56 where
57 (ModifiedJulianDay julianDay) = day
58 dayOfWeekDiff a b = mod (fromEnum a - fromEnum b) 7
59
60utctMonth :: UTCTime -> Integer
61utctMonth (UTCTime day _) = fromIntegral m
62 where
63 (_, m, _) = toGregorian day