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