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