freelance-project-34-market.../d1/f2.py
2022-10-16 16:12:07 +03:00

275 lines
7.2 KiB
Python

import os
import shutil
import datetime
import tempfile
import time
import numpy
import io
import traceback
import subprocess
import json
import sys
import pprint
sys.path.insert(0, os.path.dirname(__file__))
class Application:
def __init__(self, environ, start_response):
self.environ = environ
self.start_response = start_response
self.log_path = 'log.txt'
def trim_log(self):
if not os.path.exists(self.log_path):
return
log_size = 0
try:
log_stats = os.stat(self.log_path)
log_size = log_stats.st_size
except:
return
if log_size > 10 * 1024 * 1024:
try:
log_path2 = os.path.splitext(self.log_path)
os.rename(
self.log_path,
'%s-backup%s' % (
log_path2[0],
log_path2[1],
),
)
except:
return
def op1(self, data=None):
if data is None:
data = traceback.format_exc()
self.trim_log()
with io.open(
self.log_path,
'a'
) as f:
f.write(
'\n%s\n%s\n' % (
datetime.datetime.now().isoformat(),
data,
)
)
def op2(self, rh):
t5 = rh.split('_')
t6 = ['%s%s' % (o[0].upper(), o[1:].lower()) for o in t5]
return '-'.join(t6)
def op3(self,):
for o in [self.input_dat, self.output_dat]:
if not o is None and os.path.exists(o):
os.unlink(o)
def op4(self,):
self.output_dat = tempfile.mktemp(suffix='.dat')
self.input_dat = tempfile.mktemp(suffix='.dat')
def op5(
self,
status_code=None,
status_text=None,
content_type=None,
content=None,
headers_text=None,
):
if not headers_text is None:
if not any([o.startswith('Content-Length') for o in headers_text]):
headers_text = \
headers_text.replace(
'Transfer-Encoding: chunked\r\n',
''
)
headers_text += 'Content-Length: %d\r\n' % len(content)
t13 = headers_text.splitlines()[0]
t14 = t13.find(' ')
t15 = t13[t14 + 1:]
status_suffix = t15
headers = [
(o[:o.find(':')], o[o.find(':') + 1:])
for o in headers_text.splitlines()[1:]
]
else:
if status_code is None:
status_code = 200
if status_text is None:
status_text = 'OK'
if content_type is None:
content_type = 'text/plain'
status_suffix = '%d %s' % (status_code, status_text)
headers = [('Content-Type', content_type)]
t1 = self.start_response(
status_suffix,
headers,
)
assert isinstance(content, bytes)
t1(content)
return []
def op6(self, cmd_args,):
self.op1(json.dumps(cmd_args))
with subprocess.Popen(
cmd_args,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE
) as p:
try:
p.wait(20)
curl_stderr = p.stderr.read().decode('utf-8')
response_headers = [
o[2:]
for o in curl_stderr.splitlines()
if o.startswith('< ')
]
t9 = '\r\n'.join(response_headers)
if not 'Content-Length: 0' in t9:
for k in range(100):
try:
with io.open(self.output_dat, 'rb') as f:
t10 = f.read()
break
except:
time.sleep(0.05)
else:
t10 = b''
try:
output_dat_stat = repr(
os.stat(self.output_dat)
)
except:
output_dat_stat = None
self.op1(
json.dumps(
dict(
curl_return_code=p.returncode,
curl_stderr=curl_stderr,
output_dat=self.output_dat,
output_dat_stat=output_dat_stat,
headers=t9,
)
)
)
finally:
p.terminate()
return dict(
headers_text=t9,
content=t10
)
def op7(self):
try:
with io.open(
os.path.join(
os.environ['HOME'],
'proxy.json'
),
'r'
) as f:
return numpy.random.choice(json.load(f))
except:
with io.open('log.txt', 'a') as f:
f.write(traceback.format_exc())
return '127.0.0.1:9050'
def op8(self, input_content, headers, uri, method):
try:
self.op4()
with io.open(
self.input_dat,
'wb'
) as f:
f.write(input_content)
proxy_url = self.op7()
t17 = [
'curl',
'http://%s%s' % (proxy_url, uri),
*sum([
['--header', '%s: %s' % (k, v)]
for k, v in headers.items()
], []),
'-X', method,
'-v',
'--no-buffer',
'--silent',
'--data-binary', '@%s' % self.input_dat,
'--max-filesize', '%d' % (60 * 1024 * 1024),
'-o', self.output_dat,
'-q',
]
return self.op6(t17)
finally:
self.op3()
def run(self):
try:
t4 = int(self.environ.get('CONTENT_LENGTH', '0'))
t3 = self.environ['wsgi.input'].read(t4)
t2 = {
self.op2(k[5:]) : v
for k, v in self.environ.items()
if k.startswith('HTTP_')
}
for k, v in self.environ.items():
if k in [
'CONTENT_TYPE',
]:
t2[self.op2(k)] = v
t7 = dict(
uri=self.environ['REQUEST_URI'],
method=self.environ['REQUEST_METHOD'],
protocol=self.environ['SERVER_PROTOCOL'],
)
o_8 = self.op8(
t3,
headers=t2,
uri=t7['uri'],
method=t7['method'],
)
return self.op5(
**o_8,
)
except:
self.op1()
return self.op5(
content='internal server error',
)
def application(environ, start_response):
return Application(
environ=environ,
start_response=start_response,
).run()