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