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