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