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