]>
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
= ("i586", "arm")
270 for arch
in ("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 file.type == "iso":
303 # Show nothing when there was no image found.
307 return self
.render_string("modules/download-button.html",
308 release
=release
, image
=best_image
)
311 class PlanetAuthorBoxModule(UIModule
):
312 def render(self
, author
):
313 return self
.render_string("planet/modules/author-box.html", author
=author
)
316 class PlanetEntryModule(UIModule
):
317 def render(self
, entry
, show_avatar
=True):
318 return self
.render_string("modules/planet-entry.html",
319 entry
=entry
, show_avatar
=show_avatar
)
322 class ProgressBarModule(UIModule
):
323 def render(self
, value
, colour
=None):
326 return self
.render_string("modules/progress-bar.html",
327 colour
=colour
, value
=value
)
330 class TalkCallLogModule(UIModule
):
331 def render(self
, account
=None, viewer
=None):
332 if (account
is None or not self
.current_user
== account
) \
333 and not self
.current_user
.is_admin():
334 raise RuntimeException("Insufficient permissions")
337 viewer
= self
.current_user
339 calls
= self
.talk
.get_call_log(account
)
341 return self
.render_string("talk/modules/call-log.html",
342 calls
=calls
, viewer
=viewer
)
345 class TalkLinesModule(UIModule
):
346 def render(self
, account
=None, show_account
=False):
347 if (account
is None or not self
.current_user
== account
) \
348 and not self
.current_user
.is_admin():
349 raise RuntimeException("Insufficient permissions")
351 lines
= self
.talk
.get_lines(account
)
353 return self
.render_string("talk/modules/lines.html",
354 show_account
=show_account
, lines
=lines
)
357 class TalkOngoingCallsModule(UIModule
):
358 def render(self
, account
=None):
359 if (account
is None or not self
.current_user
== account
) \
360 and not self
.current_user
.is_admin():
361 raise RuntimeException("Insufficient permissions")
363 calls
= self
.talk
.get_ongoing_calls(account
)
366 return self
.render_string("talk/modules/ongoing-calls.html",
372 class TrackerPeerListModule(UIModule
):
373 def render(self
, peers
):
374 # Guess country code and hostname of the host
376 country_code
= self
.geoip
.get_country(peer
["ip"])
378 peer
["country_code"] = country_code
.lower()
380 peer
["country_code"] = "unknown"
383 peer
["hostname"] = socket
.gethostbyaddr(peer
["ip"])[0]
385 peer
["hostname"] = ""
387 return self
.render_string("modules/tracker-peerlist.html",
388 peers
=[backend
.database
.Row(p
) for p
in peers
])
391 class WishlistModule(UIModule
):
392 def render(self
, wishes
, short
=False):
393 return self
.render_string("wishlist/modules/wishlist.html",
394 wishes
=wishes
, short
=short
)
397 class WishModule(UIModule
):
398 def render(self
, wish
, short
=False):
399 progress_bar
= "progress-bar-warning"
401 if wish
.percentage
>= 100:
402 progress_bar
= "progress-bar-success"
404 return self
.render_string("wishlist/modules/wish.html",
405 wish
=wish
, short
=short
, progress_bar
=progress_bar
)
408 class WishlistItemsModule(UIModule
):
409 def render(self
, wishlist_items
):
410 return self
.render_string("modules/wishlist-items.html",
411 wishlist_items
=wishlist_items
)
414 class DonationBoxModule(UIModule
):
415 def render(self
, reason_for_transfer
=None):
416 if reason_for_transfer
:
417 reason_for_transfer
= "IPFire.org - %s" % reason_for_transfer
419 return self
.render_string("modules/donation-box.html",
420 reason_for_transfer
=reason_for_transfer
)
423 class DonationButtonModule(UIModule
):
424 # https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/Appx_websitestandard_htmlvariables/
460 def render(self
, reason_for_transfer
=None, currency
="EUR"):
461 if not reason_for_transfer
:
462 reason_for_transfer
= "IPFire.org"
464 primary
= (currency
== "EUR")
466 return self
.render_string("modules/donation-button.html", primary
=primary
,
467 reason_for_transfer
=reason_for_transfer
, currency
=currency
, lc
=self
.lc
)
472 Returns the locale of the user
475 locale
, delimiter
, encoding
= self
.locale
.code
.partition(".")
477 # Break for languages in specific countries
478 if locale
in self
.LOCALES
:
481 lang
, delimiter
, country_code
= locale
.partition("_")
483 if country_code
and country_code
in self
.COUNTRIES
:
487 if lang
in self
.COUNTRIES
:
492 # If anything goes wrong, fall back to GB
496 class DonationInputBoxModule(DonationButtonModule
):
498 currencies
= ("EUR", "USD", "GBP", "CHF", "AUD", "NZD", "CAD")
500 return self
.render_string("modules/donation-input-box.html",
501 currencies
=currencies
, lc
=self
.lc
)