improve logstyle and update cmd interface

This commit is contained in:
mingyang 2021-06-02 15:52:10 +08:00
parent bfd95ff7cc
commit 0de630b146
3 changed files with 76 additions and 26 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ __pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class
.vscode/ .vscode/
config.json
# C extensions # C extensions
*.so *.so

View File

@ -53,7 +53,7 @@ class BasicTCPServer():
pass pass
except (Exception, KeyboardInterrupt): except (Exception, KeyboardInterrupt):
self.socket.close() self.socket.close()
print('Bye~') print('ヾ(•ω•`)o')
def start(self, back=True): def start(self, back=True):
if back: if back:

View File

@ -19,12 +19,15 @@ def loadfile(path):
return f.read() return f.read()
class HTTPImageServer(): class HTTPImageServer():
def __init__(self, bind_addr, imgroot='.'): def __init__(self, bind_addr, imgroot='.', thumbnail='webp', allowcros=True, loglevel=2):
self.server = HTTPBaseServer(request_handler=self.handle, bind_addr=bind_addr) self.server = HTTPBaseServer(request_handler=self.handle, bind_addr=bind_addr)
self.imgroot = imgroot self.imgroot = imgroot
self.img_extension = ['png', 'jpg', 'jpeg', 'tiff', 'webp', 'bmp'] self.img_extension = ['png', 'jpg', 'jpeg', 'tiff', 'webp', 'bmp']
self.print_lock = threading.Lock() self.print_lock = threading.Lock()
self.logqueue = queue.Queue() self.logqueue = queue.Queue()
self.thumbnail = thumbnail
self.allowcros = allowcros
self.loglevel = loglevel # 0: all information 1: only for response. 2: do not log image file. 3: no log.
def start(self, back=True): def start(self, back=True):
t = threading.Thread(target=self.logger, name='Logger thread', daemon=True) t = threading.Thread(target=self.logger, name='Logger thread', daemon=True)
t.start() t.start()
@ -61,7 +64,8 @@ class HTTPImageServer():
def log(self, msg): def log(self, msg):
self.logqueue.put(msg) self.logqueue.put(msg)
def response(self, connection, header, content): def response(self, connection, header, content, loglevel=1):
if loglevel >= self.loglevel:
msg = '[{time}] {method}: {url} - {stat}'.format( msg = '[{time}] {method}: {url} - {stat}'.format(
time = time.strftime("%H:%M:%S", time.localtime()), time = time.strftime("%H:%M:%S", time.localtime()),
method = connection.header.method, method = connection.header.method,
@ -71,6 +75,8 @@ class HTTPImageServer():
self.log(msg) self.log(msg)
header['Content-Length'] = len(content) header['Content-Length'] = len(content)
if self.allowcros:
header['Access-Control-Allow-Origin'] = '*'
connection.write(header.encode() + b'\r\n\r\n') connection.write(header.encode() + b'\r\n\r\n')
connection.write(content) connection.write(content)
@ -162,7 +168,7 @@ class HTTPImageServer():
new_h, new_w = (real_h * max_ratio, real_w * max_ratio) new_h, new_w = (real_h * max_ratio, real_w * max_ratio)
img = img.resize((int(new_w), int(new_h))) img = img.resize((int(new_w), int(new_h)))
img_stream = io.BytesIO() img_stream = io.BytesIO()
img = img.save(img_stream, format='webp') img = img.save(img_stream, format=self.thumbnail)
content = img_stream.getvalue() content = img_stream.getvalue()
else: else:
with open(full_path, 'rb') as f: with open(full_path, 'rb') as f:
@ -185,35 +191,78 @@ class HTTPImageServer():
location, params = self.parse_url(url) location, params = self.parse_url(url)
location = location.strip('/\\') location = location.strip('/\\')
header, content = None, None header, content = None, None
loglevel = 0
if location == 'directory': if location == 'directory':
header, content = self.handle_index(params) header, content = self.handle_index(params)
loglevel = 2
elif location == 'img': elif location == 'img':
header, content = self.handle_image(params) header, content = self.handle_image(params)
loglevel = 1
elif location in ['', 'index', 'index.html']: elif location in ['', 'index', 'index.html']:
header = HTTPResponseHeader(200) header = HTTPResponseHeader(200)
content = loadfile(index_path).encode('utf-8') content = loadfile(index_path).encode('utf-8')
loglevel = 2
else: else:
header = HTTPResponseHeader(404) header = HTTPResponseHeader(404)
content = b'Please Do Not Try To Access Non-Image File!' content = b'Please Do Not Try To Access Non-Image File!'
self.response(connection, header, content) loglevel = 2
self.response(connection, header, content, loglevel=loglevel)
def str2bool(string):
positive = ['true',
't',
'y',
'yes',
'1',
'correct',
'accept',
'positive'
]
if string.lower() in positive:
return True
else:
return False
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
import argparse
import json
args= sys.argv[1:] args= sys.argv[1:]
port = 80 parser = argparse.ArgumentParser('HTTPImageServer')
root = '.' conf_path = 'config.json'
if len(args) > 0:
try:
port = int(args[0])
except Exception:
print('Port {0} not understood, use 80 instead'.format(args[0]), file=sys.stderr)
if len(args) > 1:
root = args[1]
if not os.path.isdir(root):
print('Path {0} is not a valid path, use current directory instead.'.format(root), file=sys.stderr)
root = '.'
print('Start HTTP server on port {0} and use web root as {1}'.format(port, root)) # load default configuration first.
server = HTTPImageServer(bind_addr='0.0.0.0:{0}'.format(port), imgroot=root) defaults = {
"port": 80,
"interface": "0.0.0.0",
"root": ".",
"thumbnail": "webp",
"cros": True,
"loglevel": 2,
}
config = defaults
if os.path.isfile(conf_path):
with open(conf_path, 'r', encoding='utf-8') as f:
config.update(json.load(f))
else:
with open(conf_path, 'w+', encoding='utf-8') as f:
json.dump(config, f, indent=4, ensure_ascii=False)
parser.add_argument('--port', '-p', type=int, default=None, help='which port to start server on.')
parser.add_argument('--interface', '-i', type=str, default=None, help='which interface to bind, default is 0.0.0.0 for all interface.')
parser.add_argument('--root', '-r', type=str, default=None, help='root directory, default is current directory.')
parser.add_argument('--thumbnail', '-t', type=str, default=None, help='thumbnail format, default is webp, if you have any trouble, change to jpeg.')
parser.add_argument('--cros', type=str2bool, default=None, help='disable cros. default is enabled.')
parser.add_argument('--loglevel', '-l', type=int, default=None, help='loglevel, 0: all information 1: only for response. 2: do not log image file. 3: no log.')
parser.add_argument('--save', default=False, action='store_true', help='save the configuration as default.')
args = parser.parse_args()
parsed = {key:value for key, value in args.__dict__.items() if value is not None}
config.update(parsed)
args.__dict__.update(config)
addr = '{0}:{1}'.format(args.interface, args.port)
print('Start HTTP server on {0} and use web root as {1}'.format(addr, args.root))
server = HTTPImageServer(bind_addr=addr, imgroot=args.root, thumbnail=args.thumbnail, allowcros=args.cros, loglevel=args.loglevel)
server.start(back=False) server.start(back=False)