Giter VIP home page Giter VIP logo

musicbrainz-scripts's Introduction

musicbrainz-scripts

Bookmarklets and Userscripts for MusicBrainz.org

In order to use one of the bookmarklets you have to save the compressed code snippet from the respective section below as a bookmark. Make sure to add the bookmark to a toolbar of your browser which you can easily access while you are editing on MusicBrainz.

While bookmarklets are good for trying things out because they do not require additional software to be installed, userscripts are more convenient if you need a snippet frequently. In case you have installed a userscript manager browser extension you can simply install userscripts from this page by clicking the Install button. Another benefit of them is that you will receive automatic updates if your userscript manager is configured accordingly.

Userscripts

Guess Unicode punctuation

Searches and replaces ASCII punctuation symbols for many input fields by their preferred Unicode counterparts. Provides “Guess punctuation” buttons for titles, names, disambiguation comments, annotations and edit notes on all entity edit and creation pages.

  • Guesses Unicode punctuation based on context as the ASCII symbols are ambiguous.
  • Highlights all updated input fields in order to allow the user to review the changes.
  • Works for release/medium/track titles and release disambiguation comments (in the release editor).
  • Also supports other entity names and disambiguation comments (on their respective edit and creation pages).
  • Detects the selected language (in the release editor) and uses localized quotes.
  • Experimental support for annotations and edit notes. Preserves apostrophe-based markup (bold, italic) and URLs.

Install Source

Also available as a bookmarklet with less features:

Supports the same fields as the userscript but without language detection and granular control over the affected fields.

