Bandcamp: Show more dates

Shows Bandcamp releases' real "publish date" below the listed release date.

当前为 2025-05-23 提交的版本,查看 最新版本

// ==UserScript==
// @name        Bandcamp: Show more dates
// @namespace   https://musicbrainz.org/user/chaban
// @version     1.0
// @description Shows Bandcamp releases' real "publish date" below the listed release date.
// @tag         ai-created
// @author      w_biggs (~joks), chaban
// @license     MIT
// @match       https://*.bandcamp.com/track/*
// @match       https://*.bandcamp.com/album/*
// @include     /^https?://web\.archive\.org/web/\d+/https?://[^/]+/(?:album|track)/[^/]+\/?$/
// @grant       none
// ==/UserScript==

(function() {
    'use strict';

    /**
     * Formats a date string into a localized string (e.g., "March 12, 2008").
     * Includes validation to ensure the date is valid.
     * @param {string} dateString - The date string to format.
     * @returns {string|null} The formatted date string, or null if input is invalid or date is unparseable.
     */
    function formatDate(dateString) {
        if (!dateString) return null;
        const date = new Date(dateString);
        if (isNaN(date.getTime())) {
            console.warn(`Invalid date string provided: "${dateString}"`);
            return null;
        }
        return date.toLocaleString('en-US', { month: 'long', day: 'numeric', year: 'numeric', timeZone: 'UTC' });
    }

    /**
     * Extracts date information from a script element and displays it in the tralbum-credits div.
     * Handles both 'application/ld+json' and 'data-tralbum' script types.
     * @param {HTMLScriptElement} scriptElement - The script element to process.
     */
    function extractAndDisplayDates(scriptElement) {
        let dates = {};
        let sourceLabel = '';

        if (scriptElement.type === 'application/ld+json') {
            try {
                const jsonld = JSON.parse(scriptElement.innerText);
                dates.published = jsonld?.datePublished;
                dates.modified = jsonld?.dateModified;
                sourceLabel = 'datePublished';
            } catch (e) {
                console.error('Error parsing JSON-LD:', e);
                return;
            }
        } else if (scriptElement.hasAttribute('data-tralbum')) {
            try {
                const tralbumAttr = scriptElement.attributes.getNamedItem('data-tralbum');
                const jsonalbum = JSON.parse(tralbumAttr.textContent);
                dates.published = jsonalbum.current?.publish_date;
                dates.modified = jsonalbum.current?.mod_date;
                dates.new = jsonalbum.current?.new_date;

                const embedAttr = scriptElement.attributes.getNamedItem('data-embed');
                const jsonembed = embedAttr ? JSON.parse(embedAttr.textContent) : null;
                dates.embeddable = typeof jsonembed?.embed_info?.public_embeddable === 'string'
                                   ? jsonembed.embed_info.public_embeddable
                                   : null;
                sourceLabel = 'publish_date';
            } catch (e) {
                console.error('Error parsing data-tralbum or data-embed:', e);
                return;
            }
        } else {
            return;
        }

        const creditsElement = document.querySelector('div.tralbum-credits');
        if (!creditsElement || !dates.published) {
            return;
        }

        const publishDateString = formatDate(dates.published);
        if (!publishDateString) return;

        let dateContent = `published ${publishDateString} (${sourceLabel})`;

        if (dates.modified) {
            const modifiedDateString = formatDate(dates.modified);
            if (modifiedDateString && modifiedDateString !== publishDateString) {
                dateContent += `<br>modified ${modifiedDateString} (mod_date)`;
            }
        }

        if (dates.new) {
            const newDateString = formatDate(dates.new);
            if (newDateString && newDateString !== publishDateString) {
                dateContent += `<br>created ${newDateString} (new_date)`;
            }
        }

        if (dates.embeddable) {
            const embedDateString = formatDate(dates.embeddable);
            if (embedDateString && embedDateString !== publishDateString) {
                dateContent += `<br>embeddable ${embedDateString} (public_embeddable)`;
            }
        }

        const pElement = document.createElement('p');
        const spanElement = document.createElement('span');
        spanElement.innerHTML = dateContent;
        pElement.appendChild(spanElement);

        creditsElement.appendChild(pElement);
    }

    const allRelevantScripts = document.querySelectorAll('script[type="application/ld+json"], script[data-tralbum]');

    allRelevantScripts.forEach(extractAndDisplayDates);

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址