Duoshuo Admin

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

目前為 2015-04-12 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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();
			}
		});
});