]> git.ipfire.org Git - ipfire.org.git/blame - src/web/__init__.py
blog: Drop unused tag page
[ipfire.org.git] / src / web / __init__.py
CommitLineData
81675874 1#/usr/bin/python
2
feb02477 3import logging
81675874 4import os.path
c01ad253 5import phonenumbers
e96e445b 6import phonenumbers.geocoder
81675874 7import tornado.locale
a49b5422 8import tornado.options
81675874 9import tornado.web
10
a95c2f97 11import ipfire
574a88c7 12import ipfire.countries
440aba92 13from .. import util
feb02477 14
11347e46 15from .handlers import *
81675874 16
08df6527 17from . import auth
12e5de7e 18from . import blog
f301d952 19from . import boot
1958a22b 20from . import docs
c7bcb9ca 21from . import donate
aec63a26 22from . import downloads
96c9bb79 23from . import fireinfo
699a0911 24from . import iuse
97e15cf6 25from . import lists
f5b01fc2 26from . import location
a41085fb 27from . import nopaste
df6180a5 28from . import ui_modules
b01a1ee3 29from . import users
4235ba55 30from . import voip
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,
cc3b928d 59 },
eabe6b8d
MT
60
61 # UI Modules
9ed02e3b 62 "ui_modules" : {
5806d6fc
MT
63 # Auth
64 "Password" : auth.PasswordModule,
65
f5b01fc2 66 # Blog
7e64f6a3
MT
67 "BlogHistoryNavigation": blog.HistoryNavigationModule,
68 "BlogList" : blog.ListModule,
f91dfcc7 69
93feb275
MT
70 # Boot
71 "BootMenuConfig" : boot.MenuConfigModule,
72 "BootMenuHeader" : boot.MenuHeaderModule,
73 "BootMenuSeparator" : boot.MenuSeparatorModule,
74
cf59466c 75 # Docs
739fff76 76 "DocsDiff" : docs.DiffModule,
cf59466c 77 "DocsHeader" : docs.HeaderModule,
d25f886f 78 "DocsList" : docs.ListModule,
cf59466c 79
e1814f16
MT
80 # Nopaste
81 "Code" : nopaste.CodeModule,
82
23f0179e 83 # Fireinfo
96c9bb79 84 "FireinfoDeviceTable" : fireinfo.DeviceTableModule,
eabe6b8d
MT
85 "FireinfoDeviceAndGroupsTable"
86 : fireinfo.DeviceAndGroupsTableModule,
87
beb13102
MT
88 # Users
89 "UsersList" : users.ListModule,
90
4235ba55 91 # VoIP
214a68a0 92 "VoIPConferences" : voip.ConferencesModule,
00465786
MT
93 "VoIPOutboundRegistrations" :
94 voip.OutboundRegistrationsModule,
8e93325b 95 "VoIPQueues" : voip.QueuesModule,
4235ba55
MT
96 "VoIPRegistrations" : voip.RegistrationsModule,
97
eabe6b8d 98 # Misc
6c6de80a 99 "IPFireLogo" : ui_modules.IPFireLogoModule,
1c4522dc 100 "Markdown" : ui_modules.MarkdownModule,
eabe6b8d
MT
101 "Map" : ui_modules.MapModule,
102 "ProgressBar" : ui_modules.ProgressBarModule,
81675874 103 },
3403dc5e
MT
104
105 # Call this when a page wasn't found
b22bc8e8 106 "default_handler_class" : base.NotFoundHandler,
9ed02e3b 107 }
9068dba1 108 settings.update(kwargs)
5cf160e0 109
ae0228e1
MT
110 tornado.web.Application.__init__(self, **settings)
111
66862195 112 authentication_handlers = [
08df6527
MT
113 (r"/login", auth.LoginHandler),
114 (r"/logout", auth.LogoutHandler),
66862195
MT
115 ]
116
c85f80e2 117 self.add_handlers(r"(www\.)?([a-z]+\.dev\.)?ipfire\.org", [
940227cb
MT
118 # Entry site that lead the user to index
119 (r"/", IndexHandler),
940227cb 120
8505c8cd
MT
121 # Authentication
122 (r"/login", auth.LoginHandler),
123 (r"/logout", auth.LogoutHandler),
124 (r"/register", auth.RegisterHandler),
42c7cc66 125 (r"/activate/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.ActivateHandler),
8505c8cd 126
34472923
MT
127 # Blog
128 (r"/blog", blog.IndexHandler),
34472923
MT
129 (r"/blog/drafts", blog.DraftsHandler),
130 (r"/blog/feed.xml", blog.FeedHandler),
4d657f4f 131 (r"/blog/write", blog.WriteHandler),
feb245e0 132 (r"/blog/years/([0-9]{4})", blog.YearHandler),
34472923
MT
133 (r"/blog/([0-9a-z\-\._]+)", blog.PostHandler),
134 (r"/blog/([0-9a-z\-\._]+)/delete", blog.DeleteHandler),
135 (r"/blog/([0-9a-z\-\._]+)/edit", blog.EditHandler),
136 (r"/blog/([0-9a-z\-\._]+)/publish", blog.PublishHandler),
56801afb 137 (r"/blog/([0-9a-z\-\._]+)/debug/email", blog.DebugEmailHandler),
34472923 138
1958a22b 139 # Docs
5f0d294e 140 (r"/docs/recent\-changes", docs.RecentChangesHandler),
0ce8cc32 141 (r"/docs/search", docs.SearchHandler),
350f391e 142 (r"/docs/tree", docs.TreeHandler),
16619e57 143 (r"/docs/watchlist", docs.WatchlistHandler),
bb998aca 144 (r"/docs/_restore", docs.RestoreHandler),
26ade731 145 (r"/docs/_upload", docs.UploadHandler),
a7342d24
MT
146 (r"/docs(?:/([A-Za-z0-9\-_\/]+))?/_edit", docs.EditHandler),
147 (r"/docs(?:/([A-Za-z0-9\-_\/]+))?/_render", docs.RenderHandler),
148 (r"/docs(?:/([A-Za-z0-9\-_\/]+))?/_(watch|unwatch)", docs.WatchHandler),
16510618 149 (r"/docs/((?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))/_delete", docs.DeleteFileHandler),
4a1bfdd5 150 (r"/docs((?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))$", docs.FileHandler),
a7342d24
MT
151 (r"/docs(?:/([A-Za-z0-9\-_\/]+))?/_files", docs.FilesHandler),
152 (r"/docs(?:/([A-Za-z0-9\-_\/]+))?", docs.PageHandler),
1958a22b 153
aec63a26
MT
154 # Downloads
155 (r"/downloads", downloads.IndexHandler),
1e71d96a 156 (r"/downloads/cloud", StaticHandler, { "template" : "../downloads/cloud.html" }),
aec63a26
MT
157 (r"/downloads/mirrors", downloads.MirrorsHandler),
158 (r"/downloads/thank-you", downloads.ThankYouHandler),
159 (r"/downloads/([0-9a-z\-\.]+)", downloads.ReleaseHandler),
160
e64ce07e 161 # Donate
c7bcb9ca
MT
162 (r"/donate", donate.DonateHandler),
163 (r"/donate/thank-you", donate.ThankYouHandler),
164 (r"/donate/error", donate.ErrorHandler),
8d48f4ef 165
97e15cf6
MT
166 # Lists
167 (r"/lists", lists.IndexHandler),
168
8066a1e7
MT
169 # Password Reset
170 (r"/password\-reset", auth.PasswordResetInitiationHandler),
171 (r"/password\-reset/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.PasswordResetHandler),
172
d9f7b6e5
MT
173 # Projects
174 (r"/projects/location", location.IndexHandler),
175 (r"/projects/location/download", StaticHandler, { "template" : "../location/download.html" }),
176 (r"/projects/location/how\-to\-use", StaticHandler, { "template" : "../location/how-to-use.html" }),
d9f7b6e5
MT
177 (r"/projects/location/lookup/(.+)", location.LookupHandler),
178
2fe1d960
MT
179 # Single-Sign-On for Discourse
180 (r"/sso/discourse", auth.SSODiscourse),
181
f2c38da0
MT
182 # User Groups
183 (r"/users/groups", users.GroupIndexHandler),
184 (r"/users/groups/([a-z_][a-z0-9_-]{0,31})", users.GroupShowHandler),
185
b01a1ee3 186 # Users
beb13102 187 (r"/users", users.IndexHandler),
53b2117f
MT
188 (r"/users/([a-z_][a-z0-9_-]{0,31})", users.ShowHandler),
189 (r"/users/([a-z_][a-z0-9_-]{0,31})\.jpg", users.AvatarHandler),
1cd4d7d3 190 (r"/users/([a-z_][a-z0-9_-]{0,31})/delete", users.DeleteHandler),
3c986f14 191 (r"/users/([a-z_][a-z0-9_-]{0,31})/edit", users.EditHandler),
e4d2f51f 192 (r"/users/([a-z_][a-z0-9_-]{0,31})/passwd", users.PasswdHandler),
b01a1ee3 193
bb440bad
MT
194 # Promotional Consent Stuff
195 (r"/subscribe", users.SubscribeHandler),
196 (r"/unsubscribe", users.UnsubscribeHandler),
197
4235ba55
MT
198 # VoIP
199 (r"/voip", voip.IndexHandler),
200
45592df5 201 # Static Pages
8ea3eaa2 202 (r"/about", StaticHandler, { "template" : "about.html" }),
45592df5 203 (r"/legal", StaticHandler, { "template" : "legal.html" }),
d2000918 204 (r"/help", StaticHandler, { "template" : "help.html" }),
d1ec64e1 205 (r"/sitemap", StaticHandler, { "template" : "sitemap.html" }),
45592df5 206
86d86819
MT
207 # API
208 (r"/api/check/email", auth.APICheckEmail),
209 (r"/api/check/uid", auth.APICheckUID),
210
14cd4fa8 211 # Handle old pages that have moved elsewhere
1f153396 212 (r"/blog/authors/(\w+)", tornado.web.RedirectHandler, { "url" : "/users/{0}" }),
7fa7d38d
MT
213 (r"/donation", tornado.web.RedirectHandler, { "url" : "/donate" }),
214 (r"/download", tornado.web.RedirectHandler, { "url" : "/downloads" }),
215 (r"/download/([0-9a-z\-\.]+)", tornado.web.RedirectHandler, { "url" : "/downloads/{0}" }),
85c977e2 216 (r"/features", tornado.web.RedirectHandler, { "url" : "/about" }),
14cd4fa8 217 (r"/imprint", tornado.web.RedirectHandler, { "url" : "/legal" }),
7fa7d38d
MT
218 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "/blog/feed.xml" }),
219 (r"/news/(.*)", tornado.web.RedirectHandler, { "url" : "/blog/{0}" }),
d2000918 220 (r"/support", tornado.web.RedirectHandler, { "url" : "/help"}),
7fa7d38d 221 (r"/(de|en)/(.*)", tornado.web.RedirectHandler, { "url" : "/{0}"}),
37ed7c3c
MT
222
223 # Export arbitrary error pages
b22bc8e8 224 (r"/error/([45][0-9]{2})", base.ErrorHandler),
0ed3ea5c
MT
225
226 # Serve any static files
227 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
940227cb
MT
228 ])
229
34472923 230 # blog.ipfire.org - LEGACY REDIRECTION
c85f80e2 231 self.add_handlers(r"blog\.([a-z]+\.dev\.)?ipfire\.org", [
34472923
MT
232 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog" }),
233 (r"/authors/(\w+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/authors/{0}" }),
234 (r"/post/([0-9a-z\-\._]+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/{0}" }),
235 (r"/tags/([0-9a-z\-\.]+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/tags/{0}" }),
f0714277
MT
236
237 # RSS Feed
34472923
MT
238 (r"/feed.xml", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/feed.xml" }),
239 ])
12e5de7e 240
940227cb 241 # downloads.ipfire.org
c85f80e2 242 self.add_handlers(r"downloads\.([a-z]+\.dev\.)?ipfire\.org", [
82d4e789 243 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download" }),
450972a3 244 (r"/release/(.*)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download/{0}" }),
aec63a26 245 (r"/(.*)", downloads.FileHandler),
54af860e 246 ])
940227cb
MT
247
248 # mirrors.ipfire.org
c85f80e2 249 self.add_handlers(r"mirrors\.([a-z]+\.dev\.)?ipfire\.org", [
278b3118
MT
250 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download/mirrors" }),
251 (r"/mirrors/(.*)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download/mirrors/{0}" }),
3808b871 252 ])
940227cb 253
d0d074e0 254 # planet.ipfire.org
c85f80e2 255 self.add_handlers(r"planet\.([a-z]+\.dev\.)?ipfire\.org", [
3d4ce901 256 (r"/", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/" }),
7fa7d38d
MT
257 (r"/post/([A-Za-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/{0}" }),
258 (r"/user/([a-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/blog/authors/{0}" }),
bcc3ed4d
MT
259
260 # RSS
f0714277 261 (r"/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
d76ec66e 262 (r"/user/([a-z0-9_-]+)/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
f0714277 263 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
3808b871 264 ])
d0d074e0 265
66862195 266 # fireinfo.ipfire.org
c85f80e2 267 self.add_handlers(r"fireinfo\.([a-z]+\.dev\.)?ipfire\.org", [
96c9bb79 268 (r"/", fireinfo.IndexHandler),
8ab37e0b 269
dc96f754
MT
270 # Admin
271 (r"/admin", fireinfo.AdminIndexHandler),
272
8ab37e0b
MT
273 # Vendors
274 (r"/vendors", fireinfo.VendorsHandler),
275 (r"/vendors/(pci|usb)/([0-9a-f]{4})", fireinfo.VendorHandler),
66862195 276
1e3b2aad 277 # Driver
0cd21a36 278 (r"/drivers/(.*)", fireinfo.DriverDetail),
1e3b2aad 279
66862195 280 # Show profiles
96c9bb79 281 (r"/profile/random", fireinfo.RandomProfileHandler),
b84b407f 282 (r"/profile/([a-z0-9]{40})", fireinfo.ProfileHandler),
91a446f0 283
ed2e3c1f 284 # Stats
19518d6e 285 (r"/processors", fireinfo.ProcessorsHandler),
ed2e3c1f
MT
286 (r"/releases", fireinfo.ReleasesHandler),
287
19518d6e 288 # Send profiles
96c9bb79 289 (r"/send/([a-z0-9]+)", fireinfo.ProfileSendHandler),
0ed3ea5c
MT
290
291 # Serve any static files
292 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
dc96f754 293 ] + authentication_handlers)
5cf160e0 294
c37ec602 295 # i-use.ipfire.org
c85f80e2 296 self.add_handlers(r"i-use\.([a-z]+\.dev\.)?ipfire\.org", [
e2f2865d 297 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/" }),
395c1ac0 298 (r"/profile/([a-f0-9]{40})/([0-9]+).png", iuse.ImageHandler),
c37ec602
MT
299 ])
300
8e2e1261
MT
301 # boot.ipfire.org
302 BOOT_STATIC_PATH = os.path.join(self.settings["static_path"], "netboot")
c85f80e2 303 self.add_handlers(r"boot\.([a-z]+\.dev\.)?ipfire\.org", [
f301d952 304 (r"/", tornado.web.RedirectHandler, { "url" : "https://wiki.ipfire.org/installation/pxe" }),
8e2e1261
MT
305
306 # Configurations
f301d952
MT
307 (r"/premenu.cfg", boot.PremenuCfgHandler),
308 (r"/menu.gpxe", boot.MenuGPXEHandler),
309 (r"/menu.cfg", boot.MenuCfgHandler),
8e2e1261
MT
310
311 # Static files
37b5c0cf 312 (r"/(boot\.png|pxelinux\.0|menu\.c32|vesamenu\.c32)",
8e2e1261
MT
313 tornado.web.StaticFileHandler, { "path" : BOOT_STATIC_PATH }),
314 ])
315
60024cc8 316 # nopaste.ipfire.org
c85f80e2 317 self.add_handlers(r"nopaste\.([a-z]+\.dev\.)?ipfire\.org", [
a41085fb
MT
318 (r"/", nopaste.CreateHandler),
319 (r"/raw/(.*)", nopaste.RawHandler),
320 (r"/view/(.*)", nopaste.ViewHandler),
0ed3ea5c
MT
321
322 # Serve any static files
323 (r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
3808b871 324 ] + authentication_handlers)
60024cc8 325
f5b01fc2 326 # location.ipfire.org
c85f80e2 327 self.add_handlers(r"location\.([a-z]+\.dev\.)?ipfire\.org", [
d9f7b6e5 328 (r"/(.*)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/projects/location/{0}" }),
f5b01fc2
MT
329 ])
330
9068dba1 331 # geoip.ipfire.org
c85f80e2 332 self.add_handlers(r"geoip\.([a-z]+\.dev\.)?ipfire\.org", [
f5b01fc2 333 (r"/", tornado.web.RedirectHandler, { "url" : "https://location.ipfire.org/" }),
3808b871 334 ])
9068dba1 335
66862195 336 # talk.ipfire.org
c85f80e2 337 self.add_handlers(r"talk\.([a-z]+\.dev\.)?ipfire\.org", [
786e9ca8
MT
338 (r"/", tornado.web.RedirectHandler, { "url" : "https://people.ipfire.org/" }),
339 ])
66862195 340
03706893 341 # people.ipfire.org
c85f80e2 342 self.add_handlers(r"people\.([a-z]+\.dev\.)?ipfire\.org", [
b6026905
MT
343 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/users" }),
344 (r"/register", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/register" }),
345 (r"/users", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/users" }),
346 (r"/users/([a-z_][a-z0-9_-]{0,31})", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/users/{0}" }),
347 (r"/users/([a-z_][a-z0-9_-]{0,31})\.jpg", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/users/{0}.jpg" }),
348 ])
2cd9af74 349
181d08f3 350 # wiki.ipfire.org
9741abf5
MT
351 self.add_handlers(r"wiki\.([a-z]+\.dev\.)?ipfire\.org", [
352 (r"/(.*)", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/docs/{0}" }),
181d08f3
MT
353 ])
354
ae0228e1 355 # ipfire.org
e65b9a6d 356 self.add_handlers(r"(.*)ipfire\.org", [
ba43a892 357 (r".*", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org" })
5cf160e0 358 ])
3add293a 359
feb02477
MT
360 logging.info("Successfully initialied application")
361
574a88c7 362 def format_country_name(self, handler, country_code):
e929ed92 363 return self.backend.get_country_name(country_code)
574a88c7 364
6eddfb50
MT
365 def format_language_name(self, handler, language):
366 _ = handler.locale.translate
367
368 if language == "de":
369 return _("German")
370 elif language == "en":
371 return _("English")
372 elif language == "es":
373 return _("Spanish")
374 elif language == "fr":
375 return _("French")
376 elif language == "it":
377 return _("Italian")
378 elif language == "nl":
379 return _("Dutch")
380 elif language == "pl":
381 return _("Polish")
382 elif language == "pt":
383 return _("Portuguese")
384 elif language == "ru":
385 return _("Russian")
386 elif language == "tr":
387 return _("Turkish")
388
389 return language
390
cc3b928d
MT
391 def format_month_name(self, handler, month):
392 _ = handler.locale.translate
393
394 if month == 1:
395 return _("January")
396 elif month == 2:
397 return _("February")
398 elif month == 3:
399 return _("March")
400 elif month == 4:
401 return _("April")
402 elif month == 5:
403 return _("May")
404 elif month == 6:
405 return _("June")
406 elif month == 7:
407 return _("July")
408 elif month == 8:
409 return _("August")
410 elif month == 9:
411 return _("September")
412 elif month == 10:
413 return _("October")
414 elif month == 11:
415 return _("November")
416 elif month == 12:
417 return _("December")
418
419 return month
401827c2 420
e96e445b
MT
421 def format_phone_number(self, handler, number):
422 if not isinstance(number, phonenumbers.PhoneNumber):
423 try:
01e73b0e 424 number = phonenumbers.parse(number, None)
e96e445b
MT
425 except phonenumbers.phonenumberutil.NumberParseException:
426 return number
c01ad253
MT
427
428 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
429
e96e445b
MT
430 def format_phone_number_to_e164(self, handler, number):
431 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.E164)
432
433 def format_phone_number_location(self, handler, number):
434 s = [
435 phonenumbers.geocoder.description_for_number(number, handler.locale.code),
436 phonenumbers.region_code_for_number(number),
437 ]
438
439 return ", ".join((e for e in s if e))