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