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