Genius MusicBrainz Buttons Has been updated!
Now supports the artist index pages:
If anybody is bored and wants to add a lot of URL relations, this is a pretty good way to do it.
Now supports the artist index pages:
If anybody is bored and wants to add a lot of URL relations, this is a pretty good way to do it.
Maybe I should make a unique jesus2099’s userscripts support thread, like them, instead of having one thread per script, and many missing…
I think I will delete mb. PLAIN TEXT TRACKLIST / mb_PLAIN-TEXT-TRACKLIST 2022.9.26.1.
It has been broken since 2021, and I was able to live without it, thanks to MB’s Track parser, and a few occasional EmEditor conversions.
Made myself with AI a script that you can paste an existing release and it will copy all the recordings in order, very helpful for different languages track lists.
@YoGo some scripts I look at and think - wonder if I can use that?
Then there are scripts like this that takes zero thought and are installed instantly. Perfect. Future me says “Thanks for saving me so much time”. ![]()
[mod: moved from the ‘new userscript’ thread, was in reply to this post. ]
Looking Good. A nice feature I would like to see is when I do a file drop of an image, then tick the boxes as per the name. i.e. “cover.jpg” tick “front”, “back.jpg” tick “back”, “CD.jpg” tick “medium”, “page 2-3.jpg” tick “booklet” and add a comment of “page 2-3”.
If I drag and drop 15 images, then let me drag the order around before hitting upload.
Now that would be a Rolls Royce of fancy features.
Obviously you can also ignore that suggestion… (and I’ll be out of town for a few days so no feedback until I get back).
@IvanDobsky would you mind adding that as issue on Github: Issues · majkinetor/musicbrainz-userscripts · GitHub
I like it.
If I drag and drop 15 images, then let me drag the order around before hitting upload.
That is possible now, better than original which lets you reorder only new stuff and put entire group at specific place among existing covers. Here, you can arrange old and new in any way you want with drag&drop which works with entire groups (right click to select).
Just make sure to Sort by Positionand disable grouping or drag&drop doesn’t work
BTW, @IvanDobsky there is also batch set type so you can quickly resolve that issue even without implicit mapping (which would be even faster though) - select few images with rightclick, and in bottom panel set type to all.
This looks cool…
1.) Could you add an “Original” button on the lower right side (like what’s your Apollo Editor script is doing) to quickly switch to the original MB view (I really like this feature also with Apollo Editor)
2.) How do I set the same comment on multiple images ?
Sure @vzell. Batch comment incoming.
@ majkinetor Thx.
Is it only me but selecting covers and pressing the download link does nothing for me (also no errors in the browser console)
Could you add another view more or less what my “Batch edit cover art script” does so that the cover art images are
shown below each other and the meta information beside it.
It would be easier to read very long comments and also see all the different types at a glance without clicking every
“Front+” button (see screenshot) if more than one type is associated with an image.
See the following screenshot:
[mod edit: moved from the new userscript thread, was in response to @dvirtz Event Seeder update post here]
Nice, for the sub event part: Can you also seed the name with “pattern” appended?
“Parent Event Name” → "Main Event Name, "
“Parent Event Name, [WeekdayName/Day X]” → "Main Event Name, [Weekdayname/Day X]: "
Examples:
Vainstream Rockfest, Saturday: Main Stage
Vainstream Rockfest, Day 2: Main Stage
And also the type of the parent event.
PS: Since I have seen this to late, I had vibe coded a version (But I think yours is better and maintained):
// ==UserScript==
// @name MusicBrainz - Copy Event
// @namespace https://musicbrainz.org/
// @version 0.1
// @description Create a new event from an existing event using seeding
// @match https://musicbrainz.org/event/*
// @grant GM_openInTab
// ==/UserScript==
(function () {
'use strict';
if (!location.pathname.match(/^\/event\/[a-f0-9-]+/)) {
return;
}
function addSidebarButton() {
// Find sidebar section titled "Editing"
const headings = [...document.querySelectorAll('h2')];
const editingHeading = headings.find(
h => h.textContent.trim() === 'Editing'
);
if (!editingHeading) {
console.log('Copy Event: Editing section not found');
return;
}
// MusicBrainz sidebar layout:
// <h2>Editing</h2>
// <ul>...</ul>
const list = editingHeading.nextElementSibling;
if (!list || list.tagName !== 'UL') {
console.log('Copy Event: Editing list not found');
return;
}
const li = document.createElement('li');
const link = document.createElement('a');
link.href = '#';
link.textContent = 'Copy Event';
link.addEventListener('click', async (e) => {
e.preventDefault();
const opts = await showDialog();
if (!opts) return;
try {
const mbid =
location.pathname.match(
/\/event\/([a-f0-9-]+)/
)[1];
const data = await fetch(
`/ws/2/event/${mbid}?fmt=json&inc=artist-rels+event-rels+place-rels+series-rels`
).then(r => r.json());
const seed = buildSeed(data, opts);
GM_openInTab(seed, {
active: true
});
} catch (err) {
console.error(err);
alert(err.message);
}
});
li.appendChild(link);
list.appendChild(li);
}
function showDialog() {
const overlay = document.createElement('div');
overlay.style = `
position:fixed;
inset:0;
background:rgba(0,0,0,.35);
z-index:9999;
`;
const box = document.createElement('div');
box.style = `
background:white;
width:320px;
padding:16px;
border-radius:6px;
margin:100px auto;
`;
box.innerHTML = `
<h3>Copy Event</h3>
<label>
<input type="checkbox" id="series" checked>
Series relations
</label><br>
<label>
<input type="checkbox" id="place" checked>
Place relations
</label><br>
<label>
<input type="checkbox" id="artist">
Artist relations
</label><br>
<label>
<input type="checkbox" id="event">
Event relations
</label>
<br><br>
<button id="copy">Create</button>
<button id="cancel">Cancel</button>
`;
overlay.appendChild(box);
document.body.appendChild(overlay);
return new Promise(resolve => {
box.querySelector('#cancel').onclick = () => {
overlay.remove();
resolve(null);
};
box.querySelector('#copy').onclick = () => {
const result = {
series: box.querySelector('#series').checked,
place: box.querySelector('#place').checked,
artist: box.querySelector('#artist').checked,
event: box.querySelector('#event').checked
};
overlay.remove();
resolve(result);
};
});
}
const EVENT_TYPE_IDS = {
'Concert': 1,
'Festival': 2,
'Launch event': 3,
'Convention/Expo': 4,
'Masterclass/Clinic': 5,
'Stage performance': 6,
'Award ceremony': 7,
'Competition': 40
};
function buildSeed(event, opts) {
const params = new URLSearchParams();
// Basic fields
params.set(
'edit-event.name',
event.name || ''
);
if (event.disambiguation) {
params.set(
'edit-event.comment',
event.disambiguation
);
}
// Event type (MusicBrainz seed expects integer enum)
if (event.type) {
const typeId =
EVENT_TYPE_IDS[event.type];
if (typeId) {
params.set(
'edit-event.type_id',
String(typeId)
);
} else {
console.warn(
'Unknown event type:',
event.type
);
}
}
// Dates
const span = event['life-span'];
if (span?.begin) {
copyDate(
params,
'edit-event.period.begin_date',
span.begin
);
}
if (span?.end) {
copyDate(
params,
'edit-event.period.end_date',
span.end
);
}
// Optional edit note
params.set(
'edit-event.edit_note',
'Seed was automatically created'
);
// Relations
let relIndex = 0;
for (const rel of event.relations || []) {
if (
(rel.target_type === 'series' && !opts.series) ||
(rel.target_type === 'place' && !opts.place) ||
(rel.target_type === 'artist' && !opts.artist) ||
(rel.target_type === 'event' && !opts.event)
) {
continue;
}
addRelationship(
params,
rel,
relIndex++
);
}
return (
'https://musicbrainz.org/event/create?' +
params.toString()
);
}
function copyDate(
params,
prefix,
date
) {
const parts = date.split('-');
params.set(
`${prefix}.year`,
parts[0] || ''
);
params.set(
`${prefix}.month`,
parts[1] || ''
);
params.set(
`${prefix}.day`,
parts[2] || ''
);
}
function addRelationship(
params,
rel,
index
) {
const base =
`rels.${index}`;
// Relation type MBID
if (rel['type-id']) {
params.set(
`${base}.type`,
rel['type-id']
);
}
// Target entity lookup
const targetType =
rel['target-type'];
const target =
targetType
? rel[targetType]
: null;
if (!target?.id) {
console.warn(
'Missing target id',
rel
);
return;
}
params.set(
`${base}.target`,
target.id
);
// backward relations
if (rel.direction === 'backward') {
params.set(
`${base}.backward`,
'1'
);
}
// optional relation dates
if (rel.begin) {
copyDate(
params,
`${base}.period.begin_date`,
rel.begin
);
}
if (rel.end) {
copyDate(
params,
`${base}.period.end_date`,
rel.end
);
}
if (rel.ended) {
params.set(
`${base}.period.ended`,
'1'
);
}
}
addSidebarButton();
})();
It sounds like the festival scaffolding script is what you want: A new MusicBrainz user script was released - #218 by dvirtz
Oh seems like it is somehow what I want.
I tried it and I have some suggestions:
And I have tried to create the stage sub events, but it just created one single stage sub event (with relation to the main place) per day sub event. I would expect that it creates a stage sub event for each sub place of the main place.
Thanks for the feedback @Relaxo5!
Just create seed URLs in new tabs instead of directly creating
I’ll add this as an option. Not sure what the default should be.
I think there developed an consensus of naming the day sub events with the Weekday names. Would it be fine for you to use that as default?
That’s not what the guidelines say.
set the event type to the type of the parent event.
I don’t think one day of a festival is a festival.
I would expect that it creates a stage sub event for each sub place of the main place.
Currently you have to add all stages manually but it’s a good suggestion.
Created scaffold-festival-days improvements · Issue #201 · dvirtz/musicbrainz-scripts · GitHub
[mod edit: moved from the new userscript thread, was in response to @majkinetor Scribe release post here]
Any plans on porting it to Linux? Would love to have it as I use track parser a lot to edit the tracklists.
It was cross platform initially. I will see what I can do now.
U should be able to use it in cross platform way now.
See Cross-platform helper · Issue #360 · majkinetor/musicbrainz-userscripts · GitHub
I tested it and it works. Thank you very much!
I think it is more save to have it default to create seeds. I just wanted to try your script on the next best event and was totally surpised that the edits got applied immediately.
Oh, I think you are right, the guidelines never mention the weekday names. I have found the disussion: Festival day 0 - #20 by Relaxo5
And I created a poll there.
Seems like it was just me for myself who came to a conclusion later.
That may be true, but it is not very common to leave the type empty. I think it is nitpicking. As long as we do not have the type “Festival day sub event” or something like that, “Festival” is the best information we can give.