]> git.ipfire.org Git - ipfire.org.git/blame - src/web/__init__.py
nopaste: Drop avatar when file is uploaded by authenticated users
[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
feb02477 13
11347e46 14from .handlers import *
81675874 15
08df6527 16from . import auth
12e5de7e 17from . import blog
e77cd04c 18from . import download
f5b01fc2 19from . import location
5613b94b 20from . import newsletter
a41085fb 21from . import nopaste
03706893 22from . import people
df6180a5 23from . import ui_modules
12e5de7e 24
81675874 25class Application(tornado.web.Application):
3e7c6ccd
MT
26 def __init__(self, config, **kwargs):
27 # Initialize backend
a95c2f97 28 self.backend = ipfire.Backend(config)
a6dc0bad 29
9ed02e3b
MT
30 settings = {
31 # Do not compress responses
32 "gzip" : False,
33
34 # Enable XSRF cookies
35 "xsrf_cookies" : True,
36
37 # Login
38 "login_url" : "/login",
39
40 # Setup directory structure
41 "static_path" : self.backend.config.get("global", "static_dir"),
42 "template_path" : self.backend.config.get("global", "templates_dir"),
43
44 # UI Modules
45 "ui_methods" : {
e96e445b
MT
46 "format_month_name" : self.format_month_name,
47 "format_phone_number" : self.format_phone_number,
48 "format_phone_number_to_e164" : self.format_phone_number_to_e164,
49 "format_phone_number_location" : self.format_phone_number_location,
50 "grouper" : grouper,
cc3b928d 51 },
9ed02e3b 52 "ui_modules" : {
f5b01fc2 53 # Blog
7e64f6a3
MT
54 "BlogHistoryNavigation": blog.HistoryNavigationModule,
55 "BlogList" : blog.ListModule,
f91dfcc7 56 "BlogPost" : blog.PostModule,
8a897d25 57 "BlogPosts" : blog.PostsModule,
f91dfcc7 58
f5b01fc2 59 # Location
df6180a5 60 "Map" : ui_modules.MapModule,
f5b01fc2 61
917434b8 62 # Talk
dbb0c109
MT
63 "AccountsList" : people.AccountsListModule,
64 "CDR" : people.CDRModule,
65 "Channels" : people.ChannelsModule,
68ece434 66 "MOS" : people.MOSModule,
dbb0c109 67 "Registrations" : people.RegistrationsModule,
7afd64bb 68 "SIPStatus" : people.SIPStatusModule,
917434b8 69
f91dfcc7 70 # Old modules
df6180a5
MT
71 "LanguageName" : ui_modules.LanguageNameModule,
72
73 "MirrorItem" : ui_modules.MirrorItemModule,
74 "MirrorsTable" : ui_modules.MirrorsTableModule,
75 "NetBootMenuConfig" : ui_modules.NetBootMenuConfigModule,
76 "NetBootMenuHeader" : ui_modules.NetBootMenuHeaderModule,
77 "NetBootMenuSeparator" : ui_modules.NetBootMenuSeparatorModule,
78 "ProgressBar" : ui_modules.ProgressBarModule,
df6180a5
MT
79 "FireinfoDeviceTable" : ui_modules.FireinfoDeviceTableModule,
80 "FireinfoDeviceAndGroupsTable" : ui_modules.FireinfoDeviceAndGroupsTableModule,
81 "FireinfoGeoTable" : ui_modules.FireinfoGeoTableModule,
81675874 82 },
3403dc5e
MT
83
84 # Call this when a page wasn't found
85 "default_handler_class" : NotFoundHandler,
9ed02e3b 86 }
9068dba1 87 settings.update(kwargs)
5cf160e0 88
ae0228e1
MT
89 tornado.web.Application.__init__(self, **settings)
90
66862195 91 authentication_handlers = [
08df6527
MT
92 (r"/login", auth.LoginHandler),
93 (r"/logout", auth.LogoutHandler),
66862195
MT
94 ]
95
d4dc517c 96 self.add_handlers(r"(dev|www)\.ipfire\.(at|org)", [
940227cb
MT
97 # Entry site that lead the user to index
98 (r"/", IndexHandler),
940227cb 99
81675874 100 # Download sites
60b0917c 101 (r"/downloads", tornado.web.RedirectHandler, { "url" : "/download" }),
e77cd04c
MT
102 (r"/download", download.IndexHandler),
103 (r"/download/([0-9a-z\-\.]+)", download.ReleaseHandler),
940227cb 104
e64ce07e
MT
105 # Donate
106 (r"/donate", DonateHandler),
107 (r"/donation", tornado.web.RedirectHandler, { "url" : "/donate" }),
8d48f4ef 108
5613b94b
MT
109 # Newsletter
110 (r"/newsletter/subscribe", newsletter.SubscribeHandler),
111
de683d7c 112 # RSS feed
f0714277 113 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
7f9dbcc0
MT
114
115 # Redirect news articles to blog
116 (r"/news/(.*)", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/posts/{1}" }),
de683d7c 117
45592df5 118 # Static Pages
84151dbf 119 (r"/chat", StaticHandler, { "template" : "chat.html" }),
45592df5 120 (r"/features", StaticHandler, { "template" : "features.html" }),
45592df5 121 (r"/legal", StaticHandler, { "template" : "legal.html" }),
00026d8b 122 (r"/support", StaticHandler, { "template" : "support.html" }),
45592df5 123
14cd4fa8
MT
124 # Handle old pages that have moved elsewhere
125 (r"/imprint", tornado.web.RedirectHandler, { "url" : "/legal" }),
3808b871 126 (r"/(de|en)/(.*)", LangCompatHandler),
37ed7c3c
MT
127
128 # Export arbitrary error pages
129 (r"/error/([45][0-9]{2})", ErrorHandler),
baa693a3
MT
130
131 # Block page
132 (r"/blocked", BlockedHandler),
940227cb
MT
133 ])
134
12e5de7e
MT
135 # blog.ipfire.org
136 self.add_handlers(r"blog(\.dev)?\.ipfire\.org", [
8a897d25 137 (r"/", blog.IndexHandler),
cfc0823a 138 (r"/authors/(\w+)", blog.AuthorHandler),
541c952b 139 (r"/compose", blog.ComposeHandler),
0b342a05 140 (r"/drafts", blog.DraftsHandler),
d17a2624
MT
141 (r"/post/([0-9a-z\-\._]+)", blog.PostHandler),
142 (r"/post/([0-9a-z\-\._]+)/edit", blog.EditHandler),
143 (r"/post/([0-9a-z\-\._]+)/publish", blog.PublishHandler),
e6b18dce 144 (r"/search", blog.SearchHandler),
8d7487d2 145 (r"/tags/([0-9a-z\-\.]+)", blog.TagHandler),
7e64f6a3 146 (r"/years/([0-9]+)", blog.YearHandler),
f0714277
MT
147
148 # RSS Feed
149 (r"/feed.xml", blog.FeedHandler),
08df6527 150 ] + authentication_handlers)
12e5de7e 151
940227cb 152 # downloads.ipfire.org
80594ae3 153 self.add_handlers(r"downloads?(\.dev)?\.ipfire\.org", [
ed8116c7
MT
154 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/" }),
155 (r"/(.*)", download.FileHandler),
54af860e 156 ])
940227cb
MT
157
158 # mirrors.ipfire.org
8fceca0a 159 self.add_handlers(r"mirrors(\.dev)?\.ipfire\.org", [
940227cb 160 (r"/", MirrorIndexHandler),
9068dba1 161 (r"/mirror/(.*)", MirrorItemHandler),
3808b871 162 ])
940227cb 163
d0d074e0 164 # planet.ipfire.org
7cad1818 165 self.add_handlers(r"planet(\.dev)?\.ipfire\.org", [
3d4ce901
MT
166 (r"/", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/" }),
167 (r"/post/([A-Za-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/posts/{1}" }),
168 (r"/user/([a-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/authors/{1}" }),
bcc3ed4d
MT
169
170 # RSS
f0714277 171 (r"/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
3d4ce901 172 (r"/user/([a-z0-9_-]+)/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/authors/{1}.rss" }),
f0714277 173 (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.xml" }),
3808b871 174 ])
d0d074e0 175
66862195 176 # fireinfo.ipfire.org
8fceca0a 177 self.add_handlers(r"fireinfo(\.dev)?\.ipfire\.org", [
66862195
MT
178 (r"/", FireinfoIndexHandler),
179 (r"/device/driver/(.*)", FireinfoDeviceDriverDetail),
180 (r"/device/vendors", FireinfoDeviceVendorsHandler),
181 (r"/device/(pci|usb)/([0-9a-f]{4})", FireinfoDeviceVendorHandler),
182 (r"/device/(pci|usb)/([0-9a-f]{4})/([0-9a-f]{4})", FireinfoDeviceModelHandler),
183
184 # Show profiles
185 (r"/profile/random", FireinfoRandomProfileHandler),
186 (r"/profile/([a-z0-9]{40})", FireinfoProfileDetailHandler),
91a446f0 187
30852a9e 188 # Send profiles.
66862195
MT
189 (r"/send/([a-z0-9]+)", FireinfoProfileSendHandler),
190
191 # Stats handlers
192 (r"/statistics", FireinfoStatsHandler),
193 (r"/statistics/processors", FireinfoStatsProcessorsHandler),
194 (r"/statistics/processors/(arm|x86)", FireinfoStatsProcessorDetailHandler),
195 (r"/statistics/geo-locations", FireinfoStatsGeoHandler),
196 (r"/statistics/languages", FireinfoStatsLanguagesHandler),
197 (r"/statistics/memory", FireinfoStatsMemoryHandler),
198 (r"/statistics/networking", FireinfoStatsNetworkingHandler),
199 (r"/statistics/releases", FireinfoStatsReleasesHandler),
200 (r"/statistics/virtualization", FireinfoStatsVirtualHandler),
201
202 # Compat handlers
203 (r"/stats", tornado.web.RedirectHandler, { "url" : "/statistics" }),
204 (r"/stats/cpus", tornado.web.RedirectHandler, { "url" : "/statistics/processors" }),
205 (r"/stats/geo", tornado.web.RedirectHandler, { "url" : "/statistics/geo-locations" }),
206 (r"/stats/network", tornado.web.RedirectHandler, { "url" : "/statistics/networking" }),
207 (r"/stats/oses", tornado.web.RedirectHandler, { "url" : "/statistics/releases" }),
208 (r"/stats/virtual", tornado.web.RedirectHandler, { "url" : "/statistics/virtualization" }),
209 (r"/vendor/(pci|usb)/([0-9a-f]{4})", FireinfoDeviceVendorCompatHandler),
210 (r"/model/(pci|usb)/([0-9a-f]{4})/([0-9a-f]{4})", FireinfoDeviceModelCompatHandler),
3808b871 211 ])
5cf160e0 212
c37ec602 213 # i-use.ipfire.org
8fceca0a 214 self.add_handlers(r"i-use(\.dev)?\.ipfire\.org", [
c37ec602
MT
215 (r"/profile/([a-f0-9]{40})/([0-9]+).png", IUseImage),
216 ])
217
8e2e1261
MT
218 # boot.ipfire.org
219 BOOT_STATIC_PATH = os.path.join(self.settings["static_path"], "netboot")
8fceca0a 220 self.add_handlers(r"boot(\.dev)?\.ipfire\.org", [
ba43a892 221 (r"/", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org/download" }),
8e2e1261
MT
222
223 # Configurations
37b5c0cf 224 (r"/premenu.cfg", PremenuCfgHandler),
8e2e1261
MT
225 (r"/menu.gpxe", MenuGPXEHandler),
226 (r"/menu.cfg", MenuCfgHandler),
8e2e1261
MT
227
228 # Static files
37b5c0cf 229 (r"/(boot\.png|pxelinux\.0|menu\.c32|vesamenu\.c32)",
8e2e1261
MT
230 tornado.web.StaticFileHandler, { "path" : BOOT_STATIC_PATH }),
231 ])
232
60024cc8 233 # nopaste.ipfire.org
8fceca0a 234 self.add_handlers(r"nopaste(\.dev)?\.ipfire\.org", [
a41085fb
MT
235 (r"/", nopaste.CreateHandler),
236 (r"/raw/(.*)", nopaste.RawHandler),
237 (r"/view/(.*)", nopaste.ViewHandler),
3808b871 238 ] + authentication_handlers)
60024cc8 239
f5b01fc2
MT
240 # location.ipfire.org
241 self.add_handlers(r"location(\.dev)?\.ipfire\.org", [
242 (r"/", location.IndexHandler),
243 (r"/lookup/(.+)", location.LookupHandler),
244 ])
245
9068dba1 246 # geoip.ipfire.org
8fceca0a 247 self.add_handlers(r"geoip(\.dev)?\.ipfire\.org", [
f5b01fc2 248 (r"/", tornado.web.RedirectHandler, { "url" : "https://location.ipfire.org/" }),
3808b871 249 ])
9068dba1 250
66862195
MT
251 # talk.ipfire.org
252 self.add_handlers(r"talk(\.dev)?\.ipfire\.org", [
786e9ca8
MT
253 (r"/", tornado.web.RedirectHandler, { "url" : "https://people.ipfire.org/" }),
254 ])
66862195 255
03706893
MT
256 # people.ipfire.org
257 self.add_handlers(r"people(\.dev)?\.ipfire\.org", [
786e9ca8 258 (r"/", people.IndexHandler),
30aeccdb 259 (r"/conferences", people.ConferencesHandler),
786e9ca8
MT
260 (r"/search", people.SearchHandler),
261 (r"/users", people.UsersHandler),
262 (r"/users/(\w+)", people.UserHandler),
03706893 263 (r"/users/(\w+)\.jpg", people.AvatarHandler),
68ece434 264 (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 265 (r"/users/(\w+)/calls(?:/(\d{4}-\d{2}-\d{2}))?", people.CallsHandler),
e96e445b 266 (r"/users/(\w+)/edit", people.UserEditHandler),
3ea97943 267 (r"/users/(\w+)/passwd", people.UserPasswdHandler),
f4672785 268 (r"/users/(\w+)/ssh-keys", people.SSHKeysIndexHandler),
44b75370
MT
269 (r"/users/(\w+)/ssh-keys/(SHA256\:.*)/delete", people.SSHKeysDeleteHandler),
270 (r"/users/(\w+)/ssh-keys/(SHA256\:.*)", people.SSHKeysDownloadHandler),
0d1fb712 271 (r"/users/(\w+)/ssh-keys/upload", people.SSHKeysUploadHandler),
e0daee8f 272 (r"/users/(\w+)/sip", people.SIPHandler),
786e9ca8 273 ] + authentication_handlers)
2cd9af74 274
ae0228e1 275 # ipfire.org
45592df5 276 self.add_handlers(r"ipfire\.org", [
ba43a892 277 (r".*", tornado.web.RedirectHandler, { "url" : "https://www.ipfire.org" })
5cf160e0 278 ])
3add293a 279
feb02477
MT
280 logging.info("Successfully initialied application")
281
cc3b928d
MT
282 def format_month_name(self, handler, month):
283 _ = handler.locale.translate
284
285 if month == 1:
286 return _("January")
287 elif month == 2:
288 return _("February")
289 elif month == 3:
290 return _("March")
291 elif month == 4:
292 return _("April")
293 elif month == 5:
294 return _("May")
295 elif month == 6:
296 return _("June")
297 elif month == 7:
298 return _("July")
299 elif month == 8:
300 return _("August")
301 elif month == 9:
302 return _("September")
303 elif month == 10:
304 return _("October")
305 elif month == 11:
306 return _("November")
307 elif month == 12:
308 return _("December")
309
310 return month
401827c2 311
e96e445b
MT
312 def format_phone_number(self, handler, number):
313 if not isinstance(number, phonenumbers.PhoneNumber):
314 try:
01e73b0e 315 number = phonenumbers.parse(number, None)
e96e445b
MT
316 except phonenumbers.phonenumberutil.NumberParseException:
317 return number
c01ad253
MT
318
319 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
320
e96e445b
MT
321 def format_phone_number_to_e164(self, handler, number):
322 return phonenumbers.format_number(number, phonenumbers.PhoneNumberFormat.E164)
323
324 def format_phone_number_location(self, handler, number):
325 s = [
326 phonenumbers.geocoder.description_for_number(number, handler.locale.code),
327 phonenumbers.region_code_for_number(number),
328 ]
329
330 return ", ".join((e for e in s if e))
331
401827c2
MT
332
333def grouper(handler, iterator, n):
334 """
335 Returns groups of n from the iterator
336 """
337 i = iter(iterator)
338
339 while True:
340 ret = list(itertools.islice(i, 0, n))
341 if not ret:
342 break
343
344 yield ret