「利用者:KJP-System/common.js」の版間の差分

提供: KPOP JPWiki
ナビゲーションに移動 検索に移動
ページの作成:「→* * KJP Harness * Owner-side maintenance helpers for KPOP JPWiki. * * - No automatic edits * - dryRun by default * - exact-match validation * - keeps an in-memory backup of the last patch: window.KJPHarness = { lastBackup: [], async getSource(title) { const api = new mw.Api(); const data = await api.get({ action: 'query', prop: 'revisions', rvprop: 'content|ids|timestamp', rvslots: 'main', titles: title, formatversion: 2 });…」
 
編集の要約なし
1行目: 1行目:
console.log('KJP personal JS loaded');
window.KJPTEST = 123;
/**
/**
  * KJP Harness
  * KJP Harness

2026年8月25日 (火) 13:42時点における版

console.log('KJP personal JS loaded');
window.KJPTEST = 123;


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

window.KJPHarness = {

	lastBackup: [],

	async getSource(title) {
		const api = new mw.Api();

		const data = await api.get({
			action: 'query',
			prop: 'revisions',
			rvprop: 'content|ids|timestamp',
			rvslots: 'main',
			titles: title,
			formatversion: 2
		});

		const page = data.query.pages[0];

		return {
			title: page.title,
			pageid: page.pageid,
			revid: page.revisions?.[0]?.revid,
			timestamp: page.revisions?.[0]?.timestamp,
			text: page.revisions?.[0]?.slots?.main?.content ?? ''
		};
	},

	async inspect(pages, needle) {
		const results = [];

		for (const title of pages) {
			try {
				const page = await this.getSource(title);
				const count = page.text.split(needle).length - 1;

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

				console.error(title, e);
			}
		}

		console.table(results);
		return results;
	},

	async bulkReplace({
		pages,
		from,
		to,
		summary = 'KJP Harness bulk patch',
		expectedMatches = 1,
		dryRun = true
	}) {
		const api = new mw.Api();
		const plan = [];
		const backups = [];

		for (const title of pages) {
			try {
				const page = await this.getSource(title);

				if (page.text.includes(to)) {
					plan.push({
						title,
						status: 'SKIP_ALREADY_DONE'
					});
					continue;
				}

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

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

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

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

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

					await api.postWithToken('csrf', {
						action: 'edit',
						title,
						text: updated,
						summary,
						minor: true,
						basetimestamp: page.timestamp,
						formatversion: 2
					});
				}

			} catch (e) {
				plan.push({
					title,
					status: 'ERROR'
				});

				console.error(title, e);
			}
		}

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

		console.table(plan);

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

		return plan;
	}
};

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