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

提供: KPOP JPWiki
ナビゲーションに移動 検索に移動
編集の要約なし
編集の要約なし
1行目: 1行目:
console.log('KJP personal JS loaded');
console.log('KJP personal JS loaded');
window.KJPTEST = 123;
window.KJPTEST = 123;


/**
/**
7行目: 6行目:
  * Owner-side maintenance helpers for KPOP JPWiki.
  * Owner-side maintenance helpers for KPOP JPWiki.
  *
  *
* ResourceLoader-compatible version.
  * - No automatic edits
  * - No automatic edits
  * - dryRun by default
  * - dryRun by default
17行目: 17行目:
lastBackup: [],
lastBackup: [],


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


const data = await api.get({
return api.get({
action: 'query',
action: 'query',
prop: 'revisions',
prop: 'revisions',
27行目: 27行目:
titles: title,
titles: title,
formatversion: 2
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;


const page = data.query.pages[0];
results.push({
title: title,
matches: count,
revid: page.revid
});
}).catch(function (e) {
results.push({
title: title,
matches: 'ERROR',
revid: null
});


return {
console.error(title, e);
title: page.title,
});
pageid: page.pageid,
});
revid: page.revisions?.[0]?.revid,
});
timestamp: page.revisions?.[0]?.timestamp,
 
text: page.revisions?.[0]?.slots?.main?.content ?? ''
return chain.then(function () {
};
console.table(results);
return results;
});
},
},


async inspect(pages, needle) {
bulkReplace: function (options) {
const results = [];
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;


for (const title of pages) {
var plan = [];
try {
var backups = [];
const page = await this.getSource(title);
var chain = Promise.resolve();
const count = page.text.split(needle).length - 1;


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


console.error(title, e);
return self.getSource(title).then(function (page) {
}
}


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


async bulkReplace({
return;
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) {
var count = page.text.split(from).length - 1;
try {
const page = await this.getSource(title);


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


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


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


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


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


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


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


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


console.error(title, e);
return chain.then(function () {
 
if (!dryRun) {
self.lastBackup = backups;
}
}
}


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


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


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


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

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

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.');