Greasy Fork is available in English.

Audible - MAM Lookup

Creates a button to generate a search on MyAnonaMouse (MAM) based on the author(s) and title from the Audible page.

// ==UserScript==
// @name         Audible - MAM Lookup
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  Creates a button to generate a search on MyAnonaMouse (MAM) based on the author(s) and title from the Audible page.
// @homepage     https://greasyfork.org/en/scripts/512166-audible-mam-lookup
// @include      https://www.audible.*/pd/*
// @include      https://www.audible.*/ac/*
// @icon         https://ptpimg.me/8477sm.png
// @grant        none
// @license      MIT
// ==/UserScript==
(function() {
    'use strict';
    const FORMATS = ['EPUB', 'M4B'];
    const BUTTON_TEXT = "🔍 MAM";

    console.log('MAM Lookup script starting...');

    function cleanName(name) {
        const titlesToRemove = new RegExp(`\\b(${[
            "PhD", "MD", "JD", "MBA", "MA", "MS", "MSc", "MFA", "MEd", "MPH", "LLM", "DDS", "DVM", "EdD", "PsyD", "ThD", "DO",
            "PharmD", "DSc", "DBA", "RN", "CPA", "Esq.", "LCSW", "PE", "AIA", "FAIA", "CSP", "CFP", "Jr.", "Sr.",
            "I", "II", "III", "IV", "Dr.", "Mr.", "Mrs.", "Ms.", "Prof.", "Rev.", "Fr.", "Sr.", "Capt.", "Col.",
            "Gen.", "Lt.", "Cmdr.", "Adm.", "Sir", "Dame", "Hon.", "Amb.", "Gov.", "Sen.", "Rep.", "BSN", "MSN", "RN", "MS", "MN"
        ].join('|')})\\b`, 'gi');
        return name.replace(titlesToRemove, '').replace(/\s+/g, ' ').trim();
    }

    function getAuthors() {
        // Try different possible author selectors
        const authorSelectors = [
            '.authorLabel > a',                    // English sites
            '.author-data-item > a',              // Alternative format
            '.authorLabel a',                      // Less specific
            'a[data-testid*="author"]',           // Using test IDs
            '.bc-section-author-contributor a',    // Another possible format
            'a[href*="/author/"]'                 // Generic author link
        ];

        // Use a Set to store unique author names
        const uniqueAuthors = new Set();

        for (const selector of authorSelectors) {
            const elements = document.querySelectorAll(selector);
            if (elements.length > 0) {
                console.log('Found authors using selector:', selector);
                elements.forEach(el => {
                    const cleanedName = cleanName(el.textContent.trim());
                    if (cleanedName) {
                        uniqueAuthors.add(cleanedName);
                    }
                });
                // Break after finding authors with the first successful selector
                break;
            }
        }

        console.log('Unique authors found:', uniqueAuthors);
        return Array.from(uniqueAuthors);
    }

    function getTitle() {
        // Try different possible title selectors
        const titleSelectors = [
            'h1[data-testid="product-title"]',
            'h1.bc-heading',
            'h1',
            '.bc-heading'
        ];

        for (const selector of titleSelectors) {
            const element = document.querySelector(selector);
            if (element) {
                console.log('Found title using selector:', selector);
                return element.textContent.trim();
            }
        }

        console.log('No title found with any selector');
        return '';
    }

    function init() {
        console.log('Checking for buy box...');
        const buyBoxElement = document.querySelector("#adbl-buy-box");
        if (!buyBoxElement) {
            console.log('Buy box not found, retrying in 1 second...');
            setTimeout(init, 1000);
            return;
        }

        console.log('Buy box found, adding button...');
        const buttonHtml = `
            <div class="bc-button-group bc-spacing-top-s1">
                <span class="bc-button bc-button-secondary">
                    <button id="createMAMQueryButton" class="bc-button-text" type="button" tabindex="0">
                        <span class="bc-text bc-button-text-inner bc-size-action-small">${BUTTON_TEXT}</span>
                    </button>
                </span>
            </div>
        `;
        buyBoxElement.insertAdjacentHTML('beforeend', buttonHtml);

        let isClicked = false;
        const button = document.getElementById('createMAMQueryButton');
        if (!button) {
            console.error('Button not found after insertion!');
            return;
        }

        button.addEventListener('click', () => {
            console.log('Button clicked!');
            if (isClicked) {
                console.log('Debouncing - click ignored');
                return;
            }
            isClicked = true;

            const authors = getAuthors();
            const title = getTitle();

            console.log('Authors found:', authors.length);
            console.log('Title found:', title);

            const authorsString = authors.join(' ');
            const cleanedTitle = (title || '').replace(/[.,/#!$%^&*;:{}=\-_`~()]/g, "");

            if (authorsString && cleanedTitle) {
                const query = `${authorsString} ${cleanedTitle} ${FORMATS.join('|')}`;
                const encodedQuery = encodeURIComponent(query);
                const url = `https://www.myanonamouse.net/tor/browse.php?tor%5Btext%5D=${encodedQuery}`;
                console.log('Opening URL:', url);
                window.open(url, '_blank');
            } else {
                console.error('Author or title not found!', {authorsString, cleanedTitle});
            }

            setTimeout(() => {
                isClicked = false;
                console.log('Debounce reset');
            }, 1000);
        });
    }

    // Start the initialization
    init();
})();