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