1717from __future__ import print_function
1818
1919import sys
20+
2021if sys .version_info [0 ] < 3 :
2122 reload (sys )
22- sys .setdefaultencoding (' utf8' )
23+ sys .setdefaultencoding (" utf8" )
2324
2425import sys
2526import logging
4344logging .basicConfig (
4445 filename = CONFIG ["path.log.main" ],
4546 level = logging .DEBUG ,
46- format = '%(asctime)s %(message)s' )
47+ format = "%(asctime)s %(message)s" ,
48+ )
4749# Fix Flask "exception and request logging" to `stderr`.
4850#
4951# When Flask's werkzeug detects that logging is already set, it
5254logging .getLogger ().addHandler (stderr_handler )
5355#
5456# Alter log format to disting log lines from everything else
55- stderr_handler .setFormatter (logging .Formatter ('%(filename)s:%(lineno)s: %(message)s' ))
57+ stderr_handler .setFormatter (logging .Formatter ("%(filename)s:%(lineno)s: %(message)s" ))
58+
59+
5660#
5761# Sometimes werkzeug starts logging before an app is imported
5862# (https://github.com/pallets/werkzeug/issues/1969)
5963# resulting in duplicating lines. In that case we need root
6064# stderr handler to skip lines from werkzeug.
6165class SkipFlaskLogger (object ):
6266 def filter (self , record ):
63- if record .name != ' werkzeug' :
67+ if record .name != " werkzeug" :
6468 return True
65- if logging .getLogger ('werkzeug' ).handlers :
69+
70+
71+ if logging .getLogger ("werkzeug" ).handlers :
6672 stderr_handler .addFilter (SkipFlaskLogger ())
6773
6874
69- app = Flask (__name__ ) # pylint: disable=invalid-name
70- app .jinja_loader = jinja2 .ChoiceLoader ([
71- app .jinja_loader ,
72- jinja2 . FileSystemLoader ( CONFIG [ "path.internal.templates" ])] )
75+ app = Flask (__name__ ) # pylint: disable=invalid-name
76+ app .jinja_loader = jinja2 .ChoiceLoader (
77+ [ app .jinja_loader , jinja2 . FileSystemLoader ( CONFIG [ "path.internal.templates" ])]
78+ )
7379
7480LIMITS = Limits ()
7581
@@ -85,32 +91,37 @@ def filter(self, record):
8591 "aiohttp" ,
8692]
8793
94+
8895def _is_html_needed (user_agent ):
8996 """
9097 Basing on `user_agent`, return whether it needs HTML or ANSI
9198 """
9299 return all ([x not in user_agent for x in PLAIN_TEXT_AGENTS ])
93100
101+
94102def is_result_a_script (query ):
95- return query in [':cht.sh' ]
103+ return query in [":cht.sh" ]
104+
96105
97- @app .route (' /files/<path:path>' )
106+ @app .route (" /files/<path:path>" )
98107def send_static (path ):
99108 """
100109 Return static file `path`.
101110 Can be served by the HTTP frontend.
102111 """
103112 return send_from_directory (CONFIG ["path.internal.static" ], path )
104113
105- @app .route ('/favicon.ico' )
114+
115+ @app .route ("/favicon.ico" )
106116def send_favicon ():
107117 """
108118 Return static file `favicon.ico`.
109119 Can be served by the HTTP frontend.
110120 """
111- return send_from_directory (CONFIG ["path.internal.static" ], 'favicon.ico' )
121+ return send_from_directory (CONFIG ["path.internal.static" ], "favicon.ico" )
122+
112123
113- @app .route (' /malformed-response.html' )
124+ @app .route (" /malformed-response.html" )
114125def send_malformed ():
115126 """
116127 Return static file `malformed-response.html`.
@@ -119,13 +130,15 @@ def send_malformed():
119130 dirname , filename = os .path .split (CONFIG ["path.internal.malformed" ])
120131 return send_from_directory (dirname , filename )
121132
133+
122134def log_query (ip_addr , found , topic , user_agent ):
123135 """
124136 Log processed query and some internal data
125137 """
126138 log_entry = "%s %s %s %s\n " % (ip_addr , found , topic , user_agent )
127- with open (CONFIG ["path.log.queries" ], 'ab' ) as my_file :
128- my_file .write (log_entry .encode ('utf-8' ))
139+ with open (CONFIG ["path.log.queries" ], "ab" ) as my_file :
140+ my_file .write (log_entry .encode ("utf-8" ))
141+
129142
130143def get_request_ip (req ):
131144 """
@@ -134,19 +147,20 @@ def get_request_ip(req):
134147
135148 if req .headers .getlist ("X-Forwarded-For" ):
136149 ip_addr = req .headers .getlist ("X-Forwarded-For" )[0 ]
137- if ip_addr .startswith (' ::ffff:' ):
150+ if ip_addr .startswith (" ::ffff:" ):
138151 ip_addr = ip_addr [7 :]
139152 else :
140153 ip_addr = req .remote_addr
141154 if req .headers .getlist ("X-Forwarded-For" ):
142155 ip_addr = req .headers .getlist ("X-Forwarded-For" )[0 ]
143- if ip_addr .startswith (' ::ffff:' ):
156+ if ip_addr .startswith (" ::ffff:" ):
144157 ip_addr = ip_addr [7 :]
145158 else :
146159 ip_addr = req .remote_addr
147160
148161 return ip_addr
149162
163+
150164def get_answer_language (request ):
151165 """
152166 Return preferred answer language based on
@@ -174,26 +188,26 @@ def _parse_accept_language(accept_language):
174188 def _find_supported_language (accepted_languages ):
175189 for lang_tuple in accepted_languages :
176190 lang = lang_tuple [0 ]
177- if '-' in lang :
178- lang = lang .split ('-' , 1 )[0 ]
191+ if "-" in lang :
192+ lang = lang .split ("-" , 1 )[0 ]
179193 return lang
180194 return None
181195
182196 lang = None
183- hostname = request .headers [' Host' ]
184- if hostname .endswith (' .cheat.sh' ):
197+ hostname = request .headers [" Host" ]
198+ if hostname .endswith (" .cheat.sh" ):
185199 lang = hostname [:- 9 ]
186200
187- if ' lang' in request .args :
188- lang = request .args .get (' lang' )
201+ if " lang" in request .args :
202+ lang = request .args .get (" lang" )
189203
190- header_accept_language = request .headers .get (' Accept-Language' , '' )
204+ header_accept_language = request .headers .get (" Accept-Language" , "" )
191205 if lang is None and header_accept_language :
192- lang = _find_supported_language (
193- _parse_accept_language (header_accept_language ))
206+ lang = _find_supported_language (_parse_accept_language (header_accept_language ))
194207
195208 return lang
196209
210+
197211def _proxy (* args , ** kwargs ):
198212 # print "method=", request.method,
199213 # print "url=", request.url.replace('/:shell-x/', ':3000/')
@@ -202,32 +216,41 @@ def _proxy(*args, **kwargs):
202216 # print "cookies=", request.cookies
203217 # print "allow_redirects=", False
204218
205- url_before , url_after = request .url .split (' /:shell-x/' , 1 )
206- url = url_before + ' :3000/'
219+ url_before , url_after = request .url .split (" /:shell-x/" , 1 )
220+ url = url_before + " :3000/"
207221
208- if 'q' in request .args :
209- url_after = '?' + "&" .join ("arg=%s" % x for x in request .args ['q' ].split ())
222+ if "q" in request .args :
223+ url_after = "?" + "&" .join ("arg=%s" % x for x in request .args ["q" ].split ())
210224
211225 url += url_after
212226 print (url )
213227 print (request .get_data ())
214228 resp = requests .request (
215229 method = request .method ,
216230 url = url ,
217- headers = {key : value for (key , value ) in request .headers if key != ' Host' },
231+ headers = {key : value for (key , value ) in request .headers if key != " Host" },
218232 data = request .get_data (),
219233 cookies = request .cookies ,
220- allow_redirects = False )
221-
222- excluded_headers = ['content-encoding' , 'content-length' , 'transfer-encoding' , 'connection' ]
223- headers = [(name , value ) for (name , value ) in resp .raw .headers .items ()
224- if name .lower () not in excluded_headers ]
234+ allow_redirects = False ,
235+ )
236+
237+ excluded_headers = [
238+ "content-encoding" ,
239+ "content-length" ,
240+ "transfer-encoding" ,
241+ "connection" ,
242+ ]
243+ headers = [
244+ (name , value )
245+ for (name , value ) in resp .raw .headers .items ()
246+ if name .lower () not in excluded_headers
247+ ]
225248
226249 response = Response (resp .content , resp .status_code , headers )
227250 return response
228251
229252
230- @app .route ("/" , methods = [' GET' , ' POST' ])
253+ @app .route ("/" , methods = [" GET" , " POST" ])
231254@app .route ("/<path:topic>" , methods = ["GET" , "POST" ])
232255def answer (topic = None ):
233256 """
@@ -242,16 +265,19 @@ def answer(topic=None):
242265 request.query_string
243266 """
244267
245- user_agent = request .headers .get (' User-Agent' , '' ).lower ()
268+ user_agent = request .headers .get (" User-Agent" , "" ).lower ()
246269 html_needed = _is_html_needed (user_agent )
247270 options = parse_args (request .args )
248271
249- if topic in ['apple-touch-icon-precomposed.png' , 'apple-touch-icon.png' , 'apple-touch-icon-120x120-precomposed.png' ] \
250- or (topic is not None and any (topic .endswith ('/' + x ) for x in ['favicon.ico' ])):
251- return ''
272+ if topic in [
273+ "apple-touch-icon-precomposed.png" ,
274+ "apple-touch-icon.png" ,
275+ "apple-touch-icon-120x120-precomposed.png" ,
276+ ] or (topic is not None and any (topic .endswith ("/" + x ) for x in ["favicon.ico" ])):
277+ return ""
252278
253- request_id = request .cookies .get ('id' )
254- if topic is not None and topic .lstrip ('/' ) == ' :last' :
279+ request_id = request .cookies .get ("id" )
280+ if topic is not None and topic .lstrip ("/" ) == " :last" :
255281 if request_id :
256282 topic = last_query (request_id )
257283 else :
@@ -260,43 +286,47 @@ def answer(topic=None):
260286 if request_id :
261287 save_query (request_id , topic )
262288
263- if request .method == ' POST' :
289+ if request .method == " POST" :
264290 process_post_request (request , html_needed )
265291 if html_needed :
266292 return redirect ("/" )
267293 return "OK\n "
268294
269- if ' topic' in request .args :
270- return redirect ("/%s" % request .args .get (' topic' ))
295+ if " topic" in request .args :
296+ return redirect ("/%s" % request .args .get (" topic" ))
271297
272298 if topic is None :
273299 topic = ":firstpage"
274300
275- if topic .startswith (' :shell-x/' ):
301+ if topic .startswith (" :shell-x/" ):
276302 return _proxy ()
277- #return requests.get('http://127.0.0.1:3000'+topic[8:]).text
303+ # return requests.get('http://127.0.0.1:3000'+topic[8:]).text
278304
279305 lang = get_answer_language (request )
280306 if lang :
281- options [' lang' ] = lang
307+ options [" lang" ] = lang
282308
283309 ip_address = get_request_ip (request )
284- if '+' in topic :
310+ if "+" in topic :
285311 not_allowed = LIMITS .check_ip (ip_address )
286312 if not_allowed :
287313 return "429 %s\n " % not_allowed , 429
288314
289315 html_is_needed = _is_html_needed (user_agent ) and not is_result_a_script (topic )
290316 if html_is_needed :
291- output_format = ' html'
317+ output_format = " html"
292318 else :
293- output_format = 'ansi'
294- result , found = cheat_wrapper (topic , request_options = options , output_format = output_format )
295- if 'Please come back in several hours' in result and html_is_needed :
296- malformed_response = open (os .path .join (CONFIG ["path.internal.malformed" ])).read ()
319+ output_format = "ansi"
320+ result , found = cheat_wrapper (
321+ topic , request_options = options , output_format = output_format
322+ )
323+ if "Please come back in several hours" in result and html_is_needed :
324+ malformed_response = open (
325+ os .path .join (CONFIG ["path.internal.malformed" ])
326+ ).read ()
297327 return malformed_response
298328
299329 log_query (ip_address , found , topic , user_agent )
300330 if html_is_needed :
301331 return result
302- return Response (result , mimetype = ' text/plain' )
332+ return Response (result , mimetype = " text/plain" )
0 commit comments