]> git.ipfire.org Git - pbs.git/blob - src/web/base.py
packages: Refactor filelist
[pbs.git] / src / web / base.py
1 #!/usr/bin/python
2
3 import http.client
4 import pytz
5 import time
6 import tornado.locale
7 import tornado.web
8 import traceback
9
10 from .. import __version__
11 from .. import misc
12 from ..decorators import *
13
14 class BaseHandler(tornado.web.RequestHandler):
15 @property
16 def backend(self):
17 return self.application.backend
18
19 @property
20 def db(self):
21 return self.backend.db
22
23 @lazy_property
24 def session(self):
25 # Get the session from the cookie
26 session_id = self.get_cookie("session_id", None)
27
28 # Search for a valid database session
29 if session_id:
30 return self.backend.sessions.get(session_id)
31
32 def get_current_user(self):
33 if self.session:
34 return self.session.user
35
36 def get_user_locale(self):
37 # Get the locale from the user settings
38 if self.current_user:
39 return self.current_user.locale
40
41 # If no locale was provided, we take what ever the browser requested
42 return self.get_browser_locale()
43
44 @property
45 def current_address(self):
46 """
47 Returns the IP address the request came from.
48 """
49 return self.request.headers.get("X-Real-IP") or self.request.remote_ip
50
51 @property
52 def user_agent(self):
53 """
54 Returns the HTTP user agent
55 """
56 return self.request.headers.get("User-Agent", None)
57
58 @property
59 def timezone(self):
60 if self.current_user:
61 return self.current_user.timezone
62
63 return pytz.utc
64
65 def format_date(self, date, relative=True, shorter=False,
66 full_format=False):
67 # XXX not very precise but working for now.
68 gmt_offset = self.timezone.utcoffset(date).total_seconds() / -60
69
70 return self.locale.format_date(date, gmt_offset=gmt_offset,
71 relative=relative, shorter=shorter, full_format=full_format)
72
73 def get_template_namespace(self):
74 ns = tornado.web.RequestHandler.get_template_namespace(self)
75
76 ns.update({
77 "backend" : self.backend,
78 "hostname" : self.request.host,
79 "format_date" : self.format_date,
80 "format_size" : misc.format_size,
81 "friendly_time" : misc.friendly_time,
82 "lang" : self.locale.code[:2],
83 "session" : self.session,
84 "version" : __version__,
85 "year" : time.strftime("%Y"),
86 })
87
88 return ns
89
90 def write_error(self, status_code, exc_info=None, **kwargs):
91 if status_code in (400, 403, 404):
92 error_document = "errors/error-%s.html" % status_code
93 else:
94 error_document = "errors/error.html"
95
96 try:
97 status_message = http.client.responses[status_code]
98 except KeyError:
99 status_message = None
100
101 # Collect more information about the exception if possible.
102 if exc_info:
103 tb = traceback.format_exception(*exc_info)
104 else:
105 tb = None
106
107 self.render(error_document, status_code=status_code,
108 status_message=status_message, exc_info=exc_info, tb=tb, **kwargs)
109
110 # Typed Arguments
111
112 def get_argument_bool(self, name):
113 arg = self.get_argument(name, default=None)
114
115 return arg == "on"
116
117 def get_argument_int(self, *args, **kwargs):
118 arg = self.get_argument(*args, **kwargs)
119
120 # Return nothing
121 if not arg:
122 return None
123
124 try:
125 return int(arg)
126 except (TypeError, ValueError):
127 raise tornado.web.HTTPError(400, "%s is not an integer" % arg)
128
129 def get_argument_distro(self, *args, **kwargs):
130 slug = self.get_argument(*args, **kwargs)
131
132 if slug:
133 return self.backend.distros.get_by_slug(slug)