百度Ueditor与Tornado后端接口集成

概述:

由于Ueditor官方的后端只有PHP, ASP, ASP.NET, JSP四种,没有相应的python实现。我结合python的tornado框架实现了ueditor中的图片,文件及涂鸭上传的功能。

一. 下载Ueditor

从Ueditor官网下载最新版本: http://ueditor.baidu.com/build/build_down.php?n=ueditor&v=1_4_3_3-utf8-php
(这里我用的是php的版本)

二. 集成到tornado中

2.1 解压放置ueditor到项目中
将ueditor1_4_3_3-utf8-php.zip解压到项目目录 /static 下, 项目目录结构如下:
百度Ueditor与Tornado后端接口集成

2.2 index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>Ueditor</title>
        <script type="text/javascript" src="/static/ueditor/ueditor.config.js"></script>
        <script type="text/javascript" src="/static/ueditor/ueditor.all.js"></script>
        <script type="text/javascript" src="/static/ueditor/ueditor.parse.js"></script>
        <link rel=stylesheet href='/static/ueditor/third-party/SyntaxHighlighter/shCoreDefault.css' />
        <script type=text/javascript src='/static/ueditor/third-party/SyntaxHighlighter/shCore.js'></script>        
        <script type=text/javascript>SyntaxHighlighter.all()</script>
    </head>
<body>
<script id="container" name="content" type="text/plain"></script>
<script type="text/javascript">
    var config = {
        initialFrameWidth: null,
        initialFrameHeight: 600,
    }
    var ue = UE.getEditor('container', config);

</script>
</body></html>

2.3 修改Ueditor的配置文件ueditor.config.js

window.UEDITOR_HOME_URL = "/static/ueditor/"     // 添加ueditor在项目中的相对路径
, serverUrl: "/upload"                                                   // 修改服务器统一请求接口路径

2.4 添加后端部署文件config.json

    "imageActionName": "uploadimage",
    "imageFieldName": "upfile",
    "imageMaxSize": 2048000,
    "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],
    "imageCompressEnable": true,
    "imageCompressBorder": 1600,
    "imageInsertAlign": "none",
    "imageUrlPrefix": "http://127.0.0.1:5000/",
    "imagePathFormat": "static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", 

    "scrawlActionName": "uploadscrawl",
    "scrawlFieldName": "upfile",
    "scrawlPathFormat": "static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
    "scrawlMaxSize": 2048000,
    "scrawlUrlPrefix": "http://127.0.0.1:5000/",
    "scrawlInsertAlign": "none",

    "snapscreenActionName": "uploadimage",
    "snapscreenPathFormat": "static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
    "snapscreenUrlPrefix": "http://127.0.0.1:5000/",
    "snapscreenInsertAlign": "none",

    "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
    "catcherActionName": "catchimage",
    "catcherFieldName": "source",
    "catcherPathFormat": "static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
    "catcherUrlPrefix": "http://127.0.0.1:5000/",
    "catcherMaxSize": 2048000,
    "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],

    "videoActionName": "uploadvideo",
    "videoFieldName": "upfile",
    "videoPathFormat": "static/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}",
    "videoUrlPrefix": "http://127.0.0.1:5000/",
    "videoMaxSize": 102400000,
    "videoAllowFiles": [
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"],

    "fileActionName": "uploadfile",
    "fileFieldName": "upfile",
    "filePathFormat": "static/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}",
    "fileUrlPrefix": "http://127.0.0.1:5000/",
    "fileMaxSize": 51200000,
    "fileAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ],

    "imageManagerActionName": "listimage",
    "imageManagerListPath": "static/upload/image/",
    "imageManagerListSize": 20,
    "imageManagerUrlPrefix": "http://127.0.0.1:5000/",
    "imageManagerInsertAlign": "none",
    "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],

    "fileManagerActionName": "listfile",
    "fileManagerListPath": "static/upload/file/",
    "fileManagerUrlPrefix": "http://127.0.0.1:5000/",
    "fileManagerListSize": 20,
    "fileManagerAllowFiles": [
        ".png", ".jpg", ".jpeg", ".gif", ".bmp",
        ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
        ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
        ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
        ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
    ]
}

此文件由php目录中的config.json改写而成,但是需要注意: *PathFormat的static前不能有'/', 在windows进行路径连接时会出现问题。

2.5 tornado实现
myapp.py代码:

