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