添加七牛cdn上传功能

This commit is contained in:
deepzz0
2016-12-18 18:00:11 +08:00
parent 7305192ca9
commit 5064894ab5
14 changed files with 223 additions and 184 deletions
+33 -6
View File
@@ -48,6 +48,8 @@ func init() {
APIs["trash-recover"] = apiTrashRecover APIs["trash-recover"] = apiTrashRecover
// 上传文件 // 上传文件
APIs["file-upload"] = apiFileUpload APIs["file-upload"] = apiFileUpload
// 删除文件
APIs["file-delete"] = apiFileDelete
} }
func apiAccount(c *gin.Context) { func apiAccount(c *gin.Context) {
@@ -407,23 +409,48 @@ func apiFileUpload(c *gin.Context) {
type Size interface { type Size interface {
Size() int64 Size() int64
} }
file, header, err := c.Request.FormFile("upload") file, header, err := c.Request.FormFile("file")
if err != nil { if err != nil {
responseNotice(c, NOTICE_NOTICE, "上传失败", "") logd.Error(err)
c.String(http.StatusBadRequest, err.Error())
return return
} }
s, ok := file.(Size) s, ok := file.(Size)
if !ok { if !ok {
responseNotice(c, NOTICE_NOTICE, "文件太大", "") logd.Error("assert failed")
c.String(http.StatusBadRequest, "false")
return return
} }
filename := strings.ToLower(header.Filename) filename := strings.ToLower(header.Filename)
url, err := Upload(filename, s.Size(), file) url, err := FileUpload(filename, s.Size(), file)
if err != nil { if err != nil {
responseNotice(c, NOTICE_NOTICE, "上传失败", "") logd.Error(err)
c.String(http.StatusBadRequest, err.Error())
return return
} }
responseNotice(c, NOTICE_SUCCESS, url, "") typ := c.Request.Header.Get("Content-Type")
c.JSON(http.StatusOK, gin.H{
"name": filename,
"isImage": typ[:5] == "image",
"url": url,
"bytes": fmt.Sprintf("%dkb", s.Size()/1000),
})
}
func apiFileDelete(c *gin.Context) {
var err error
defer func() {
if err != nil {
logd.Error(err)
}
c.String(http.StatusOK, "删掉了吗?鬼知道。。。")
}()
name := c.PostForm("name")
if name == "" {
err = errors.New("参数错误")
return
}
err = FileDelete(name)
} }
func responseNotice(c *gin.Context, typ, content, hl string) { func responseNotice(c *gin.Context, typ, content, hl string) {
+47 -19
View File
@@ -7,11 +7,16 @@ import (
"path/filepath" "path/filepath"
"github.com/eiblog/eiblog/setting" "github.com/eiblog/eiblog/setting"
"qiniupkg.com/api.v7/conf"
"qiniupkg.com/api.v7/kodo" "qiniupkg.com/api.v7/kodo"
"qiniupkg.com/api.v7/kodocli" "qiniupkg.com/api.v7/kodocli"
) )
var qiniu_cfg = &kodo.Config{
AccessKey: setting.Conf.Kodo.AccessKey,
SecretKey: setting.Conf.Kodo.SecretKey,
Scheme: "https",
}
type bucket struct { type bucket struct {
name string name string
domain string domain string
@@ -33,15 +38,13 @@ func onProgress(fsize, uploaded int64) {
} }
} }
func Upload(name string, size int64, data io.Reader) (string, error) { func FileUpload(name string, size int64, data io.Reader) (string, error) {
if setting.Conf.Kodo.AccessKey == "" || setting.Conf.Kodo.SecretKey == "" { if setting.Conf.Kodo.AccessKey == "" || setting.Conf.Kodo.SecretKey == "" {
return "", errors.New("qiniu config error") return "", errors.New("qiniu config error")
} }
conf.ACCESS_KEY = setting.Conf.Kodo.AccessKey
conf.SECRET_KEY = setting.Conf.Kodo.SecretKey
// 创建一个client // 创建一个client
c := kodo.New(0, nil) c := kodo.New(0, qiniu_cfg)
// 设置上传的策略 // 设置上传的策略
policy := &kodo.PutPolicy{ policy := &kodo.PutPolicy{
@@ -56,20 +59,8 @@ func Upload(name string, size int64, data io.Reader) (string, error) {
zone := 0 zone := 0
uploader := kodocli.NewUploader(zone, nil) uploader := kodocli.NewUploader(zone, nil)
ext := filepath.Ext(name) key := getKey(name)
var key string if key == "" {
switch ext {
case ".bmp", ".png", ".jpg", ".gif", ".ico":
key = "blog/img/" + name
case ".mov", ".mp4":
key = "blog/video/" + name
case ".go", ".js", ".css", ".cpp", ".php", ".rb", ".java", ".py", ".sql", ".lua", ".html", ".sh", ".xml", ".cs":
key = "blog/code/" + name
case ".txt", ".md", ".ini", ".yaml", ".yml", ".doc", ".ppt", ".pdf":
key = "blog/document/" + name
case ".zip", ".rar", ".tar", ".gz":
key = "blog/archive/" + name
default:
return "", errors.New("不支持的文件类型") return "", errors.New("不支持的文件类型")
} }
@@ -83,3 +74,40 @@ func Upload(name string, size int64, data io.Reader) (string, error) {
url := kodo.MakeBaseUrl(setting.Conf.Kodo.Domain, ret.Key) url := kodo.MakeBaseUrl(setting.Conf.Kodo.Domain, ret.Key)
return url, nil return url, nil
} }
func FileDelete(name string) error {
// new一个Bucket管理对象
c := kodo.New(0, qiniu_cfg)
p := c.Bucket(setting.Conf.Kodo.Name)
key := getKey(name)
if key == "" {
return errors.New("不支持的文件类型")
}
// 调用Delete方法删除文件
err := p.Delete(nil, key)
// 打印返回值以及出错信息
if err != nil {
return err
}
return nil
}
func getKey(name string) string {
ext := filepath.Ext(name)
var key string
switch ext {
case ".bmp", ".png", ".jpg", ".gif", ".ico":
key = "blog/img/" + name
case ".mov", ".mp4":
key = "blog/video/" + name
case ".go", ".js", ".css", ".cpp", ".php", ".rb", ".java", ".py", ".sql", ".lua", ".html", ".sh", ".xml", ".cs":
key = "blog/code/" + name
case ".txt", ".md", ".ini", ".yaml", ".yml", ".doc", ".ppt", ".pdf":
key = "blog/document/" + name
case ".zip", ".rar", ".tar", ".gz":
key = "blog/archive/" + name
}
return key
}
+1 -1
View File
@@ -13,7 +13,7 @@ func TestUpload(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
info, _ := file.Stat() info, _ := file.Stat()
url, err := Upload(info.Name(), info.Size(), file) url, err := FileUpload(info.Name(), info.Size(), file)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -8,7 +8,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.Title}}</title> <title>{{.Title}}</title>
<meta name="robots" content="noindex, nofollow"> <meta name="robots" content="noindex, nofollow">
<link rel="stylesheet" href="/static/admin/background.css">
<link rel="stylesheet" href="/static/admin/style.css"> <link rel="stylesheet" href="/static/admin/style.css">
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
+2 -2
View File
@@ -6,7 +6,7 @@
<meta content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name=viewport> <meta content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name=viewport>
<meta name=robots content="noindex, nofollow"> <meta name=robots content="noindex, nofollow">
<title>登录 | {{.BTitle}}</title> <title>登录 | {{.BTitle}}</title>
<link rel=stylesheet href="/static/admin/background.css"> <link rel=stylesheet href="/static/admin/style.css">
</head> </head>
<body class="body-100"> <body class="body-100">
@@ -16,7 +16,7 @@
<form action="/admin/login" method=post> <form action="/admin/login" method=post>
<p> <p>
<label for=user class="sr-only">用户名</label> <label for=user class="sr-only">用户名</label>
<input type=text id=user name=user value="" placeholder="用户名" class="text-l w-100"> <input type=text id=user name=user placeholder="用户名" class="text-l w-100">
</p> </p>
<p> <p>
<label for=password class="sr-only">密码</label> <label for=password class="sr-only">密码</label>
+133 -150
View File
@@ -41,9 +41,13 @@
<section class="typecho-post-option category-option"> <section class="typecho-post-option category-option">
<label class="typecho-label">专题</label> <label class="typecho-label">专题</label>
<ul> <ul>
<li>
<input type="radio" id="serie-0" value="0" name="serie" checked="true"/>
<label for="serie-0">默认专题</label>
</li>
{{range $k,$v:=.Series}} {{range $k,$v:=.Series}}
<li> <li>
<input type="checkbox" id="serie-{{$v.ID}}" value="{{$v.ID}}" name="serie" {{with $.Edit}}{{if eq .SerieID $v.ID}}checked="true"{{end}}{{end}}/> <input type="radio" id="serie-{{$v.ID}}" value="{{$v.ID}}" name="serie" {{with $.Edit}}{{if eq .SerieID $v.ID}}checked="true"{{end}}{{end}}/>
<label for="serie-{{$v.ID}}">{{$v.Name}}</label> <label for="serie-{{$v.ID}}">{{$v.Name}}</label>
</li> </li>
{{end}} {{end}}
@@ -143,9 +147,6 @@ $(document).ready(function() {
// 聚焦 // 聚焦
$('#title').select(); $('#title').select();
// text 自动拉伸
// Typecho.editorResize('text', 'http://localhost/index.php/action/ajax?do=editorResize&_=53e23a1bd0daab03b05d9c23190904a4');
// tag autocomplete 提示 // tag autocomplete 提示
var tags = $('#tags'), var tags = $('#tags'),
tagsPre = []; tagsPre = [];
@@ -329,12 +330,6 @@ $(document).ready(function() {
return false; return false;
}); });
// 高级选项控制
$('#advance-panel-btn').click(function() {
$('#advance-panel').toggle();
return false;
});
// 自动隐藏密码框 // 自动隐藏密码框
$('#visibility').change(function() { $('#visibility').change(function() {
var val = $(this).val(), var val = $(this).val(),
@@ -346,10 +341,20 @@ $(document).ready(function() {
password.addClass('hidden'); password.addClass('hidden');
} }
}); });
// 草稿删除确认
$('.edit-draft-notice a').click(function () {
if (confirm('您确认要删除这份草稿吗?')) {
window.location.href = $(this).attr('href');
}
return false;
});
}); });
</script> </script>
<script src="/static/admin/hyperdown.js"></script>
<script src="/static/admin/pagedown.js"></script> <script src="/static/admin/pagedown.js"></script>
<script src="/static/admin/stmd.js"></script> <script src="/static/admin/pagedown-extra.js"></script>
<script src="/static/admin/diff.js"></script> <script src="/static/admin/diff.js"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
@@ -406,36 +411,26 @@ $(document).ready(function() {
help: 'Markdown语法帮助' help: 'Markdown语法帮助'
}; };
var converter = new Typecho.Markdown, var converter = new HyperDown(),
editor = new Markdown.Editor(converter, '', options), editor = new Markdown.Editor(converter, '', options),
diffMatch = new diff_match_patch(), diffMatch = new diff_match_patch(), last = '', preview = $('#wmd-preview'),
last = '',
preview = $('#wmd-preview'),
mark = '@mark' + Math.ceil(Math.random() * 100000000) + '@', mark = '@mark' + Math.ceil(Math.random() * 100000000) + '@',
span = '<span class="diff" />', span = '<span class="diff" />',
cache = {}; cache = {};
// 自动跟随 // 自动跟随
converter.hooks.chain('postConversion', function(html) { converter.hook('makeHtml', function (html) {
// clear special html tags // convert all comment
html = html.replace(/<\/?(\!doctype|html|head|body|link|title|input|select|button|textarea|style|noscript)[^>]*>/ig, function(all) { html = html.replace(/&lt;!--(.+?)--&gt;/g, '<!--$1-->');
return all.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/'/g, '&#039;')
.replace(/"/g, '&quot;');
});
// clear hard breaks
html = html.replace(/\s*((?:<br>\n)+)\s*(<\/?(?:p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|li|dd|dt)[^\w])/gm, '$2');
if (html.indexOf('<!--more-->') > 0) { if (html.indexOf('<!--more-->') > 0) {
var parts = html.split(/\s*<\!\-\-more\-\->\s*/), var parts = html.split(/\s*<\!\-\-more\-\->\s*/),
summary = parts.shift(), summary = parts.shift(),
details = parts.join(''); details = parts.join('');
html = '<div class="summary">' + summary + '</div>' + '<div class="details">' + details + '</div>'; html = '<div class="summary">' + summary + '</div>'
+ '<div class="details">' + details + '</div>';
} }
@@ -443,22 +438,18 @@ $(document).ready(function() {
last = html; last = html;
if (diffs.length > 0) { if (diffs.length > 0) {
var stack = [], var stack = [], markStr = mark;
markStr = mark;
for (var i = 0; i < diffs.length; i ++) {
for (var i = 0; i < diffs.length; i++) { var diff = diffs[i], op = diff[0], str = diff[1]
var diff = diffs[i], sp = str.lastIndexOf('<'), ep = str.lastIndexOf('>');
op = diff[0],
str = diff[1]
sp = str.lastIndexOf('<'), ep = str.lastIndexOf('>');
if (op != 0) { if (op != 0) {
if (sp >= 0 && sp > ep) { if (sp >=0 && sp > ep) {
if (op > 0) { if (op > 0) {
stack.push(str.substring(0, sp) + markStr + str.substring(sp)); stack.push(str.substring(0, sp) + markStr + str.substring(sp));
} else { } else {
var lastStr = stack[stack.length - 1], var lastStr = stack[stack.length - 1], lastSp = lastStr.lastIndexOf('<');
lastSp = lastStr.lastIndexOf('<');
stack[stack.length - 1] = lastStr.substring(0, lastSp) + markStr + lastStr.substring(lastSp); stack[stack.length - 1] = lastStr.substring(0, lastSp) + markStr + lastStr.substring(lastSp);
} }
} else { } else {
@@ -468,7 +459,7 @@ $(document).ready(function() {
stack.push(markStr); stack.push(markStr);
} }
} }
markStr = ''; markStr = '';
} else { } else {
stack.push(str); stack.push(str);
@@ -478,11 +469,9 @@ $(document).ready(function() {
html = stack.join(''); html = stack.join('');
if (!markStr) { if (!markStr) {
var pos = html.indexOf(mark), var pos = html.indexOf(mark), prev = html.substring(0, pos),
prev = html.substring(0, pos),
next = html.substr(pos + mark.length), next = html.substr(pos + mark.length),
sp = prev.lastIndexOf('<'), sp = prev.lastIndexOf('<'), ep = prev.lastIndexOf('>');
ep = prev.lastIndexOf('>');
if (sp >= 0 && sp > ep) { if (sp >= 0 && sp > ep) {
html = prev.substring(0, sp) + span + prev.substring(sp) + next; html = prev.substring(0, sp) + span + prev.substring(sp) + next;
@@ -491,55 +480,54 @@ $(document).ready(function() {
} }
} }
} }
// 替换img // 替换img
html = html.replace(/<(img)\s+([^>]*)\s*src="([^"]+)"([^>]*)>/ig, function(all, tag, prefix, src, suffix) { html = html.replace(/<(img)\s+([^>]*)\s*src="([^"]+)"([^>]*)>/ig, function (all, tag, prefix, src, suffix) {
if (!cache[src]) { if (!cache[src]) {
cache[src] = false; cache[src] = false;
} else { } else {
return '<span class="cache" data-width="' + cache[src][0] + '" data-height="' + cache[src][1] + '" ' + 'style="background:url(' + src + ') no-repeat left top; width:' + cache[src][0] + 'px; height:' + cache[src][1] + 'px; display: inline-block; max-width: 100%;' + '-webkit-background-size: contain;-moz-background-size: contain;-o-background-size: contain;background-size: contain;" />'; return '<span class="cache" data-width="' + cache[src][0] + '" data-height="' + cache[src][1] + '" '
+ 'style="background:url(' + src + ') no-repeat left top; width:'
+ cache[src][0] + 'px; height:' + cache[src][1] + 'px; display: inline-block; max-width: 100%;'
+ '-webkit-background-size: contain;-moz-background-size: contain;-o-background-size: contain;background-size: contain;" />';
} }
return all; return all;
}); });
// 替换block // 替换block
html = html.replace(/<(iframe|embed)\s+([^>]*)>/ig, function(all, tag, src) { html = html.replace(/<(iframe|embed)\s+([^>]*)>/ig, function (all, tag, src) {
if (src[src.length - 1] == '/') { if (src[src.length - 1] == '/') {
src = src.substring(0, src.length - 1); src = src.substring(0, src.length - 1);
} }
return '<div style="background: #ddd; height: 40px; overflow: hidden; line-height: 40px; text-align: center; font-size: 12px; color: #777">' + tag + ' : ' + $.trim(src) + '</div>'; return '<div style="background: #ddd; height: 40px; overflow: hidden; line-height: 40px; text-align: center; font-size: 12px; color: #777">'
+ tag + ' : ' + $.trim(src) + '</div>';
}); });
return html; return html;
}); });
function cacheResize() { function cacheResize() {
var t = $(this), var t = $(this), w = parseInt(t.data('width')), h = parseInt(t.data('height')),
w = parseInt(t.data('width')),
h = parseInt(t.data('height')),
ow = t.width(); ow = t.width();
t.height(h * ow / w); t.height(h * ow / w);
} }
var to; var to;
editor.hooks.chain('onPreviewRefresh', function() { editor.hooks.chain('onPreviewRefresh', function () {
var diff = $('.diff', preview), var diff = $('.diff', preview), scrolled = false;
scrolled = false;
if (to) { if (to) {
clearTimeout(to); clearTimeout(to);
} }
$('img', preview).load(function() { $('img', preview).load(function () {
var t = $(this), var t = $(this), src = t.attr('src');
src = t.attr('src');
if (scrolled) { if (scrolled) {
preview.scrollTo(diff, { preview.scrollTo(diff, {
offset: -50 offset : - 50
}); });
} }
@@ -549,64 +537,62 @@ $(document).ready(function() {
}); });
$('.cache', preview).resize(cacheResize).each(cacheResize); $('.cache', preview).resize(cacheResize).each(cacheResize);
var changed = $('.diff', preview).parent(); var changed = $('.diff', preview).parent();
if (!changed.is(preview)) { if (!changed.is(preview)) {
changed.css('background-color', 'rgba(255,230,0,0.5)'); changed.css('background-color', 'rgba(255,230,0,0.5)');
to = setTimeout(function() { to = setTimeout(function () {
changed.css('background-color', 'transparent'); changed.css('background-color', 'transparent');
}, 4500); }, 4500);
} }
if (diff.length > 0) { if (diff.length > 0) {
var p = diff.position(), var p = diff.position(), lh = diff.parent().css('line-height');
lh = diff.parent().css('line-height');
lh = !!lh ? parseInt(lh) : 0; lh = !!lh ? parseInt(lh) : 0;
if (p.top < 0 || p.top > preview.height() - lh) { if (p.top < 0 || p.top > preview.height() - lh) {
preview.scrollTo(diff, { preview.scrollTo(diff, {
offset: -50 offset : - 50
}); });
scrolled = true; scrolled = true;
} }
} }
}); });
var input = $('#text'), th = textarea.height(), ph = preview.height(),
uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">'
+ '<i class="i-upload">附件</i></button>')
.prependTo('.submit .right')
.click(function() {
$('a', $('.typecho-option-tabs li').not('.active')).trigger('click');
return false;
});
var input = $('#text'), $('.typecho-option-tabs li').click(function () {
th = textarea.height(),
ph = preview.height(),
uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">' + '<i class="i-upload">附件</i></button>')
.prependTo('.submit .right')
.click(function() {
$('a', $('.typecho-option-tabs li').not('.active')).trigger('click');
return false;
});
$('.typecho-option-tabs li').click(function() {
uploadBtn.find('i').toggleClass('i-upload-active', uploadBtn.find('i').toggleClass('i-upload-active',
$('#tab-files-btn', this).length > 0); $('#tab-files-btn', this).length > 0);
}); });
editor.hooks.chain('enterFakeFullScreen', function() { editor.hooks.chain('enterFakeFullScreen', function () {
th = textarea.height(); th = textarea.height();
ph = preview.height(); ph = preview.height();
$(document.body).addClass('fullscreen'); $(document.body).addClass('fullscreen');
var h = $(window).height() - toolbar.outerHeight(); var h = $(window).height() - toolbar.outerHeight();
textarea.css('height', h); textarea.css('height', h);
preview.css('height', h); preview.css('height', h);
}); });
editor.hooks.chain('enterFullScreen', function() { editor.hooks.chain('enterFullScreen', function () {
$(document.body).addClass('fullscreen'); $(document.body).addClass('fullscreen');
var h = window.screen.height - toolbar.outerHeight(); var h = window.screen.height - toolbar.outerHeight();
textarea.css('height', h); textarea.css('height', h);
preview.css('height', h); preview.css('height', h);
}); });
editor.hooks.chain('exitFullScreen', function() { editor.hooks.chain('exitFullScreen', function () {
$(document.body).removeClass('fullscreen'); $(document.body).removeClass('fullscreen');
textarea.height(th); textarea.height(th);
preview.height(ph); preview.height(ph);
@@ -618,13 +604,13 @@ $(document).ready(function() {
var imageButton = $('#wmd-image-button'), var imageButton = $('#wmd-image-button'),
linkButton = $('#wmd-link-button'); linkButton = $('#wmd-link-button');
Typecho.insertFileToEditor = function(file, url, isImage) { Typecho.insertFileToEditor = function (file, url, isImage) {
var button = isImage ? imageButton : linkButton; var button = isImage ? imageButton : linkButton;
options.strings[isImage ? 'imagename' : 'linkname'] = file; options.strings[isImage ? 'imagename' : 'linkname'] = file;
button.trigger('click'); button.trigger('click');
var checkDialog = setInterval(function() { var checkDialog = setInterval(function () {
if ($('.wmd-prompt-dialog').length > 0) { if ($('.wmd-prompt-dialog').length > 0) {
$('.wmd-prompt-dialog input').val(url).select(); $('.wmd-prompt-dialog input').val(url).select();
clearInterval(checkDialog); clearInterval(checkDialog);
@@ -633,7 +619,7 @@ $(document).ready(function() {
}, 10); }, 10);
}; };
Typecho.uploadComplete = function(file) { Typecho.uploadComplete = function (file) {
Typecho.insertFileToEditor(file.title, file.url, file.isImage); Typecho.insertFileToEditor(file.title, file.url, file.isImage);
}; };
@@ -645,7 +631,7 @@ $(document).ready(function() {
$(".wmd-edittab a").removeClass('active'); $(".wmd-edittab a").removeClass('active');
$(this).addClass("active"); $(this).addClass("active");
$("#wmd-editarea, #wmd-preview").addClass("wmd-hidetab"); $("#wmd-editarea, #wmd-preview").addClass("wmd-hidetab");
var selected_tab = $(this).attr("href"), var selected_tab = $(this).attr("href"),
selected_el = $(selected_tab).removeClass("wmd-hidetab"); selected_el = $(selected_tab).removeClass("wmd-hidetab");
@@ -669,7 +655,7 @@ $(document).ready(function() {
<script src="/static/admin/plupload.js"></script> <script src="/static/admin/plupload.js"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
function updateAttacmentNumber() { function updateAttacmentNumber () {
var btn = $('#tab-files-btn'), var btn = $('#tab-files-btn'),
balloon = $('.balloon', btn), balloon = $('.balloon', btn),
count = $('#file-list li .insert').length; count = $('#file-list li .insert').length;
@@ -687,38 +673,37 @@ $(document).ready(function() {
} }
$('.upload-area').bind({ $('.upload-area').bind({
dragenter: function() { dragenter : function () {
$(this).parent().addClass('drag'); $(this).parent().addClass('drag');
}, },
dragover: function(e) { dragover : function (e) {
$(this).parent().addClass('drag'); $(this).parent().addClass('drag');
}, },
drop: function() { drop : function () {
$(this).parent().removeClass('drag');
},
dragend : function () {
$(this).parent().removeClass('drag'); $(this).parent().removeClass('drag');
}, },
dragend: function() { dragleave : function () {
$(this).parent().removeClass('drag');
},
dragleave: function() {
$(this).parent().removeClass('drag'); $(this).parent().removeClass('drag');
} }
}); });
updateAttacmentNumber(); updateAttacmentNumber();
function fileUploadStart(file) { function fileUploadStart (file) {
$('<li id="' + file.id + '" class="loading">' + file.name + '</li>').appendTo('#file-list'); $('<li id="' + file.id + '" class="loading">'
+ file.name + '</li>').appendTo('#file-list');
} }
function fileUploadError(error) { function fileUploadError (error) {
var file = error.file, var file = error.file, code = error.code, word;
code = error.code,
word;
switch (code) { switch (code) {
case plupload.FILE_SIZE_ERROR: case plupload.FILE_SIZE_ERROR:
word = '文件大小超过限制'; word = '文件大小超过限制';
@@ -744,22 +729,26 @@ $(document).ready(function() {
li = $('<li>' + fileError + '<br />' + word + '</li>').appendTo('#file-list'); li = $('<li>' + fileError + '<br />' + word + '</li>').appendTo('#file-list');
} }
li.effect('highlight', { li.effect('highlight', {color : '#FBC2C4'}, 2000, function () {
color: '#FBC2C4'
}, 2000, function() {
$(this).remove(); $(this).remove();
}); });
// fix issue #341
this.removeFile(file);
} }
var completeFile = null; var completeFile = null;
function fileUploadComplete (id, data) {
function fileUploadComplete(id, url, data) { var li = $('#' + id).removeClass('loading').data('name', data.name)
var li = $('#' + id).removeClass('loading').data('cid', data.cid)
.data('url', data.url) .data('url', data.url)
.data('image', data.isImage) .data('image', data.isImage)
.html('<input type="hidden" name="attachment[]" value="' + data.cid + '" />' + '<a class="insert" target="_blank" href="###" title="点击插入文件">' + data.title + '</a><div class="info">' + data.bytes + ' <a class="file" target="_blank" href="http://localhost/admin/media.php?cid=' + data.cid + '" title="编辑"><i class="i-edit"></i></a>' + ' <a class="delete" href="###" title="删除"><i class="i-delete"></i></a></div>') .html('<input type="hidden" name="attachment[]" value="' + data.cid + '" />'
+ '<a class="insert" target="_blank" href="###" title="点击插入文件">' + data.name + '</a><div class="info">' + data.bytes
+ ' <a class="file" target="_blank" href="'
+ data.url + '" title="查看"><i class="i-edit"></i></a>'
+ ' <a class="delete" href="###" title="删除"><i class="i-delete"></i></a></div>')
.effect('highlight', 1000); .effect('highlight', 1000);
attachInsertEvent(li); attachInsertEvent(li);
attachDeleteEvent(li); attachDeleteEvent(li);
updateAttacmentNumber(); updateAttacmentNumber();
@@ -769,56 +758,53 @@ $(document).ready(function() {
} }
} }
$('#tab-files').bind('init', function() { $('#tab-files').bind('init', function () {
var uploader = new plupload.Uploader({ var uploader = new plupload.Uploader({
browse_button: $('.upload-file').get(0), browse_button : $('.upload-file').get(0),
url: '/admin/api/file-upload', url : '/admin/api/file-upload',
runtimes: 'html5,flash,html4', runtimes : 'html5,flash,html4',
flash_swf_url: '/static/admin/js/Moxie.swf', flash_swf_url : '/static/admin/js/Moxie.swf',
drop_element: $('.upload-area').get(0), drop_element : $('.upload-area').get(0),
filters: { filters : {
max_file_size: '2mb', max_file_size : '2mb',
mime_types: [{ <!-- mime_types : [{'title' : '允许上传的文件', 'extensions' : 'gif,jpg,jpeg,png,tiff,bmp'}], -->
'title': '允许上传的文件', prevent_duplicates : true
'extensions': 'gif,jpg,jpeg,png,tiff,bmp'
}],
prevent_duplicates: true
}, },
init: { init : {
FilesAdded: function(up, files) { FilesAdded : function (up, files) {
plupload.each(files, function(file) { for (var i = 0; i < files.length; i ++) {
fileUploadStart(file); fileUploadStart(files[i]);
}); }
completeFile = null; completeFile = null;
uploader.start(); uploader.start();
}, },
UploadComplete: function() { UploadComplete : function () {
if (completeFile) { if (completeFile) {
Typecho.uploadComplete(completeFile); Typecho.uploadComplete(completeFile);
} }
}, },
FileUploaded: function(up, file, result) { FileUploaded : function (up, file, result) {
if (200 == result.status) { if (200 == result.status) {
var data = $.parseJSON(result.response); var data = $.parseJSON(result.response);
if (data) { if (data) {
fileUploadComplete(file.id, data[0], data[1]); fileUploadComplete(file.id, data);
uploader.removeFile(file);
return; return;
} }
} }
fileUploadError({ fileUploadError.call(uploader, {
code: plupload.HTTP_ERROR, code : plupload.HTTP_ERROR,
file: file file : file
}); });
}, },
Error: function(up, error) { Error : function (up, error) {
fileUploadError(error); fileUploadError.call(uploader, error);
} }
} }
}); });
@@ -826,26 +812,23 @@ $(document).ready(function() {
uploader.init(); uploader.init();
}); });
function attachInsertEvent(el) { function attachInsertEvent (el) {
$('.insert', el).click(function() { $('.insert', el).click(function () {
var t = $(this), var t = $(this), p = t.parents('li');
p = t.parents('li');
Typecho.insertFileToEditor(t.text(), p.data('url'), p.data('image')); Typecho.insertFileToEditor(t.text(), p.data('url'), p.data('image'));
return false; return false;
}); });
} }
function attachDeleteEvent(el) { function attachDeleteEvent (el) {
var file = $('a.insert', el).text(); var file = $('a.insert', el).text();
$('.delete', el).click(function() { $('.delete', el).click(function () {
if (confirm('确认要删除文件 %s 吗?'.replace('%s', file))) { if (confirm('确认要删除文件 %s 吗?'.replace('%s', file))) {
var cid = $(this).parents('li').data('cid'); var name = $(this).parents('li').data('name');
$.post('http://localhost/index.php/action/contents-attachment-edit?_=53e23a1bd0daab03b05d9c23190904a4', { $.post('/admin/api/file-delete',
'do': 'delete', {'name' : name},
'cid': cid function () {
}, $(el).fadeOut(function () {
function() {
$(el).fadeOut(function() {
$(this).remove(); $(this).remove();
updateAttacmentNumber(); updateAttacmentNumber();
}); });
@@ -856,7 +839,7 @@ $(document).ready(function() {
}); });
} }
$('#file-list li').each(function() { $('#file-list li').each(function () {
attachInsertEvent(this); attachInsertEvent(this);
attachDeleteEvent(this); attachDeleteEvent(this);
}); });