def chapter_cover(lib_id, chapter_id): file_root = None with Database() as db: rows = db.select("select dir from library where id=%s", (lib_id,)) if rows: file_root = rows[0]['dir'] else: return not_found() if request.method == 'POST': if 'file' not in request.files: return not_found() file = request.files['file'] filename = str(chapter_id)+'.'+file.filename.split(".")[-1] file.save(file_root+'/'+filename) # 封面都保存在 库目录下根目录,文件名为chapter id db.execute("update chapter set cover=%s where id=%s", (filename, chapter_id)) return { 'message': "上传封面成功" } rows = db.select( "select cover from chapter where id=%s", (chapter_id,)) if rows: if rows[0]['cover']: filename = rows[0]['cover'] return send_file(file_root+'/'+filename, mimetype=mimetypes.guess_type(filename)[0], as_attachment=True) else: return not_found() else: return not_found()
def chapter_info(lib_id, chapter_id): chapter = Chapter.getChapter(chapter_id) if chapter is None: return not_found("没有找到章节") if request.method == 'PUT': data = request.get_data() json_data = json.loads(data.decode('utf8')) current_update_id = chapter.update_id for name in ('title', 'summary', 'note', 'status', 'chapter_type', 'context', 'update_id'): if name in json_data: if json_data[name]: chapter.__dict__[name] = json_data[name] ''' 注意,这里为了防止客户端服务端时间不一,响应时间不一的情况,导致更新乱序(比如自动保存触发的update,后发先至),chapter更新时候需要附带update id,只有update id大于当前update id的情况,才会触发章节更新 ''' if chapter.update_id > current_update_id: chapter.update() return json_return({ 'utime': chapter.utime, "message": f"修改章节 {chapter.title} 成功" }) else: return json_return({ 'utime': chapter.utime, "message": "这是一个过老的更新请求,请设置最新的update id" }) if request.method == 'POST': data = request.get_data() json_data = json.loads(data.decode('utf8')) title = json_data['title'] summary = json_data['summary'] new_chapter = chapter.newChapter(title, summary) return json_return({ "chapter": { 'id': new_chapter.id }, "message": f"新增章节 {title} 成功" }) if request.method == 'DELETE': chapter.drop() return json_return({"message": f"删除章节 {chapter.title} 成功"}) # GET full = request.args.get("full", "false") == 'true' if not full: chapter.children = chapter.getChildren() chapter.parents = chapter.getParents() return json_return(chapter.__dict__) else: chapter.children = chapter.getChildren(all=True, asList=False) chapter.parents = chapter.getParents() return json_return(chapter.__dict__)
def web_file_video_info(file_id): with Database() as db: rows = db.select( "select id,path,name,parent,order_id,library_id from item where id=%s", (file_id,), dict_result=True) if rows: file = rows[0] ptype = file['name'].split('.')[-1] result = { 'id': file_id, 'name': file['name'], 'parent': file['parent'], 'order_id': file['order_id'], 'library_id': file['library_id'], 'file_type': file_ex2type(file['name']) } ffprobe_command = f'{ffprobe_path} "{file["path"]}" -show_streams -hide_banner -v quiet' ffprobe_out = os.popen(ffprobe_command).read() if ffprobe_out: result['video_info'] = ffprobe_out return result return not_found()
def photo(file_id): ''' 对于需要缩略图的情况,这里先查找缓存,如果缓存未命中,生成缩略图后返回 缩略图为240*320 如果纵横比变化,取最大值 ''' cached_photo = request.args.get('cache', 'true') == 'true' if file_id == 0: return not_found() def cached_file(file_id): # 不考虑压缩文件的话,这里调用get file photo_file = get_pic_from_comress(file_id) file_name = photo_file['name'] ptype = file_name.split('.')[-1] file_path = photo_file['path'] img_open=photo_file['file'] if photo_file['file'] is not None else file_path if file_ex2type(file_name) == 'video': return get_cover_for_video(file_name, file_path) cn = hashlib.md5(file_path.encode()).hexdigest() cache = PHOTO_CATCH+f"/{cn}.{ptype}" if not os.path.exists(cache): with Image.open(img_open) as img: width, height = img.size widpct = width*1.0/240 heightpct = height*1.0/320 dest_pct = max([widpct, heightpct]) resized_im = img.resize( (int(width/dest_pct), int(height/dest_pct))) resized_im.save(cache) if cached_photo: return file_name, cache else: ''' 对于非缓存类型,也进行压缩,减小其大小 压缩为高度1024的图片 ''' re_cache = PHOTO_CATCH+f"/{cn}.1024.{ptype}" if not os.path.exists(re_cache): with Image.open(img_open) as img: width, height = img.size dest_pct = height*1.0/1024 resized_im = img.resize( (int(width/dest_pct), int(height/dest_pct))) resized_im.save(re_cache) return file_name, re_cache file_name, file_path = cached_file(file_id) ''' 这里是直接获取原始文件的api影片播放页数从这个路径走 ''' if request.args.get('cache', 'true') == 'origin': photo_file = get_pic_from_comress(file_id) file_name = photo_file['name'] file_path = photo_file['path'] img_open=photo_file['file'] if photo_file['file'] is not None else file_path mtype=mimetypes.guess_type(file_name)[0] if not file_name.endswith('flv') else 'video/x-flv' ''' 这里需要处理不支持的格式,目前暂时考虑使用ffmpeg转码输出 ''' return send_file(img_open,attachment_filename=file_name, mimetype=mtype, as_attachment=True, conditional=True) return send_file(file_path, mimetype=mimetypes.guess_type(file_name)[0], as_attachment=True, conditional=True)