This repository was archived by the owner on Oct 19, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbaseserver.py
More file actions
executable file
·197 lines (156 loc) · 6.13 KB
/
baseserver.py
File metadata and controls
executable file
·197 lines (156 loc) · 6.13 KB
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
# ##### BEGIN AGPL LICENSE BLOCK #####
# This file is part of SimpleMMO.
#
# Copyright (C) 2011, 2012 Charles Nelson
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ##### END AGPL LICENSE BLOCK #####
import settings
import logging
logging.getLogger('requests.packages.urllib3.connectionpool').setLevel(logging.WARN)
from tornado.web import Application, RequestHandler
from tornado.options import options, define
from tornado.ioloop import IOLoop
define("dburi", default='simplemmo.sqlite', help="Where is the database?", type=str)
from elixir_models import setup
client = False
try:
if settings.SENTRY:
from raven import Client
import requests
try:
r = requests.get(settings.SENTRY_SERVER)
sentry_up = 'Sentry' in r.content
except requests.ConnectionError:
sentry_up = False
if sentry_up:
client = Client(settings.SENTRY_DSN)
if settings.SENTRY_LOG:
from raven.handlers.logging import SentryHandler
from raven.conf import setup_logging
handler = SentryHandler(client)
setup_logging(handler)
except ImportError:
print "Set up Sentry for consolidated logging and error reporting!"
class BaseHandler(RequestHandler):
def _handle_request_exception(self, e):
if client:
client.captureException()
RequestHandler._handle_request_exception(self, e)
def get_login_url(self):
return u"/login"
def get_current_user(self):
user_json = self.get_secure_cookie("user")
if user_json:
return user_json
else:
return None
def HTTPError(self, code, message):
def write_error(status_code, **kwargs):
self.write(message)
self.write_error = write_error
self.send_error(code)
self.write_error = old_write_error
class SimpleHandler(BaseHandler):
def __init__(self, output, *args):
self.output = output
RequestHandler.__init__(self, *args)
def get(self):
self.write(self.output)
from subprocess import Popen, PIPE
def get_gitsha():
return Popen("git rev-parse --short HEAD", shell=True, stdout=PIPE).communicate()[0].strip()
def get_commits():
return Popen("git rev-list --all | wc -l", shell=True, stdout=PIPE).communicate()[0].strip()
class VersionHandler(BaseHandler):
def get(self):
gitsha = get_gitsha()
commits = get_commits()
self.write('\n'.join((gitsha, commits)))
class SelfServe(BaseHandler):
'''Provides a method to comply with AGPL licensing.
This allows a request handler to respond to something like "/source"
and iterate through the local directory, adding files it finds with an
AGPL license to a zipfile and returning that when it is done.
It skips any directories that contain any of the strings in settings.SKIP_FOLDERS.
'''
def get(self):
from zipfile import ZipFile
import os
import uuid
# Get all files in this folder and all folders below it.
outfile = "/tmp/%s.zip" % str(uuid.uuid4())
z = ZipFile(outfile, "w")
for root, dirs, files in os.walk("."):
skip = False
for no in settings.SKIP_FOLDERS:
if no in root:
skip = True
break
if skip:
continue
for filename in files:
# Search them all for "BEGIN AGPL LICENSE BLOCK"
print "Searching %s" % os.path.join(root, filename)
if settings.AGPL_STRING in open(os.path.join(root, filename), "r").read():
print "Added %s to archive." % filename
z.write(os.path.join(root, filename))
z.close()
# Zip all those up and return it.
self.set_header('content-type', 'application/zip')
self.set_header('content-disposition', "attachment;filename=SimpleMMO_%s-%s.zip" % (get_commits(), get_gitsha()))
with open(outfile, "r") as f:
archive = f.read()
# Delete outfile.
self.write(archive)
class PingHandler(BaseHandler):
'''An easy way to see if the server is alive.
.. http:get:: /ping
Always the string "pong".
**Example request**:
.. sourcecode:: http
GET /ping HTTP/1.1
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Content-Type: text/plain
pong
'''
def get(self):
self.write("pong")
self.set_header("Content-Type", "text/plain")
class BaseServer(Application):
def __init__(self, extra_handlers):
'''Expects a list of tuple handlers like:
[(r"/", MainHandler), (r"/chatsocket", ChatSocketHandler),]
'''
url = settings._server_str % (settings.PROTOCOL, settings.HOSTNAME, settings.AUTHSERVERPORT)
app_settings = {
"cookie_secret": settings.COOKIE_SECRET,
"login_url": ''.join((url, "/login")),
}
handlers = []
handlers.append((r"/version", VersionHandler))
handlers.append((r"/source", SelfServe))
handlers.append((r"/ping", PingHandler))
handlers.append((r"/", PingHandler))
handlers.extend(extra_handlers)
options.parse_command_line()
dburi = options.dburi
# Connect to the elixir db
setup(db_uri=dburi)
Application.__init__(self, handlers, debug=True, **app_settings)
def start(self):
IOLoop.current().start()