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