]> git.ipfire.org Git - ipfire.org.git/blob - www/webapp/ui_modules.py
Remove obsolete pakfire CGI scripts.
[ipfire.org.git] / www / webapp / ui_modules.py
1 #!/usr/bin/python
2
3 from __future__ import division
4
5 import hashlib
6 import logging
7 import operator
8 import socket
9 import textile
10 import tornado.escape
11 import tornado.locale
12 import tornado.web
13
14 from tornado.database import Row
15
16 import backend
17 import backend.stasy
18
19 class UIModule(tornado.web.UIModule):
20 @property
21 def accounts(self):
22 return self.handler.accounts
23
24 @property
25 def advertisements(self):
26 return self.handler.advertisements
27
28 @property
29 def banners(self):
30 return self.handler.banners
31
32 @property
33 def memcached(self):
34 return self.handler.memcached
35
36 @property
37 def releases(self):
38 return self.handler.releases
39
40 @property
41 def geoip(self):
42 return self.handler.geoip
43
44 @property
45 def news(self):
46 return self.handler.news
47
48
49 class AdvertisementModule(UIModule):
50 def render(self, where):
51 assert where in ("download-splash",), where
52
53 ad = self.advertisements.get(where)
54 if not ad:
55 return ""
56
57 # Mark that advert has been shown.
58 ad.update_impressions()
59
60 return self.render_string("modules/ads/%s.html" % where, ad=ad)
61
62
63 class MenuModule(UIModule):
64 def render(self):
65 return self.render_string("modules/menu.html")
66
67
68 class NewsItemModule(UIModule):
69 def get_author(self, author):
70 # Get name of author
71 author = self.accounts.find(author)
72 if author:
73 return author.cn
74 else:
75 _ = self.locale.translate
76 return _("Unknown author")
77
78 def render(self, item, uncut=True, announcement=False, show_heading=True):
79 # Get author
80 item.author = self.get_author(item.author_id)
81
82 if not uncut and len(item.text) >= 400:
83 item.text = item.text[:400] + "..."
84
85 # Render text
86 text_id = "news-%s" % hashlib.md5(item.text.encode("utf-8")).hexdigest()
87
88 text = self.memcached.get(text_id)
89 if not text:
90 text = textile.textile(item.text)
91 self.memcached.set(text_id, text, 60)
92
93 item.text = text
94
95 return self.render_string("modules/news-item.html", item=item,
96 uncut=uncut, announcement=announcement, show_heading=show_heading)
97
98
99 class NewsLineModule(UIModule):
100 def render(self, item):
101 return self.render_string("modules/news-line.html", item=item)
102
103
104 class NewsTableModule(UIModule):
105 def render(self, news):
106 return self.render_string("modules/news-table.html", news=news)
107
108
109 class NewsYearNavigationModule(UIModule):
110 def render(self, active=None):
111 try:
112 active = int(active)
113 except:
114 active = None
115
116 return self.render_string("modules/news-year-nav.html",
117 active=active, years=self.news.years)
118
119
120 class MirrorItemModule(UIModule):
121 def render(self, item):
122 return self.render_string("modules/mirror-item.html", item=item)
123
124
125 class SidebarItemModule(UIModule):
126 def render(self):
127 return self.render_string("modules/sidebar-item.html")
128
129
130 class SidebarReleaseModule(UIModule):
131 def render(self):
132 return self.render_string("modules/sidebar-release.html",
133 latest=self.releases.get_latest())
134
135
136 class ReleaseItemModule(UIModule):
137 def render(self, release, latest=False):
138 files = {
139 "i586" : [],
140 "arm" : [],
141 }
142
143 for file in release.files:
144 try:
145 files[file.arch].append(file)
146 except KeyError:
147 pass
148
149 return self.render_string("modules/release-item.html",
150 release=release, latest=latest, files=files)
151
152
153 class SidebarBannerModule(UIModule):
154 def render(self, item=None):
155 if not item:
156 item = self.banners.get_random()
157
158 return self.render_string("modules/sidebar-banner.html", item=item)
159
160
161 class DownloadButtonModule(UIModule):
162 def render(self, release, text="Download now!"):
163 best_image = None
164
165 for file in release.files:
166 if file.type == "iso":
167 best_image = file
168 break
169
170 # Show nothing when there was no image found.
171 if not best_image:
172 return ""
173
174 return self.render_string("modules/download-button.html",
175 release=release, image=best_image)
176
177
178 class PlanetEntryModule(UIModule):
179 def render(self, entry, show_avatar=True):
180 return self.render_string("modules/planet-entry.html",
181 entry=entry, show_avatar=show_avatar)
182
183
184 class TrackerPeerListModule(UIModule):
185 def render(self, peers, percentages=False):
186 # Guess country code and hostname of the host
187 for peer in peers:
188 country_code = backend.GeoIP().get_country(peer["ip"])
189 peer["country_code"] = country_code or "unknown"
190
191 try:
192 peer["hostname"] = socket.gethostbyaddr(peer["ip"])[0]
193 except:
194 peer["hostname"] = ""
195
196 return self.render_string("modules/tracker-peerlist.html",
197 peers=[Row(p) for p in peers], percentages=percentages)
198
199
200 class StasyTableModule(UIModule):
201 def _make_percentages(self, items):
202 total = sum(items.values())
203
204 for k in items.keys():
205 items[k] *= 100
206 items[k] /= total
207
208 return items
209
210 def render(self, items, sortby="key", reverse=False, percentage=False, flags=False, locale=False):
211 hundred_percent = 0
212 for v in items.values():
213 hundred_percent += v
214
215 keys = []
216 if sortby == "key":
217 keys = sorted(items.keys(), reverse=reverse)
218 elif sortby == "percentage":
219 keys = [k for k,v in sorted(items.items(), key=operator.itemgetter(1))]
220 if not reverse:
221 keys = reversed(keys)
222 else:
223 raise Exception, "Unknown sortby parameter was provided"
224
225 if hundred_percent:
226 _items = []
227 for k in keys:
228 if not percentage:
229 v = items[k] * 100 / hundred_percent
230 else:
231 v = items[k] * 100
232 _items.append((k, v))
233 items = _items
234
235 if items and type(items[0][0]) == type(()) :
236 _ = self.locale.translate
237 _items = []
238 for k, v in items:
239 k = _("%s to %s") % k
240 _items.append((k, v))
241 items = _items
242
243 if locale:
244 flags = False
245 locales = tornado.locale.LOCALE_NAMES
246 _items = []
247 for k, v in items:
248 if k:
249 for code, locale in locales.items():
250 if code.startswith(k):
251 k = locale["name"].split()[0]
252 _items.append((k, v))
253 items = _items
254
255 return self.render_string("modules/stasy-table.html", items=items, flags=flags)
256
257
258 class StasyCPUCoreTableModule(StasyTableModule):
259 def render(self, items):
260 items = self._make_percentages(items)
261
262 items = items.items()
263 items.sort()
264
265 return self.render_string("modules/stasy-table.html", items=items,
266 flags=None #XXX
267 )
268
269
270 class StasyDeviceTableModule(UIModule):
271 def render(self, devices):
272 groups = {}
273
274 for device in devices:
275 if not groups.has_key(device.cls):
276 groups[device.cls] = []
277
278 groups[device.cls].append(device)
279
280 return self.render_string("modules/stasy-table-devices.html",
281 groups=groups.items())
282
283
284 class StasyGeoTableModule(UIModule):
285 def render(self, items):
286 _ = self.locale.translate
287
288 # Sort all items by value
289 items = sorted(items.items(), key=operator.itemgetter(1), reverse=True)
290
291 countries = []
292 for code, value in items:
293 country = tornado.database.Row({
294 "code" : code.lower(),
295 "name" : _(self.geoip.get_country_name(code)),
296 "value" : value * 100,
297 })
298 countries.append(country)
299
300 return self.render_string("modules/stasy-table-geo.html", countries=countries)
301
302
303 class MirrorsTableModule(UIModule):
304 def render(self, mirrors):
305 return self.render_string("modules/mirrors-table.html", mirrors=mirrors)
306
307
308 class WishlistModule(UIModule):
309 def render(self, wishes, short=False):
310 return self.render_string("wishlist/modules/wishlist.html",
311 wishes=wishes, short=short)
312
313
314 class WishModule(UIModule):
315 def render(self, wish, short=False):
316 progress_bar = "progress-warning"
317
318 if wish.percentage >= 100:
319 progress_bar = "progress-success"
320
321 return self.render_string("wishlist/modules/wish.html",
322 wish=wish, short=short, progress_bar=progress_bar)
323
324
325 class DonationBoxModule(UIModule):
326 def render(self, reason_for_transfer=None):
327 if reason_for_transfer:
328 reason_for_transfer = "IPFire.org - %s" % reason_for_transfer
329
330 return self.render_string("modules/donation-box.html",
331 reason_for_transfer=reason_for_transfer)