]>
git.ipfire.org Git - people/shoehn/ipfire.org.git/blob - webapp/ui_modules.py
3 from __future__
import division
18 class UIModule(tornado
.web
.UIModule
):
21 return self
.handler
.accounts
24 def advertisements(self
):
25 return self
.handler
.advertisements
29 return self
.handler
.banners
33 return self
.handler
.memcached
37 return self
.handler
.releases
41 return self
.handler
.geoip
45 return self
.handler
.news
49 return self
.handler
.planet
53 return self
.handler
.talk
57 return self
.handler
.wishlist
60 class AdvertisementModule(UIModule
):
61 def render(self
, where
):
62 assert where
in ("download-splash",), where
64 ad
= self
.advertisements
.get(where
)
68 # Mark that advert has been shown.
69 ad
.update_impressions()
71 return self
.render_string("modules/ads/%s.html" % where
, ad
=ad
)
74 class FireinfoDeviceTableModule(UIModule
):
75 def render(self
, devices
):
76 return self
.render_string("fireinfo/modules/table-devices.html",
80 class FireinfoDeviceAndGroupsTableModule(UIModule
):
81 def render(self
, devices
):
82 _
= self
.locale
.translate
86 for device
in devices
:
87 if not groups
.has_key(device
.cls
):
88 groups
[device
.cls
] = []
90 groups
[device
.cls
].append(device
)
93 for key
in groups
.keys():
96 # Order the groups by their name
97 groups
= groups
.items()
100 return self
.render_string("fireinfo/modules/table-devices-and-groups.html",
104 class FireinfoGeoTableModule(UIModule
):
105 def render(self
, items
):
108 for code
, value
in items
:
109 # Skip the satellite providers in this ranking
110 if code
in (None, "A1", "A2"):
113 name
= self
.geoip
.get_country_name(code
)
115 # Don't add countries with a small share on the list
117 other_countries
.append(name
)
120 country
= backend
.database
.Row({
125 countries
.append(country
)
127 return self
.render_string("fireinfo/modules/table-geo.html",
128 countries
=countries
, other_countries
=other_countries
)
131 class LanguageNameModule(UIModule
):
132 def render(self
, language
):
133 _
= self
.locale
.translate
137 elif language
== "en":
139 elif language
== "es":
141 elif language
== "fr":
143 elif language
== "it":
145 elif language
== "nl":
147 elif language
== "pl":
149 elif language
== "pt":
150 return _("Portuguese")
151 elif language
== "ru":
153 elif language
== "tr":
159 class MapModule(UIModule
):
160 def render(self
, latitude
, longitude
):
161 return self
.render_string("modules/map.html", latitude
=latitude
, longitude
=longitude
)
164 class MenuModule(UIModule
):
166 return self
.render_string("modules/menu.html")
169 class MirrorItemModule(UIModule
):
170 def render(self
, item
):
171 return self
.render_string("modules/mirror-item.html", item
=item
)
174 class MirrorsTableModule(UIModule
):
175 def render(self
, mirrors
, preferred_mirrors
=[]):
176 return self
.render_string("modules/mirrors-table.html",
177 mirrors
=mirrors
, preferred_mirrors
=preferred_mirrors
)
180 class NetBootMenuConfigModule(UIModule
):
181 def render(self
, release
, arch
=None, platform
=None):
182 return self
.render_string("netboot/menu-config.cfg", release
=release
,
183 arch
=arch
, platform
=platform
)
186 class NetBootMenuHeaderModule(UIModule
):
187 def render(self
, title
, releases
, arch
=None, platform
=None):
188 id = unicodedata
.normalize("NFKD", unicode(title
)).encode("ascii", "ignore")
189 id = re
.sub(r
"[^\w]+", " ", id)
190 id = "-".join(id.lower().strip().split())
192 return self
.render_string("netboot/menu-header.cfg", id=id,
193 title
=title
, releases
=releases
, arch
=arch
, platform
=platform
)
196 class NetBootMenuSeparatorModule(UIModule
):
198 return self
.render_string("netboot/menu-separator.cfg")
201 class NewsItemModule(UIModule
):
202 def get_author(self
, author
):
204 author
= self
.accounts
.find(author
)
208 _
= self
.locale
.translate
209 return _("Unknown author")
211 def render(self
, item
, uncut
=True, announcement
=False, show_heading
=True):
213 item
.author
= self
.get_author(item
.author_id
)
215 if not uncut
and len(item
.text
) >= 400:
216 item
.text
= item
.text
[:400] + "..."
219 item
.text
= textile
.textile(item
.text
.decode("utf8"))
221 # Find a release if one exists
222 release
= self
.releases
.get_by_news_id(item
.uuid
)
224 return self
.render_string("modules/news-item.html", item
=item
, release
=release
,
225 uncut
=uncut
, announcement
=announcement
, show_heading
=show_heading
)
228 class NewsLineModule(UIModule
):
229 def render(self
, item
):
230 return self
.render_string("modules/news-line.html", item
=item
)
233 class NewsTableModule(UIModule
):
234 def render(self
, news
):
235 return self
.render_string("modules/news-table.html", news
=news
)
238 class NewsYearNavigationModule(UIModule
):
239 def render(self
, active
=None):
245 return self
.render_string("modules/news-year-nav.html",
246 active
=active
, years
=self
.news
.years
)
249 class PlanetSearchBoxModule(UIModule
):
250 def render(self
, query
=None):
251 return self
.render_string("modules/planet/search-box.html", query
=query
)
254 class SidebarItemModule(UIModule
):
256 return self
.render_string("modules/sidebar-item.html")
259 class SidebarReleaseModule(UIModule
):
261 return self
.render_string("modules/sidebar-release.html",
262 latest
=self
.releases
.get_latest())
265 class ReleaseItemModule(UIModule
):
266 def render(self
, release
, latest
=False):
267 arches
= ("x86_64", "i586", "arm")
273 for file in release
.files
:
274 if not file.arch
== arch
:
280 downloads
.append((arch
, files
))
282 return self
.render_string("modules/release-item.html",
283 release
=release
, latest
=latest
, downloads
=downloads
)
286 class SidebarBannerModule(UIModule
):
287 def render(self
, item
=None):
289 item
= self
.banners
.get_random()
291 return self
.render_string("modules/sidebar-banner.html", item
=item
)
294 class DownloadButtonModule(UIModule
):
295 def render(self
, release
, text
="Download now!"):
298 for file in release
.files
:
299 if (release
.sname
< "ipfire-2.19-core100" or file.arch
== "x86_64") \
300 and file.type == "iso":
304 # Show nothing when there was no image found.
308 return self
.render_string("modules/download-button.html",
309 release
=release
, image
=best_image
)
312 class PlanetAuthorBoxModule(UIModule
):
313 def render(self
, author
):
314 return self
.render_string("planet/modules/author-box.html", author
=author
)
317 class PlanetEntryModule(UIModule
):
318 def render(self
, entry
, show_avatar
=True):
319 return self
.render_string("modules/planet-entry.html",
320 entry
=entry
, show_avatar
=show_avatar
)
323 class ProgressBarModule(UIModule
):
324 def render(self
, value
, colour
=None):
327 return self
.render_string("modules/progress-bar.html",
328 colour
=colour
, value
=value
)
331 class TalkCallLogModule(UIModule
):
332 def render(self
, account
=None, viewer
=None):
333 if (account
is None or not self
.current_user
== account
) \
334 and not self
.current_user
.is_admin():
335 raise RuntimeException("Insufficient permissions")
338 viewer
= self
.current_user
340 calls
= self
.talk
.get_call_log(account
)
342 return self
.render_string("talk/modules/call-log.html",
343 calls
=calls
, viewer
=viewer
)
346 class TalkLinesModule(UIModule
):
347 def render(self
, account
=None, show_account
=False):
348 if (account
is None or not self
.current_user
== account
) \
349 and not self
.current_user
.is_admin():
350 raise RuntimeException("Insufficient permissions")
352 lines
= self
.talk
.get_lines(account
)
354 return self
.render_string("talk/modules/lines.html",
355 show_account
=show_account
, lines
=lines
)
358 class TalkOngoingCallsModule(UIModule
):
359 def render(self
, account
=None):
360 if (account
is None or not self
.current_user
== account
) \
361 and not self
.current_user
.is_admin():
362 raise RuntimeException("Insufficient permissions")
364 calls
= self
.talk
.get_ongoing_calls(account
)
367 return self
.render_string("talk/modules/ongoing-calls.html",
373 class TrackerPeerListModule(UIModule
):
374 def render(self
, peers
):
375 # Guess country code and hostname of the host
377 country_code
= self
.geoip
.get_country(peer
["ip"])
379 peer
["country_code"] = country_code
.lower()
381 peer
["country_code"] = "unknown"
384 peer
["hostname"] = socket
.gethostbyaddr(peer
["ip"])[0]
386 peer
["hostname"] = ""
388 return self
.render_string("modules/tracker-peerlist.html",
389 peers
=[backend
.database
.Row(p
) for p
in peers
])
392 class WishlistModule(UIModule
):
393 def render(self
, wishes
, short
=False):
394 return self
.render_string("wishlist/modules/wishlist.html",
395 wishes
=wishes
, short
=short
)
398 class WishModule(UIModule
):
399 def render(self
, wish
, short
=False):
400 progress_bar
= "progress-bar-warning"
402 if wish
.percentage
>= 100:
403 progress_bar
= "progress-bar-success"
405 return self
.render_string("wishlist/modules/wish.html",
406 wish
=wish
, short
=short
, progress_bar
=progress_bar
)
409 class WishlistItemsModule(UIModule
):
410 def render(self
, wishlist_items
):
411 return self
.render_string("modules/wishlist-items.html",
412 wishlist_items
=wishlist_items
)
415 class DonationBoxModule(UIModule
):
416 def render(self
, reason_for_transfer
=None):
417 if reason_for_transfer
:
418 reason_for_transfer
= "IPFire.org - %s" % reason_for_transfer
420 return self
.render_string("modules/donation-box.html",
421 reason_for_transfer
=reason_for_transfer
)
424 class DonationButtonModule(UIModule
):
425 # https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/
461 def render(self
, reason_for_transfer
=None, currency
="EUR"):
462 if not reason_for_transfer
:
463 reason_for_transfer
= "IPFire.org"
465 primary
= (currency
== "EUR")
467 return self
.render_string("modules/donation-button.html", primary
=primary
,
468 reason_for_transfer
=reason_for_transfer
, currency
=currency
, lc
=self
.lc
)
473 Returns the locale of the user
476 locale
, delimiter
, encoding
= self
.locale
.code
.partition(".")
478 # Break for languages in specific countries
479 if locale
in self
.LOCALES
:
482 lang
, delimiter
, country_code
= locale
.partition("_")
484 if country_code
and country_code
in self
.COUNTRIES
:
488 if lang
in self
.COUNTRIES
:
493 # If anything goes wrong, fall back to GB
497 class DonationInputBoxModule(DonationButtonModule
):
499 currencies
= ("EUR", "USD", "GBP", "CHF", "AUD", "NZD", "CAD")
501 return self
.render_string("modules/donation-input-box.html",
502 currencies
=currencies
, lc
=self
.lc
)