Greasy Fork is available in English.
试着将 infobox 里手写的章节参与信息提取到关联里
当前为
// ==UserScript==
// @name BGM维基动画老条目关联人物参与章节填充
// @namespace hyary
// @version 0.1.0
// @description 试着将 infobox 里手写的章节参与信息提取到关联里
// @author hyary
// @license MIT
// @match https://bgm.tv/subject/*/add_related/person
// @match https://bangumi.tv/subject/*/add_related/person
// @match https://chii.in/subject/*/add_related/person
// @run-at document-idle
// ==/UserScript==
(function () {
addRelatedPersonParts();
})()
function addRelatedPersonParts() {
const staffValue = (() => {
let sv = {};
genPrsnStaffList(-1)
.replace(/<option value="(\d+)">([^<]+) \/ .*?<\/option>/g, (m, v, k) => { sv[k] = parseInt(v); });
return sv;
})();
async function getInfoboxFieldLinks() {
const rsp = await fetch(document.URL.split('/add_related/person')[0], { method: 'GET' });
if (!rsp.ok) {
console.error('无法获取页面信息');
return;
}
const raw = await rsp.text();
const parser = new DOMParser();
const doc = parser.parseFromString(raw, 'text/html');
return $("ul#infobox > li", doc)
.filter((_, el) => /\(.*\d.*\)/.test(el.innerHTML) && $("a", el).length > 0)
.map((_, el) => {
const raw = el.innerHTML;
const role = $("span", el).text().trim().slice(0, -1);
const roleID = staffValue[role];
if (!roleID) {
return;
}
const segments = raw.split('</span>')[1].split('、');
let linkParts = [];
appendLog(`--- 正在解析 ${role} ---`);
segments.forEach(seg => {
const keys = Array.from(seg.matchAll(/<a href="([^"]+)"/g)).map(m => m[1]).sort();
if (keys.length > 1) {
appendLog(`解析失败:${seg}`);
return;
}
if (keys.length === 0) {
appendLog(`无关联信息:${seg}`);
return;
}
const parts = /\(([^()]*?)\)$/.exec(seg);
if (!parts) {
appendLog(`无章节信息:${seg}`);
return;
}
const p = parts[1].replaceAll('/', ',');
// if (['OP', 'ED'].includes(p)) {
// appendLog(`跳过 OP/ED:${seg}`);
// return;
// }
if (!/^(\d+[,-])*\d+$/.test(p)) {
appendLog(`格式可能不符,需复查:${seg}`);
}
linkParts.push([keys[0], p]);
});
return [[roleID, linkParts]];
}).get();
}
function getExistingRelation() {
// relaTabs: { role_id: { link: partElem } }
let relaTabs = Object.fromEntries(Object.values(staffValue).map(x => [x, {}]));
$('#crtRelateSubjects li').each((_, el) => {
const link = $('p.title > a', el).attr('href');
const roleID = parseInt($('select', el).attr('value'));
const partElem = $('input[type="text"]', el);
relaTabs[roleID][link] = partElem;
});
return relaTabs;
}
$('.subjectListWrapper').after(`
<div id="dougarenovate-main">
<div style="margin: 1rem 0.5rem 0 0.5rem; display: flex; justify-content: space-between;">
<div style="margin: 0.5rem; font-size: 16px; color: #AAA; flex-basis: 40%;"></div>
<input type="button" id="dougarenovate-btn-start" class="searchBtnL" value="从 infobox 补充参与信息" style="flex-basis: 30%;">
</div>
<div id="dougarenovate-prog" style="position: fixed; backdrop-filter: blur(10px); padding: 0 0.5rem; font-size: 14px; color: #AAA;"></div>
</div>
`);
$('#dougarenovate-btn-start').on('click', async () => {
const infoboxLinks = await getInfoboxFieldLinks();
const existingRelation = getExistingRelation();
appendLog("--- 开始装填 ---");
for (const [roleID, linkParts] of infoboxLinks) {
const linkParkElem = existingRelation[roleID];
for (const [link, parts] of linkParts) {
console.log(link, linkParkElem[link], parts);
linkParkElem[link].val(parts);
}
}
$('#editSummary').val('参照 infobox 补充人物参与章节');
});
}
function appendLog(text) {
$('#dougarenovate-prog').append(`<div>${text}</div>`);
}