// ==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();
})();