1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/usr/bin/env python
# -*- coding: utf_8 -*-
import os
import re
import sys
import traceback
import tempfile
import shutil
import base64
import logging
from flask import Blueprint, request, redirect, url_for, json
from app.setting import config
if ((3, 0) <= sys.version_info <= (3, 10)):
from hashlib import md5 as fmd5
elif ((2, 0) <= sys.version_info <= (2, 10)):
import md5
fmd5 = md5.new
logger = logging.getLogger("filesApi")
file_api = Blueprint("file_api", __name__, url_prefix="/api/v1/file")
FileStoragePath = os.path.join(config.get("UPLOAD_PATH"), config.get("NETDISC"))
def ajaxCheckAcess(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": {}, "message": "[%s] arg missed!" % path}
fpath = os.path.abspath(os.sep.join([os.path.abspath(FileStoragePath), path]))
if not ajaxCheckAcess(fpath):
return False, {"code": -1, "data": {}, "message": "You have no access to [%s]!" % fpath}
if not os.path.exists(fpath):
return False, {"code": -1, "data": {}, "message": "[%s] is not existed!" % fpath}
return True, os.path.abspath(fpath)
def saveToFile(saveFile, content):
try:
tfn = tempfile.mktemp()
tf = open(tfn, 'wb+')
tf.write(content)
tf.close()
os.rename(tfn, saveFile)
return True
except Exception as e:
traceback.format_exc()
logger.error(str(e))
return False
def getFileInfo(infofile):
return {
"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)
}
# 参数 {"path":"/xxx/xxx.png"}
# path 需要下载的文件名
@file_api.route("/download", methods=["POST"])
def download():
try:
obj = json.loads(request.data)
isAcessed, path = checkPath(obj["path"])
if not isAcessed:
return { "code": -1, "data": {}, "message": "invaild access" }
if not os.path.isfile(path):
return {"code": -1, "data": {}, "message": "Path [%s] is not a valid file!" % path}
with open(path, "rb") as f:
content = base64.b64encode(f.read())
md5code = fmd5(content).hexdigest()
return {
"code": 0,
"data": {
"content": content,
"md5": md5code,
"filename": os.path.basename(path)
},
"message": "download file [%s] successfully!" % obj['path']
}
except Exception as e:
return {"code": -1, "data": {}, "message": "upload file [%s] failed!\n %s" % (obj['path'], repr(e))}
# 参数 {"filename":"xxx.jpg","path":"/upload/","content":"xxxxxxx","md5":"xxxxxxxxxxxxxx"}
# filename 保存的文件名,不带路径
# path 保存的路径
# content 文件的内容,采用base64编码
# md5 文件的MD5校验值
@file_api.route("/upload", methods=["POST"])
def upload():
try:
obj = json.loads(request.data)
if not obj['filename'] or not obj['content']:
return {"code": -1, "data": {}, "message": "filename、path、content and md5 is not completed"}
saveFile = os.path.normpath(os.sep.join([FileStoragePath, obj['filename']]))
if not ajaxCheckAcess(saveFile):
return {"code": -1, "data": {}, "message": "You have no access to [%s]!" % saveFile}
if os.path.exists(saveFile):
return {"code": -1, "data": {}, "message": "File [%s] is existed! Please remove firstly" % saveFile}
fr = base64.b64decode(obj['content'])
md5code = fmd5(obj['content']).hexdigest()
if obj['md5'] != md5code:
return {"code": -1, "data": {}, "message": "File md5 [%s] != [%s]" % (obj['md5'], md5code)}
if saveToFile(saveFile, fr):
return {"code": 0, "data": {}, "message": "upload file [%s] successfully!" % obj['filename']}
else:
return {"code": -1, "data": {}, "message": "upload file [%s] failed!" % obj['filename']}
except Exception as e:
logger.error(str(e))
binfile = request.files.get("binfile")
obj = {}
obj['filename'] = binfile.filename
obj['content'] = binfile.stream.read()
saveFile = os.path.normpath(os.sep.join([FileStoragePath, obj['filename']]))
with open(saveFile, 'wb') as f:
f.write(obj['content'])
return {"code": 0, "data": {}, "message": "upload file by ElementUI[%s] successfully!" % obj['filename']}
# 参数 {"path":"/xxx/xxx.png"}
# path 需要删除的文件名或者目录名
@file_api.route("/remove", methods=["POST"])
def delete():
obj = json.loads(request.data)
isAcessed, path = checkPath(obj["path"])
if not isAcessed:
return { "code": -1, "data": {}, "message": "invaild access" }
try:
if os.path.isfile(path):
os.remove(path)
return {"code": 0, "data": {}, "message": "delete file [%s] successfully!" % path}
elif os.path.isdir(path):
os.rmdir(path)
return {"code": 0, "data": {}, "message": "delete dir [%s] successfully!" % path}
else:
return {"code": 0, "data": {}, "message": "Path [%s] is not a valid file or path!" % path}
except Exception as e:
return {"code": -1, "data": {}, "message": repr(e)}
# 参数 {"path":"/"}
# path 路径
@file_api.route("getDirectoryList", methods=["POST"])
def dirlist():
obj = json.loads(request.data)
isAcessed, path = checkPath(obj["path"])
if not isAcessed:
return { "code": -1, "data": {}, "message": "invaild access" }
result = []
for p in os.listdir(path):
result.append(getFileInfo(os.path.join(FileStoragePath, p)))
return {"code": 0, "data": result, "message": "Get [%s] successfully!" % path}
# 参数 {"path":"/xe/xxx.png"}
# file 需求获取MD5的文件
@file_api.route("/getFileMD5", methods=["POST"])
def filemd5():
obj = json.loads(request.data)
isAcessed, path = checkPath(obj["path"])
if not isAcessed:
return { "code": -1, "data": {}, "message": "invaild access" }
if not os.path.isfile(path):
return {"code": -1, "data": {}, "message": "Path [%s] is not a valid file!" % path}
with open(path, "rb") as f:
filemd5 = fmd5(f.read()).hexdigest()
return {"code": 0, "data": filemd5, "message": "Get md5 of [%s] successfully!" % path}
# 参数 {"path":"/xe/xxx.png"}
# file 需要获取信息的文件或目录
@file_api.route("/getFileInfo", methods=["POST"])
def fileinfo():
obj = json.loads(request.data)
isAcessed, path = checkPath(obj["path"])
if not isAcessed:
return { "code": -1, "data": {}, "message": "invaild access" }
if not os.path.isfile(path):
return {"code": -1, "data": {}, "message": "Path [%s] is not a valid file!" % path}
return {"code": 0, "result": getFileInfo(path), "message": "Get md5 of [%s] successfully!" % path}