views.py 12 KB

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