import os
import stat
from datetime import datetime
import random
import json
import base64

import tornado.httpserver
import tornado.ioloop
from tornado.web import Application, RequestHandler, authenticated
from tornado.options import define, options

define("port", default=5000, help="port", type=int)

basedir = os.path.dirname(os.path.abspath(__file__))

class Upload(object):
    ''' upload image or file    '''
    def __init__(self):
        self.config = {}

        self.oriName = ''      # 原始文件名
        self.fileName = ''     # 新文件名
        self.fullName = ''     # 完整文件名,即从当前配置目录开始的URL
        self.filePath = ''     # 完整文件名,即从当前配置目录开始的URL
        self.fileSize = 0      # 文件大小
        self.fileType = ''     # 文件类型
        self.stateMap = {
            "SUCCESS": "SUCCESS",             # 上传成功标记,在UEditor中内不可改变,否则flash判断会出错
            "ERROR_FILE_MAXSIZE": "文件大小超出 upload_max_filesize 限制",
            "ERROR_FILE_LIMITSIZE": "文件大小超出 MAX_FILE_SIZE 限制",
            "ERROR_FILE_UPLOAD_FAILED": "文件未被完整上传",
            "ERROR_FILE_NOT_UPLOAD": "没有文件被上传",
            "ERROR_FILE_NULL": "上传文件为空",
            "ERROR_SIZE_EXCEED": "文件大小超出网站限制",
            "ERROR_TYPE_NOT_ALLOWED": "文件类型不允许",
            "ERROR_CREATE_DIR": "目录创建失败",
            "ERROR_DIR_NOT_WRITEABLE": "目录没有写权限",
            "ERROR_FILE_SAVE": "文件保存时出错",
            "ERROR_FILE_NOT_FOUND": "找不到上传文件",
            "ERROR_WRITE_CONTENT": "写入文件内容错误"
        }

    def getItem(self, key):
        fp = open("static/ueditor/config.json", 'r')
        config = json.loads(fp.read())
        fp.close()
        for k, v in config.items():
            if k == key:
                return v

    def getStateInfo(self, stateinfo):
        for k, v in self.stateMap.items():
            if k == stateinfo:
                return v

    def checkSize(self):
        if self.fileSize > self.config['maxSize']:
            return False
        else:
            return True

    def checkType(self):
        if self.fileType in self.config['allowFiles']:
            return True
        else:
            return False

    def getFullName(self):
        now = datetime.now()
        randint = random.randint(100000, 999999)
        format = self.config['pathFormat']
        format = format.replace("{yyyy}", now.strftime("%Y"))
        format = format.replace("{mm}", now.strftime("%m"))
        format = format.replace("{dd}", now.strftime("%d"))
        format = format.replace("{time}", now.strftime("%H%M%S"))
        format = format.replace("{rand:6}", str(randint))

        ext = self.oriName[self.oriName.rfind("."):]
        self.fileName = "%s%s%s" % (now.strftime("%H%M%S"), randint, ext)
        return format + ext

    def getFilePath(self):
        fullpath = os.path.join(basedir, self.fullName)
        return fullpath

    def uploadFile(self, upfile):
        result = {'state': '', 'url': '', 'title': '', 'original': ''}

        if not upfile or len(upfile) == 0:
            result['state'] = self.getStateInfo('ERROR_FILE_NOT_UPLOAD')
            return result

        self.oriName = upfile[0]['filename']
        self.fileType = self.oriName[self.oriName.rfind('.'):]
        data = upfile[0]['body']
        self.fileSize = len(data)

        if self.fileSize == 0:
            result['state'] = self.getStateInfo('ERROR_FILE_NULL')
            return result

        if not self.checkSize():
            result['state'] = self.getStateInfo('ERROR_SIZE_EXCEED')
            return result

        if not self.checkType():
            result['state'] = self.getStateInfo('ERROR_TYPE_NOT_ALLOWED')
            return result

        self.fullName = self.getFullName()
        self.filePath = self.getFilePath()

        dirname = os.path.dirname(self.filePath)
        if not os.path.exists(dirname):
            try:
                os.makedirs(dirname)
            except Exception as e:
                result['state'] = self.getStateInfo('ERROR_CREATE_DIR')
                return result

        if not os.access(dirname, os.R_OK | os.W_OK):
            try:
                os.chmod(dirname, stat.S_IREAD | stat.S_IWRITE)
            except Exception as e:
                result['state'] = self.getStateInfo('ERROR_DIR_NOT_WRITEABLE')
                return result

        try:
            fp = open(self.filePath, 'wb')
            fp.write(data)
            fp.close()
        except Exception as e:
            result['state'] = self.getStateInfo('ERROR_FILE_SAVE')
            return result

        result['state'] = self.stateMap['SUCCESS']
        result['url'] = self.fullName
        result['title'] = self.fileName
        result['original'] = self.oriName
        return result

    def getFileList(self, start, size):
        result = {'state': '', 'list': [], 'start': 0, 'total': 0}
        path = self.config['path']
        listSize = self.config['listSize']

        listfiles = []
        for root, dirs, files in os.walk(path):
            for file in files:
                self.fileType = file[file.rfind('.'):]
                if self.checkType():
                    url = root + '/' + file
                    listfiles.append({'url': '%s' % url})

        if size > listSize:
            num = listSize
        else:
            num = size

        listfiles.sort()
        lists = listfiles[start:(start + num)]

        result['state'] = self.stateMap['SUCCESS']
        result['list'] = lists
        result['start'] = start
        result['total'] = len(listfiles)
        return result

