]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blame - webapp/ui_modules.py
Add more vhosts to the dev namespace.
[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
fa7e1a0a
MT
50 @property
51 def planet(self):
52 return self.handler.planet
53
e64ce07e
MT
54 @property
55 def wishlist(self):
56 return self.handler.wishlist
57
5a1018ab 58
a0048e66
MT
59class AdvertisementModule(UIModule):
60 def render(self, where):
61 assert where in ("download-splash",), where
62
63 ad = self.advertisements.get(where)
64 if not ad:
65 return ""
66
67 # Mark that advert has been shown.
68 ad.update_impressions()
69
70 return self.render_string("modules/ads/%s.html" % where, ad=ad)
71
72
9068dba1
MT
73class MapModule(UIModule):
74 def render(self, latitude, longitude):
75 return self.render_string("modules/map.html", latitude=latitude, longitude=longitude)
76
77
940227cb
MT
78class MenuModule(UIModule):
79 def render(self):
60024cc8 80 return self.render_string("modules/menu.html")
81675874 81
82
9068dba1
MT
83class MirrorItemModule(UIModule):
84 def render(self, item):
85 return self.render_string("modules/mirror-item.html", item=item)
86
87
88class MirrorsTableModule(UIModule):
89 def render(self, mirrors, preferred_mirrors=[]):
90 return self.render_string("modules/mirrors-table.html",
91 mirrors=mirrors, preferred_mirrors=preferred_mirrors)
92
93
94class NetBootMenuConfigModule(UIModule):
95 def render(self, release):
96 return self.render_string("netboot/menu-config.cfg", release=release)
97
98
99class NetBootMenuHeaderModule(UIModule):
100 def render(self, title, releases):
101 id = unicodedata.normalize("NFKD", unicode(title)).encode("ascii", "ignore")
102 id = re.sub(r"[^\w]+", " ", id)
103 id = "-".join(id.lower().strip().split())
104
105 return self.render_string("netboot/menu-header.cfg", id=id,
106 title=title, releases=releases)
107
108
109class NetBootMenuSeparatorModule(UIModule):
110 def render(self):
111 return self.render_string("netboot/menu-separator.cfg")
112
113
81675874 114class NewsItemModule(UIModule):
940227cb
MT
115 def get_author(self, author):
116 # Get name of author
117 author = self.accounts.find(author)
118 if author:
119 return author.cn
120 else:
121 _ = self.locale.translate
122 return _("Unknown author")
123
60024cc8 124 def render(self, item, uncut=True, announcement=False, show_heading=True):
940227cb
MT
125 # Get author
126 item.author = self.get_author(item.author_id)
81675874 127
940227cb
MT
128 if not uncut and len(item.text) >= 400:
129 item.text = item.text[:400] + "..."
81675874 130
940227cb 131 # Render text
9068dba1 132 item.text = textile.textile(item.text)
81675874 133
60024cc8
MT
134 return self.render_string("modules/news-item.html", item=item,
135 uncut=uncut, announcement=announcement, show_heading=show_heading)
940227cb
MT
136
137
7771acea 138class NewsLineModule(UIModule):
940227cb
MT
139 def render(self, item):
140 return self.render_string("modules/news-line.html", item=item)
141
142
7771acea
MT
143class NewsTableModule(UIModule):
144 def render(self, news):
145 return self.render_string("modules/news-table.html", news=news)
146
147
148class NewsYearNavigationModule(UIModule):
149 def render(self, active=None):
150 try:
151 active = int(active)
152 except:
153 active = None
154
155 return self.render_string("modules/news-year-nav.html",
156 active=active, years=self.news.years)
157
158
fa7e1a0a
MT
159class PlanetSearchBoxModule(UIModule):
160 def render(self, query=None):
161 years = self.planet.get_years()
162
163 return self.render_string("modules/planet/search-box.html",
164 query=query, years=years)
165
166
81675874 167class SidebarItemModule(UIModule):
168 def render(self):
169 return self.render_string("modules/sidebar-item.html")
170
171
172class SidebarReleaseModule(UIModule):
81675874 173 def render(self):
174 return self.render_string("modules/sidebar-release.html",
940227cb 175 latest=self.releases.get_latest())
81675874 176
177
178class ReleaseItemModule(UIModule):
60024cc8 179 def render(self, release, latest=False):
110e8687 180 arches = ("i586", "arm")
60024cc8 181
110e8687
MT
182 downloads = []
183 for arch in ("i586", "arm"):
184 files = []
185
186 for file in release.files:
187 if not file.arch == arch:
188 continue
189
190 files.append(file)
191
192 if files:
193 downloads.append((arch, files))
60024cc8
MT
194
195 return self.render_string("modules/release-item.html",
110e8687 196 release=release, latest=latest, downloads=downloads)
81675874 197
198
199class SidebarBannerModule(UIModule):
940227cb
MT
200 def render(self, item=None):
201 if not item:
202 item = self.banners.get_random()
203
81675874 204 return self.render_string("modules/sidebar-banner.html", item=item)
205
206
60024cc8
MT
207class DownloadButtonModule(UIModule):
208 def render(self, release, text="Download now!"):
209 best_image = None
210
211 for file in release.files:
212 if file.type == "iso":
213 best_image = file
214 break
215
216 # Show nothing when there was no image found.
217 if not best_image:
218 return ""
219
220 return self.render_string("modules/download-button.html",
221 release=release, image=best_image)
222
223
940227cb 224class PlanetEntryModule(UIModule):
60024cc8 225 def render(self, entry, show_avatar=True):
940227cb 226 return self.render_string("modules/planet-entry.html",
60024cc8 227 entry=entry, show_avatar=show_avatar)
d0d074e0
MT
228
229
940227cb
MT
230class TrackerPeerListModule(UIModule):
231 def render(self, peers, percentages=False):
232 # Guess country code and hostname of the host
233 for peer in peers:
234 country_code = backend.GeoIP().get_country(peer["ip"])
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
MT
242 return self.render_string("modules/tracker-peerlist.html",
243 peers=[Row(p) for p in peers], percentages=percentages)
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:
339 country = tornado.database.Row({
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)