]>
Commit | Line | Data |
---|---|---|
7771acea MT |
1 | #!/usr/bin/python |
2 | ||
3 | from __future__ import division | |
4 | ||
5 | import datetime | |
6 | import textile | |
7 | ||
9068dba1 | 8 | from misc import Object |
7771acea | 9 | |
9068dba1 | 10 | class Wishlist(Object): |
7771acea | 11 | def get(self, slug): |
918284e8 | 12 | wish = self.db.get("SELECT * FROM wishlist WHERE slug = %s", slug) |
7771acea MT |
13 | |
14 | if wish: | |
15 | return Wish(self, wish.id) | |
16 | ||
1bf8d482 | 17 | def get_all_by_query(self, query, *args): |
7771acea MT |
18 | wishes = [] |
19 | ||
1bf8d482 | 20 | for row in self.db.query(query, *args): |
918284e8 | 21 | wish = Wish(self, row.id, row) |
7771acea MT |
22 | wishes.append(wish) |
23 | ||
24 | return wishes | |
25 | ||
26 | def get_all_running(self): | |
918284e8 | 27 | return self.get_all_by_query("SELECT * FROM wishlist \ |
9068dba1 MT |
28 | WHERE (CASE \ |
29 | WHEN date_end IS NULL THEN \ | |
30 | NOW() >= date_start AND goal >= donated \ | |
31 | ELSE \ | |
32 | NOW() BETWEEN date_start AND date_end \ | |
33 | END) AND status = 'running' \ | |
7771acea MT |
34 | ORDER BY prio ASC, date_end ASC") |
35 | ||
1bf8d482 | 36 | def get_all_finished(self, limit=5, offset=None): |
9068dba1 MT |
37 | query = "SELECT * FROM wishlist \ |
38 | WHERE (CASE \ | |
39 | WHEN date_end IS NULL THEN \ | |
40 | donated >= goal \ | |
41 | ELSE \ | |
42 | NOW() > date_end \ | |
43 | END) AND status IS NOT NULL \ | |
1bf8d482 MT |
44 | ORDER BY date_end DESC" |
45 | args = [] | |
46 | ||
47 | if limit: | |
9068dba1 MT |
48 | query += " LIMIT %s" |
49 | args.append(limit) | |
50 | ||
1bf8d482 | 51 | if offset: |
9068dba1 MT |
52 | query += " OFFSET %s" |
53 | args.append(offset) | |
1bf8d482 MT |
54 | |
55 | return self.get_all_by_query(query, *args) | |
7771acea | 56 | |
9d7e697a MT |
57 | def get_hot_wishes(self, limit=3): |
58 | query = "SELECT * FROM wishlist \ | |
9068dba1 MT |
59 | WHERE \ |
60 | status = %s \ | |
61 | AND \ | |
62 | date_start <= NOW() \ | |
63 | AND \ | |
64 | (CASE WHEN date_end IS NOT NULL THEN \ | |
65 | NOW() BETWEEN date_start AND date_end \ | |
66 | ELSE \ | |
67 | TRUE \ | |
68 | END) \ | |
69 | AND \ | |
70 | (AGE(NOW(), date_start) <= INTERVAL '10 days' \ | |
71 | OR \ | |
72 | AGE(date_end, NOW()) <= INTERVAL '14 days' \ | |
73 | OR \ | |
74 | (donated / goal) >= 0.85 \ | |
75 | OR \ | |
76 | goal >= 3000 \ | |
77 | OR \ | |
78 | prio <= 5 \ | |
79 | ) \ | |
80 | ORDER BY prio ASC, date_end ASC LIMIT %s" | |
9d7e697a MT |
81 | |
82 | return self.get_all_by_query(query, "running", limit) | |
83 | ||
60b0917c MT |
84 | def get_hottest_wish(self): |
85 | wishes = self.get_hot_wishes(limit=1) | |
86 | ||
87 | if wishes: | |
88 | return wishes[0] | |
89 | ||
7771acea MT |
90 | |
91 | class Wish(object): | |
918284e8 | 92 | def __init__(self, wishlist, id, data=None): |
7771acea MT |
93 | self.wishlist = wishlist |
94 | self.id = id | |
95 | ||
918284e8 | 96 | self.__data = data |
7771acea | 97 | |
9d7e697a MT |
98 | def __repr__(self): |
99 | return "<%s %s>" % (self.__class__.__name__, self.title) | |
100 | ||
7771acea MT |
101 | def __cmp__(self, other): |
102 | return cmp(self.date_end, other.date_end) | |
103 | ||
104 | @property | |
105 | def db(self): | |
106 | return self.wishlist.db | |
107 | ||
108 | @property | |
109 | def data(self): | |
110 | if self.__data is None: | |
111 | self.__data = self.db.get("SELECT * FROM wishlist WHERE id = %s", self.id) | |
112 | assert self.__data | |
113 | ||
114 | return self.__data | |
115 | ||
116 | @property | |
117 | def title(self): | |
118 | return self.data.title | |
119 | ||
9d7e697a MT |
120 | @property |
121 | def title_short(self): | |
122 | if len(self.title) > 30: | |
123 | return "%s..." % self.title[:30] | |
124 | ||
125 | return self.title | |
126 | ||
7771acea MT |
127 | @property |
128 | def slug(self): | |
129 | return self.data.slug | |
130 | ||
131 | @property | |
132 | def tag(self): | |
133 | return self.data.tag | |
134 | ||
135 | @property | |
136 | def description(self): | |
137 | return textile.textile(self.data.description) | |
138 | ||
139 | @property | |
140 | def goal(self): | |
141 | return self.data.goal | |
142 | ||
143 | @property | |
144 | def donated(self): | |
145 | return self.data.donated | |
146 | ||
147 | @property | |
148 | def percentage(self): | |
149 | return (self.donated / self.goal) * 100 | |
150 | ||
918284e8 MT |
151 | @property |
152 | def percentage_bar(self): | |
153 | if self.percentage > 100: | |
154 | return 100 | |
155 | ||
156 | return self.percentage | |
157 | ||
9d7e697a MT |
158 | @property |
159 | def progressbar_colour(self): | |
160 | if self.is_new(): | |
161 | return "bar-success" | |
162 | ||
163 | if self.percentage >= 90: | |
164 | return "bar-danger" | |
165 | ||
166 | return "bar-warning" | |
167 | ||
1bf8d482 MT |
168 | @property |
169 | def status(self): | |
170 | if self.data.status == "running" and not self.running: | |
171 | return "closed" | |
172 | ||
173 | return self.data.status | |
174 | ||
7771acea MT |
175 | @property |
176 | def running(self): | |
9068dba1 MT |
177 | if self.date_end: |
178 | if self.remaining_days and self.remaining_days < 0: | |
179 | return False | |
180 | ||
181 | else: | |
182 | if self.donated >= self.goal: | |
183 | return False | |
7771acea MT |
184 | |
185 | return True | |
186 | ||
187 | @property | |
188 | def date_start(self): | |
189 | return self.data.date_start | |
190 | ||
191 | @property | |
192 | def date_end(self): | |
193 | return self.data.date_end | |
194 | ||
195 | @property | |
196 | def running_days(self): | |
9068dba1 | 197 | running = datetime.datetime.today() - self.date_start |
7771acea MT |
198 | return running.days |
199 | ||
200 | @property | |
201 | def remaining_days(self): | |
9068dba1 MT |
202 | if self.date_end: |
203 | remaining = self.date_end - datetime.datetime.today() | |
204 | return remaining.days | |
7771acea | 205 | |
9d7e697a | 206 | def is_new(self): |
11ed5673 | 207 | return self.running_days < 10 |
9d7e697a | 208 | |
7771acea MT |
209 | def get_tweet(self, locale): |
210 | _ = locale.translate | |
211 | ||
212 | t = [ | |
213 | _("Checkout this crowdfunding wish from #ipfire:"), | |
214 | "http://wishlist.ipfire.org/wish/%s" % self.slug, | |
215 | ] | |
216 | ||
217 | return " ".join(t) |