]>
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 | ||
7771acea MT |
84 | |
85 | class Wish(object): | |
918284e8 | 86 | def __init__(self, wishlist, id, data=None): |
7771acea MT |
87 | self.wishlist = wishlist |
88 | self.id = id | |
89 | ||
918284e8 | 90 | self.__data = data |
7771acea | 91 | |
9d7e697a MT |
92 | def __repr__(self): |
93 | return "<%s %s>" % (self.__class__.__name__, self.title) | |
94 | ||
7771acea MT |
95 | def __cmp__(self, other): |
96 | return cmp(self.date_end, other.date_end) | |
97 | ||
98 | @property | |
99 | def db(self): | |
100 | return self.wishlist.db | |
101 | ||
102 | @property | |
103 | def data(self): | |
104 | if self.__data is None: | |
105 | self.__data = self.db.get("SELECT * FROM wishlist WHERE id = %s", self.id) | |
106 | assert self.__data | |
107 | ||
108 | return self.__data | |
109 | ||
110 | @property | |
111 | def title(self): | |
112 | return self.data.title | |
113 | ||
9d7e697a MT |
114 | @property |
115 | def title_short(self): | |
116 | if len(self.title) > 30: | |
117 | return "%s..." % self.title[:30] | |
118 | ||
119 | return self.title | |
120 | ||
7771acea MT |
121 | @property |
122 | def slug(self): | |
123 | return self.data.slug | |
124 | ||
125 | @property | |
126 | def tag(self): | |
127 | return self.data.tag | |
128 | ||
129 | @property | |
130 | def description(self): | |
131 | return textile.textile(self.data.description) | |
132 | ||
133 | @property | |
134 | def goal(self): | |
135 | return self.data.goal | |
136 | ||
137 | @property | |
138 | def donated(self): | |
139 | return self.data.donated | |
140 | ||
141 | @property | |
142 | def percentage(self): | |
143 | return (self.donated / self.goal) * 100 | |
144 | ||
918284e8 MT |
145 | @property |
146 | def percentage_bar(self): | |
147 | if self.percentage > 100: | |
148 | return 100 | |
149 | ||
150 | return self.percentage | |
151 | ||
9d7e697a MT |
152 | @property |
153 | def progressbar_colour(self): | |
154 | if self.is_new(): | |
155 | return "bar-success" | |
156 | ||
157 | if self.percentage >= 90: | |
158 | return "bar-danger" | |
159 | ||
160 | return "bar-warning" | |
161 | ||
1bf8d482 MT |
162 | @property |
163 | def status(self): | |
164 | if self.data.status == "running" and not self.running: | |
165 | return "closed" | |
166 | ||
167 | return self.data.status | |
168 | ||
7771acea MT |
169 | @property |
170 | def running(self): | |
9068dba1 MT |
171 | if self.date_end: |
172 | if self.remaining_days and self.remaining_days < 0: | |
173 | return False | |
174 | ||
175 | else: | |
176 | if self.donated >= self.goal: | |
177 | return False | |
7771acea MT |
178 | |
179 | return True | |
180 | ||
181 | @property | |
182 | def date_start(self): | |
183 | return self.data.date_start | |
184 | ||
185 | @property | |
186 | def date_end(self): | |
187 | return self.data.date_end | |
188 | ||
189 | @property | |
190 | def running_days(self): | |
9068dba1 | 191 | running = datetime.datetime.today() - self.date_start |
7771acea MT |
192 | return running.days |
193 | ||
194 | @property | |
195 | def remaining_days(self): | |
9068dba1 MT |
196 | if self.date_end: |
197 | remaining = self.date_end - datetime.datetime.today() | |
198 | return remaining.days | |
7771acea | 199 | |
9d7e697a | 200 | def is_new(self): |
11ed5673 | 201 | return self.running_days < 10 |
9d7e697a | 202 | |
7771acea MT |
203 | def get_tweet(self, locale): |
204 | _ = locale.translate | |
205 | ||
206 | t = [ | |
207 | _("Checkout this crowdfunding wish from #ipfire:"), | |
208 | "http://wishlist.ipfire.org/wish/%s" % self.slug, | |
209 | ] | |
210 | ||
211 | return " ".join(t) |