#!/usr/bin/env python # -*- coding: utf_8 -*- import os import sys import copy import time import types import json import logging import traceback import re import tempfile import shutil import base64 import uuid from hashlib import md5 as fmd5 from urllib import parse from datetime import datetime from threading import Thread from werkzeug.security import check_password_hash from flask import request from app.setting import config from utils import md5_salt, random_string logger = logging.getLogger("UploadManager") FileStoragePath = os.getcwd() # 判断目录是否存在,不存在则创建 # if not os.path.exists(os.path.join(FileStoragePath, config.get("UPLOAD_DIR"))): # os.makedirs(os.path.join(FileStoragePath, config.get("UPLOAD_DIR"))) def ajaxCheckAccess(path): realpath = os.path.realpath(path) if not realpath.startswith(FileStoragePath): return False return True def checkPath(path): if not path: return False, {"code": -1, "data": None, "message": "[%s] arg missed!" % path} fpath = os.path.abspath(os.sep.join( [os.path.abspath(FileStoragePath), path])) if not ajaxCheckAccess(fpath): return False, {"code": -1, "data": None, "message": "You have no access to [%s]!" % fpath} if not os.path.exists(fpath): return False, {"code": -1, "data": None, "message": "[%s] is not existed!" % fpath} return True, os.path.abspath(fpath) def saveToFile(saveFile, content): try: tfn = tempfile.mktemp() tf = open(tfn, 'w+b') tf.write(content) tf.close() os.rename(tfn, saveFile) return True except Exception as e: traceback.print_exc() logger.error(str(e)) return False def getFileInfo(infofile): info = dict() info.update({ "isfile": os.path.isfile(infofile), "isdir": os.path.isdir(infofile), "size": os.path.getsize(infofile), "atime": os.path.getatime(infofile), "mtime": os.path.getmtime(infofile), "ctime": os.path.getctime(infofile), "name": os.path.basename(infofile) }) return info class UploadManager(object): def __init__(self): super(UploadManager, self).__init__() def download(self, data): obj = json.loads(data) isAccessed, path = checkPath(obj["path"]) if not isAccessed: return {"code": -1, "data": None, "message": "invaild access"} if not os.path.isfile(path): return {"code": -1, "data": None, "message": "Path [%s] is not a valid file!" % path} try: with open(path, "rb") as f: content = base64.b64encode(f.read()) md5code = fmd5(content).hexdigest() return { "data": { "content": content, "md5": md5code, "filename": os.path.basename(path) }, "code": 0, "message": "download file [%s] successfully!" % obj['path'] } except Exception as e: traceback.print_exc() logger.error(str(e)) return { "data": None, "code": -1, "message": "upload file [%s] failed!\n %s" % (obj['path'], repr(e)) } def upload(self): try: binfile = request.files.get("binfile") if not binfile: return None, "file can not be null" obj = dict() obj['filename'] = binfile.filename obj['content'] = binfile.stream.read() # 目录结构:模块类型/年/月/项目名/文件名_时间日期.文件后缀 # 模块类型:项目管理模块、资质管理模块、 # filename = random_string() + os.path.splitext(obj['filename'])[-1] current = datetime.now() # 文件重命名后缀 # 拼接文件名 filename = os.path.splitext(obj['filename'])[0] + "_{}".format(current.strftime("%Y%m%d%H%M%S")) + os.path.splitext(obj['filename'])[-1] # 获取相对路径 relative_path = os.path.join(config.get("UPLOAD_DIR")) # 获取最终存储的绝对路径 savePath = os.path.normpath(os.sep.join([config.get("UPLOAD_PATH"), relative_path])) # 获取最终存储的文件路径 saveFile = os.path.normpath(os.sep.join([savePath, filename])) if not os.path.exists(savePath): os.makedirs(savePath) with open(saveFile, 'wb') as f: # 保存文件 f.write(obj['content']) return { "uuid": str(uuid.uuid4()), # 附件唯一编号 "filename": obj['filename'], # 附件名称 "filesize": os.path.getsize(saveFile), # 附件大小 "filepath": os.sep.join([relative_path, filename]).replace("\\", "/"), # 附件存储路径 }, "upload file [%s] successfully!" % obj['filename'] except Exception as e: # repr(e) traceback.print_exc() logger.error(str(e)) return None, repr(e) def delete(self, data): try: isAccessed, path = checkPath(data["path"]) if not isAccessed: return {"code": -1, "data": None, "message": "invaild access"} if os.path.isfile(path): os.remove(path) return {"code": 0, "data": None, "message": "delete file [%s] successfully!" % path} elif os.path.isdir(path): os.rmdir(path) return {"code": 0, "data": None, "message": "delete dir [%s] successfully!" % path} else: return {"code": 0, "data": None, "message": "Path [%s] is not a valid file or path!" % path} except Exception as e: traceback.print_exc() logger.error(str(e)) return {"code": -1, "data": None, "message": repr(e)} def dirlist(self, data): obj = json.loads(data) isAccessed, path = checkPath(obj["path"]) if not isAccessed: return {"code": -1, "data": None, "message": "invaild access"} result = [] for p in os.listdir(path): result.append(getFileInfo(os.path.join(FileStoragePath, p))) return {"code": 0, "result": result, "message": "Get [%s] successfully!" % path} def filemd5(self, data): obj = json.loads(data) isAccessed, path = checkPath(obj["path"]) if not isAccessed: return {"code": -1, "data": None, "message": "invaild access"} if not os.path.isfile(path): return {"code": -1, "data": None, "message": "Path [%s] is not a valid file!" % path} with open(path, "rb") as f: filemd5 = fmd5(f.read()).hexdigest() return {"code": 0, "result": filemd5, "message": "Get md5 of [%s] successfully!" % path} def fileinfo(self, data): obj = json.loads(data) isAccessed, path = checkPath(obj["path"]) if not isAccessed: return {"code": -1, "data": None, "message": "invaild access"} if not os.path.isfile(path): return {"code": -1, "data": None, "message": "Path [%s] is not a valid file!" % path} return {"code": 0, "result": getFileInfo(path), "message": "Get md5 of [%s] successfully!" % path} uploadManager = UploadManager()