]> git.ipfire.org Git - ipfire.org.git/blame - src/web/__init__.py
location: Use country name from location database
[ipfire.org.git] / src / web / __init__.py
CommitLineData
81675874 1#/usr/bin/python
2
feb02477 3import logging
401827c2 4import itertools
81675874 5import os.path
c01ad253 6import phonenumbers
e96e445b 7import phonenumbers.geocoder
81675874 8import tornado.locale
a49b5422 9import tornado.options
81675874 10import tornado.web
11
a95c2f97 12import ipfire
574a88c7 13import ipfire.countries
440aba92 14from .. import util
feb02477 15
11347e46 16from .handlers import *
81675874 17
08df6527 18from . import auth
12e5de7e 19from . import blog
f301d952 20from . import boot
c7bcb9ca 21from . import donate
e77cd04c 22from . import download
96c9bb79 23from . import fireinfo
699a0911 24from . import iuse
f5b01fc2 25from . import location
95483f04 26from . import mirrors
a41085fb 27from . import nopaste
03706893 28from . import people
df6180a5 29from . import ui_modules
181d08f3 30from . import wiki
12e5de7e 31
81675874 32class Application(tornado.web.Application):
3e7c6ccd
MT
33 def __init__(self, config, **kwargs):
34 # Initialize backend
a95c2f97 35 self.backend = ipfire.Backend(config)
a6dc0bad 36
9ed02e3b
MT
37 settings = {
38 # Do not compress responses
39 "gzip" : False,
40
41 # Enable XSRF cookies
42 "xsrf_cookies" : True,
43
44 # Login
45 "login_url" : "/login",
46
47 # Setup directory structure
48 "static_path" : self.backend.config.get("global", "static_dir"),
49 "template_path" : self.backend.config.get("global", "templates_dir"),
50
eabe6b8d 51 # UI Methods
9ed02e3b 52 "ui_methods" : {
574a88c7 53 "format_country_name" : self.format_country_name,
6eddfb50 54 "format_language_name" : self.format_language_name,
e96e445b
MT
55 "format_month_name" : self.format_month_name,
56 "format_phone_number" : self.format_phone_number,
57 "format_phone_number_to_e164" : self.format_phone_number_to_e164,
58 "format_phone_number_location" : self.format_phone_number_location,
59 "grouper" : grouper,
cc3b928d 60 },
eabe6b8d
MT
61
62 # UI Modules
9ed02e3b 63 "ui_modules" : {
f5b01fc2 64 # Blog
7e64f6a3
MT
65 "BlogHistoryNavigation": blog.HistoryNavigationModule,
66 "BlogList" : blog.ListModule,
f91dfcc7 67 "BlogPost" : blog.PostModule,
8a897d25 68 "BlogPosts" : blog.PostsModule,
f91dfcc7 69
93feb275
MT
70 # Boot
71 "BootMenuConfig" : boot.MenuConfigModule,
72 "BootMenuHeader" : boot.MenuHeaderModule,
73 "BootMenuSeparator" : boot.MenuSeparatorModule,
74
eabe6b8d 75 # People
dbb0c109 76 "AccountsList" : people.AccountsListModule,
c66f2152 77 "Agent" : people.AgentModule,
dbb0c109
MT
78 "CDR" : people.CDRModule,
79 "Channels" : people.ChannelsModule,
68ece434 80 "MOS" : people.MOSModule,
9150881e 81 "NewAccounts" : people.NewAccountsModule,
b5e2077f 82 "Password" : people.PasswordModule,
dbb0c109 83 "Registrations" : people.RegistrationsModule,
7afd64bb 84 "SIPStatus" : people.SIPStatusModule,
917434b8 85
e1814f16
MT
86 # Nopaste
87 "Code" : nopaste.CodeModule,
88
23f0179e 89 # Fireinfo
96c9bb79 90 "FireinfoDeviceTable" : fireinfo.DeviceTableModule,
eabe6b8d
MT
91 "FireinfoDeviceAndGroupsTable"
92 : fireinfo.DeviceAndGroupsTableModule,
93
6ac7e934 94 # Wiki
c21ffadb 95 "WikiDiff" : wiki.WikiDiffModule,
6ac7e934 96 "WikiNavbar" : wiki.WikiNavbarModule,
f9db574a 97 "WikiList" : wiki.WikiListModule,
6ac7e934 98
eabe6b8d 99 # Misc
6563eb49 100 "ChristmasBanner" : ui_modules.ChristmasBannerModule,
1c4522dc 101 "Markdown" : ui_modules.MarkdownModule,
eabe6b8d
MT
102 "Map" : ui_modules.MapModule,
103 "ProgressBar" : ui_modules.ProgressBarModule,
81675874 104 },
3403dc5e
MT
105
106 # Call this when a page wasn't found
b22bc8e8 107 "default_handler_class" : base.NotFoundHandler,
9ed02e3b 108 }
9068dba1 109 settings.update(kwargs)
5cf160e0 110
ae0228e1
MT
111 tornado.web.Application.__init__(self, **settings)
112
66862195 113 authentication_handlers = [
08df6527
MT
114 (r"/login", auth.LoginHandler),
115 (r"/logout", auth.LogoutHandler),
66862195
MT
116 ]
117
399506a8 118 self.add_handlers(r"(dev|www)\.ipfire\.org", [
940227cb
MT
119 # Entry site that lead the user to index
120 (r"/", IndexHandler),
940227cb 121
81675874 122 # Download sites
60b0917c 123 (r"/downloads", tornado.web.RedirectHandler, { "url" : "/download" }),
e77cd04c
MT
124 (r"/download", download.IndexHandler),
125 (r"/download/([0-9a-z\-\.]+)", download.ReleaseHandler),
940227cb 126
e64ce07e 127 # Donate
c7bcb9ca
MT
128 (r"/donate", donate.DonateHandler),
129 (r"/donate/thank-you", donate.ThankYouHandler),
130 (r"/donate/error", donate.ErrorHandler),
e64ce07e 131 (r"/donation", tornado.web.RedirectHandler, { "url" : "/donate" }),
8d48f4ef 132
de683d7c 133 # RSS feed
f0714277 134 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
7f9dbcc0
MT
135
136 # Redirect news articles to blog
d76ec66e 137 (r"/news/(.*)", handlers.NewsHandler),
de683d7c 138
45592df5 139 # Static Pages
45592df5 140 (r"/features", StaticHandler, { "template" : "features.html" }),
45592df5 141 (r"/legal", StaticHandler, { "template" : "legal.html" }),
00026d8b 142 (r"/support", StaticHandler, { "template" : "support.html" }),
45592df5 143
14cd4fa8
MT
144 # Handle old pages that have moved elsewhere
145 (r"/imprint", tornado.web.RedirectHandler, { "url" : "/legal" }),
3808b871 146 (r"/(de|en)/(.*)", LangCompatHandler),
37ed7c3c
MT
147
148 # Export arbitrary error pages
b22bc8e8 149 (r"/error/([45][0-9]{2})", base.ErrorHandler),
940227cb
MT
150 ])
151
12e5de7e 152 # blog.ipfire.org
440aba92 153 self.add_handlers(r"blog\.ipfire\.org", [
8a897d25 154 (r"/", blog.IndexHandler),
cfc0823a 155 (r"/authors/(\w+)", blog.AuthorHandler),
541c952b 156 (r"/compose", blog.ComposeHandler),
0b342a05 157 (r"/drafts", blog.DraftsHandler),
d17a2624 158 (r"/post/([0-9a-z\-\._]+)", blog.PostHandler),
914238a5 159 (r"/post/([0-9a-z\-\._]+)/delete", blog.DeleteHandler),
d17a2624
MT
160 (r"/post/([0-9a-z\-\._]+)/edit", blog.EditHandler),
161 (r"/post/([0-9a-z\-\._]+)/publish", blog.PublishHandler),
e6b18dce 162 (r"/search", blog.SearchHandler),
8d7487d2 163 (r"/tags/([0-9a-z\-\.]+)", blog.TagHandler),
7e64f6a3 164 (r"/years/([0-9]+)", blog.YearHandler),
f0714277
MT
165
166 # RSS Feed
167 (r"/feed.xml", blog.FeedHandler),
08df6527 168 ] + authentication_handlers)
12e5de7e 169
940227cb 170 # downloads.ipfire.org
440aba92 171 self.add_handlers(r"downloads?\.ipfire\.org", [
ed8116c7 172 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/" }),
5cf65b4f 173 (r"/release/(.*)", download.ReleaseRedirectHandler),
ed8116c7 174 (r"/(.*)", download.FileHandler),
54af860e 175 ])
940227cb
MT
176
177 # mirrors.ipfire.org
440aba92 178 self.add_handlers(r"^mirrors\.ipfire\.org", [
95483f04
MT
179 (r"/", mirrors.IndexHandler),
180 (r"/mirrors/(.*)", mirrors.MirrorHandler),
3808b871 181 ])
940227cb 182
d0d074e0 183 # planet.ipfire.org
440aba92 184 self.add_handlers(r"planet\.ipfire\.org", [
3d4ce901 185 (r"/", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/" }),
d76ec66e
MT
186 (r"/post/([A-Za-z0-9_-]+)", handlers.PlanetPostHandler),
187 (r"/user/([a-z0-9_-]+)", handlers.PlanetUserHandler),
bcc3ed4d
MT
188
189 # RSS
f0714277 190 (r"/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
d76ec66e 191 (r"/user/([a-z0-9_-]+)/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
f0714277 192 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
3808b871 193 ])
d0d074e0 194
66862195 195 # fireinfo.ipfire.org
440aba92 196 self.add_handlers(r"fireinfo\.ipfire\.org", [
96c9bb79 197 (r"/", fireinfo.IndexHandler),
8ab37e0b 198
dc96f754
MT
199 # Admin
200 (r"/admin", fireinfo.AdminIndexHandler),
201
8ab37e0b
MT
202 # Vendors
203 (r"/vendors", fireinfo.VendorsHandler),
204 (r"/vendors/(pci|usb)/([0-9a-f]{4})", fireinfo.VendorHandler),
66862195 205
1e3b2aad 206 # Driver
0cd21a36 207 (r"/drivers/(.*)", fireinfo.DriverDetail),
1e3b2aad 208
66862195 209 # Show profiles
96c9bb79 210 (r"/profile/random", fireinfo.RandomProfileHandler),
b84b407f 211 (r"/profile/([a-z0-9]{40})", fireinfo.ProfileHandler),
91a446f0 212
ed2e3c1f 213 # Stats
19518d6e 214 (r"/processors", fireinfo.ProcessorsHandler),
ed2e3c1f
MT
215 (r"/releases", fireinfo.ReleasesHandler),
216
19518d6e 217 # Send profiles
96c9bb79 218 (r"/send/([a-z0-9]+)", fireinfo.ProfileSendHandler),
dc96f754 219 ] + authentication_handlers)
5cf160e0 220
c37ec602 221 # i-use.ipfire.org
440aba92 222 self.add_handlers(r"i-use\.ipfire\.org", [
e2f2865d 223 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/" }),
395c1ac0 224 (r"/profile/([a-f0-9]{40})/([0-9]+).png", iuse.ImageHandler),
c37ec602
MT
225 ])
226
8e2e1261
MT
227 # boot.ipfire.org
228 BOOT_STATIC_PATH = os.path.join(self.settings["static_path"], "netboot")
8fceca0a 229 self.add_handlers(r"boot(\.dev)?\.ipfire\.org", [
f301d952 230 (r"/", tornado.web.RedirectHandler, { "url" : "https://wiki.ipfire.org/installation/pxe" }),
8e2e1261
MT
231
232 # Configurations
f301d952
MT
233 (r"/premenu.cfg", boot.PremenuCfgHandler),
234 (r"/menu.gpxe", boot.MenuGPXEHandler),
235 (r"/menu.cfg", boot.MenuCfgHandler),
8e2e1261
MT
236
237 # Static files
37b5c0cf 238 (r"/(boot\.png|pxelinux\.0|menu\.c32|vesamenu\.c32)",
8e2e1261
MT
239 tornado.web.StaticFileHandler, { "path" : BOOT_STATIC_PATH }),
240 ])
241
60024cc8 242 # nopaste.ipfire.org
440aba92 243 self.add_handlers(r"nopaste\.ipfire\.org", [
a41085fb
MT
244 (r"/", nopaste.CreateHandler),
245 (r"/raw/(.*)", nopaste.RawHandler),
246 (r"/view/(.*)", nopaste.ViewHandler),
3808b871 247 ] + authentication_handlers)
60024cc8 248
f5b01fc2 249 # location.ipfire.org
440aba92 250 self.add_handlers(r"location\.ipfire\.org", [
f5b01fc2 251 (r"/", location.IndexHandler),
9c83876f 252 (r"/download", StaticHandler, { "template" : "../location/download.html" }),
55eea098 253 (r"/how\-to\-use", StaticHandler, { "template" : "../location/how-to-use.html" }),
2517822e 254 (r"/lookup/(.+)/blacklists", location.BlacklistsHandler),
f5b01fc2
MT
255 (r"/lookup/(.+)", location.LookupHandler),
256 ])
257
9068dba1 258 # geoip.ipfire.org
440aba92 259 self.add_handlers(r"geoip\.ipfire\.org", [
f5b01fc2 260 (r"/", tornado.web.RedirectHandler, { "url" : "https://location.ipfire.org/" }),
3808b871 261 ])
9068dba1 262
66862195 263 # talk.ipfire.org
440aba92 264 self.add_handlers(r"talk\.ipfire\.org", [
786e9ca8
MT
265 (r"/", tornado.web.RedirectHandler, { "url" : "https://people.ipfire.org/" }),
266 ])
66862195 267
03706893 268 # people.ipfire.org
440aba92 269 self.add_handlers(r"people\.ipfire\.org", [
786e9ca8 270 (r"/", people.IndexHandler),
2c65e17c 271 (r"/activate/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.ActivateHandler),
30aeccdb 272 (r"/conferences", people.ConferencesHandler),
18b13823 273 (r"/groups", people.GroupsHandler),
736e7544 274 (r"/groups/([a-z_][a-z0-9_-]{0,31})", people.GroupHandler),
f32dd17f 275 (r"/register", auth.RegisterHandler),
786e9ca8
MT
276 (r"/search", people.SearchHandler),
277 (r"/users", people.UsersHandler),
2c65e17c
MT
278 (r"/users/([a-z_][a-z0-9_-]{0,31})", people.UserHandler),
279 (r"/users/([a-z_][a-z0-9_-]{0,31})\.jpg", people.AvatarHandler),
280 (r"/users/([a-z_][a-z0-9_-]{0,31})/calls/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})", people.CallHandler),
281 (r"/users/([a-z_][a-z0-9_-]{0,31})/calls(?:/(\d{4}-\d{2}-\d{2}))?", people.CallsHandler),
282 (r"/users/([a-z_][a-z0-9_-]{0,31})/edit", people.UserEditHandler),
283 (r"/users/([a-z_][a-z0-9_-]{0,31})/passwd", people.UserPasswdHandler),
284 (r"/users/([a-z_][a-z0-9_-]{0,31})/sip", people.SIPHandler),
2dac7110 285
92c4b559
MT
286 # Promotional Consent Stuff
287 (r"/subscribe", people.SubscribeHandler),
288 (r"/unsubscribe", people.UnsubscribeHandler),
289
2dac7110
MT
290 # Single-Sign-On for Discourse
291 (r"/sso/discourse", people.SSODiscourse),
689effd0 292
c7594d58 293 # Password Reset
391ede9e
MT
294 (r"/password\-reset", auth.PasswordResetInitiationHandler),
295 (r"/password\-reset/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.PasswordResetHandler),
c7594d58 296
226d2676
MT
297 # Stats
298 (r"/stats", people.StatsHandler),
299
689effd0 300 # API
66181c96 301 (r"/api/check/email", auth.APICheckEmail),
689effd0 302 (r"/api/check/uid", auth.APICheckUID),
786e9ca8 303 ] + authentication_handlers)
2cd9af74 304
181d08f3 305 # wiki.ipfire.org
440aba92 306 self.add_handlers(r"wiki\.ipfire\.org",
181d08f3
MT
307 authentication_handlers + [
308
f2cfd873 309 # Actions
b26c705a 310 (r"((?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))/_delete", wiki.ActionDeleteHandler),
40cb87a4 311 (r"([A-Za-z0-9\-_\/]+)?/_edit", wiki.ActionEditHandler),
2901b734 312 (r"([A-Za-z0-9\-_\/]+)?/_render", wiki.ActionRenderHandler),
9db2e89f 313 (r"([A-Za-z0-9\-_\/]+)?/_(watch|unwatch)", wiki.ActionWatchHandler),
d4c68c5c 314 (r"/actions/restore", wiki.ActionRestoreHandler),
f2cfd873
MT
315 (r"/actions/upload", wiki.ActionUploadHandler),
316
f9db574a
MT
317 # Handlers
318 (r"/recent\-changes", wiki.RecentChangesHandler),
181d08f3 319 (r"/search", wiki.SearchHandler),
86368c12 320 (r"/tree", wiki.TreeHandler),
2f23c558 321 (r"/watchlist", wiki.WatchlistHandler),
f9db574a 322
f2cfd873 323 # Media
3b33319e 324 (r"([A-Za-z0-9\-_\/]+)?/_files", wiki.FilesHandler),
f2cfd873
MT
325 (r"((?!/static)(?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))$", wiki.FileHandler),
326
f9db574a 327 # Render pages
181d08f3
MT
328 (r"([A-Za-z0-9\-_\/]+)?", wiki.PageHandler),
329 ])
330
ae0228e1 331 # ipfire.org
45592df5 332 self.add_handlers(r"ipfire\.org", [
ba43a892 333 (r".*", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org" })
5cf160e0 334 ])
3add293a 335
feb02477
MT
336 logging.info("Successfully initialied application")
337
574a88c7 338 def format_country_name(self, handler, country_code):
e929ed92 339 return self.backend.get_country_name(country_code)
574a88c7 340
6eddfb50
MT
341 def format_language_name(self, handler, language):
342 _ = handler.locale.translate
343
344 if language == "de":
345 return _("German")
346 elif language == "en":
347 return _("English")
348 elif language == "es":
349 return _("Spanish")
350 elif language == "fr":
351 return _("French")
352 elif language == "it":
353 return _("Italian")
354 elif language == "nl":
355 return _("Dutch")
356 elif language == "pl":
357 return _("Polish")
358 elif language == "pt":
359 return _("Portuguese")
360 elif language == "ru":
361 return _("Russian")
362 elif language == "tr":
363 return _("Turkish")
364
365 return language
366
cc3b928d
MT
367 def format_month_name(self, handler, month):
368 _ = handler.locale.translate
369
370 if month == 1:
371 return _("January")
372 elif month == 2:
373 return _("February")
374 elif month == 3:
375 return _("March")
376 elif month == 4:
377 return _("April")
378 elif month == 5:
379 return _("May")
380 elif month == 6:
381 return _("June")
382 elif month == 7:
383 return _("July")
384 elif month == 8:
385 return _("August")
386 elif month == 9:
387 return _("September")
388 elif month == 10:
389 return _("October")
390 elif month == 11:
391 return _("November")
392 elif month == 12:
393 return _("December")
394
395 return month
401827c2 396
e96e445b
MT
397 def format_phone_number(self, handler, number):
398 if not isinstance(number, phonenumbers.PhoneNumber):
399 try:
01e73b0e 400 number = phonenumbers.parse(number, None)
e96e445b
MT
401 except phonenumbers.phonenumberutil.NumberParseException:
402 return number
c01ad253
MT
403
404 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
405
e96e445b
MT
406 def format_phone_number_to_e164(self, handler, number):
407 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.E164)
408
409 def format_phone_number_location(self, handler, number):
410 s = [
411 phonenumbers.geocoder.description_for_number(number, handler.locale.code),
412 phonenumbers.region_code_for_number(number),
413 ]
414
415 return ", ".join((e for e in s if e))
416
401827c2
MT
417
418def grouper(handler, iterator, n):
419 """
420 Returns groups of n from the iterator
421 """
422 i = iter(iterator)
423
424 while True:
425 ret = list(itertools.islice(i, 0, n))
426 if not ret:
427 break
428
429 yield ret