1
2
3 """ Models to redis entities """
4 import time
5 from math import ceil
6 from datetime import timedelta
10 _KEY_BASE = "copr:generic"
11
12 @classmethod
18
21 """
22 Wraps hset structure, where:
23 **key** - name of event, fix prefix specifying events type
24 **member** - bucket representing one day
25 **score** - events count
26 """
27 _KEY_BASE = "copr:tse"
28
29 @staticmethod
31 """
32 :param ut: unix timestamp
33 :type ut: float
34 :return: name for the day bucket
35 """
36 td = timedelta(days=1).total_seconds()
37 return int(ceil(ut / td))
38
39 @classmethod
41 """
42 Generate list of days bucket names which contains
43 all events between `min_ts` and `max_ts`
44 :param min_ts: min unix timestamp
45 :param max_ts: max unix timestamp
46 :rtype: list
47 """
48 start_ut = cls.timestamp_to_day(min_ts)
49 end_ut = cls.timestamp_to_day(max_ts)
50
51 return range(start_ut, end_ut + 1)
52
53 @classmethod
54 - def add_event(cls, rconnect, name, timestamp, count=1, prefix=None):
55 """
56 Stoted new event to redist
57 :param rconnect: Connection to a redis
58 :type rconnect: StrictRedis
59 :param name: statistics name
60 :param timestamp: timestamp of event
61 :param count: number of events, default=1
62 :param prefix: prefix for statistics, default is None
63 """
64 count = int(count)
65 ut_day = cls.timestamp_to_day(timestamp)
66
67 key = cls._get_key(name, prefix)
68
69 rconnect.hincrby(key, ut_day, count)
70
71 @classmethod
72 - def get_count(cls, rconnect, name, day_min=None, prefix=None, day_max=None):
73 """
74 Count total event occurency between day_min and day_max
75 :param rconnect: Connection to a redis
76 :type rconnect: StrictRedis
77 :param name: statistics name
78 :param day_min: default: seven days ago
79 :param day_max: default: tomorrow
80 :param prefix: prefix for statistics, default is None
81
82 :rtype: int
83 """
84 key = cls._get_key(name, prefix)
85 if day_min is None:
86 day_min = time.time() - timedelta(days=7).total_seconds()
87
88 if day_max is None:
89 day_max = time.time() + timedelta(days=1).total_seconds()
90
91 interval = cls.gen_days_interval(day_min, day_max)
92 if len(interval) == 0:
93 return 0
94
95 res = rconnect.hmget(key, interval)
96 return sum(int(amount) for amount in res if amount is not None)
97
98
99 @classmethod
100 - def trim_before(cls, rconnect, name, threshold_timestamp,
101 prefix=None):
102 """
103 Removes all records occurred before `threshold_timestamp`
104 :param rconnect: StrictRedis
105 :param name: statistics name
106 :param threshold_timestamp: int
107 :param prefix: prefix for statistics, default is None
108 """
109
110 key = cls._get_key(name, prefix)
111
112 threshold_day = cls.timestamp_to_day(threshold_timestamp) + 1
113 all_members = rconnect.hgetall(key)
114 to_del = [mb for mb in all_members.keys() if int(mb) < threshold_day]
115
116 rconnect.hdel(key, *to_del)
117