「利用者:KJP-System/common.js」の版間の差分
ナビゲーションに移動
検索に移動
KJP-System (トーク | 投稿記録) 編集の要約なし |
KJP-System (トーク | 投稿記録) 編集の要約なし |
||
| 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: [], | ||
getSource: function (title) { | |||
var api = new mw.Api(); | |||
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; | |||
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({ | plan.push({ | ||
title, | title: title, | ||
status: ' | status: dryRun ? 'READY' : 'PATCH' | ||
}); | }); | ||
if (dryRun) { | |||
return; | |||
} | |||
backups.push({ | backups.push({ | ||
title, | title: title, | ||
revid: page.revid, | revid: page.revid, | ||
text: page.text | text: page.text | ||
}); | }); | ||
var updated = page.text.replace(from, to); | |||
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' | |||
}); | |||
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.'); | 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.');