利用者:KJP-System/common.js

提供: KPOP JPWiki
2026年8月25日 (火) 14:02時点におけるKJP-System (トーク | 投稿記録)による版
ナビゲーションに移動 検索に移動

注意: 保存後、変更を確認するにはブラウザーのキャッシュを消去する必要がある場合があります。

  • Firefox / Safari: Shift を押しながら 再読み込み をクリックするか、Ctrl-F5 または Ctrl-R を押してください (Mac では ⌘-R)
  • Google Chrome: Ctrl-Shift-R を押してください (Mac では ⌘-Shift-R)
  • Microsoft Edge: Ctrl を押しながら 最新の情報に更新 をクリックするか、Ctrl-F5 を押してください。
console.log('KJP personal JS loaded');
window.KJPTEST = 123;

/**
 * KJP Harness
 * Owner-side maintenance helpers for KPOP JPWiki.
 *
 * ResourceLoader-compatible version.
 * - No automatic edits
 * - dryRun by default
 * - exact-match validation
 * - keeps an in-memory backup of the last patch
 */

window.KJPHarness = {

	lastBackup: [],

	getSource: function (title) {
		var api = new mw.Api();

		return api.get({
			action: 'query',
			prop: 'revisions',
			rvprop: 'content|ids|timestamp',
			rvslots: 'main',
			titles: title,
			formatversion: 2
		}).then(function (data) {
			var page = data.query.pages[0];
			var revision = null;
			var text = '';

			if (page.revisions && page.revisions.length > 0) {
				revision = page.revisions[0];

				if (
					revision.slots &&
					revision.slots.main &&
					typeof revision.slots.main.content === 'string'
				) {
					text = revision.slots.main.content;
				}
			}

			return {
				title: page.title,
				pageid: page.pageid,
				revid: revision ? revision.revid : null,
				timestamp: revision ? revision.timestamp : null,
				text: text
			};
		});
	},

	inspect: function (pages, needle) {
		var self = this;
		var results = [];
		var chain = Promise.resolve();

		pages.forEach(function (title) {
			chain = chain.then(function () {
				return self.getSource(title).then(function (page) {
					var count = page.text.split(needle).length - 1;

					results.push({
						title: title,
						matches: count,
						revid: page.revid
					});
				}).catch(function (e) {
					results.push({
						title: title,
						matches: 'ERROR',
						revid: null
					});

					console.error(title, e);
				});
			});
		});

		return chain.then(function () {
			console.table(results);
			return results;
		});
	},

	bulkReplace: function (options) {
		var self = this;
		var api = new mw.Api();

		var pages = options.pages;
		var from = options.from;
		var to = options.to;

		var summary = options.summary || 'KJP Harness bulk patch';

		var expectedMatches =
			typeof options.expectedMatches === 'number'
				? options.expectedMatches
				: 1;

		var dryRun =
			typeof options.dryRun === 'boolean'
				? options.dryRun
				: true;

		var plan = [];
		var backups = [];
		var chain = Promise.resolve();

		pages.forEach(function (title) {
			chain = chain.then(function () {

				return self.getSource(title).then(function (page) {

					if (page.text.indexOf(to) !== -1) {
						plan.push({
							title: title,
							status: 'SKIP_ALREADY_DONE'
						});

						return;
					}

					var count = page.text.split(from).length - 1;

					if (count !== expectedMatches) {
						plan.push({
							title: title,
							status: 'SKIP_MATCH_COUNT',
							matches: count
						});

						return;
					}

					plan.push({
						title: title,
						status: dryRun ? 'READY' : 'PATCH'
					});

					if (dryRun) {
						return;
					}

					backups.push({
						title: title,
						revid: page.revid,
						text: page.text
					});

					var updated = page.text.replace(from, to);

					return api.postWithToken('csrf', {
						action: 'edit',
						title: title,
						text: updated,
						summary: summary,
						minor: true,
						basetimestamp: page.timestamp,
						formatversion: 2
					});
				}).catch(function (e) {
					plan.push({
						title: title,
						status: 'ERROR'
					});

					console.error(title, e);
				});
			});
		});

		return chain.then(function () {

			if (!dryRun) {
				self.lastBackup = backups;
			}

			console.table(plan);

			if (dryRun) {
				console.log('DRY RUN: Wikiは変更されていません。');
			} else {
				console.log(
					'PATCH完了。バックアップ: ' +
					backups.length +
					'件'
				);
			}

			return plan;
		});
	}
};

console.log('KJP Harness loaded.');