views.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. # -*- coding: utf-8 -*-
  2. from importlib import import_module
  3. from django.http import HttpResponse
  4. from . import settings as USettings
  5. import os
  6. import json
  7. from django.views.decorators.csrf import csrf_exempt
  8. import datetime
  9. import random
  10. from django.utils import six
  11. from django.utils.six.moves.urllib.request import urlopen
  12. from django.utils.six.moves.urllib.parse import urljoin
  13. if six.PY3:
  14. long = int
  15. def get_path_format_vars():
  16. return {
  17. "year": datetime.datetime.now().strftime("%Y"),
  18. "month": datetime.datetime.now().strftime("%m"),
  19. "day": datetime.datetime.now().strftime("%d"),
  20. "date": datetime.datetime.now().strftime("%Y%m%d"),
  21. "time": datetime.datetime.now().strftime("%H%M%S"),
  22. "datetime": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
  23. "rnd": random.randrange(100, 999)
  24. }
  25. # 保存上传的文件
  26. def save_upload_file(PostFile, FilePath):
  27. try:
  28. f = open(FilePath, 'wb')
  29. for chunk in PostFile.chunks():
  30. f.write(chunk)
  31. except Exception as E:
  32. f.close()
  33. return u"写入文件错误: {}".format(E.message)
  34. f.close()
  35. return u"SUCCESS"
  36. @csrf_exempt
  37. def get_ueditor_settings(request):
  38. json_data = json.dumps(
  39. USettings.UEditorUploadSettings,
  40. ensure_ascii=False)
  41. return HttpResponse(json_data, content_type="application/javascript")
  42. @csrf_exempt
  43. def get_ueditor_controller(request):
  44. """获取ueditor的后端URL地址"""
  45. action = request.GET.get("action", "")
  46. reponseAction = {
  47. "config": get_ueditor_settings,
  48. "uploadimage": UploadFile,
  49. "uploadscrawl": UploadFile,
  50. "uploadvideo": UploadFile,
  51. "uploadfile": UploadFile,
  52. "catchimage": catcher_remote_image,
  53. "listimage": list_files,
  54. "listfile": list_files
  55. }
  56. return reponseAction[action](request)
  57. @csrf_exempt
  58. def list_files(request):
  59. """列出文件"""
  60. if request.method != "GET":
  61. return HttpResponse(
  62. json.dumps(u"{'state:'ERROR'}"),
  63. content_type="application/javascript"
  64. )
  65. # 取得动作
  66. action = request.GET.get("action", "listimage")
  67. allowFiles = {
  68. "listfile": USettings.UEditorUploadSettings.get("fileManagerAllowFiles", []),
  69. "listimage": USettings.UEditorUploadSettings.get("imageManagerAllowFiles", [])
  70. }
  71. listSize = {
  72. "listfile": USettings.UEditorUploadSettings.get("fileManagerListSize", ""),
  73. "listimage": USettings.UEditorUploadSettings.get("imageManagerListSize", "")
  74. }
  75. listpath = {
  76. "listfile": USettings.UEditorUploadSettings.get("fileManagerListPath", ""),
  77. "listimage": USettings.UEditorUploadSettings.get("imageManagerListPath", "")
  78. }
  79. # 取得参数
  80. list_size = long(request.GET.get("size", listSize[action]))
  81. list_start = long(request.GET.get("start", 0))
  82. files = []
  83. root_path = os.path.join(
  84. USettings.gSettings.MEDIA_ROOT, listpath[action]).replace("\\", "/")
  85. files = get_files(root_path, root_path, allowFiles[action])
  86. if (len(files) == 0):
  87. return_info = {
  88. "state": u"未找到匹配文件!",
  89. "list": [],
  90. "start": list_start,
  91. "total": 0
  92. }
  93. else:
  94. return_info = {
  95. "state": "SUCCESS",
  96. "list": files[list_start:list_start + list_size],
  97. "start": list_start,
  98. "total": len(files)
  99. }
  100. return HttpResponse(json.dumps(return_info), content_type="application/javascript")
  101. def get_files(root_path, cur_path, allow_types=[]):
  102. files = []
  103. items = os.listdir(cur_path)
  104. for item in items:
  105. item_fullname = os.path.join(
  106. root_path, cur_path, item).replace("\\", "/")
  107. if os.path.isdir(item_fullname):
  108. files.extend(get_files(root_path, item_fullname, allow_types))
  109. else:
  110. ext = os.path.splitext(item_fullname)[1]
  111. is_allow_list = (len(allow_types) == 0) or (ext in allow_types)
  112. if is_allow_list:
  113. files.append({
  114. "url": urljoin(
  115. USettings.gSettings.MEDIA_URL,
  116. os.path.join(
  117. os.path.relpath(cur_path, root_path), item
  118. ).replace("\\", "/")),
  119. "mtime": os.path.getmtime(item_fullname)
  120. })
  121. return files
  122. @csrf_exempt
  123. def UploadFile(request):
  124. """上传文件"""
  125. if not request.method == "POST":
  126. return HttpResponse(json.dumps({'state':'ERROR'}), content_type="application/javascript")
  127. state = "SUCCESS"
  128. action = request.GET.get("action")
  129. # 上传文件
  130. upload_field_name = {
  131. "uploadfile": "fileFieldName", "uploadimage": "imageFieldName",
  132. "uploadscrawl": "scrawlFieldName", "catchimage": "catcherFieldName",
  133. "uploadvideo": "videoFieldName",
  134. }
  135. UploadFieldName = request.GET.get(
  136. upload_field_name[action], USettings.UEditorUploadSettings.get(action, "upfile"))
  137. # 上传涂鸦,涂鸦是采用base64编码上传的,需要单独处理
  138. if action == "uploadscrawl":
  139. upload_file_name = "scrawl.png"
  140. upload_file_size = 0
  141. else:
  142. # 取得上传的文件
  143. file = request.FILES.get(UploadFieldName, None)
  144. if file is None:
  145. return HttpResponse(json.dumps({'state':'ERROR'}), content_type="application/javascript")
  146. upload_file_name = file.name
  147. upload_file_size = file.size
  148. # 取得上传的文件的原始名称
  149. upload_original_name, upload_original_ext = os.path.splitext(
  150. upload_file_name)
  151. # 文件类型检验
  152. upload_allow_type = {
  153. "uploadfile": "fileAllowFiles",
  154. "uploadimage": "imageAllowFiles",
  155. "uploadvideo": "videoAllowFiles"
  156. }
  157. if action in upload_allow_type:
  158. allow_type = list(request.GET.get(upload_allow_type[
  159. action], USettings.UEditorUploadSettings.get(upload_allow_type[action], "")))
  160. if not upload_original_ext in allow_type:
  161. state = u"服务器不允许上传%s类型的文件。" % upload_original_ext
  162. # 大小检验
  163. upload_max_size = {
  164. "uploadfile": "filwMaxSize",
  165. "uploadimage": "imageMaxSize",
  166. "uploadscrawl": "scrawlMaxSize",
  167. "uploadvideo": "videoMaxSize"
  168. }
  169. max_size = long(request.GET.get(upload_max_size[
  170. action], USettings.UEditorUploadSettings.get(upload_max_size[action], 0)))
  171. if max_size != 0:
  172. from .utils import FileSize
  173. MF = FileSize(max_size)
  174. if upload_file_size > MF.size:
  175. state = u"上传文件大小不允许超过%s。" % MF.FriendValue
  176. # 检测保存路径是否存在,如果不存在则需要创建
  177. upload_path_format = {
  178. "uploadfile": "filePathFormat",
  179. "uploadimage": "imagePathFormat",
  180. "uploadscrawl": "scrawlPathFormat",
  181. "uploadvideo": "videoPathFormat"
  182. }
  183. path_format_var = get_path_format_vars()
  184. path_format_var.update({
  185. "basename": upload_original_name,
  186. "extname": upload_original_ext[1:],
  187. "filename": upload_file_name,
  188. })
  189. # 取得输出文件的路径
  190. OutputPathFormat, OutputPath, OutputFile = get_output_path(
  191. request, upload_path_format[action], path_format_var)
  192. # 所有检测完成后写入文件
  193. if state == "SUCCESS":
  194. if action == "uploadscrawl":
  195. state = save_scrawl_file(
  196. request, os.path.join(OutputPath, OutputFile))
  197. else:
  198. # 保存到文件中,如果保存错误,需要返回ERROR
  199. upload_module_name = USettings.UEditorUploadSettings.get(
  200. "upload_module", None)
  201. if upload_module_name:
  202. mod = import_module(upload_module_name)
  203. state = mod.upload(file, OutputPathFormat)
  204. else:
  205. state = save_upload_file(
  206. file, os.path.join(OutputPath, OutputFile))
  207. # 返回数据
  208. return_info = {
  209. # 保存后的文件名称
  210. 'url': urljoin(USettings.gSettings.MEDIA_URL, OutputPathFormat),
  211. 'original': upload_file_name, # 原始文件名
  212. 'type': upload_original_ext,
  213. 'state': state, # 上传状态,成功时返回SUCCESS,其他任何值将原样返回至图片上传框中
  214. 'size': upload_file_size
  215. }
  216. return HttpResponse(json.dumps(return_info, ensure_ascii=False), content_type="application/javascript")
  217. @csrf_exempt
  218. def catcher_remote_image(request):
  219. """远程抓图,当catchRemoteImageEnable:true时,
  220. 如果前端插入图片地址与当前web不在同一个域,则由本函数从远程下载图片到本地
  221. """
  222. if not request.method == "POST":
  223. return HttpResponse(json.dumps(u"{'state:'ERROR'}"), content_type="application/javascript")
  224. state = "SUCCESS"
  225. allow_type = list(request.GET.get(
  226. "catcherAllowFiles", USettings.UEditorUploadSettings.get("catcherAllowFiles", "")))
  227. max_size = long(request.GET.get(
  228. "catcherMaxSize", USettings.UEditorUploadSettings.get("catcherMaxSize", 0)))
  229. remote_urls = request.POST.getlist("source[]", [])
  230. catcher_infos = []
  231. path_format_var = get_path_format_vars()
  232. for remote_url in remote_urls:
  233. # 取得上传的文件的原始名称
  234. remote_file_name = os.path.basename(remote_url)
  235. remote_original_name, remote_original_ext = os.path.splitext(
  236. remote_file_name)
  237. # 文件类型检验
  238. if remote_original_ext in allow_type:
  239. path_format_var.update({
  240. "basename": remote_original_name,
  241. "extname": remote_original_ext[1:],
  242. "filename": remote_original_name
  243. })
  244. # 计算保存的文件名
  245. o_path_format, o_path, o_file = get_output_path(
  246. request, "catcherPathFormat", path_format_var)
  247. o_filename = os.path.join(o_path, o_file).replace("\\", "/")
  248. # 读取远程图片文件
  249. try:
  250. remote_image = urlopen(remote_url)
  251. # 将抓取到的文件写入文件
  252. try:
  253. f = open(o_filename, 'wb')
  254. f.write(remote_image.read())
  255. f.close()
  256. state = "SUCCESS"
  257. except Exception as E:
  258. state = u"写入抓取图片文件错误:%s" % E.message
  259. except Exception as E:
  260. state = u"抓取图片错误:%s" % E.message
  261. catcher_infos.append({
  262. "state": state,
  263. "url": urljoin(USettings.gSettings.MEDIA_URL, o_path_format),
  264. "size": os.path.getsize(o_filename),
  265. "title": os.path.basename(o_file),
  266. "original": remote_file_name,
  267. "source": remote_url
  268. })
  269. return_info = {
  270. "state": "SUCCESS" if len(catcher_infos) > 0 else "ERROR",
  271. "list": catcher_infos
  272. }
  273. return HttpResponse(json.dumps(return_info, ensure_ascii=False), content_type="application/javascript")
  274. def get_output_path(request, path_format, path_format_var):
  275. # 取得输出文件的路径
  276. OutputPathFormat = (request.GET.get(path_format, USettings.UEditorSettings[
  277. "defaultPathFormat"]) % path_format_var).replace("\\", "/")
  278. # 分解OutputPathFormat
  279. OutputPath, OutputFile = os.path.split(OutputPathFormat)
  280. OutputPath = os.path.join(USettings.gSettings.MEDIA_ROOT, OutputPath)
  281. # 如果OutputFile为空说明传入的OutputPathFormat没有包含文件名,因此需要用默认的文件名
  282. if not OutputFile:
  283. OutputFile = USettings.UEditorSettings[
  284. "defaultPathFormat"] % path_format_var
  285. OutputPathFormat = os.path.join(OutputPathFormat, OutputFile)
  286. if not os.path.exists(OutputPath):
  287. os.makedirs(OutputPath)
  288. return (OutputPathFormat, OutputPath, OutputFile)
  289. # 涂鸦功能上传处理
  290. @csrf_exempt
  291. def save_scrawl_file(request, filename):
  292. import base64
  293. try:
  294. content = request.POST.get(
  295. USettings.UEditorUploadSettings.get("scrawlFieldName", "upfile"))
  296. f = open(filename, 'wb')
  297. f.write(base64.decodestring(content))
  298. f.close()
  299. state = "SUCCESS"
  300. except Exception as E:
  301. state = "写入图片文件错误: {}".format(E.message)
  302. return state