Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2@file
3@brief Defines handlers for a Tornado application.
4"""
5import logging
6import pprint
7from tornado.web import RequestHandler
8import tornado.web
11class _BaseRequestHandler(RequestHandler):
12 """
13 Base handler. Returns the user.
14 """
16 def __init__(self, application, request, **kwargs):
17 """
18 Constructor.
19 See `web.py <https://github.com/tornadoweb/tornado/blob/master/tornado/web.py>`_.
20 """
21 if 'ut_logged' in kwargs:
22 # For unit test, we impose a logged user.
23 self._logged_user = kwargs['ut_logged']['user']
24 del kwargs['ut_logged']
25 if 'dbman' in kwargs:
26 self._db = kwargs['dbman']
27 del kwargs['dbman']
28 RequestHandler.__init__(self, application, request, **kwargs)
29 self._app_log = logging.getLogger("tornado.application")
31 def info(self, message):
32 """
33 Log information.
34 """
35 self._app_log.info('[{0}] {1}'.format(
36 self.__class__.__name__, message))
38 def get_current_user(self):
39 """
40 Returns the current user.
41 """
42 if hasattr(self, '_logged_user'):
43 res = {'user': self._logged_user}
44 else:
45 res = self.get_secure_cookie("user")
46 if isinstance(res, bytes):
47 res = {'user': res.decode('utf-8')}
48 self.info('user={0}'.format(res))
49 return res
52class _TemplateHandler(_BaseRequestHandler):
53 """
54 Defines the main page handler.
55 """
57 def __init__(self, application, tmpl_name, request, **kwargs):
58 """
59 Constructor.
60 See `web.py <https://github.com/tornadoweb/tornado/blob/master/tornado/web.py>`_.
62 @param tmpl_name template name
63 @param context additional context for the template
64 """
65 tmpl, torn = self._process_kwargs(kwargs)
66 _BaseRequestHandler.__init__(self, application, request, **torn)
67 self._tmpl_name = "templates/{0}".format(tmpl_name)
68 self._tmpl_context = {'style': '/static/style.css',
69 'icon': '/static/icon.ico',
70 'image': '/static/icon.png'}
71 self._tmpl_context.update(tmpl)
72 self.info("template='{0}'".format(self._tmpl_name))
73 self.info("kwargs={0}".format(torn))
74 self.info("context={0}".format(self._tmpl_context))
76 def _process_kwargs(self, kwargs):
77 """
78 Separates attributes templates / tornado.
80 @param kwargs attributes
81 @return attributes for temples, attributes for tornado
83 An attributes for the template is prefixed with ``'tmpl_'``.
84 """
85 tmpl = {}
86 torn = {}
87 for k, v in kwargs.items():
88 if k.startswith("tmpl_"):
89 tmpl[k[5:]] = v
90 else:
91 torn[k] = v
92 return tmpl, torn
94 @tornado.web.authenticated
95 def get(self):
96 """
97 Returns the content page.
98 """
99 return self.render(self._tmpl_name, **self._tmpl_context)
102class LogoutHandler(_TemplateHandler):
103 """
104 Logout Handler.
105 """
107 def __init__(self, application, request, **kwargs):
108 """
109 Expected additional parameters:
111 * tmpl_title: application title
112 """
113 _TemplateHandler.__init__(
114 self, application, "unused", request, **kwargs)
116 @tornado.web.authenticated
117 def get(self):
118 """
119 Page.
120 """
121 self.info("logout {0}".format(self.get_current_user()))
122 self.clear_cookie("user")
123 self.redirect("/")
126class LoginHandler(_TemplateHandler):
127 """
128 Login Handler.
129 """
131 def __init__(self, application, request, **kwargs):
132 """
133 Expected additional parameters:
135 * title: application title
136 """
137 users = kwargs.get('users')
138 if users is None:
139 raise ValueError("No users was defined.\n{0}".format(
140 pprint.pformat(kwargs)))
141 del kwargs['users']
142 _TemplateHandler.__init__(self, application, "login.{0}.html".format(kwargs.get('lang', 'fr')),
143 request, **kwargs)
144 self._users = users
145 if not isinstance(users, dict):
146 raise TypeError(
147 "users must be a dictionary not {0}.".format(type(users)))
148 if hasattr(self, '_logged_user'):
149 self.set_current_user(self._logged_user)
151 @tornado.gen.coroutine
152 def get(self):
153 """
154 Page.
155 """
156 self.info('processing GET')
157 incorrect = self.get_secure_cookie("incorrect")
158 if incorrect and int(incorrect) > 20:
159 self.write('<center>blocked</center>')
160 return None
161 return self.render(self._tmpl_name, **self._tmpl_context)
163 def set_current_user(self, user):
164 """
165 Sets the current user or clear the cookie if None.
166 """
167 if user:
168 self.info("set user '{0}'".format(user))
169 self.set_secure_cookie("user", tornado.escape.json_encode(user))
170 else:
171 self.clear_cookie("user")
173 @tornado.gen.coroutine
174 def post(self):
175 "post"
176 self.info('processing POST')
177 self.info(str(self.request.arguments))
178 self.info(str(self.request.headers))
179 incorrect = self.get_secure_cookie("incorrect")
180 if incorrect and int(incorrect) > 20:
181 self.write('<center>blocked</center>')
182 return
184 getusername = tornado.escape.xhtml_escape(
185 self.get_argument("username", ""))
186 getpassword = tornado.escape.xhtml_escape(
187 self.get_argument("password", ""))
188 self.info("login='{0}'".format(getusername))
189 self.info("nb users={0}".format(len(self._users)))
190 if getusername in self._users:
191 val = self._users[getusername]
192 if isinstance(val, dict):
193 goodpwd = val['pwd'] == getpassword
194 else:
195 goodpwd = self._users[getusername] == getpassword
196 if goodpwd:
197 self.set_current_user(getusername)
198 self.set_secure_cookie("incorrect", "0")
199 self.redirect("/")
200 else:
201 incorrect = self.get_secure_cookie("incorrect") or 0
202 increased = str(int(incorrect) + 1)
203 self.set_secure_cookie("incorrect", increased)
204 self.set_current_user(None)
205 self.write("""<center>
206 Something Wrong With Login<br />
207 <a href="/login">Try Again</a>
208 </center>""")
211class MainHandler(_TemplateHandler):
212 """
213 Handlers for the main page.
214 """
216 def __init__(self, application, request, **kwargs):
217 """
218 Constructor.
219 """
220 _TemplateHandler.__init__(
221 self, application, "index.{0}.html".format(
222 kwargs.get('lang', 'fr')),
223 request, **kwargs)
226class SubmitForm(_TemplateHandler):
227 """
228 Handlers for the form to upload dataset.
229 """
231 def __init__(self, application, request, **kwargs):
232 """
233 Constructor.
234 """
235 _TemplateHandler.__init__(
236 self, application, "submit.{0}.html".format(
237 kwargs.get('lang', 'fr')),
238 request, **kwargs)
239 val = self.get_argument('cpt_value', None)
240 if val is None:
241 raise ValueError(
242 "cpt_value is not defined in the list of arguments.")
243 self._tmpl_context['cpt_value'] = val
244 self._tmpl_context['cptidname'] = self._db.get_competitions()
247class UploadData(_TemplateHandler):
248 """
249 Upload data.
250 Handlers for the form to upload dataset.
251 """
253 def __init__(self, application, request, **kwargs):
254 """
255 Constructor.
256 """
257 _TemplateHandler.__init__(
258 self, application, "waiting.{0}.html".format(
259 kwargs.get('lang', 'fr')),
260 request, **kwargs)
261 self._tmpl_context['waitgif'] = "/static/giphy.gif"
263 @tornado.gen.coroutine
264 def post(self):
265 "post"
266 fileinfo = self.request.files['filearg'][0]
267 self.info("fileinfo={0}".format(fileinfo))
268 fname = fileinfo['filename']
269 self.info("filename='{0}'".format(fname))
270 content = fileinfo['body']
271 self.info("downloaded size={0}".format(len(content)))
274class CompetitionHandler(_TemplateHandler):
275 """
276 Handlers for the page on competitions.
277 """
279 def __init__(self, application, request, **kwargs):
280 """
281 Constructor.
282 """
283 _TemplateHandler.__init__(
284 self, application, "challenge.{0}.html".format(
285 kwargs.get('lang', 'fr')),
286 request, **kwargs)
287 val = self.get_argument('cpt_id', None)
288 if val is None:
289 raise ValueError(
290 "cpt_id is not defined in the list of arguments.")
291 self._tmpl_context['cpt'] = self._db.get_competition(val)
292 self._tmpl_context['results'] = self._db.get_results(val)