]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blame - webapp/ui_modules.py
Fix various errors with newer versions of python
[people/shoehn/ipfire.org.git] / webapp / ui_modules.py
CommitLineData
81675874 1#!/usr/bin/python
2
91a446f0
MT
3from __future__ import division
4
de683d7c 5import hashlib
940227cb 6import logging
91a446f0 7import operator
9068dba1 8import re
940227cb
MT
9import socket
10import textile
11import tornado.escape
6af40477 12import tornado.locale
feb02477 13import tornado.web
9068dba1 14import unicodedata
81675874 15
940227cb 16import backend
91a446f0 17import backend.stasy
940227cb 18
81675874 19class UIModule(tornado.web.UIModule):
940227cb
MT
20 @property
21 def accounts(self):
22 return self.handler.accounts
81675874 23
a0048e66
MT
24 @property
25 def advertisements(self):
26 return self.handler.advertisements
27
d0d074e0 28 @property
940227cb
MT
29 def banners(self):
30 return self.handler.banners
d0d074e0 31
de683d7c
MT
32 @property
33 def memcached(self):
34 return self.handler.memcached
35
940227cb
MT
36 @property
37 def releases(self):
38 return self.handler.releases
81675874 39
638e9782
MT
40 @property
41 def geoip(self):
42 return self.handler.geoip
43
7771acea
MT
44 @property
45 def news(self):
46 return self.handler.news
47
fa7e1a0a
MT
48 @property
49 def planet(self):
50 return self.handler.planet
51
e64ce07e
MT
52 @property
53 def wishlist(self):
54 return self.handler.wishlist
55
5a1018ab 56
a0048e66
MT
57class AdvertisementModule(UIModule):
58 def render(self, where):
59 assert where in ("download-splash",), where
60
61 ad = self.advertisements.get(where)
62 if not ad:
63 return ""
64
65 # Mark that advert has been shown.
66 ad.update_impressions()
67
68 return self.render_string("modules/ads/%s.html" % where, ad=ad)
69
70
9068dba1
MT
71class MapModule(UIModule):
72 def render(self, latitude, longitude):
73 return self.render_string("modules/map.html", latitude=latitude, longitude=longitude)
74
75
940227cb
MT
76class MenuModule(UIModule):
77 def render(self):
60024cc8 78 return self.render_string("modules/menu.html")
81675874 79
80
9068dba1
MT
81class MirrorItemModule(UIModule):
82 def render(self, item):
83 return self.render_string("modules/mirror-item.html", item=item)
84
85
86class MirrorsTableModule(UIModule):
87 def render(self, mirrors, preferred_mirrors=[]):
88 return self.render_string("modules/mirrors-table.html",
89 mirrors=mirrors, preferred_mirrors=preferred_mirrors)
90
91
92class NetBootMenuConfigModule(UIModule):
93 def render(self, release):
94 return self.render_string("netboot/menu-config.cfg", release=release)
95
96
97class NetBootMenuHeaderModule(UIModule):
98 def render(self, title, releases):
99 id = unicodedata.normalize("NFKD", unicode(title)).encode("ascii", "ignore")
100 id = re.sub(r"[^\w]+", " ", id)
101 id = "-".join(id.lower().strip().split())
102
103 return self.render_string("netboot/menu-header.cfg", id=id,
104 title=title, releases=releases)
105
106
107class NetBootMenuSeparatorModule(UIModule):
108 def render(self):
109 return self.render_string("netboot/menu-separator.cfg")
110
111
81675874 112class NewsItemModule(UIModule):
940227cb
MT
113 def get_author(self, author):
114 # Get name of author
115 author = self.accounts.find(author)
116 if author:
117 return author.cn
118 else:
119 _ = self.locale.translate
120 return _("Unknown author")
121
60024cc8 122 def render(self, item, uncut=True, announcement=False, show_heading=True):
940227cb
MT
123 # Get author
124 item.author = self.get_author(item.author_id)
81675874 125
940227cb
MT
126 if not uncut and len(item.text) >= 400:
127 item.text = item.text[:400] + "..."
81675874 128
940227cb 129 # Render text
e46e8df8 130 item.text = textile.textile(item.text.decode("utf8"))
81675874 131
60024cc8
MT
132 return self.render_string("modules/news-item.html", item=item,
133 uncut=uncut, announcement=announcement, show_heading=show_heading)
940227cb
MT
134
135
7771acea 136class NewsLineModule(UIModule):
940227cb
MT
137 def render(self, item):
138 return self.render_string("modules/news-line.html", item=item)
139
140
7771acea
MT
141class NewsTableModule(UIModule):
142 def render(self, news):
143 return self.render_string("modules/news-table.html", news=news)
144
145
146class NewsYearNavigationModule(UIModule):
147 def render(self, active=None):
148 try:
149 active = int(active)
150 except:
151 active = None
152
153 return self.render_string("modules/news-year-nav.html",
154 active=active, years=self.news.years)
155
156
fa7e1a0a
MT
157class PlanetSearchBoxModule(UIModule):
158 def render(self, query=None):
159 years = self.planet.get_years()
160
161 return self.render_string("modules/planet/search-box.html",
162 query=query, years=years)
163
164
81675874 165class SidebarItemModule(UIModule):
166 def render(self):
167 return self.render_string("modules/sidebar-item.html")
168
169
170class SidebarReleaseModule(UIModule):
81675874 171 def render(self):
172 return self.render_string("modules/sidebar-release.html",
940227cb 173 latest=self.releases.get_latest())
81675874 174
175
176class ReleaseItemModule(UIModule):
60024cc8 177 def render(self, release, latest=False):
110e8687 178 arches = ("i586", "arm")
60024cc8 179
110e8687
MT
180 downloads = []
181 for arch in ("i586", "arm"):
182 files = []
183
184 for file in release.files:
185 if not file.arch == arch:
186 continue
187
188 files.append(file)
189
190 if files:
191 downloads.append((arch, files))
60024cc8
MT
192
193 return self.render_string("modules/release-item.html",
110e8687 194 release=release, latest=latest, downloads=downloads)
81675874 195
196
197class SidebarBannerModule(UIModule):
940227cb
MT
198 def render(self, item=None):
199 if not item:
200 item = self.banners.get_random()
201
81675874 202 return self.render_string("modules/sidebar-banner.html", item=item)
203
204
60024cc8
MT
205class DownloadButtonModule(UIModule):
206 def render(self, release, text="Download now!"):
207 best_image = None
208
209 for file in release.files:
210 if file.type == "iso":
211 best_image = file
212 break
213
214 # Show nothing when there was no image found.
215 if not best_image:
216 return ""
217
218 return self.render_string("modules/download-button.html",
219 release=release, image=best_image)
220
221
940227cb 222class PlanetEntryModule(UIModule):
60024cc8 223 def render(self, entry, show_avatar=True):
940227cb 224 return self.render_string("modules/planet-entry.html",
60024cc8 225 entry=entry, show_avatar=show_avatar)
d0d074e0
MT
226
227
940227cb 228class TrackerPeerListModule(UIModule):
6d524cba 229 def render(self, peers):
940227cb
MT
230 # Guess country code and hostname of the host
231 for peer in peers:
6d524cba
MT
232 country_code = self.geoip.get_country(peer["ip"])
233 if country_code:
234 country_code = country_code.lower()
940227cb 235 peer["country_code"] = country_code or "unknown"
d0d074e0 236
940227cb
MT
237 try:
238 peer["hostname"] = socket.gethostbyaddr(peer["ip"])[0]
239 except:
240 peer["hostname"] = ""
d0d074e0 241
940227cb 242 return self.render_string("modules/tracker-peerlist.html",
e46e8df8 243 peers=[backend.database.Row(p) for p in peers])
372efc19
MT
244
245
246class StasyTableModule(UIModule):
62c3fa48
MT
247 def _make_percentages(self, items):
248 total = sum(items.values())
249
250 for k in items.keys():
251 items[k] *= 100
252 items[k] /= total
253
254 return items
255
6af40477 256 def render(self, items, sortby="key", reverse=False, percentage=False, flags=False, locale=False):
372efc19
MT
257 hundred_percent = 0
258 for v in items.values():
259 hundred_percent += v
260
91a446f0
MT
261 keys = []
262 if sortby == "key":
263 keys = sorted(items.keys(), reverse=reverse)
264 elif sortby == "percentage":
265 keys = [k for k,v in sorted(items.items(), key=operator.itemgetter(1))]
266 if not reverse:
267 keys = reversed(keys)
268 else:
269 raise Exception, "Unknown sortby parameter was provided"
270
372efc19
MT
271 if hundred_percent:
272 _items = []
91a446f0 273 for k in keys:
e6cff1b1
MT
274 if not percentage:
275 v = items[k] * 100 / hundred_percent
276 else:
277 v = items[k] * 100
372efc19
MT
278 _items.append((k, v))
279 items = _items
280
0d01fda0
MT
281 if items and type(items[0][0]) == type(()) :
282 _ = self.locale.translate
283 _items = []
284 for k, v in items:
285 k = _("%s to %s") % k
286 _items.append((k, v))
287 items = _items
288
6af40477
MT
289 if locale:
290 flags = False
291 locales = tornado.locale.LOCALE_NAMES
292 _items = []
293 for k, v in items:
02888488
MT
294 if k:
295 for code, locale in locales.items():
296 if code.startswith(k):
297 k = locale["name"].split()[0]
6af40477
MT
298 _items.append((k, v))
299 items = _items
300
665ef07e 301 return self.render_string("modules/stasy-table.html", items=items, flags=flags)
91a446f0
MT
302
303
62c3fa48
MT
304class StasyCPUCoreTableModule(StasyTableModule):
305 def render(self, items):
306 items = self._make_percentages(items)
307
308 items = items.items()
309 items.sort()
310
311 return self.render_string("modules/stasy-table.html", items=items,
312 flags=None #XXX
313 )
314
315
91a446f0
MT
316class StasyDeviceTableModule(UIModule):
317 def render(self, devices):
318 groups = {}
319
320 for device in devices:
321 if not groups.has_key(device.cls):
322 groups[device.cls] = []
323
324 groups[device.cls].append(device)
325
326 return self.render_string("modules/stasy-table-devices.html",
327 groups=groups.items())
638e9782
MT
328
329
330class StasyGeoTableModule(UIModule):
331 def render(self, items):
332 _ = self.locale.translate
333
334 # Sort all items by value
335 items = sorted(items.items(), key=operator.itemgetter(1), reverse=True)
336
337 countries = []
338 for code, value in items:
e46e8df8 339 country = backend.database.Row({
638e9782
MT
340 "code" : code.lower(),
341 "name" : _(self.geoip.get_country_name(code)),
342 "value" : value * 100,
343 })
344 countries.append(country)
345
346 return self.render_string("modules/stasy-table-geo.html", countries=countries)
0673d1b0
MT
347
348
7771acea
MT
349class WishlistModule(UIModule):
350 def render(self, wishes, short=False):
351 return self.render_string("wishlist/modules/wishlist.html",
352 wishes=wishes, short=short)
353
354
355class WishModule(UIModule):
356 def render(self, wish, short=False):
3907b320 357 progress_bar = "progress-bar-warning"
7771acea 358
f60b79ce 359 if wish.percentage >= 100:
3907b320 360 progress_bar = "progress-bar-success"
7771acea
MT
361
362 return self.render_string("wishlist/modules/wish.html",
363 wish=wish, short=short, progress_bar=progress_bar)
364
365
e64ce07e
MT
366class WishlistItemsModule(UIModule):
367 def render(self, wishlist_items):
368 return self.render_string("modules/wishlist-items.html",
369 wishlist_items=wishlist_items)
370
371
7771acea 372class DonationBoxModule(UIModule):
e64ce07e 373 def render(self, reason_for_transfer=None, show_wishlist_items=False):
353880e5
MT
374 if reason_for_transfer:
375 reason_for_transfer = "IPFire.org - %s" % reason_for_transfer
376
e64ce07e
MT
377 # Interesting items from the wishlist.
378 wishlist_items = []
379 if show_wishlist_items:
380 wishlist_items = self.wishlist.get_hot_wishes()
381
353880e5 382 return self.render_string("modules/donation-box.html",
e64ce07e 383 reason_for_transfer=reason_for_transfer, wishlist_items=wishlist_items)