From bf9433150d231bfdbbfb67f9bd02f068ecca6e65 Mon Sep 17 00:00:00 2001 From: SuperSaltyGamer Date: Fri, 9 Feb 2024 10:42:19 +0200 Subject: [PATCH] [musicbrainz-works] Obtain arrangers from minc --- dist/musicbrainz-works.user.js | 8 ++++---- src/musicbrainz-works/bus.ts | 1 + src/musicbrainz-works/main.ts | 2 +- src/musicbrainz-works/modules/minc.ts | 2 ++ src/musicbrainz-works/modules/musicbrainz.ts | 6 ++++-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/dist/musicbrainz-works.user.js b/dist/musicbrainz-works.user.js index 83f26ac..64e9a6f 100644 --- a/dist/musicbrainz-works.user.js +++ b/dist/musicbrainz-works.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @namespace ame-musicbrainz-works // @name Ame (MusicBrainz - Works) -// @version 0.2.0 +// @version 0.3.0 // @author SuperSaltyGamer // @run-at document-end // @match https://musicbrainz.org/* @@ -17,8 +17,8 @@ // @updateURL https://notabug.org/SuperSaltyGamer/ame/raw/main/dist/musicbrainz-works.user.js // ==/UserScript== -(function(u){typeof define=="function"&&define.amd?define(u):u()})(function(){"use strict";function u(e){return new Promise(t=>{setTimeout(t,e)})}function B(e){const t=document.createElement("template");return t.innerHTML=e,t.content.firstElementChild}function g(e,t){return new Promise(r=>{const o=t==null?void 0:t.waitSelector,n=(t==null?void 0:t.timeout)??3e3;if(n!==0){const c=document.querySelector(e);if(c){r(c);return}}const i=setTimeout(()=>{n!==0&&(a.disconnect(),r(null))},n),a=new MutationObserver(c=>{for(const l of c)for(const s of Array.from(l.addedNodes))if(s instanceof Element&&s.matches(o??e)){n!==0&&(a.disconnect(),clearTimeout(i)),r(o?document.querySelector(e):s);return}});a.observe(document.body,{childList:!0,subtree:!0})})}function E(e,t){new MutationObserver(async o=>{for(const n of o)for(const i of n.addedNodes){if(!(i instanceof HTMLElement))continue;const a=i.matches(e)?i:i.querySelector(e);a&&await t(a)}}).observe(document.body,{childList:!0,subtree:!0})}function m(e,t){return document.evaluate(t,e,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}function S(e,t){const r=document.evaluate(t,e,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);return Array.from({length:r.snapshotLength},(o,n)=>r.snapshotItem(n))}var d=(e=>(e.Work="work",e))(d||{});function k(e,t){if(document.visibilityState==="visible")return t==null?GM.deleteValue(e):(console.info("setBusValue",e,t),GM.setValue(e,{value:t,timestamp:new Date().getTime()+60*1e3}))}async function W(e){if(document.visibilityState!=="visible")return null;const t=await GM.getValue(e);return!t||(await k(e,null),t.timestamp>﹥≯¬¬||~~−⁻₋⁒∓-∕⁄∖-∛؆∜؇∝-∭⨌∮-∼≁∽-≀≂-≅≇≆≈-≍≭≎-≟≡-≤≰≥≱≦-≬≲≴≳≵≶≸≷≹≺⊀≻⊁≼⋠≽⋡≾≿⊂⊄⊃⊅⊆⊈⊇⊉-⊑⋢⊒⋣⊓-⊢⊬⊣-⊨⊭⊩⊮⊪⊫⊯-⊲⋪⊳⋫⊴⋬⊵⋭⊶-⊼⅋⊽-⋟⋤-⋩⋮-⋿⌠⌡⍼⎛-⎳⏜-⏡▷◁◸-◺◿⟀-⟄⟇-⟥⟰-⟿⤀-⤳⤶-⦂⦙-⧗⧜-⧻⧾-⨋⨍-⩳⩷-⫛⫝⫝̸⫞-⫿⬰-⭄⭇-⭌♯↔↮⤴⤵‼⁉〰〽◼◻◾◽]`.split("")),A={0:1,"0":1,1:2,"1":2,2:3,"2":3,3:4,"3":4,4:5,"4":5,5:6,"5":6,6:7,"6":7,7:8,"7":8,8:9,"8":9,9:10,"9":10,a:11,a:11,ä:11,b:12,b:12,c:13,c:13,d:14,d:14,e:15,e:15,f:16,f:16,g:17,g:17,h:18,h:18,i:19,i:19,j:20,j:20,k:21,k:21,l:22,l:22,m:23,m:23,n:24,n:24,o:25,o:25,ö:25,õ:25,p:26,p:26,q:27,q:27,r:28,r:28,s:29,s:29,$:29,t:30,t:30,u:31,u:31,ü:31,v:32,v:32,w:33,w:33,x:34,x:34,y:35,y:35,z:36,z:36},D=Object.entries(A).reduce((e,[t,r])=>(r in e||(e[r]=[]),e[r].push(t),e),{});function I(e){const t=A[e];return t?D[t]??[e]:[e]}function v(e){return e=e.replace(/[\s・]+/g,"").split("").map(t=>N.has(t)?"":`[${I(t).join("")}]`).join("[\\s\\p{Pc}\\p{Pd}\\p{Pe}\\p{Pf}\\p{Pi}\\p{Po}\\p{Ps}\\p{Sm}]{0,4}"),new RegExp(`(?)${e}`,"gui")}function _(e,t){e.innerHTML=e.innerHTML.replaceAll(t,r=>{const o=document.createElement("span");o.classList.add("ame__mark--inner"),o.innerText=r;const n=document.createElement("span");return n.classList.add("ame__mark"),n.appendChild(o),n.outerHTML})}function T(e){const t=e.value;return e.addEventListener("input",()=>{e.value!==t&&(e.style.backgroundColor="yellow")}),e}function y(e,t){if(e instanceof HTMLInputElement){Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value").set.call(e,t),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("focusout",{bubbles:!0}));return}if(e instanceof HTMLSelectElement){Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,"value").set.call(e,t),e.dispatchEvent(new Event("change",{bubbles:!0})),e.dispatchEvent(new Event("focusout",{bubbles:!0}));return}}function P(e,t){const r=p.createOscillator(),o=p.createGain();r.connect(o),o.connect(p.destination),o.gain.value=.25,r.frequency.value=t,r.start(p.currentTime),r.stop(p.currentTime+e/1e3)}async function z(){E("a[class^='LandingPage_languageButton__']",()=>{location.href="/search"})}async function G(){let e=!1;await b(d.Work,async t=>{if(!t.iswc)return;const r=document.querySelector("#iswc"),o=document.querySelector("button[type='submit']");if(y(r,t.iswc),o==null||o.click(),e=await Promise.any([g("div[class^='Search_resultsContainer__'] div[class^='AlertMessage_text__']").then(()=>!0),g("[class^='Search_sectionTitle__']").then(a=>!a)]),e)return;const n=document.querySelector("[id='View More']");n.click(),await u(100);const i=m(document,"//button[.='Copy work codes']");i?(i.click(),t.workCodes=!0):n.after(B('
Install Bulk copy-paste work codes for better integration.
')),t.sources.push(location.href),t.sources=Array.from(new Set(t.sources)),P(50,1e3)}),e&&(location.href="/")}function j(){const e=document.querySelector(".logo > a");e&&(e.href=`${location.origin}/search`)}function U(){return b(d.Work,async e=>{if(!e.name)return;const t=document.querySelector("#kyokunm"),r=document.querySelector("#search-by-track-and-artist");t.value=e.name,r.click()})}function F(){for(const e of document.querySelectorAll(".saku-detail-link")){const t=document.createElement("a");t.target="_blank",t.href=`/saku/detail/?${e.getAttribute("data-href")}`,t.innerHTML=e.innerHTML,e.replaceWith(t)}return b(d.Work,async e=>{for(const o of e.context.tokens){const n=v(o);for(const i of document.querySelectorAll("#track-list tr td:nth-child(3), #track-list tr td:nth-child(4)"))_(i,n)}if(e.name)for(const o of document.querySelectorAll("#track-list tr td:nth-child(2)"))_(o,v(e.name));const t=document.querySelector("#kyokunm"),r=document.querySelector("#search-by-track-and-artist");!e.name||t.value===e.name||(t.value=e.name,r.click())})}function $(){return b(d.Work,async e=>{var l,s,f,h,R,C,V,H;const t=((s=(l=m(document,"//h2/text()"))==null?void 0:l.nodeValue)==null?void 0:s.trim())||null,r=((h=(f=m(document,"//h3/text()[.!='-']"))==null?void 0:f.nodeValue)==null?void 0:h.replaceAll(" ",""))||null,o=((C=(R=m(document,"//a[@href='#jasrac']/following-sibling::*/span[2][.!='']"))==null?void 0:R.innerText)==null?void 0:C.trim())||null,n=((H=(V=m(document,"//a[@href='#nextone']/following-sibling::*/span[2][.!='']"))==null?void 0:V.innerText)==null?void 0:H.trim())||null,i=new Set(S(document,"//td[contains(., '作詞')]/parent::tr/*[2]").map(w=>w.innerText.trim()).filter(Boolean)),a=new Set(S(document,"//td[contains(., '作曲')]/parent::tr/*[2]").map(w=>w.innerText.trim()).filter(Boolean)),c=new Set(S(document,"//td[contains(., '出版者')]/parent::tr/*[2]").map(w=>w.innerText.trim()).filter(Boolean));r&&(e.iswc=r),n&&(e.nextone=n),e.lyricists=Array.from(i),e.composers=Array.from(a),e.publishers=Array.from(c),e.sources.push(location.href),e.sources=Array.from(new Set(e.sources)),P(50,1e3)})}let M=!1;function Q(){L(),E("#add-relationship-dialog",async e=>{const t=m(e,"//td[.='Work']/following-sibling::td//button");await u(100),t==null||t.click()})}async function X(){L();const e=T(document.querySelector("#id-edit-work\\.name")),t=T(document.querySelector("input[name='edit-work.iswcs.0']")),r=document.querySelector("#id-edit-work\\.edit_note"),o=await W(d.Work);if(!(o!=null&&o.sources.length)){M||(await k(d.Work,{name:e.value||null,iswc:t.value||null,nextone:null,lyricists:[],composers:[],publishers:[],sources:[],workCodes:!1,context:{tokens:Array.from(x(parent===window?document.body:parent.document.body))}}),P(50,1e3));return}if(M=!0,o.iswc&&y(t,o.iswc),o.nextone&&O("nextone",o.nextone),o.sources.length&&(r.value=`Filled out with Ame (MusicBrainz - Works): +(function(l){typeof define=="function"&&define.amd?define(l):l()})(function(){"use strict";function l(e){return new Promise(t=>{setTimeout(t,e)})}function N(e){const t=document.createElement("template");return t.innerHTML=e,t.content.firstElementChild}function S(e,t){return new Promise(r=>{const o=t==null?void 0:t.waitSelector,n=(t==null?void 0:t.timeout)??3e3;if(n!==0){const c=document.querySelector(e);if(c){r(c);return}}const i=setTimeout(()=>{n!==0&&(a.disconnect(),r(null))},n),a=new MutationObserver(c=>{for(const u of c)for(const s of Array.from(u.addedNodes))if(s instanceof Element&&s.matches(o??e)){n!==0&&(a.disconnect(),clearTimeout(i)),r(o?document.querySelector(e):s);return}});a.observe(document.body,{childList:!0,subtree:!0})})}function k(e,t){new MutationObserver(async o=>{for(const n of o)for(const i of n.addedNodes){if(!(i instanceof HTMLElement))continue;const a=i.matches(e)?i:i.querySelector(e);a&&await t(a)}}).observe(document.body,{childList:!0,subtree:!0})}function d(e,t){return document.evaluate(t,e,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}function g(e,t){const r=document.evaluate(t,e,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);return Array.from({length:r.snapshotLength},(o,n)=>r.snapshotItem(n))}var m=(e=>(e.Work="work",e))(m||{});function v(e,t){if(document.visibilityState==="visible")return t==null?GM.deleteValue(e):(console.info("setBusValue",e,t),GM.setValue(e,{value:t,timestamp:new Date().getTime()+60*1e3}))}async function W(e){if(document.visibilityState!=="visible")return null;const t=await GM.getValue(e);return!t||(await v(e,null),t.timestamp>﹥≯¬¬||~~−⁻₋⁒∓-∕⁄∖-∛؆∜؇∝-∭⨌∮-∼≁∽-≀≂-≅≇≆≈-≍≭≎-≟≡-≤≰≥≱≦-≬≲≴≳≵≶≸≷≹≺⊀≻⊁≼⋠≽⋡≾≿⊂⊄⊃⊅⊆⊈⊇⊉-⊑⋢⊒⋣⊓-⊢⊬⊣-⊨⊭⊩⊮⊪⊫⊯-⊲⋪⊳⋫⊴⋬⊵⋭⊶-⊼⅋⊽-⋟⋤-⋩⋮-⋿⌠⌡⍼⎛-⎳⏜-⏡▷◁◸-◺◿⟀-⟄⟇-⟥⟰-⟿⤀-⤳⤶-⦂⦙-⧗⧜-⧻⧾-⨋⨍-⩳⩷-⫛⫝⫝̸⫞-⫿⬰-⭄⭇-⭌♯↔↮⤴⤵‼⁉〰〽◼◻◾◽]`.split("")),A={0:1,"0":1,1:2,"1":2,2:3,"2":3,3:4,"3":4,4:5,"4":5,5:6,"5":6,6:7,"6":7,7:8,"7":8,8:9,"8":9,9:10,"9":10,a:11,a:11,ä:11,b:12,b:12,c:13,c:13,d:14,d:14,e:15,e:15,f:16,f:16,g:17,g:17,h:18,h:18,i:19,i:19,j:20,j:20,k:21,k:21,l:22,l:22,m:23,m:23,n:24,n:24,o:25,o:25,ö:25,õ:25,p:26,p:26,q:27,q:27,r:28,r:28,s:29,s:29,$:29,t:30,t:30,u:31,u:31,ü:31,v:32,v:32,w:33,w:33,x:34,x:34,y:35,y:35,z:36,z:36},I=Object.entries(A).reduce((e,[t,r])=>(r in e||(e[r]=[]),e[r].push(t),e),{});function z(e){const t=A[e];return t?I[t]??[e]:[e]}function _(e){return e=e.replace(/[\s・]+/g,"").split("").map(t=>D.has(t)?"":`[${z(t).join("")}]`).join("[\\s\\p{Pc}\\p{Pd}\\p{Pe}\\p{Pf}\\p{Pi}\\p{Po}\\p{Ps}\\p{Sm}]{0,4}"),new RegExp(`(?)${e}`,"gui")}function T(e,t){e.innerHTML=e.innerHTML.replaceAll(t,r=>{const o=document.createElement("span");o.classList.add("ame__mark--inner"),o.innerText=r;const n=document.createElement("span");return n.classList.add("ame__mark"),n.appendChild(o),n.outerHTML})}function P(e){const t=e.value;return e.addEventListener("input",()=>{e.value!==t&&(e.style.backgroundColor="yellow")}),e}function w(e,t){if(e instanceof HTMLInputElement){Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value").set.call(e,t),e.dispatchEvent(new Event("input",{bubbles:!0})),e.dispatchEvent(new Event("focusout",{bubbles:!0}));return}if(e instanceof HTMLSelectElement){Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,"value").set.call(e,t),e.dispatchEvent(new Event("change",{bubbles:!0})),e.dispatchEvent(new Event("focusout",{bubbles:!0}));return}}function q(e,t){const r=y.createOscillator(),o=y.createGain();r.connect(o),o.connect(y.destination),o.gain.value=.25,r.frequency.value=t,r.start(y.currentTime),r.stop(y.currentTime+e/1e3)}async function G(){k("a[class^='LandingPage_languageButton__']",()=>{location.href="/search"})}async function j(){let e=!1;await b(m.Work,async t=>{if(!t.iswc)return;const r=document.querySelector("#iswc"),o=document.querySelector("button[type='submit']");if(w(r,t.iswc),o==null||o.click(),e=await Promise.any([S("div[class^='Search_resultsContainer__'] div[class^='AlertMessage_text__']").then(()=>!0),S("[class^='Search_sectionTitle__']").then(a=>!a)]),e)return;const n=document.querySelector("[id='View More']");n.click(),await l(100);const i=d(document,"//button[.='Copy work codes']");i?(i.click(),t.workCodes=!0):n.after(N('
Install Bulk copy-paste work codes for better integration.
')),t.sources.push(location.href),t.sources=Array.from(new Set(t.sources)),q(50,1e3)}),e&&(location.href="/")}function U(){const e=document.querySelector(".logo > a");e&&(e.href=`${location.origin}/search`)}function $(){return b(m.Work,async e=>{if(!e.name)return;const t=document.querySelector("#kyokunm"),r=document.querySelector("#search-by-track-and-artist");t.value=e.name,r.click()})}function F(){for(const e of document.querySelectorAll(".saku-detail-link")){const t=document.createElement("a");t.target="_blank",t.href=`/saku/detail/?${e.getAttribute("data-href")}`,t.innerHTML=e.innerHTML,e.replaceWith(t)}return b(m.Work,async e=>{for(const o of e.context.tokens){const n=_(o);for(const i of document.querySelectorAll("#track-list tr td:nth-child(3), #track-list tr td:nth-child(4)"))T(i,n)}if(e.name)for(const o of document.querySelectorAll("#track-list tr td:nth-child(2)"))T(o,_(e.name));const t=document.querySelector("#kyokunm"),r=document.querySelector("#search-by-track-and-artist");!e.name||t.value===e.name||(t.value=e.name,r.click())})}function Q(){return b(m.Work,async e=>{var s,h,p,R,C,V,H,B;const t=((h=(s=d(document,"//h2/text()"))==null?void 0:s.nodeValue)==null?void 0:h.trim())||null,r=((R=(p=d(document,"//h3/text()[.!='-']"))==null?void 0:p.nodeValue)==null?void 0:R.replaceAll(" ",""))||null,o=((V=(C=d(document,"//a[@href='#jasrac']/following-sibling::*/span[2][.!='']"))==null?void 0:C.innerText)==null?void 0:V.trim())||null,n=((B=(H=d(document,"//a[@href='#nextone']/following-sibling::*/span[2][.!='']"))==null?void 0:H.innerText)==null?void 0:B.trim())||null,i=new Set(g(document,"//td[contains(., '作詞')]/parent::tr/*[2]").map(f=>f.innerText.trim()).filter(Boolean)),a=new Set(g(document,"//td[contains(., '作曲')]/parent::tr/*[2]").map(f=>f.innerText.trim()).filter(Boolean)),c=new Set(g(document,"//td[contains(., '編曲')]/parent::tr/*[2]").map(f=>f.innerText.trim()).filter(Boolean)),u=new Set(g(document,"//td[contains(., '出版者')]/parent::tr/*[2]").map(f=>f.innerText.trim()).filter(Boolean));r&&(e.iswc=r),n&&(e.nextone=n),e.lyricists=Array.from(i),e.composers=Array.from(a),e.arrangers=Array.from(c),e.publishers=Array.from(u),e.sources.push(location.href),e.sources=Array.from(new Set(e.sources)),q(50,1e3)})}let M=!1;function X(){x(),k("#add-relationship-dialog",async e=>{const t=d(e,"//td[.='Work']/following-sibling::td//button");await l(100),t==null||t.click()})}async function Y(){x();const e=P(document.querySelector("#id-edit-work\\.name")),t=P(document.querySelector("input[name='edit-work.iswcs.0']")),r=document.querySelector("#id-edit-work\\.edit_note"),o=await W(m.Work);if(!(o!=null&&o.sources.length)){M||(await v(m.Work,{name:e.value||null,iswc:t.value||null,nextone:null,lyricists:[],composers:[],arrangers:[],publishers:[],sources:[],workCodes:!1,context:{tokens:Array.from(L(parent===window?document.body:parent.document.body))}}),q(50,1e3));return}if(M=!0,o.iswc&&w(t,o.iswc),o.nextone&&O("nextone",o.nextone),o.sources.length&&(r.value=`Filled out with Ame (MusicBrainz - Works): ${o.sources.join(` `)} -`),o.workCodes){const n=document.querySelector("#ROpdebee_MB_Paste_Work");n==null||n.click()}for(const n of o.composers)await q("artist","composed / composer",n);for(const n of o.lyricists)await q("artist","lyrics / lyricist",n);for(const n of o.publishers)await q("label","published / publisher",n)}function L(){E("ul[id^='relationship-target']",async e=>{new MutationObserver(async r=>{const o=r[0],n=e.style.visibility;if(n==="hidden"||n===o.oldValue)return;const i=e.firstElementChild;if(i!=null&&i.innerText.includes("Click here to try again")){await u(100),i.click();return}const c=document.getElementById(e.getAttribute("aria-labelledby")).control,l=x();c.value&&l.add(c.value);for(const s of l){const f=v(s);for(const h of e.children)_(h,f)}}).observe(e,{attributes:!0,attributeOldValue:!0,attributeFilter:["style"]})})}function x(e=document.body){return new Set(Array.from(e.querySelectorAll("a[href^='/artist/'][title]")).map(t=>t.innerText.trim()))}async function q(e,t,r){document.querySelector("button.add-relationship").click();const n=await g("#add-relationship-dialog");if(!n)return;const i=n.querySelector("select.entity-type");y(i,e);const a=n.querySelector("input.relationship-type");y(a,t),n.querySelector("li.option-item").click();const c=n.querySelector(".relationship-target input");y(c,r),await u(300),n.querySelector(".relationship-target button").click(),await new Promise(s=>{const f=n.querySelector("button.negative"),h=n.querySelector("button.positive");f.addEventListener("click",()=>s()),h.addEventListener("click",()=>s())}),await u(300)}function O(e,t){e=e.toLowerCase();const r=document.querySelector("#add-work-attribute");for(let o=0;o<2;o++){for(const n of document.querySelectorAll("#work-attributes tr:not(:last-child)")){const i=n.querySelector("select"),a=i.selectedOptions[0],c=Array.from(i.options).filter(s=>s.innerText.trim().toLowerCase().startsWith(e))[0];if(a!==c&&a.value)continue;c.selected=!0;const l=T(n.querySelector("input"));l.value=t;return}r.click(),O(e,t)}}const Y=`.ame__mark{background-color:#ff0e!important;outline:2px solid #ffff00ee!important}.ame__mark--inner{color:#000!important;filter:brightness(.1)} -`;GM.addStyle(Y);const K=new URLSearchParams(location.search);window.addEventListener("focus",async()=>{var e,t;await u(100),!(!window.document.hasFocus()&&!((e=window.top)!=null&&e.document.hasFocus()))&&(location.host.endsWith("musicbrainz.org")?location.pathname.startsWith("/release/")&&location.pathname.endsWith("/edit-relationships")?await Q():(location.pathname.startsWith("/work/")&&location.pathname.endsWith("/edit")||location.pathname.startsWith("/dialog")&&((t=K.get("path"))!=null&&t.startsWith("/work/create")))&&await X():location.host.endsWith("minc.or.jp")?(await j(),location.pathname.startsWith("/search")?await U():location.pathname.startsWith("/music/list")?await F():location.pathname.startsWith("/saku/detail")&&await $()):location.host.endsWith("cisac.org")&&(await z(),location.pathname.startsWith("/search")&&await G()))}),window.dispatchEvent(new Event("focus"))}); +`),o.workCodes){const n=document.querySelector("#ROpdebee_MB_Paste_Work");n==null||n.click()}for(const n of o.lyricists)await E("artist","lyrics / lyricist",n);for(const n of o.composers)await E("artist","composed / composer",n);for(const n of o.arrangers)await E("artist","arranged / arranger",n);for(const n of o.publishers)await E("label","published / publisher",n)}function x(){k("ul[id^='relationship-target']",async e=>{new MutationObserver(async r=>{const o=r[0],n=e.style.visibility;if(n==="hidden"||n===o.oldValue)return;const i=e.firstElementChild;if(i!=null&&i.innerText.includes("Click here to try again")){await l(100),i.click();return}const c=document.getElementById(e.getAttribute("aria-labelledby")).control,u=L();c.value&&u.add(c.value);for(const s of u){const h=_(s);for(const p of e.children)T(p,h)}}).observe(e,{attributes:!0,attributeOldValue:!0,attributeFilter:["style"]})})}function L(e=document.body){return new Set(Array.from(e.querySelectorAll("a[href^='/artist/'][title]")).map(t=>t.innerText.trim()))}async function E(e,t,r){document.querySelector("button.add-relationship").click();const n=await S("#add-relationship-dialog");if(!n)return;const i=n.querySelector("select.entity-type");w(i,e);const a=n.querySelector("input.relationship-type");w(a,t),d(n,`//li[contains(@class, 'option-item') and contains(., '${t}')]`).click();const c=n.querySelector(".relationship-target input");w(c,r),await l(300),n.querySelector(".relationship-target button").click(),await new Promise(s=>{const h=n.querySelector("button.negative"),p=n.querySelector("button.positive");h.addEventListener("click",()=>s()),p.addEventListener("click",()=>s())}),await l(300)}function O(e,t){e=e.toLowerCase();const r=document.querySelector("#add-work-attribute");for(let o=0;o<2;o++){for(const n of document.querySelectorAll("#work-attributes tr:not(:last-child)")){const i=n.querySelector("select"),a=i.selectedOptions[0],c=Array.from(i.options).filter(s=>s.innerText.trim().toLowerCase().startsWith(e))[0];if(a!==c&&a.value)continue;c.selected=!0;const u=P(n.querySelector("input"));u.value=t;return}r.click(),O(e,t)}}const K=`.ame__mark{background-color:#ff0e!important;outline:2px solid #ffff00ee!important}.ame__mark--inner{color:#000!important;filter:brightness(.1)} +`;GM.addStyle(K);const J=new URLSearchParams(location.search);window.addEventListener("focus",async()=>{var e,t;await l(100),!(!window.document.hasFocus()&&!((e=window.top)!=null&&e.document.hasFocus()))&&(location.host.endsWith("musicbrainz.org")?location.pathname.startsWith("/release/")&&location.pathname.endsWith("/edit-relationships")?await X():(location.pathname.startsWith("/work/")&&location.pathname.endsWith("/edit")||location.pathname.startsWith("/dialog")&&((t=J.get("path"))!=null&&t.startsWith("/work/create")))&&await Y():location.host.endsWith("minc.or.jp")?(await U(),location.pathname.startsWith("/search")?await $():location.pathname.startsWith("/music/list")?await F():location.pathname.startsWith("/saku/detail")&&await Q()):location.host.endsWith("cisac.org")&&(await G(),location.pathname.startsWith("/search")&&await j()))}),window.dispatchEvent(new Event("focus"))}); diff --git a/src/musicbrainz-works/bus.ts b/src/musicbrainz-works/bus.ts index d9aa251..1abf888 100644 --- a/src/musicbrainz-works/bus.ts +++ b/src/musicbrainz-works/bus.ts @@ -17,6 +17,7 @@ interface Work { nextone: string | null lyricists: string[] composers: string[] + arrangers: string[] publishers: string[] sources: string[] workCodes: boolean, diff --git a/src/musicbrainz-works/main.ts b/src/musicbrainz-works/main.ts index d74a76b..e823fd0 100644 --- a/src/musicbrainz-works/main.ts +++ b/src/musicbrainz-works/main.ts @@ -1,7 +1,7 @@ // ==UserScript== // @namespace ame-musicbrainz-works // @name Ame (MusicBrainz - Works) -// @version 0.2.0 +// @version 0.3.0 // @author SuperSaltyGamer // @run-at document-end // @match https://musicbrainz.org/* diff --git a/src/musicbrainz-works/modules/minc.ts b/src/musicbrainz-works/modules/minc.ts index fca56c0..dd13111 100644 --- a/src/musicbrainz-works/modules/minc.ts +++ b/src/musicbrainz-works/modules/minc.ts @@ -54,12 +54,14 @@ export function onMincWorkPage() { const nextone = pathSelector(document, "//a[@href='#nextone']/following-sibling::*/span[2][.!='']")?.innerText?.trim() || null; const lyricists = new Set(pathSelectorAll(document, "//td[contains(., '作詞')]/parent::tr/*[2]").map(el => el.innerText.trim()).filter(Boolean)); const composers = new Set(pathSelectorAll(document, "//td[contains(., '作曲')]/parent::tr/*[2]").map(el => el.innerText.trim()).filter(Boolean)); + const arrangers = new Set(pathSelectorAll(document, "//td[contains(., '編曲')]/parent::tr/*[2]").map(el => el.innerText.trim()).filter(Boolean)); const publishers = new Set(pathSelectorAll(document, "//td[contains(., '出版者')]/parent::tr/*[2]").map(el => el.innerText.trim()).filter(Boolean)); if (iswc) work.iswc = iswc; if (nextone) work.nextone = nextone; work.lyricists = Array.from(lyricists); work.composers = Array.from(composers); + work.arrangers = Array.from(arrangers); work.publishers = Array.from(publishers); work.sources.push(location.href); work.sources = Array.from(new Set(work.sources)); diff --git a/src/musicbrainz-works/modules/musicbrainz.ts b/src/musicbrainz-works/modules/musicbrainz.ts index 0a314a9..4bc2e3e 100644 --- a/src/musicbrainz-works/modules/musicbrainz.ts +++ b/src/musicbrainz-works/modules/musicbrainz.ts @@ -31,6 +31,7 @@ export async function onMusicBrainzEditWorkPage() { nextone: null, lyricists: [], composers: [], + arrangers: [], publishers: [], sources: [], workCodes: false, @@ -56,8 +57,9 @@ export async function onMusicBrainzEditWorkPage() { pasteWorkCodesEl?.click(); } - for (const composer of work.composers) await addRelationship("artist", "composed / composer", composer); for (const lyricist of work.lyricists) await addRelationship("artist", "lyrics / lyricist", lyricist); + for (const composer of work.composers) await addRelationship("artist", "composed / composer", composer); + for (const arranger of work.arrangers) await addRelationship("artist", "arranged / arranger", arranger); for (const publisher of work.publishers) await addRelationship("label", "published / publisher", publisher); } @@ -112,7 +114,7 @@ async function addRelationship(relatedType: string, relationshipType: string, va const relationshipTypeEl = dialogEl.querySelector("input.relationship-type")!; setReactInputValue(relationshipTypeEl, relationshipType); - dialogEl.querySelector("li.option-item")!.click(); + pathSelector(dialogEl, `//li[contains(@class, 'option-item') and contains(., '${relationshipType}')]`)!.click(); const targetEl = dialogEl.querySelector(".relationship-target input")!; setReactInputValue(targetEl, value);