]> rtime.felk.cvut.cz Git - hubacji1/coffee-getter.git/blob - cbdb.py
Add top drinks to top5 runnable
[hubacji1/coffee-getter.git] / cbdb.py
1 # -*- coding: utf-8 -*-
2 """Database access."""
3 from sqlite3 import connect
4
5 class FileNotSetError(ValueError):
6     pass
7
8 class ArgCountError(ValueError):
9     pass
10
11 class Db:
12     def __init__(self, dbpath=False):
13         if dbpath:
14             self.con = connect(dbpath)
15         else:
16             self.con = None
17             raise FileNotSetError("Database file must be set")
18         self.cur = self.con.cursor()
19         return None
20
21     def __del__(self):
22         if self.con:
23             self.con.close()
24
25     def get_top_drinks(self):
26         """Return list of pairs of drink name and count."""
27         q = """
28
29         SELECT count(*), flavor
30         FROM coffees
31         WHERE time BETWEEN
32             datetime('now', 'localtime', '-7 days')
33             AND datetime('now', 'localtime')
34         GROUP BY flavor
35
36         """
37         top = []
38         for (cnt, dn) in self.cur.execute(q):
39             top.append((dn, cnt))
40         top.sort(key=lambda x: (x[1], x[0]), reverse=True)
41         return top
42
43     def getTopMateDrinkers(self):
44         """Return list of pairs of name, count for Mate drinkers."""
45         users = {}
46         que = """
47             SELECT count(*), users.name FROM coffees
48             INNER JOIN users ON coffees.id = users.id
49             WHERE flavor = 'Club-Mate 0,5 l'
50             AND coffees.time BETWEEN
51                 datetime('now', 'localtime', '-7 days') AND
52                 datetime('now', 'localtime')
53             GROUP BY coffees.id
54         """
55         for (cnt, un) in self.cur.execute(que):
56             users[un] = cnt * 0.5
57         que = """
58             SELECT count(*), users.name FROM coffees
59             INNER JOIN users ON coffees.id = users.id
60             WHERE flavor = 'Club-Mate 0,33 l'
61             AND coffees.time BETWEEN
62                 datetime('now', 'localtime', '-7 days') AND
63                 datetime('now', 'localtime')
64             GROUP BY coffees.id
65         """
66         for (cnt, un) in self.cur.execute(que):
67             if un in users:
68                 users[un] += cnt * 0.33
69             else:
70                 users[un] = cnt * 0.33
71         top = []
72         for (un, cnt) in users.items():
73             top.append((un, cnt))
74         top.sort(key=lambda x: (x[1], x[0]), reverse=True)
75         return top
76
77     def get_top_tea_drinkers(self):
78         """Return list of pairs of name, count for tea drinkers."""
79         q = """
80
81         SELECT count(*), users.name FROM coffees
82         INNER JOIN users ON coffees.id = users.id
83         WHERE flavor = 'tea'
84         AND coffees.time BETWEEN
85             datetime('now', 'localtime', '-7 days') AND
86             datetime('now', 'localtime')
87         GROUP BY coffees.id
88
89         """
90         top = []
91         for (cnt, un) in self.cur.execute(q):
92             top.append((un, cnt))
93         top.sort(key=lambda x: (x[1], x[0]), reverse=True)
94         return top
95
96     def getDrunkSum(self, *args, **kwargs):
97         """Return list of drunken ``flavor`` from ``dtf`` to ``dtt``.
98
99         Keyword arguments:
100         flavor -- The flavor of beverage.
101         dtf -- Date and time *from*.
102         dtt -- Date and time *to*.
103         """
104         if not ((len(args) == 3 and len(kwargs) == 0) or
105                 (len(args) == 0 and len(kwargs) == 3)):
106             raise ArgCountError("3 arguments needed: flavor, from, and to")
107         if args:
108             flavor = args[0]
109             dtf = args[1]
110             dtt = args[2]
111         elif kwargs:
112             flavor = kwargs["flavor"]
113             dtf = kwargs["dtf"]
114             dtt = kwargs["dtt"]
115         flavors = flavor.split(";")
116         que = """
117             SELECT count(*), users.name FROM coffees
118             INNER JOIN users ON coffees.id = users.id
119         """
120         for f in flavors:
121             if f is flavors[0]:
122                 que += "WHERE flavor = '{}'".format(f)
123             else:
124                 que += "OR flavor = '{}'".format(f)
125         que += """
126             AND coffees.time BETWEEN
127                 datetime('{}', 'localtime') AND
128                 datetime('{}', 'localtime')
129             GROUP BY coffees.id
130         """.format(dtf, dtt)
131         drunk = []
132         for (cnt, un) in self.cur.execute(que):
133             drunk.append((un, cnt))
134         return drunk
135
136     def getDrunkList(self, *args, **kwargs):
137         """Return dict of lists of drunken ``flavor`` from ``dtf`` to ``dtt``.
138
139         Keyword arguments:
140         flavor -- The flavor of beverage.
141         dtf -- Date and time *from*.
142         dtt -- Date and time *to*.
143         """
144         if not ((len(args) == 3 and len(kwargs) == 0) or
145                 (len(args) == 0 and len(kwargs) == 3)):
146             raise ArgCountError("3 arguments needed: flavor, from, and to")
147         if args:
148             flavor = args[0]
149             dtf = args[1]
150             dtt = args[2]
151         elif kwargs:
152             flavor = kwargs["flavor"]
153             dtf = kwargs["dtf"]
154             dtt = kwargs["dtt"]
155         flavors = flavor.split(";")
156         drunk = {}
157         i = 0
158         for f in flavors:
159             que = """
160                 SELECT count(*), users.name FROM coffees
161                 INNER JOIN users ON coffees.id = users.id
162                 WHERE flavor = '{}'
163                 AND coffees.time BETWEEN
164                     datetime('{}', 'localtime') AND
165                     datetime('{}', 'localtime')
166                 GROUP BY coffees.id
167             """.format(f, dtf, dtt)
168             for (cnt, un) in self.cur.execute(que):
169                 if not un in drunk:
170                     drunk[un] = [0 for j in range(i)]
171                 drunk[un].append(cnt)
172             i += 1
173         return drunk