// ==UserScript==
// @name Duoshuo Admin
// @name:zh-CN 多说评论管理
// @namespace http://gerald.top
// @homepage http://gerald.top/code/DuoshuoAdmin
// @author Gerald <[email protected]>
// @icon http://cn.gravatar.com/avatar/a0ad718d86d21262ccd6ff271ece08a3?s=80
// @description 更加强大的多说评论管理脚本,可以自动分析所有有评论的页面,方便地修改thread_key,避免评论丢失。
// @version 0.2.1
// @match http://*.duoshuo.com/admin/*
// @grant none
// ==/UserScript==
var threads;
try {
threads=JSON.parse(localStorage.threadData);
} catch(e) {
threads=[];
}
function save(){
localStorage.threadData=JSON.stringify(threads);
}
$('<style>')
.html('\
.dsa-popup{background:white;position:fixed;top:70px;right:70px;padding:10px;border-radius:5px;box-shadow:1px 2px 5px gray;}\
.dsa-dialog{background:white;position:absolute;top:50px;right:500px;width:400px;z-index:10;box-shadow:4px 4px 5px gray;border:1px solid gray;padding:10px;border-radius:10px;}\
.dsa-dialog h4{color:purple;}\
.dsa-panel{background:white;position:fixed;top:50px;right:0;bottom:0;width:500px;box-shadow:-2px 0 5px gray;}\
.dsa-panel .area{position:absolute;top:30px;left:10px;right:10px;bottom:10px;overflow:auto;}\
.dsa-panel table{width:100%;border-spacing:5px;border-collapse:separate;}\
.dsa-panel td>*{padding:5px;}\
.dsa-panel .key{cursor:pointer;}\
.dsa-panel .key:hover{background:purple;color:white;}\
').appendTo(document.head);
var menu=$('<ul class="dropdown-menu">')
.appendTo(
$('<li class="dropdown">')
.prependTo('.navbar-nav')
.html('<a href class="dropdown-toggle" data-toggle="dropdown">评论管理<b class="caret"></b>')
);
$('<a href="http://gerald.top/code/DuoshuoAdmin" target=_blank>使用须知</a>')
.appendTo($('<li>').appendTo(menu));
function getThreadByKey(key,cb){
$.get('/api/threads/listPosts.json',{
thread_key:key,
limit:1
},function(r){
cb(r.thread);
});
}
function updateKey(id,key,cb){
$.post('/api/threads/update.json',{
thread_id:id,
thread_key:key,
},function(r){
cb(r.response);
});
}
function editKey(e){
var cur=$(e.target);
var i=cur.data('num');
var thread=threads[i];
if(!thread) return;
current=cur;
editPanel.current.threadKey.val(thread.thread_key);
editPanel.current.find('.title').html($('<a target=_blank>').attr('href',thread.url).text(thread.title));
editPanel.current.find('.msg').html('');
editPanel.other.hide();
editPanel.show();
}
function saveKey(e){
var i=current.data('num');
var thread=threads[i];
if(!thread) return;
updateKey(thread.thread_id,editPanel.current.threadKey.val(),function(r){
if(r){
threads[i]=r;
current.text(r.thread_key);
closeEdit();
} else {
getThreadByKey(editPanel.current.threadKey.val(),function(r){
var other=editPanel.other;
other.data('id',r.thread_id);
other.threadKey.val(r.thread_key);
other.find('.title').html($('<a target=_blank>').attr('href',r.url).text(r.title));
editPanel.current.find('.msg').html('您要使用的thread_key被以下thread占用,请先修改之。');
other.show();
});
}
});
}
function saveOtherKey(e){
var other=editPanel.other;
updateKey(other.data('id'),other.threadKey.val(),function(r){
if(r){
editPanel.current.find('.msg').html('占用thread已修改,可以继续修改当前thread。');
other.hide();
} else {
other.find('.msg').html('thread_key修改失败,请换一个thread_key试试。');
}
});
}
function closeEdit(e){
if(e) e.preventDefault();
current=null;
editPanel.fadeOut();
}
var current=null;
var editPanel=$('<div class="dsa-dialog">').appendTo(document.body).hide()
.html('\
<h3>修改Thread</h3>\
<div class=current>\
<h4>thread_key</h4>\
<div><input type=text class=thread-key style="width:100%"></div>\
<h4>title</h4>\
<p class=title></p>\
<button class="btn btn-primary save">修改</button>\
<span class=msg></span>\
</div><div class=other><hr>\
<h3>占用此thread_key的Thread</h3>\
<h4>thread_key</h4>\
<div><input type=text class=thread-key style="width:100%"></div>\
<h4>title</h4>\
<p class=title></p>\
<button class="btn btn-primary save">修改</button>\
<span class="msg"></span>\
</div>\
');
editPanel.current=editPanel.find('.current');
editPanel.current.threadKey=editPanel.current.find('.thread-key');
editPanel.current.find('.save').click(saveKey);
editPanel.other=editPanel.find('.other');
editPanel.other.threadKey=editPanel.other.find('.thread-key');
editPanel.other.find('.save').click(saveOtherKey);
$('<a href>关闭</a>').prependTo(editPanel).css('float','right').click(closeEdit);
var panel=$('<div class="dsa-panel">').appendTo(document.body).hide();
$('<a href>关闭</a>').appendTo(panel).css({
position:'absolute',
top:10,
right:20,
}).click(function(e){
e.preventDefault();
panel.hide();
});
panel.area=$('<div class="area">').appendTo(panel);
$('<a href>显示文章列表</a>')
.appendTo($('<li>').appendTo(menu))
.click(function(e){
e.preventDefault();
panel.area.html('');
var table=$('<table>').appendTo(panel.area);
$('<tr><th>thread_key</th><th>title</th></tr>').appendTo(table);
$.each(threads,function(i,o){
var row=$('<tr>').appendTo(table);
$('<span class="key">').data('num',i).text(o.thread_key).appendTo($('<td>').appendTo(row)).click(editKey);
$('<a target=_blank>').attr('href',o.url).text(o.title).appendTo($('<td>').appendTo(row));
});
panel.show();
});
$('<a href>自动分析评论</a>')
.appendTo($('<li>').appendTo(menu))
.click(function(e){
e.preventDefault();
var dthreads={};
var limit=100,n=Math.ceil(DUOSHUO.site.comments/limit),i;
var finished=0;
var popup=$('<div class="dsa-popup">').html('正在分析评论:<span></span>/'+n).appendTo(document.body);
var prog=popup.find('span').html(finished);
for(i=0;i<n;i++)
$.get('/api/posts/list.json',{
order:'desc',
source:'duoshuo,repost',
max_depth:1,
limit:limit,
'related[]':'thread',
nonce:DUOSHUO.nonce,
status:'all',
page:i+1,
},function(r){
$.each(r.response,function(i,p){
var t=p.thread;
dthreads[t.thread_id]=t;
});
prog.html(++finished);
if(finished==n) {
popup.html('评论分析完成!');
popup.fadeOut(5000,function(){
popup.remove();
});
threads=[];
for(var i in dthreads) threads.push(dthreads[i]);
threads.sort(function(a,b){return a.thread_id>b.thread_id;});
save();
}
});
});