-
Notifications
You must be signed in to change notification settings - Fork 2
/
voiceActorCredits.user.js
95 lines (79 loc) · 3.54 KB
/
voiceActorCredits.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import {
addButton,
addParserButton,
buildCreditParserUI,
} from '../creditParserUI.js';
import { addMessageToEditNote } from '../editNote.js';
import { buildEntityURL } from '../entity.js';
import { nameToMBIDCache } from '../nameToMBIDCache.js';
import { discogsToMBIDCache } from '../discogs/entityMapping.js';
import {
fetchEntity,
} from '../publicAPI.js';
import { seedURLForEntity } from '../seeding.js';
import {
addVoiceActor,
importVoiceActorsFromDiscogs,
} from '../relationship-editor/voiceActorCredits.js';
import { dom } from '@kellnerd/es-utils/dom/select.js';
import { getPattern } from '@kellnerd/es-utils/regex/parse.js';
import { guessUnicodePunctuation } from '@kellnerd/es-utils/string/punctuation.js';
const UI = `
<div id="credit-import-tools">
<div id="credit-import-status" class="row no-label"></div>
<div id="credit-import-errors" class="row no-label error"></div>
</div>`;
function buildVoiceActorCreditParserUI() {
const creditSeparatorInput = dom('credit-separator');
nameToMBIDCache.load();
addParserButton('Parse voice actor credits', async (creditLine, event) => {
const creditTokens = creditLine.split(getPattern(creditSeparatorInput.value) || /$/);
if (creditTokens.length === 2) {
let [roleName, artistName] = creditTokens.map((token) => guessUnicodePunctuation(token.trim()));
const swapNames = event.shiftKey;
if (swapNames) {
[artistName, roleName] = [roleName, artistName];
}
const bypassCache = event.ctrlKey || event.metaKey;
const result = await addVoiceActor(artistName, roleName, bypassCache);
nameToMBIDCache.store();
return result;
} else {
return 'skipped';
}
}, [
'SHIFT key to swap the order of artist names and their role names',
'CTRL or ⌘ key to bypass the cache and force a search',
].join('\n'));
}
function buildVoiceActorCreditImporterUI() {
discogsToMBIDCache.load();
dom('credit-parser').insertAdjacentHTML('beforeend', UI);
addButton('Import voice actors', async () => {
const releaseData = await fetchEntity(window.location.href, ['release-groups', 'url-rels']);
const releaseURL = buildEntityURL('release', releaseData.id)
let discogsURL = releaseData.relations.find((rel) => rel.type === 'discogs')?.url.resource;
if (!discogsURL) {
discogsURL = prompt('Discogs release URL');
}
if (discogsURL) {
const result = await importVoiceActorsFromDiscogs(discogsURL);
addMessageToEditNote(`Imported voice actor credits from ${discogsURL}`);
// mapping suggestions
const newMatches = result.unmappedArtists.filter((mapping) => mapping.MBID);
const artistSeedNote = `Matching artist identified while importing credits from ${discogsURL} to ${releaseURL}`;
const messages = newMatches.map((match) => [
'Please add the external link',
`<a href="${match.externalURL}" target="_blank">${match.externalName}</a>`,
'to the matched entity:',
`<a href="${seedURLForEntity('artist', match.MBID, match.externalURL, 180, artistSeedNote)}" target="_blank">${match.name}</a>`,
match.comment ? `<span class="comment">(<bdi>${match.comment}</bdi>)</span>` : '',
].join(' '));
// import statistics
const importedCredits = result.mappedCredits + newMatches.length;
messages.unshift(`Successfully imported ${importedCredits} of ${result.totalCredits} credits, ${result.mappedCredits} of them were mapped automatically.`);
dom('credit-import-status').innerHTML = messages.map((message) => `<p>${message}</p>`).join('\n');
}
}, 'Import credits from Discogs');
}
buildCreditParserUI(buildVoiceActorCreditParserUI, buildVoiceActorCreditImporterUI);