You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

349 lines
12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- 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