# -*- coding: utf-8 -*- from importlib import import_module from django.http import HttpResponse from . import settings as USettings import os import json from django.views.decorators.csrf import csrf_exempt import datetime import random import six from six.moves.urllib.request import urlopen from six.moves.urllib.parse import urljoin if six.PY3: long = int def get_path_format_vars(): return { "year": datetime.datetime.now().strftime("%Y"), "month": datetime.datetime.now().strftime("%m"), "day": datetime.datetime.now().strftime("%d"), "date": datetime.datetime.now().strftime("%Y%m%d"), "time": datetime.datetime.now().strftime("%H%M%S"), "datetime": datetime.datetime.now().strftime("%Y%m%d%H%M%S"), "rnd": random.randrange(100, 999) } # 保存上传的文件 def save_upload_file(PostFile, FilePath): try: f = open(FilePath, 'wb') for chunk in PostFile.chunks(): f.write(chunk) except Exception as E: f.close() return u"写入文件错误: {}".format(E.message) f.close() return u"SUCCESS" @csrf_exempt def get_ueditor_settings(request): json_data = json.dumps( USettings.UEditorUploadSettings, ensure_ascii=False) return HttpResponse(json_data, content_type="application/javascript") @csrf_exempt def get_ueditor_controller(request): """获取ueditor的后端URL地址""" action = request.GET.get("action", "") reponseAction = { "config": get_ueditor_settings, "uploadimage": UploadFile, "uploadscrawl": UploadFile, "uploadvideo": UploadFile, "uploadfile": UploadFile, "catchimage": catcher_remote_image, "listimage": list_files, "listfile": list_files } return reponseAction[action](request) @csrf_exempt def list_files(request): """列出文件""" if request.method != "GET": return HttpResponse( json.dumps(u"{'state:'ERROR'}"), content_type="application/javascript" ) # 取得动作 action = request.GET.get("action", "listimage") allowFiles = { "listfile": USettings.UEditorUploadSettings.get("fileManagerAllowFiles", []), "listimage": USettings.UEditorUploadSettings.get("imageManagerAllowFiles", []) } listSize = { "listfile": USettings.UEditorUploadSettings.get("fileManagerListSize", ""), "listimage": USettings.UEditorUploadSettings.get("imageManagerListSize", "") } listpath = { "listfile": USettings.UEditorUploadSettings.get("fileManagerListPath", ""), "listimage": USettings.UEditorUploadSettings.get("imageManagerListPath", "") } # 取得参数 list_size = long(request.GET.get("size", listSize[action])) list_start = long(request.GET.get("start", 0)) files = [] root_path = os.path.join( USettings.gSettings.MEDIA_ROOT, listpath[action]).replace("\\", "/") files = get_files(root_path, root_path, allowFiles[action]) if (len(files) == 0): return_info = { "state": u"未找到匹配文件!", "list": [], "start": list_start, "total": 0 } else: return_info = { "state": "SUCCESS", "list": files[list_start:list_start + list_size], "start": list_start, "total": len(files) } return HttpResponse(json.dumps(return_info), content_type="application/javascript") def get_files(root_path, cur_path, allow_types=[]): files = [] items = os.listdir(cur_path) for item in items: item_fullname = os.path.join( root_path, cur_path, item).replace("\\", "/") if os.path.isdir(item_fullname): files.extend(get_files(root_path, item_fullname, allow_types)) else: ext = os.path.splitext(item_fullname)[1] is_allow_list = (len(allow_types) == 0) or (ext in allow_types) if is_allow_list: files.append({ "url": urljoin( USettings.gSettings.MEDIA_URL, os.path.join( os.path.relpath(cur_path, root_path), item ).replace("\\", "/")), "mtime": os.path.getmtime(item_fullname) }) return files @csrf_exempt def UploadFile(request): """上传文件""" if not request.method == "POST": return HttpResponse(json.dumps({'state':'ERROR'}), content_type="application/javascript") state = "SUCCESS" action = request.GET.get("action") # 上传文件 upload_field_name = { "uploadfile": "fileFieldName", "uploadimage": "imageFieldName", "uploadscrawl": "scrawlFieldName", "catchimage": "catcherFieldName", "uploadvideo": "videoFieldName", } UploadFieldName = request.GET.get( upload_field_name[action], USettings.UEditorUploadSettings.get(action, "upfile")) # 上传涂鸦,涂鸦是采用base64编码上传的,需要单独处理 if action == "uploadscrawl": upload_file_name = "scrawl.png" upload_file_size = 0 else: # 取得上传的文件 file = request.FILES.get(UploadFieldName, None) if file is None: return HttpResponse(json.dumps({'state':'ERROR'}), content_type="application/javascript") upload_file_name = file.name upload_file_size = file.size # 取得上传的文件的原始名称 upload_original_name, upload_original_ext = os.path.splitext( upload_file_name) # 文件类型检验 upload_allow_type = { "uploadfile": "fileAllowFiles", "uploadimage": "imageAllowFiles", "uploadvideo": "videoAllowFiles" } if action in upload_allow_type: allow_type = list(request.GET.get(upload_allow_type[ action], USettings.UEditorUploadSettings.get(upload_allow_type[action], ""))) if not upload_original_ext in allow_type: state = u"服务器不允许上传%s类型的文件。" % upload_original_ext # 大小检验 upload_max_size = { "uploadfile": "filwMaxSize", "uploadimage": "imageMaxSize", "uploadscrawl": "scrawlMaxSize", "uploadvideo": "videoMaxSize" } max_size = long(request.GET.get(upload_max_size[ action], USettings.UEditorUploadSettings.get(upload_max_size[action], 0))) if max_size != 0: from .utils import FileSize MF = FileSize(max_size) if upload_file_size > MF.size: state = u"上传文件大小不允许超过%s。" % MF.FriendValue # 检测保存路径是否存在,如果不存在则需要创建 upload_path_format = { "uploadfile": "filePathFormat", "uploadimage": "imagePathFormat", "uploadscrawl": "scrawlPathFormat", "uploadvideo": "videoPathFormat" } path_format_var = get_path_format_vars() path_format_var.update({ "basename": upload_original_name, "extname": upload_original_ext[1:], "filename": upload_file_name, }) # 取得输出文件的路径 OutputPathFormat, OutputPath, OutputFile = get_output_path( request, upload_path_format[action], path_format_var) # 所有检测完成后写入文件 if state == "SUCCESS": if action == "uploadscrawl": state = save_scrawl_file( request, os.path.join(OutputPath, OutputFile)) else: # 保存到文件中,如果保存错误,需要返回ERROR upload_module_name = USettings.UEditorUploadSettings.get( "upload_module", None) if upload_module_name: mod = import_module(upload_module_name) state = mod.upload(file, OutputPathFormat) else: state = save_upload_file( file, os.path.join(OutputPath, OutputFile)) # 返回数据 return_info = { # 保存后的文件名称 'url': urljoin(USettings.gSettings.MEDIA_URL, OutputPathFormat), 'original': upload_file_name, # 原始文件名 'type': upload_original_ext, 'state': state, # 上传状态,成功时返回SUCCESS,其他任何值将原样返回至图片上传框中 'size': upload_file_size } return HttpResponse(json.dumps(return_info, ensure_ascii=False), content_type="application/javascript") @csrf_exempt def catcher_remote_image(request): """远程抓图,当catchRemoteImageEnable:true时, 如果前端插入图片地址与当前web不在同一个域,则由本函数从远程下载图片到本地 """ if not request.method == "POST": return HttpResponse(json.dumps(u"{'state:'ERROR'}"), content_type="application/javascript") state = "SUCCESS" allow_type = list(request.GET.get( "catcherAllowFiles", USettings.UEditorUploadSettings.get("catcherAllowFiles", ""))) max_size = long(request.GET.get( "catcherMaxSize", USettings.UEditorUploadSettings.get("catcherMaxSize", 0))) remote_urls = request.POST.getlist("source[]", []) catcher_infos = [] path_format_var = get_path_format_vars() for remote_url in remote_urls: # 取得上传的文件的原始名称 remote_file_name = os.path.basename(remote_url) remote_original_name, remote_original_ext = os.path.splitext( remote_file_name) # 文件类型检验 if remote_original_ext in allow_type: path_format_var.update({ "basename": remote_original_name, "extname": remote_original_ext[1:], "filename": remote_original_name }) # 计算保存的文件名 o_path_format, o_path, o_file = get_output_path( request, "catcherPathFormat", path_format_var) o_filename = os.path.join(o_path, o_file).replace("\\", "/") # 读取远程图片文件 try: remote_image = urlopen(remote_url) # 将抓取到的文件写入文件 try: f = open(o_filename, 'wb') f.write(remote_image.read()) f.close() state = "SUCCESS" except Exception as E: state = u"写入抓取图片文件错误:%s" % E.message except Exception as E: state = u"抓取图片错误:%s" % E.message catcher_infos.append({ "state": state, "url": urljoin(USettings.gSettings.MEDIA_URL, o_path_format), "size": os.path.getsize(o_filename), "title": os.path.basename(o_file), "original": remote_file_name, "source": remote_url }) return_info = { "state": "SUCCESS" if len(catcher_infos) > 0 else "ERROR", "list": catcher_infos } return HttpResponse(json.dumps(return_info, ensure_ascii=False), content_type="application/javascript") def get_output_path(request, path_format, path_format_var): # 取得输出文件的路径 OutputPathFormat = (request.GET.get(path_format, USettings.UEditorSettings[ "defaultPathFormat"]) % path_format_var).replace("\\", "/") # 分解OutputPathFormat OutputPath, OutputFile = os.path.split(OutputPathFormat) OutputPath = os.path.join(USettings.gSettings.MEDIA_ROOT, OutputPath) # 如果OutputFile为空说明传入的OutputPathFormat没有包含文件名,因此需要用默认的文件名 if not OutputFile: OutputFile = USettings.UEditorSettings[ "defaultPathFormat"] % path_format_var OutputPathFormat = os.path.join(OutputPathFormat, OutputFile) if not os.path.exists(OutputPath): os.makedirs(OutputPath) return (OutputPathFormat, OutputPath, OutputFile) # 涂鸦功能上传处理 @csrf_exempt def save_scrawl_file(request, filename): import base64 try: content = request.POST.get( USettings.UEditorUploadSettings.get("scrawlFieldName", "upfile")) f = open(filename, 'wb') f.write(base64.decodestring(content)) f.close() state = "SUCCESS" except Exception as E: state = "写入图片文件错误: {}".format(E.message) return state