forked from pyfa-org/Pyfa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
160 lines (133 loc) · 4.79 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
import BaseHTTPServer
import urlparse
import socket
import threading
from logbook import Logger
from service.settings import CRESTSettings
pyfalog = Logger(__name__)
# noinspection PyPep8
HTML = '''
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>pyfa Local Server</title>
<style type="text/css">
body {{ text-align: center; padding: 150px; }}
h1 {{ font-size: 40px; }}
h2 {{ font-size: 32px; }}
body {{ font: 20px Helvetica, sans-serif; color: #333; }}
#article {{ display: block; text-align: left; width: 650px; margin: 0 auto; }}
a {{ color: #dc8100; text-decoration: none; }}
a:hover {{ color: #333; text-decoration: none; }}
</style>
</head>
<body>
<!-- Layout from Short Circuit's CREST login. Shout out! https://github.com/farshield/shortcircuit -->
<div id="article">
<h1>pyfa</h1>
{0}
</div>
<script type="text/javascript">
function extractFromHash(name, hash) {{
var match = hash.match(new RegExp(name + "=([^&]+)"));
return !!match && match[1];
}}
var hash = window.location.hash;
var token = extractFromHash("access_token", hash);
var step2 = extractFromHash("step2", hash);
function doRedirect() {{
if (token){{
// implicit authentication
var redirect = window.location.origin.concat('/?', window.location.hash.substr(1), '&step=2');
window.location = redirect;
}}
else {{
// user-defined
var redirect = window.location.href + '&step=2';
window.location = redirect;
}}
}}
// do redirect if we are not already on step 2
if (window.location.href.indexOf('step=2') == -1) {{
setTimeout(doRedirect(), 1000);
}}
</script>
</body>
</html>
'''
# https://github.com/fuzzysteve/CREST-Market-Downloader/
class AuthHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/favicon.ico":
return
parsed_path = urlparse.urlparse(self.path)
parts = urlparse.parse_qs(parsed_path.query)
msg = ""
step2 = 'step' in parts
try:
if step2:
self.server.callback(parts)
pyfalog.info("Successfully logged into CREST.")
msg = "If you see this message then it means you should be logged into CREST. You may close this window and return to the application."
else:
# For implicit mode, we have to serve up the page which will take the hash and redirect useing a querystring
pyfalog.info("Processing response from EVE Online.")
msg = "Processing response from EVE Online"
except Exception, ex:
pyfalog.error("Error in CREST AuthHandler")
pyfalog.error(ex)
msg = "<h2>Error</h2>\n<p>{}</p>".format(ex.message)
finally:
self.send_response(200)
self.end_headers()
self.wfile.write(HTML.format(msg))
if step2:
# Only stop once if we've received something in the querystring
self.server.stop()
def log_message(self, format, *args):
return
# http://code.activestate.com/recipes/425210-simple-stoppable-server-using-socket-timeout/
class StoppableHTTPServer(BaseHTTPServer.HTTPServer):
def server_bind(self):
BaseHTTPServer.HTTPServer.server_bind(self)
self.settings = CRESTSettings.getInstance()
# Allow listening for x seconds
sec = self.settings.get('timeout')
pyfalog.debug("Running server for {0} seconds", sec)
self.socket.settimeout(1)
self.max_tries = sec / self.socket.gettimeout()
self.tries = 0
self.run = True
def get_request(self):
while self.run:
try:
sock, addr = self.socket.accept()
sock.settimeout(None)
return sock, addr
except socket.timeout:
pyfalog.warning("Server timed out waiting for connection")
pass
def stop(self):
pyfalog.warning("Setting CREST server to stop.")
self.run = False
def handle_timeout(self):
pyfalog.debug("Number of tries: {0}", self.tries)
self.tries += 1
if self.tries == self.max_tries:
pyfalog.debug("Server timed out waiting for connection")
self.stop()
def serve(self, callback=None):
self.callback = callback
while self.run:
try:
self.handle_request()
except TypeError:
pyfalog.debug("Caught exception in serve")
pass
self.server_close()
if __name__ == "__main__":
httpd = StoppableHTTPServer(('', 6461), AuthHandler)
t = threading.Thread(target=httpd.serve)
raw_input("Press <RETURN> to stop server\n")
httpd.stop()