javascript:(()=>{function e(e,t){const a="background-color";$(e).css(a,"").each((e,n)=>{let g=n.value;g&&(g=((e,t)=>(t.forEach(([t,a])=>{e=e.replace(t,a)}),e))(g,t),g!=n.value&&$(n).val(g).trigger("change").css(a,"yellow"))})}const t=[[/(?<=[^\p{L}\d]|^)"(.+?)"(?=[^\p{L}\d]|$)/gu,"\u201c$1\u201d"],[/(?<=\W|^)'(n)'(?=\W|$)/gi,"\u2019$1\u2019"],[/(?<=[^\p{L}\d]|^)'(.+?)'(?=[^\p{L}\d]|$)/gu,"\u2018$1\u2019"],[/(\d+)"/g,"$1\u2033"],[/(\d+)'(\d+)/g,"$1\u2032$2"],[/'/g,"\u2019"],[/(?<!\.)\.{3}(?!\.)/g,"\u2026"],[/ - /g," \u2013 "],[/\d{4}-\d{2}(?:-\d{2})?(?=\W|$)/g,e=>Number.isNaN(Date.parse(e))?e:e.replaceAll("-","\u2010")],[/\d+(-\d+){2,}/g,e=>e.replaceAll("-","\u2012")],[/(\d+)-(\d+)/g,"$1\u2013$2"],[/(?<=\S)-(?=\S)/g,"\u2010"]],a=[[/\[(.+?)(\|.+?)?\]/g,(e,t,a="")=>`[${btoa(t)}${a}]`],[/(?<=\/\/)(\S+)/g,(e,t)=>btoa(t)],[/'''/g,"<b>"],[/''/g,"<i>"],...t,[/<b>/g,"'''"],[/<i>/g,"''"],[/(?<=\/\/)([A-Za-z0-9+/=]+)/g,(e,t)=>atob(t)],[/\[([A-Za-z0-9+/=]+)(\|.+?)?\]/g,(e,t,a="")=>`[${atob(t)}${a}]`]];e("input#name,input#comment,input.track-name,input[id^=medium-title],input[name$=name],input[name$=comment]",t),e("#annotation,#edit-note-text,textarea[name$=text],.edit-note",a)})();

Import ARD radio dramas

Imports German broadcast releases from the ARD radio drama database.

  • Adds an import button to the sidebar of detail pages (“Vollinformation”) on https://hoerspiele.dra.de
  • Lets the user enter persistent name to MBID mappings for artists and labels
  • Provides a button to copy voice actor credits to clipboard (can be pasted into the credit parser)

Install Source

Parse copyright notice

Parses copyright notices and automates the process of creating release and recording relationships for these.

  • Extracts all copyright and legal information from the given text.
  • Automates the process of creating label-release (or artist-release) relationships for these credits.
  • Also creates phonographic copyright relationships for all selected recordings.
  • Detects artists who own the copyright of their own release and defaults to adding artist-release relationships for these credits.
  • See the wiki page for more details.
  • Allows seeding of the credit input (credits) and the edit note (edit-note) via custom query parameters, which are encoded into the hash of the URL (Example: /edit-relationships#credits=(C)+2023+Test&edit-note=Seeding+example).

Install Source

Voice actor credits

Parses voice actor credits from text and automates the process of creating release or recording relationships for these. Also imports credits from Discogs.

  • Simplifies the addition of “spoken vocals” relationships by providing a pre-filled dialogue in the relationship editor.
  • Parses a list of voice actor credits from text and remembers name to MBID mappings.
  • Adds relationships to selected recordings, falls back to release relationships (if no recordings are selected).
  • Imports voice actor credits from linked Discogs release pages.
  • Automatically matches artists whose Discogs pages are linked to MB (unlinked artists can be selected from the already opened inline search).
  • Allows seeding of the credit input (credits) and the edit note (edit-note) via custom query parameters, which are encoded into the hash of the URL (Example: /edit-relationships#credits=Narrator+-+John+Doe&edit-note=Seeding+example).

Install Source

Bookmarklets

  • Allows entity annotations to be (partly) written in basic Markdown and converts them into valid annotation markup.
  • Shortens absolute URLs to MusicBrainz entities to [entity-type:mbid|label] links.
  • Automatically fetches and uses the name of the linked entity as label if none was given.
  • Also supports collection descriptions and user profile biographies.
javascript:((a,e)=>{const t="background-color";$("textarea[name$=text],textarea[name$=description],textarea[name$=biography]").css(t,"").each((a,n)=>{let r=n.value;r&&(r=((a,e)=>(e.forEach(([e,t])=>{a=a.replace(e,t)}),a))(r,e),r!=n.value&&$(n).val(r).trigger("change").css(t,"yellow"))})})(0,[[/\[(.+?)\]\((.+?)\)/g,"[$2|$1]"],[/(?<!\[)(https?:\/\/\S+)/g,"[$1]"],[/\[(.+?)(\|.+?)?\]/g,(a,e,t="")=>`[${btoa(e)}${t}]`],[/(__|\*\*)(?=\S)(.+?)(?<=\S)\1/g,"'''$2'''"],[/(_|\*)(?=\S)(.+?)(?<=\S)\1/g,"''$2''"],[/^\# +(.+?)( +\#*)?$/gm,"= $1 ="],[/^\#{2} +(.+?)( +\#*)?$/gm,"== $1 =="],[/^\#{3} +(.+?)( +\#*)?$/gm,"=== $1 ==="],[/^(\d+)\. +/gm,"    $1. "],[/^[-+*] +/gm,"    * "],[/\[([A-Za-z0-9+/=]+)(\|.+?)?\]/g,(a,e,t="")=>`[${atob(e)}${t}]`]]),void $("textarea[name$=text],textarea[name$=description],textarea[name$=biography]").each(async(a,e)=>{e.disabled=!0;let t=await(n=e.value,(async(a,e,t)=>{const $=[];a.replace(e,(a,...e)=>{const t=((a,e,t)=>(async(a,e)=>{if(a.includes("musicbrainz.org")){const t=new URL(a),[$,n,r]=t.pathname.match(/^\/(.+?)\/([0-9a-f-]{36})$/)||[];if($)return e||(e=await(async a=>{a.pathname="/ws/2"+a.pathname,a.search="?fmt=json";let e=await fetch(a);return e=await e.json(),e.name||e.title})(t)),`[${n}:${r}|${e}]`}return((a,e)=>e?`[${a}|${e}]`:`[${a}]`)(a,e)})(e,t))(a,...e);$.push(t)});const n=await Promise.all($);return a.replace(e,()=>n.shift())})(n,/\[(.+?)(?:\|(.+?))?\]/g));var n;t!=e.value&&$(e).val(t),e.disabled=!1});
  • Batch-adds release groups as parts of the currently edited series.
  • Automatically extracts numbers from titles and uses them as relationship attributes.
javascript:(()=>{async function t(t){return(await fetch("/ws/js/entity/"+t)).json()}const e={_lineage:[],_original:null,_status:1,attributes:null,begin_date:null,editsPending:!1,end_date:null,ended:!1,entity0_credit:"",entity1_credit:"",id:null,linkOrder:0,linkTypeID:null};function i({source:t=MB.relationshipEditor.state.entity,target:i,batchSelectionCount:n=null,...a}){const r=((t,e,i=!1)=>t===e?i:t>e)(t.entityType,i.entityType,a.backward??!1);MB.relationshipEditor.dispatch({type:"update-relationship-state",sourceEntity:t,batchSelectionCount:n,creditsToChangeForSource:"",creditsToChangeForTarget:"",newRelationshipState:{...e,entity0:r?i:t,entity1:r?t:i,id:MB.relationshipEditor.getRelationshipStateId(),...a},oldRelationshipState:null})}function n(...t){return MB.tree.fromDistinctAscArray(t.map(t=>{const e=MB.linkedEntities.link_attribute_type[t.type.gid];return{...t,type:e,typeID:e.id}}))}const a=prompt("MBIDs of RGs which should be added as parts of the series:");a&&(async e=>{for(let a of e){const e=await t(a),r=e.name.match(/\d+/)?.[0];i({target:e,linkTypeID:742,attributes:n({type:{gid:"a59c5830-5ec7-38fe-9a21-c7ea54f6650a"},text_value:r??""})})}})(Array.from(a.matchAll(/[0-9a-f-]{36}/gm),t=>t[0]))})();
  • Changes the date for all release events of a release according to the user's input.
  • Useful to correct the dates for digital media releases with lots of release events which are using the wrong first release date of the release group.
javascript:(()=>{function e(e,t){$("input.partial-date-"+e).val(t).trigger("change")}const t=prompt("Date for all release events (YYYY-MM-DD):");if(null!==t){const[,a,n,l]=/(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?/.exec(t)||[];((t,a,n)=>{e("year",t),e("month",a),e("day",n)})(a,n,l)}})();
  • Clears medium titles if they are redundant and contain only the medium format and position.
  • Adds a link to the relevant guideline to the edit note.
javascript:(()=>{function e(e,t,i=new Event("change")){e.value=t,e.dispatchEvent(i)}((e,t=document)=>t.querySelectorAll(e))("input[id^=medium-title]").forEach(t=>e(t,t.value.replace(/^(Cassette|CD|Dis[ck]|DVD|SACD|Vinyl)\s*\d+/i,"").trim()));const t=document.getElementById("edit-note-text");e(t,"Clear redundant medium titles, see https://musicbrainz.org/doc/Style/Release#Medium_title\n"+t.value)})();
  • Detects and fills the image types and comment of all pending uploads using their filenames.
  • Treats filename parts in parentheses as image comments.
javascript:(()=>{function t(t,e=document){return e.querySelector(t)}function e(t,e=document){return e.querySelectorAll(t)}const n='ul.cover-art-type-checkboxes input[type="checkbox"]';(({additionalTypes:c=[],commentPattern:o}={})=>{const a=e('tbody[data-bind="foreach: files_to_upload"] > tr'),r={};e(n,a[0]).forEach(t=>{t.parentElement.textContent.trim().toLowerCase().split("/").forEach(e=>r[e]=t.value)});const i=RegExp(String.raw`(?<=\W|_|^)(${Object.keys(r).join("|")})(?=\W|_|$)`,"gi");a.forEach(a=>{const l=t('.file-info span[data-bind="text: name"]',a).textContent,s=Array.from(l.matchAll(i),t=>t[0]);if(c&&s.push(...c),s.length&&((t,c=[])=>{e(n,t).forEach(t=>{c.includes(t.value)&&(t.checked=!0,t.dispatchEvent(new Event("click")))})})(a,s.map(t=>r[t.toLowerCase()])),o){const e=l.match(o);e&&((e,n)=>{const c=t("input.comment",e);c.value=n,c.dispatchEvent(new Event("change"))})(a,e[0])}})})({commentPattern:/(?<=\().+?(?=\))/})})();
  • Renames all tracks using their absolute track number and a customizable prefix (which can be empty).
  • Useful to number the parts of an audiobook without chapters and other releases with untitled tracks.
  • Asks the user to input a numbering prefix which can optionally be preceded by flags:
    • Append the number (including the given prefix) to the current titles: +
    • Pad numbers with leading zeros to the same length: _
    • Example: +_, Part renames track 27/143 "Title" to "Title, Part 027"
javascript:(()=>{const e=prompt("Numbering prefix, preceded by flags:\n+ append to current titles\n_ pad numbers","Part ");if(null!==e){let[,t,n]=e.match(/^([+_]*)(.*)/);t={append:t.includes("+"),padNumbers:t.includes("_")},((e="",t={})=>{let n=$("input.track-name");const r=n.length.toString().length,a=new Intl.NumberFormat("en",{minimumIntegerDigits:r});n.each((n,r)=>{let l=n+1;t.padNumbers&&(l=a.format(l));let p=e+l;t.append&&(p=(r.value+p).replace(/([.!?]),/,"$1")),$(r).val(p)}).trigger("change")})(n,t)}})();
  • Expands all collapsed mediums in the release editor, useful for large releases.
javascript:void $(".expand-medium").trigger("click");
  • Guesses the series name from the name of the currently edited entity and adds a relationship.
  • Tries to extract the series number from the entity name to use it as relationship attribute.
  • Currently limited to release groups, both via their edit pages and via the release relationship editor.
javascript:(()=>{function t(t){return new Promise(e=>setTimeout(e,t))}(async e=>{const i=document.querySelector("h1 bdi").textContent.match(/(.+?)(?: (\d+))?:/);if(!i)return;const a=MB.relationshipEditor.state.entity;(async({source:e=MB.relationshipEditor.state.entity,target:i,targetType:a,linkTypeId:o,attributes:r,batchSelection:s=!1}={})=>{const n="string"==typeof i;var p,c;if(i&&!n&&(a=i.entityType),MB.relationshipEditor.dispatch({type:"update-dialog-location",location:{source:e,batchSelection:s}}),await(p=()=>!!MB.relationshipEditor.relationshipDialogDispatch,new Promise(async e=>{for(;!1===p();)await t(1);e()})),a&&MB.relationshipEditor.relationshipDialogDispatch({type:"update-target-type",source:e,targetType:a}),o){const i=await(async(e,{retries:i=10,wait:a=0}={})=>{do{const i=await e();if(void 0!==i)return i;a&&await t(a)}while(i--)})(()=>MB.relationshipEditor.relationshipDialogState.linkType.autocomplete.items.find(t=>t.id==o),{wait:10});i&&MB.relationshipEditor.relationshipDialogDispatch({type:"update-link-type",source:e,action:{type:"update-autocomplete",source:e,action:{type:"select-item",item:i}}})}r&&(t=>{MB.relationshipEditor.relationshipDialogDispatch({type:"set-attributes",attributes:t})})(r),i&&((n?[{type:"type-value",value:i},{type:"search-after-timeout",searchTerm:i}]:[{type:"select-item",item:(c=i,{type:"option",id:c.id,name:c.name,entity:c})}]).forEach(t=>{MB.relationshipEditor.relationshipDialogDispatch({type:"update-target-entity",source:e,action:{type:"update-autocomplete",source:e,action:t}})}),n&&((t,e=document)=>e.querySelector(t))("input.relationship-target").focus())})({source:a.releaseGroup??a,target:i[1],targetType:"series",linkTypeId:742,attributes:[{type:{gid:"a59c5830-5ec7-38fe-9a21-c7ea54f6650a"},text_value:i[2]}]})})()})();
javascript:(()=>{const a=location.pathname.match(/release\/([0-9a-f-]{36})/)?.[1];(a=>{a&&open("https://magicisrc.kepstin.ca?mbid="+a)})(a)})();
  • Removes all release events except for the first one and changes its country to [Worldwide].
  • Allows to replace an exhaustive list of release countries/events with a single release event.
javascript:$(".remove-release-event:not(:first)").trigger("click"),void $("#country-0").val(240).trigger("change");
  • Relates the currently edited entity to multiple entities given by their MBIDs.
  • Uses the selected relationship type of the currently active relationship dialog.
javascript:(()=>{async function t(t){return(await fetch("/ws/js/entity/"+t)).json()}const e={_lineage:[],_original:null,_status:1,attributes:null,begin_date:null,editsPending:!1,end_date:null,ended:!1,entity0_credit:"",entity1_credit:"",id:null,linkOrder:0,linkTypeID:null};function i({source:t=MB.relationshipEditor.state.entity,target:i,batchSelectionCount:n=null,...a}){const o=((t,e,i=!1)=>t===e?i:t>e)(t.entityType,i.entityType,a.backward??!1);MB.relationshipEditor.dispatch({type:"update-relationship-state",sourceEntity:t,batchSelectionCount:n,creditsToChangeForSource:"",creditsToChangeForTarget:"",newRelationshipState:{...e,entity0:o?i:t,entity1:o?t:i,id:MB.relationshipEditor.getRelationshipStateId(),...a},oldRelationshipState:null})}const n=prompt("MBIDs of entities which should be related to this entity:");if(n){const e=Array.from(n.matchAll(/[0-9a-f-]{36}/gm),t=>t[0]),a=MB.relationshipEditor.relationshipDialogState;a&&(async(e,n,a=!1)=>{for(let o of e)i({target:await t(o),linkTypeID:n,backward:a})})(e,a.linkType.autocomplete.selectedItem.entity.id,a.backward)}})();
  • Shows all countries in which the currently visited Qobuz release is available.
javascript:(()=>{const e=Array.from(document.querySelectorAll("head > link[rel=alternate]")).map(e=>e.hreflang).map(e=>e.split("-")[1]).filter((e,l,r)=>e&&r.indexOf(e)===l);alert(`Available in ${e.length} countries\n${e.sort().join(", ")}`)})();
  • Views the API response for the currently visited Discogs entity (in a new tab).
javascript:(()=>{const s=window.location.href.match(/(artist|label|master|release)\/(\d+)/)?.slice(1);s&&open(((s,e)=>`https://api.discogs.com/${s}s/${e}`)(...s))})();

Development

Running npm run build compiles all userscripts and all bookmarklets before it generates an updated version of README.md. Before you can run this command you have to ensure that you have setup Node.js and have installed the dependencies of the build script via npm install.

Node.js Package

Do you want to create your own userscript or bookmarklet project for MusicBrainz without having to rewrite everything from scratch?

Have a look at my userscript bundler tools which are used to build the userscripts, bookmarklets and the README in this repository.

You can also reuse code from this repository by installing it as a dependency of your own Node.js project: npm install kellnerd/musicbrainz-scripts

The package gives you access to all the MusicBrainz specific modules under src except for the main modules of the bookmarklets and userscripts themselves.

The primary entry point of the @kellnerd/musicbrainz-scripts package is index.js which provides import shortcuts for stable, potentially useful pieces of code from src/.

  • Shortcut usage: import { buildEditNote } from '@kellnerd/musicbrainz-scripts';

  • Full specifier: import { buildEditNote } from '@kellnerd/musicbrainz-scripts/src/editNote.js';

musicbrainz-scripts's People

Contributors

jesus2099 avatar kellnerd avatar ropdebee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

uroesch zabe40

musicbrainz-scripts's Issues

Track Range Parser/Renamer

  • Rename multiple tracks based on an input like "01. - 05. Title" to "01. Title, Part 1" ... "05. Title, Part 5"
  • Custom number prefix (default to ", Part ", automatic language detection?)
  • Detect and number parts of consecutive tracks with the same title
  • Strip existing part numbers at the end of titles
  • Allow absolute track numbers or track numbers with medium number prefixes
  • Support multi-level hierarchies: "01. - 10. Part I, 04. - 07. Chapter 2" results in "06. Part I: Chapter 2, Part 3"
  • Allow negative numbers to count tracks from the end of the medium/release
  • Customizable line parser presets (e.g. %start%. - %end%. %title% [- %artist%], square brackets to mark optional parts)

Detect Cover Art Types

Extract cover art types and comments from filenames during upload to the CAA.

  • Detect all possible cover art types which are contained in the filename /\b(front|booklet|etc)\b/gi
  • Use text in rounded brackets as image comment
  • Make image comment extraction customizable
  • Allow the user to specify additional types which should be selected for all uploads (e.g. Raw or Booklet)
  • Suggest to fill image comment with "page x" if there are multiple images of type booklet
    • Allow adaption of the numbering pattern with prefix (e.g. "page "), first page number (e.g. 2), step (e.g. 2) and joinphrase (e.g. " & "), which results in "page 2 & 3", "page 4 & 5" etc.
    • Skip this step if the commments are already filled (or append/prefix?)

Migrate from ambient types to explicit type imports

Ambient type declarations are no longer visible if you try to import code from this package into another project. Using explicit type imports in the affected JSDoc type annotations should fix this issue.

Parser fails to handle multi-line copyright input

Just now when I tried the following, only the phonographic copyright was added:
© «2017 The Media Champ»
℗ «2003 The Media Champ»

It was working before, but I think it's because of the cache. I had another release that had the same label, but only a phonographic copyright line and I had to do a search. When I entered this, it didn't do a search and just added this as a phonographic copyright and ignored the copyright line entirely. I like the fact that it just adds the label once you've found it before, but obviously, this wasn't intended.

Originally posted by @tigerman325 in ROpdebee/mb-userscripts#77 (comment)

Greasemonkey compatibility

The voice actor userscript does not work with GM because it requires access to the MB global. Also, the script still contains a few jQuery references which had also broken the punctuation userscript in GM.

I should replace all remaining usages of jQuery and create a utility function to access MB and check all existing scripts again to see if they are working with GM then.

  • Replace jQuery with native DOM utilities
  • Provide save access to MB and other global MBS variables (GM context)

Batch-edit entities

Collection of ideas for my Batch-edit release groups userscript.

Please be aware that I do not recommend you to use the script in its current version because the usage is not self-explanatory and it is possible to cause a lot of damage with it!

Overall goal: Extend the script from release groups to (all) other entities, especially releases

Unstructured notes

  • Rate limiter (requests per second and/or pending requests)
  • Safely extract edit source data for all entity types. Attention, the embedding has been changed on test.mb.org! (using ws/js for simplicity and compatibility with *.mb.org)
  • Extract error messages from the asynchronously fetched result pages and display them
  • Abort unnecessary page loads after redirects (for successful edits)
  • Search and replace with RegEx and/or conditions (e.g. language == eng => script = latin)
  • Validate edit data and preview non-trivial changes
  • Select-menu and textbox based UI
    • Select for Field & Action (Set to, Condition, Search & Replace), Input for Search/Condition & Replace/Value
    • Restrict values for certain fields with select (e.g. RG types, multi-select for secondary types)
    • Button to add/remove actions/conditions
    • Allow JSON for advanced fields (e.g. artist credits, arrays) until there is a better solution
  • Hidden feature: Code injection, e.g. (data) => (data.name + data.comment), using eval() or safer alternatives?
  • Automatically generate a description for the edit note ("Set x to y if z", MB Batch-edit 2021.m.d on mb.org/artist/mbid)
  • Propagate recording name to selected tracks (make name of current entity available as variable?)
    • Related idea: Use recording titles as track titles (from inside the release editor)

Adapt scripts to the new React relationship editors

MusicBrainz' new React relationship editor is currently in beta testing and introduced lots of breaking changes with regard to the functionality which is exposed to browser scripts.
This issue tracks the features (which have to be reimplemented) and other steps which are required to make my userscripts and bookmarklets work again.
The code and the built userscripts (working with both the old and the new relationship editor!) can already be found in the main branch. Updated versions of my bookmarklets can be found in my beta branch currently, the old versions are still available in the main branch.

  • Create and prefill relationship dialogs
    • Target entity input & trigger autocomplete
    • Autofocus the target entity input / first search result
    • Link/Relationship type
    • Credited name
    • Date period
    • Relationship direction (not needed and tested so far)
    • Attributes (vocals, part of series) (did not work before metabrainz/musicbrainz-server#2733)
  • Wait for a dialog to be closed and return the selected target entity
  • Create relationships automatically (without a visible dialog)
    • Target entity
    • Link/Relationship type
    • Credited name
    • Date period
    • Relationship direction (not needed and tested so far)
    • Attributes (vocals, part of series) (finally working as expected)
  • Batch-create recording/work relationships via dialog
  • Batch-create recording/work relationships automatically (instead of using a loop)
  • Wait until React has finished rendering the page (metabrainz/musicbrainz-server#2566)
  • Ensure that the link type options were already refreshed after a change of the target entity type before trying to select one
  • Extract Fetch entity source data from edit pages /ws/js/entity
  • Migrate userscripts to make them work with the old and new relationship editors
    • Parse Copyright Notice
    • Voice Actor Credits
    • Batch‐edit release groups (has its own branch, requires updated source data extraction)
  • Update bookmarklets to make them work with the new relationship editors only
    • Batch Add Parts Of Series
    • Guess Series Relationship
    • Relate This Entity To Multiple MBID
  • Convert flow type definitions to TS
  • Make use of the new /ws/js/type-info endpoint (metabrainz/musicbrainz-server@29627fd) in the future? MB.linkedEntities might also be sufficient.

After deployment of the React relationship editors:

  • Delete legacy code and type definitions
  • Drop "Voice Actor" bookmarklet (no longer useful with the more powerful new rel editor)
  • Drop "Parse Copyright Notice" bookmarklet (already required duplicated code before in order to not grow too large, the new React code makes this even worse)
  • Merge beta bookmarklets into main

Tracklist/Title Transformer

  • Create and store custom search & replace rules
  • Group them into rulesets and run these sets on all kinds of input fields, especially track titles

"John J. Mellencamp" label wrongly "Credited as: John J"

Given the back scan at https://i.discogs.com/xcUK2GTKqWV14LwCuk6aXlACij8_7bOgCTP_Lw3X3nc/rs:fit/g:sm/q:90/h:466/w:600/czM6Ly9kaXNjb2dz/LWltYWdlcy9SLTIx/ODM0MDMxLTE2NDI4/MDI0ODUtODk2OS5q/cGVn.jpeg for release https://musicbrainz.org/release/ff1b1be9-9e3a-41c2-aecf-ba65c3516212 there is the following credit:

℗© 2021 John J. Mellencamp, under exclusive license to Republic Records, a division of UMG Recordings, Inc.

which fails at the "dot" as you can see in the following screenshot:

image

The label can be found here https://musicbrainz.org/label/0de712ce-8c53-48bb-962d-51c8351ca75e

Copyright parser edge case

While filling in copyrights for this release today, the copyright parser handled the © credit without a problem, but it doesn't seem to like the ℗ credit:
℗ «2024 Living,Dining&kitchen Records»

I was hoping to have it parse this as one complete label entry (for me to match with this label), but it only seems to pick up the Living part alone.

I don't know if there's a way to adjust the parser to handle this in a way that wouldn't negatively affect the function of the parser for more normal cases, but if not, I'm hoping that you might be able to help me figure out a way to make adjustments even just for my personal copy.

I've confirmed that this occurs in the latest version of the parser userscript, v2024.7.1.

Wrong Unicode conversion for "dash within numbers" and "range of numbers"

I tried the following conversion in an annotation field with the "Guess Unicode Punctuation" script:

Before conversion (all three lines use hyphen minus (U0012) from the standard keyboard)

Figure Dash (U2012) Used as a dash within numbers (e.g. 555-1212).
En Dash (U2013) Indicates a range of numbers (e.g. 1989-90).
Hyphen (U2010) Joins words and syllables of a word (e.g. co-operate) and used within dates (e.g. 2022-01-01 or 2021-31)

After conversion

Figure Dash (U2012) Used as a dash within numbers (e.g. 555–1212). actual result: U2013 expected result: U2012
En Dash (U2013) Indicates a range of numbers (e.g. 1989‐90). actual result: U2010 expected result: U2013
Hyphen (U2010) Joins words and syllables of a word (e.g. co‐operate) and used within dates (e.g. 2022‐01‐01 or 2021‐31) actual result: U2010

So according to https://wiki.musicbrainz.org/User:Jacobbrett/English_Punctuation_Guide the first two lines seem to be wrong after conversion. Is this a supported case by the script ?

Punctuation: Support artist credits

It would be nice if the Punctuation script/bookmarklet could support artist credits, both on the release editor and in the artist credit editor (/artist/<gid>/credit/<id>/edit). I've added an example in the test.MB release.

There's about 4.8k unique artist credits with " in their name, 31k unique artist credits with ', 70k with -, and 341 with .... If the script were able to support artist credits, that could save us quite some time and keystrokes cleaning those up.

When HYPHEN-MINUS is on the extremity of a word, it should not be turned into HYPHEN

Hello @kellnerd,

It happens to me that I have to manually type EN DASH instead of HYPHEN-MINUS that have been turned into HYPHEN.
It must be difficult to handle all cases.

I think a HYPHEN-MINUS should be replaced to HYPHEN only when it is surrounded by \S.
Otherwise it's used like parenthesis and should be a DASH (EN DASH more than EM DASH, because of its length proximity with HYPHEN-MINUS): https://musicbrainz.org/edit/86608589 (manual)

But that's not that easy.
With some CJK tracklists, there may not always be spaces around those DASH that are used like parenthesis.
But we cannot guess everything.

Credit parser and importer

Collection of ideas to combine features of the Voice Actor Credits and Parse Copyright Notice userscripts and enhance it to be a general purpose credit parser and importer.

Unstructured notes

  • Parse release level credits from a textarea input
  • Use OCR (maybe tesseract.js) for (booklet) images from the CAA or an URL to fill the textarea
  • Use role descriptions to guess relationship types
  • Customizable line parser presets (e.g. %role%: %artist% [(%date%)], square brackets to mark optional parts)
  • Create a custom entity name to MBID mapping for each user (names are usually unambiguous then) and cache it
    • CTRL click to circumvent mapping cache
    • SHIFT click to force artist instead of label search (copyrights)
  • Import credits from Discogs and other sources
    • Import voice actor credits from Discogs
    • Cache Discogs to MB entity mappings
    • Suggest to link new matches (seed Discogs link for MB artist edit page) to improve mappings
    • Map Discogs roles to MB relationship types and attributes
      • Let the user select the correct type for unknown roles, cache it and suggest to share the new mapping data on GH?
  • Place UI before release relationships, checkbox to auto-focus (no unnecessary scrolling)
  • Checkbox "Auto-parse (on paste)"
  • Checkbox "Track level credits" to (un)select all recordings and works
  • Checkbox "Add release relationships" (if appropriate) in order to be able to add only track level rels
  • Checkbox "Use credited names"?
  • Clean up pasted credit lines before adding them to the edit note (trim, replace tabs by dashes or similar)

Punctuation: Incorrect substitutions at end of words on non-Latin titles

I've added a new medium to the test.MB release to illustrate. I haven't looked into the regexes, but I guess it's not recognising Greek script as word characters, and therefore matches a ‘’ pair instead of two separate s.

Not sure whether this is straightforward to fix. If it's not, then feel free to just close this with a wontfix, as this is pretty rare. A quick replica DB query gives maybe 15 releases with Greek script whose title might be affected by this bug.

Regular expression look behind not handled in Firefox 68

It will most probably be a won't fix because I am in a niche use-case, but as it took me much trouble to pin point why the unicode punctuation user script does not work in Firefox for Android 68 (the last version to support user scripts):

Regex lookbehind (?<= and negative lookbehind (?<! is not supported before Firefox 78.

Some tr[ai]cks:

Purpose of duplicating Copyright information in the Edit Text

Hello there!

I come here with a question: in the parseCopyrightNotice.user.js when creating an edit what's the point of duplicating the copyright information in the edit comment itself? It seems redundant to me and I pointed this out in one of the edits, where the editor directed me here.

I wonder if this information can be dropped from the Edit Comment as this duplication (unless there's a reason for it) just pollutes the database.

Cheers!

Adding recording relationships is broken

Since the new changes today (2/28/2023), it no longer is adding the labels to the individual recordings when the boxes are checked. Still works fine on the release.

Trim whitespace, replace bullets

Great work!
I love how you condensed the meat into regexp transformationRules.

What do you think about adding

  • trimming of whitespace (leading, trailing, extra)
  • replacing embedded bullets with middle dots (interpuncts)

?

Problem recognizing "℗ 2012 & © 2017 ..."

Given the following credit:

℗ 2012 & © 2017 Casino Records Entertainment. Distributed by The Family Affair Company.

I get

image

I would expect the label filled in with "Casino Records Entertainment" ...
Even if I choose "Casino Records Entertainment" from the pull-down list I end up with:

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.