Duoshuo Admin

更加强大的多说评论管理脚本,可以自动分析所有有评论的页面,方便地修改thread_key,避免评论丢失。

当前为 2015-04-12 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name Duoshuo Admin
// @name:zh-CN 多说评论管理
// @namespace http://gerald.top
// @author Gerald <[email protected]>
// @icon	http://cn.gravatar.com/avatar/a0ad718d86d21262ccd6ff271ece08a3?s=80
// @description 更加强大的多说评论管理脚本,可以自动分析所有有评论的页面,方便地修改thread_key,避免评论丢失。
// @version 0.2
// @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.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();
			}
		});
});