This repository has been archived by the owner on Aug 30, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.py
206 lines (161 loc) · 7.04 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# coding=UTF-8
### Some global variables
CONF_NAME = 'server.conf'
TEMPLATES_DIRNAME = 'templates'
# Import all stuff we need
import os
import socket
import logging
from logging import handlers
import cherrypy
import urlparse
from mako.template import Template
from mako.lookup import TemplateLookup
current_folder = os.path.dirname(__file__)
# Transform relative path to absolute
template_folder = os.path.join(current_folder, TEMPLATES_DIRNAME)
class MakoHandler(cherrypy.dispatch.LateParamPageHandler):
""" Callable which sets response.body.
Source: http://tools.cherrypy.org/wiki/Mako
"""
def __init__(self, template, next_handler):
self.template = template
self.next_handler = next_handler
def __call__(self):
env = globals().copy()
env.update(self.next_handler())
return self.template.render(**env)
class MakoLoader(object):
def __init__(self):
self.lookups = {}
def __call__(self, filename, directories=[template_folder], module_directory=None,
collection_size=-1, output_encoding='utf-8', input_encoding='utf-8',
encoding_errors='replace'):
# Find the appropriate template lookup.
key = (tuple(directories), module_directory)
try:
lookup = self.lookups[key]
except KeyError:
lookup = TemplateLookup(directories=directories,
module_directory=module_directory,
collection_size=collection_size,
input_encoding=input_encoding,
output_encoding=output_encoding,
encoding_errors=encoding_errors)
self.lookups[key] = lookup
cherrypy.request.lookup = lookup
# Replace the current handler.
cherrypy.request.template = t = lookup.get_template(filename)
cherrypy.request.handler = MakoHandler(t, cherrypy.request.handler)
def authorize():
""" This method check session data and allow the current user to access a page or not
Source: http://tools.cherrypy.org/wiki/HandlerTool
"""
PASSTHROUGH_URLS = [
# Common assets
'/static', '/css', '/js', '/favicon.',
# Content pages
'/login', '/callback'
]
authorized = has_session = cherrypy.session.get('access_token')
if not authorized:
for url in PASSTHROUGH_URLS:
if cherrypy.request.path_info.startswith(url):
authorized = True
break
if authorized:
# Allow normal handler to run and display the page
return False
else:
raise cherrypy.HTTPRedirect('/login')
# Suppress normal handler from running
return True
def force_https():
""" Based on: http://tools.cherrypy.org/wiki/ApacheSSL
"""
url = urlparse.urlparse(cherrypy.url())
if url[0] != 'https':
secure_url = urlparse.urlunsplit(('https', url[1], url[2],
url[3], url[4]))
raise cherrypy.HTTPRedirect(secure_url)
def main():
# Set default network timeout
socket.setdefaulttimeout(10)
# Git doesn't seems to track empty directory so let's create one for the logs
log_dir = os.path.join(current_folder, 'logs')
if not os.path.exists(log_dir):
os.mkdir(log_dir)
# Here is the default config for static content
conf = { '/static': { 'tools.staticdir.on' : True
, 'tools.staticdir.dir': os.path.join(current_folder, 'static')
}
, '/css': { 'tools.staticdir.on' : True
, 'tools.staticdir.dir': os.path.join(current_folder, 'static', 'css')
}
, '/js': { 'tools.staticdir.on' : True
, 'tools.staticdir.dir': os.path.join(current_folder, 'static', 'js')
}
, '/favicon.ico': { 'tools.staticfile.on' : True
, 'tools.staticfile.filename': os.path.join(current_folder, 'favicon.ico')
}
}
cherrypy.config.update(conf)
# Enable sessions
cherrypy.config.update( { 'tools.sessions.on' : True
, 'tools.sessions.timeout' : 60
#, 'tools.sessions.storage_type': "file"
#, 'tools.sessions.storage_path': os.path.join(current_folder, 'sessions')
})
# Let our server honor proxied requests
# cherrypy.config.update({'tools.proxy.on': True})
# Force HTTPS all over the place
cherrypy.config.update( { 'server.ssl_certificate': os.path.join(current_folder, 'ssl/self-signed.pem')
, 'server.ssl_private_key': os.path.join(current_folder, 'ssl/private.key')
})
# Force all request to use HTTPS URL scheme
cherrypy.tools.secure = cherrypy.Tool('before_handler', force_https)
cherrypy.config.update({'tools.secure.on': True})
# Gzip eveything that looks like text
cherrypy.config.update({'tools.gzip.mime_types': ['text/*', 'application/json', 'application/javascript']})
# Load and apply the global config file
conf_file = os.path.join(current_folder, CONF_NAME)
cherrypy.config.update(conf_file)
# Set the default error page
cherrypy.config.update({'error_page.default': os.path.join(current_folder, 'static/error.html')})
# Setup our Mako decorator
loader = MakoLoader()
cherrypy.tools.mako = cherrypy.Tool('on_start_resource', loader)
# Register a tool to check for authentication
cherrypy.tools.authorize = cherrypy._cptools.HandlerTool(authorize)
# Import our application logic
from app import Root
# Prepare the app
app_root = Root()
app = cherrypy.tree.mount(app_root, config=conf)
# Change the default logger to a one that rotate
# Based on: http://www.cherrypy.org/wiki/Logging#CustomHandlers
MAX_LOG_SIZE = 10 * 1024 * 1024
LOGS_TO_KEEP = 100
# Set default log files
cherrypy.config.update( { 'log.screen' : False
#, 'log.access_file': os.path.join(current_folder, 'logs/access.log')
#, 'log.error_file' : os.path.join(current_folder, 'logs/cherrypy.log')
})
# Make a new RotatingFileHandler for each type of log
logs = [ ('error' , 'logs/cherrypy.log')
, ('access', 'logs/access.log' )
]
log = app.log
for (log_type, log_path) in logs:
# Remove the default FileHandlers if present.
file_path = os.path.join(current_folder, log_path)
h = handlers.RotatingFileHandler(file_path, 'a', MAX_LOG_SIZE, LOGS_TO_KEEP)
h.setLevel(logging.DEBUG)
h.setFormatter(cherrypy._cplogging.logfmt)
getattr(log, '%s_log' % log_type).addHandler(h)
# Start the engine
cherrypy.engine.start()
# Wait for requests
cherrypy.engine.block()
if __name__ == '__main__':
main()