コンテンツにスキップ

利用者:Bot2255/common.js

お知らせ: 保存した後、ブラウザのキャッシュをクリアしてページを再読み込みする必要があります。

多くの WindowsLinux のブラウザ

  • Ctrl を押しながら F5 を押す。

Mac における Safari

  • Shift を押しながら、更新ボタン をクリックする。

Mac における ChromeFirefox

  • 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);
});
 
})();