forked from pyfa-org/Pyfa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
155 lines (129 loc) · 4.66 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
import http.server
import urllib.parse
import socket
import threading
from logbook import Logger
import socketserver
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(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/favicon.ico":
return
parsed_path = urllib.parse.urlparse(self.path)
parts = urllib.parse.parse_qs(parsed_path.query)
msg = ""
step2 = 'step' in parts
try:
if step2:
self.server.callback(parts)
pyfalog.info("Successfully logged into EVE.")
msg = "If you see this message then it means you should be logged into EVE SSO. 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 using a querystring
pyfalog.info("Processing response from EVE Online.")
msg = "Processing response from EVE Online"
except (KeyboardInterrupt, SystemExit):
raise
except Exception as ex:
pyfalog.error("Error logging into EVE")
pyfalog.error(ex)
msg = "<h2>Error</h2>\n<p>{}</p>".format(ex.message)
finally:
self.send_response(200)
self.end_headers()
self.wfile.write(str.encode(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(socketserver.TCPServer):
def server_bind(self):
# Can't use HTTPServer due to reliance on socket.getfqdn() which seems to be bugged.
# See https://github.com/pyfa-org/Pyfa/issues/1560#issuecomment-390095101
socketserver.TCPServer.server_bind(self)
host, port = self.server_address[:2]
self.server_name = host
self.server_port = port
# self.settings = CRESTSettings.getInstance()
self.socket.settimeout(1)
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 pyfa server to stop.")
self.run = False
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)
input("Press <RETURN> to stop server\n")
httpd.stop()