blivechat/api/main.py

97 lines
2.9 KiB
Python
Raw Normal View History

2019-06-12 13:55:49 +08:00
# -*- coding: utf-8 -*-
2022-02-27 22:05:37 +08:00
import asyncio
import hashlib
import logging
2022-02-27 22:05:37 +08:00
import os
2019-06-12 13:55:49 +08:00
import tornado.web
2020-02-06 19:51:03 +08:00
import api.base
import config
import update
logger = logging.getLogger(__name__)
EMOTICON_UPLOAD_PATH = os.path.join(config.DATA_PATH, 'emoticons')
EMOTICON_BASE_URL = '/emoticons'
2019-06-12 13:55:49 +08:00
2023-09-08 20:53:04 +08:00
class MainHandler(tornado.web.StaticFileHandler):
2020-08-18 21:48:33 +08:00
"""为了使用Vue Router的history模式把不存在的文件请求转发到index.html"""
async def get(self, path, include_body=True):
if path == '':
await self._get_index(include_body)
return
2020-08-18 21:48:33 +08:00
try:
await super().get(path, include_body)
except tornado.web.HTTPError as e:
if e.status_code != 404:
raise
# 不存在的文件请求转发到index.html交给前端路由
await self._get_index(include_body)
async def _get_index(self, include_body=True):
# index.html不缓存防止更新后前端还是旧版
self.set_header('Cache-Control', 'no-cache')
await super().get('index.html', include_body)
2020-02-06 19:51:03 +08:00
2023-09-08 20:53:04 +08:00
class ServerInfoHandler(api.base.ApiHandler):
2020-02-06 19:51:03 +08:00
async def get(self):
cfg = config.get_config()
self.write({
'version': update.VERSION,
'config': {
2020-08-30 17:46:04 +08:00
'enableTranslate': cfg.enable_translate,
2022-02-27 22:05:37 +08:00
'enableUploadFile': cfg.enable_upload_file,
2020-08-30 17:46:04 +08:00
'loaderUrl': cfg.loader_url
2020-02-06 19:51:03 +08:00
}
})
2022-02-27 22:05:37 +08:00
2023-09-08 20:53:04 +08:00
class UploadEmoticonHandler(api.base.ApiHandler):
2022-02-27 22:05:37 +08:00
async def post(self):
cfg = config.get_config()
if not cfg.enable_upload_file:
raise tornado.web.HTTPError(403)
try:
file = self.request.files['file'][0]
except LookupError:
raise tornado.web.MissingArgumentError('file')
if len(file.body) > 1024 * 1024:
raise tornado.web.HTTPError(413, 'file is too large, size=%d', len(file.body))
if not file.content_type.lower().startswith('image/'):
raise tornado.web.HTTPError(415)
2023-07-29 12:48:57 +08:00
url = await asyncio.get_running_loop().run_in_executor(
None, self._save_file, file.body, self.request.remote_ip
2022-02-27 22:05:37 +08:00
)
self.write({'url': url})
2022-02-27 22:05:37 +08:00
@staticmethod
def _save_file(body, client):
2022-02-27 22:05:37 +08:00
md5 = hashlib.md5(body).hexdigest()
filename = md5 + '.png'
path = os.path.join(EMOTICON_UPLOAD_PATH, filename)
logger.info('client=%s uploaded file, path=%s, size=%d', client, path, len(body))
tmp_path = path + '.tmp'
2022-02-27 22:05:37 +08:00
with open(tmp_path, 'wb') as f:
f.write(body)
os.replace(tmp_path, path)
2022-02-27 22:05:37 +08:00
return f'{EMOTICON_BASE_URL}/{filename}'
2023-09-08 20:53:04 +08:00
ROUTES = [
(r'/api/server_info', ServerInfoHandler),
(r'/api/emoticon', UploadEmoticonHandler),
]
# 通配的放在最后
LAST_ROUTES = [
(rf'{EMOTICON_BASE_URL}/(.*)', tornado.web.StaticFileHandler, {'path': EMOTICON_UPLOAD_PATH}),
(r'/(.*)', MainHandler, {'path': config.WEB_ROOT}),
]