]> git.ipfire.org Git - ipfire.org.git/blame - src/web/__init__.py
people: Allow to modify if people want to receive promotional updates
[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
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
95483f04 25from . import mirrors
5613b94b 26from . import newsletter
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
5613b94b
MT
133 # Newsletter
134 (r"/newsletter/subscribe", newsletter.SubscribeHandler),
135
de683d7c 136 # RSS feed
f0714277 137 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
7f9dbcc0
MT
138
139 # Redirect news articles to blog
d76ec66e 140 (r"/news/(.*)", handlers.NewsHandler),
de683d7c 141
45592df5 142 # Static Pages
45592df5 143 (r"/features", StaticHandler, { "template" : "features.html" }),
45592df5 144 (r"/legal", StaticHandler, { "template" : "legal.html" }),
00026d8b 145 (r"/support", StaticHandler, { "template" : "support.html" }),
45592df5 146
14cd4fa8
MT
147 # Handle old pages that have moved elsewhere
148 (r"/imprint", tornado.web.RedirectHandler, { "url" : "/legal" }),
3808b871 149 (r"/(de|en)/(.*)", LangCompatHandler),
37ed7c3c
MT
150
151 # Export arbitrary error pages
b22bc8e8 152 (r"/error/([45][0-9]{2})", base.ErrorHandler),
baa693a3
MT
153
154 # Block page
b22bc8e8 155 (r"/blocked", base.BlockedHandler),
940227cb
MT
156 ])
157
12e5de7e
MT
158 # blog.ipfire.org
159 self.add_handlers(r"blog(\.dev)?\.ipfire\.org", [
8a897d25 160 (r"/", blog.IndexHandler),
cfc0823a 161 (r"/authors/(\w+)", blog.AuthorHandler),
541c952b 162 (r"/compose", blog.ComposeHandler),
0b342a05 163 (r"/drafts", blog.DraftsHandler),
d17a2624 164 (r"/post/([0-9a-z\-\._]+)", blog.PostHandler),
914238a5 165 (r"/post/([0-9a-z\-\._]+)/delete", blog.DeleteHandler),
d17a2624
MT
166 (r"/post/([0-9a-z\-\._]+)/edit", blog.EditHandler),
167 (r"/post/([0-9a-z\-\._]+)/publish", blog.PublishHandler),
e6b18dce 168 (r"/search", blog.SearchHandler),
8d7487d2 169 (r"/tags/([0-9a-z\-\.]+)", blog.TagHandler),
7e64f6a3 170 (r"/years/([0-9]+)", blog.YearHandler),
f0714277
MT
171
172 # RSS Feed
173 (r"/feed.xml", blog.FeedHandler),
08df6527 174 ] + authentication_handlers)
12e5de7e 175
940227cb 176 # downloads.ipfire.org
80594ae3 177 self.add_handlers(r"downloads?(\.dev)?\.ipfire\.org", [
ed8116c7 178 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/" }),
5cf65b4f 179 (r"/release/(.*)", download.ReleaseRedirectHandler),
ed8116c7 180 (r"/(.*)", download.FileHandler),
54af860e 181 ])
940227cb
MT
182
183 # mirrors.ipfire.org
8fceca0a 184 self.add_handlers(r"mirrors(\.dev)?\.ipfire\.org", [
95483f04
MT
185 (r"/", mirrors.IndexHandler),
186 (r"/mirrors/(.*)", mirrors.MirrorHandler),
3808b871 187 ])
940227cb 188
d0d074e0 189 # planet.ipfire.org
7cad1818 190 self.add_handlers(r"planet(\.dev)?\.ipfire\.org", [
3d4ce901 191 (r"/", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/" }),
d76ec66e
MT
192 (r"/post/([A-Za-z0-9_-]+)", handlers.PlanetPostHandler),
193 (r"/user/([a-z0-9_-]+)", handlers.PlanetUserHandler),
bcc3ed4d
MT
194
195 # RSS
f0714277 196 (r"/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
d76ec66e 197 (r"/user/([a-z0-9_-]+)/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
f0714277 198 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
3808b871 199 ])
d0d074e0 200
66862195 201 # fireinfo.ipfire.org
8fceca0a 202 self.add_handlers(r"fireinfo(\.dev)?\.ipfire\.org", [
96c9bb79 203 (r"/", fireinfo.IndexHandler),
8ab37e0b
MT
204
205 # Vendors
206 (r"/vendors", fireinfo.VendorsHandler),
207 (r"/vendors/(pci|usb)/([0-9a-f]{4})", fireinfo.VendorHandler),
66862195 208
1e3b2aad 209 # Driver
0cd21a36 210 (r"/drivers/(.*)", fireinfo.DriverDetail),
1e3b2aad 211
66862195 212 # Show profiles
96c9bb79 213 (r"/profile/random", fireinfo.RandomProfileHandler),
b84b407f 214 (r"/profile/([a-z0-9]{40})", fireinfo.ProfileHandler),
91a446f0 215
ed2e3c1f 216 # Stats
19518d6e 217 (r"/processors", fireinfo.ProcessorsHandler),
ed2e3c1f
MT
218 (r"/releases", fireinfo.ReleasesHandler),
219
19518d6e 220 # Send profiles
96c9bb79 221 (r"/send/([a-z0-9]+)", fireinfo.ProfileSendHandler),
3808b871 222 ])
5cf160e0 223
c37ec602 224 # i-use.ipfire.org
8fceca0a 225 self.add_handlers(r"i-use(\.dev)?\.ipfire\.org", [
e2f2865d 226 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/" }),
395c1ac0 227 (r"/profile/([a-f0-9]{40})/([0-9]+).png", iuse.ImageHandler),
c37ec602
MT
228 ])
229
8e2e1261
MT
230 # boot.ipfire.org
231 BOOT_STATIC_PATH = os.path.join(self.settings["static_path"], "netboot")
8fceca0a 232 self.add_handlers(r"boot(\.dev)?\.ipfire\.org", [
f301d952 233 (r"/", tornado.web.RedirectHandler, { "url" : "https://wiki.ipfire.org/installation/pxe" }),
8e2e1261
MT
234
235 # Configurations
f301d952
MT
236 (r"/premenu.cfg", boot.PremenuCfgHandler),
237 (r"/menu.gpxe", boot.MenuGPXEHandler),
238 (r"/menu.cfg", boot.MenuCfgHandler),
8e2e1261
MT
239
240 # Static files
37b5c0cf 241 (r"/(boot\.png|pxelinux\.0|menu\.c32|vesamenu\.c32)",
8e2e1261
MT
242 tornado.web.StaticFileHandler, { "path" : BOOT_STATIC_PATH }),
243 ])
244
60024cc8 245 # nopaste.ipfire.org
8fceca0a 246 self.add_handlers(r"nopaste(\.dev)?\.ipfire\.org", [
a41085fb
MT
247 (r"/", nopaste.CreateHandler),
248 (r"/raw/(.*)", nopaste.RawHandler),
249 (r"/view/(.*)", nopaste.ViewHandler),
3808b871 250 ] + authentication_handlers)
60024cc8 251
f5b01fc2
MT
252 # location.ipfire.org
253 self.add_handlers(r"location(\.dev)?\.ipfire\.org", [
254 (r"/", location.IndexHandler),
55eea098 255 (r"/how\-to\-use", StaticHandler, { "template" : "../location/how-to-use.html" }),
2517822e 256 (r"/lookup/(.+)/blacklists", location.BlacklistsHandler),
f5b01fc2
MT
257 (r"/lookup/(.+)", location.LookupHandler),
258 ])
259
9068dba1 260 # geoip.ipfire.org
8fceca0a 261 self.add_handlers(r"geoip(\.dev)?\.ipfire\.org", [
f5b01fc2 262 (r"/", tornado.web.RedirectHandler, { "url" : "https://location.ipfire.org/" }),
3808b871 263 ])
9068dba1 264
66862195
MT
265 # talk.ipfire.org
266 self.add_handlers(r"talk(\.dev)?\.ipfire\.org", [
786e9ca8
MT
267 (r"/", tornado.web.RedirectHandler, { "url" : "https://people.ipfire.org/" }),
268 ])
66862195 269
03706893
MT
270 # people.ipfire.org
271 self.add_handlers(r"people(\.dev)?\.ipfire\.org", [
786e9ca8 272 (r"/", people.IndexHandler),
2c65e17c 273 (r"/activate/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.ActivateHandler),
30aeccdb 274 (r"/conferences", people.ConferencesHandler),
18b13823 275 (r"/groups", people.GroupsHandler),
bef47ee8 276 (r"/groups/(\w+)", people.GroupHandler),
f32dd17f 277 (r"/register", auth.RegisterHandler),
786e9ca8
MT
278 (r"/search", people.SearchHandler),
279 (r"/users", people.UsersHandler),
2c65e17c
MT
280 (r"/users/([a-z_][a-z0-9_-]{0,31})", people.UserHandler),
281 (r"/users/([a-z_][a-z0-9_-]{0,31})\.jpg", people.AvatarHandler),
282 (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),
283 (r"/users/([a-z_][a-z0-9_-]{0,31})/calls(?:/(\d{4}-\d{2}-\d{2}))?", people.CallsHandler),
284 (r"/users/([a-z_][a-z0-9_-]{0,31})/edit", people.UserEditHandler),
285 (r"/users/([a-z_][a-z0-9_-]{0,31})/passwd", people.UserPasswdHandler),
286 (r"/users/([a-z_][a-z0-9_-]{0,31})/sip", people.SIPHandler),
2dac7110 287
92c4b559
MT
288 # Promotional Consent Stuff
289 (r"/subscribe", people.SubscribeHandler),
290 (r"/unsubscribe", people.UnsubscribeHandler),
291
2dac7110
MT
292 # Single-Sign-On for Discourse
293 (r"/sso/discourse", people.SSODiscourse),
689effd0 294
c7594d58 295 # Password Reset
391ede9e
MT
296 (r"/password\-reset", auth.PasswordResetInitiationHandler),
297 (r"/password\-reset/([a-z_][a-z0-9_-]{0,31})/(\w+)", auth.PasswordResetHandler),
c7594d58 298
689effd0
MT
299 # API
300 (r"/api/check/uid", auth.APICheckUID),
786e9ca8 301 ] + authentication_handlers)
2cd9af74 302
181d08f3
MT
303 # wiki.ipfire.org
304 self.add_handlers(r"wiki(\.dev)?\.ipfire\.org",
305 authentication_handlers + [
306
f2cfd873 307 # Actions
b26c705a 308 (r"((?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))/_delete", wiki.ActionDeleteHandler),
40cb87a4 309 (r"([A-Za-z0-9\-_\/]+)?/_edit", wiki.ActionEditHandler),
2901b734 310 (r"([A-Za-z0-9\-_\/]+)?/_render", wiki.ActionRenderHandler),
9db2e89f 311 (r"([A-Za-z0-9\-_\/]+)?/_(watch|unwatch)", wiki.ActionWatchHandler),
d4c68c5c 312 (r"/actions/restore", wiki.ActionRestoreHandler),
f2cfd873
MT
313 (r"/actions/upload", wiki.ActionUploadHandler),
314
f9db574a
MT
315 # Handlers
316 (r"/recent\-changes", wiki.RecentChangesHandler),
181d08f3 317 (r"/search", wiki.SearchHandler),
2f23c558 318 (r"/watchlist", wiki.WatchlistHandler),
f9db574a 319
f2cfd873 320 # Media
3b33319e 321 (r"([A-Za-z0-9\-_\/]+)?/_files", wiki.FilesHandler),
f2cfd873
MT
322 (r"((?!/static)(?:[A-Za-z0-9\-_\/]+)?(?:.*)\.(?:\w+))$", wiki.FileHandler),
323
f9db574a 324 # Render pages
181d08f3
MT
325 (r"([A-Za-z0-9\-_\/]+)?", wiki.PageHandler),
326 ])
327
ae0228e1 328 # ipfire.org
45592df5 329 self.add_handlers(r"ipfire\.org", [
ba43a892 330 (r".*", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org" })
5cf160e0 331 ])
3add293a 332
feb02477
MT
333 logging.info("Successfully initialied application")
334
574a88c7
MT
335 def format_country_name(self, handler, country_code):
336 return ipfire.countries.get_name(country_code)
337
6eddfb50
MT
338 def format_language_name(self, handler, language):
339 _ = handler.locale.translate
340
341 if language == "de":
342 return _("German")
343 elif language == "en":
344 return _("English")
345 elif language == "es":
346 return _("Spanish")
347 elif language == "fr":
348 return _("French")
349 elif language == "it":
350 return _("Italian")
351 elif language == "nl":
352 return _("Dutch")
353 elif language == "pl":
354 return _("Polish")
355 elif language == "pt":
356 return _("Portuguese")
357 elif language == "ru":
358 return _("Russian")
359 elif language == "tr":
360 return _("Turkish")
361
362 return language
363
cc3b928d
MT
364 def format_month_name(self, handler, month):
365 _ = handler.locale.translate
366
367 if month == 1:
368 return _("January")
369 elif month == 2:
370 return _("February")
371 elif month == 3:
372 return _("March")
373 elif month == 4:
374 return _("April")
375 elif month == 5:
376 return _("May")
377 elif month == 6:
378 return _("June")
379 elif month == 7:
380 return _("July")
381 elif month == 8:
382 return _("August")
383 elif month == 9:
384 return _("September")
385 elif month == 10:
386 return _("October")
387 elif month == 11:
388 return _("November")
389 elif month == 12:
390 return _("December")
391
392 return month
401827c2 393
e96e445b
MT
394 def format_phone_number(self, handler, number):
395 if not isinstance(number, phonenumbers.PhoneNumber):
396 try:
01e73b0e 397 number = phonenumbers.parse(number, None)
e96e445b
MT
398 except phonenumbers.phonenumberutil.NumberParseException:
399 return number
c01ad253
MT
400
401 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
402
e96e445b
MT
403 def format_phone_number_to_e164(self, handler, number):
404 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.E164)
405
406 def format_phone_number_location(self, handler, number):
407 s = [
408 phonenumbers.geocoder.description_for_number(number, handler.locale.code),
409 phonenumbers.region_code_for_number(number),
410 ]
411
412 return ", ".join((e for e in s if e))
413
401827c2
MT
414
415def grouper(handler, iterator, n):
416 """
417 Returns groups of n from the iterator
418 """
419 i = iter(iterator)
420
421 while True:
422 ret = list(itertools.islice(i, 0, n))
423 if not ret:
424 break
425
426 yield ret