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