class UploadHandler(RequestHandler):
    def get(self):
        action = self.get_argument('action')
        upload = Upload()
        result = {}
        if action == "config":
            fp = open("static/ueditor/config.json", 'r')
            config = json.loads(fp.read())
            fp.close()
            result = config

        if action == "listimage":
            start = self.get_argument('start')
            size = self.get_argument('size')

            upload.config['path'] = upload.getItem('imageManagerListPath')
            upload.config['listSize'] = upload.getItem('imageManagerListSize')
            upload.config['allowFiles'] = upload.getItem('imageManagerAllowFiles')

            result = upload.getFileList(int(start), int(size))

        if action == "listfile":
            start = self.get_argument('start')
            size = self.get_argument('size')

            upload.config['path'] = upload.getItem('fileManagerListPath')
            upload.config['listSize'] = upload.getItem('fileManagerListSize')
            upload.config['allowFiles'] = upload.getItem('fileManagerAllowFiles')

            result = upload.getFileList(int(start), int(size))

        self.write(result)

    def post(self):
        action = self.get_argument('action')
        upload = Upload()
        result = {}

        if action == "uploadimage":
            fieldName = upload.getItem('imageFieldName')
            upload.config['pathFormat'] = upload.getItem('imagePathFormat')
            upload.config['maxSize'] = upload.getItem('imageMaxSize')
            upload.config['allowFiles'] = upload.getItem('imageAllowFiles')

            upfile = self.request.files[fieldName]
            result = upload.uploadFile(upfile)

        if action == "uploadfile":
            fieldName = upload.getItem('fileFieldName')
            upload.config['pathFormat'] = upload.getItem('filePathFormat')
            upload.config['maxSize'] = upload.getItem('fileMaxSize')
            upload.config['allowFiles'] = upload.getItem('fileAllowFiles')

            upfile = self.request.files[fieldName]
            result = upload.uploadFile(upfile)

        if action == "uploadvideo":
            fieldName = upload.getItem('videoFieldName')
            upload.config['pathFormat'] = upload.getItem('videoPathFormat')
            upload.config['maxSize'] = upload.getItem('videoMaxSize')
            upload.config['allowFiles'] = upload.getItem('videoAllowFiles')

            upfile = self.request.files[fieldName]
            result = upload.uploadFile(upfile)

        if action == "uploadscrawl":
            upload.config['pathFormat'] = upload.getItem('scrawlPathFormat')
            upload.config['maxSize'] = upload.getItem('scrawlMaxSize')
            upload.config['allowFiles'] = ['.png']

            data = self.request.body_arguments
            upfile = []
            upfile.append({'filename': 'scrawl.png', 'body': base64.b64decode(data['upfile'][0])})
            result = upload.uploadFile(upfile)

        self.write(result)

def main():
    settings = {
        "autoreload": True,
        "debug": True,
        "static_path": os.path.join(basedir, "static"),
        "template_path": os.path.join(basedir, "templates")
    }
    app = Application(
        [
            (r"/", IndexHandler),
            (r"/upload", UploadHandler)
        ],
        **settings
    )

    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.current().start()

if __name__ == '__main__':
    main()

转载于:https://blog.51cto.com/lang8027/2045136

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值