Reveal those Black Market mofos
// ==UserScript==
// @name Mofo Revealer
// @namespace http://tampermonkey.net/
// @version 1.5.2
// @description Reveal those Black Market mofos
// @author You
// @match https://www.vinomofo.com/wines/*
// @match https://www.vinomofo.com/events/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=vinomofo.com
// @require https://code.jquery.com/jquery-3.6.4.min.js
// @grant none
// ==/UserScript==
(function() {
'use strict';
$(() => startup(true));
function productTitleH2 () { return $("h2[class^='Heading__StyledHeading'][class*='OfferHeroCard__StyledHeading']:first"); }
function isProductPage() { return productTitleH2().length == 1};
function startup(loadCached) {
if(loadCached && (staleCache() || !getWines())) {
fetch('https://api.jsonsilo.com/public/5d89a725-be62-469c-8745-37191c281eb6', { method: 'get' })
.then((response) => response.json())
.then((json) => {
json.cacheDate = new Date();
localStorage.setItem("wines", JSON.stringify(json));
startup(false);
})
.catch(function() { localStorage.setItem("wines", JSON.stringify({})); });
return;
} else {
//handle spa page changes
let previousUrl = '';
const observer = new MutationObserver(function(mutations) {
if (location.href !== previousUrl) {
previousUrl = location.href;
setTimeout(() => setWineTitles(1, true), 500);
}
});
const config = {subtree: true, childList: true};
observer.observe(document, config);
setupXMLHttpRequestIntercept();
}
}
function setWineTitles(i, fetchWine) {
if(isProductPage()) {
var wineID = extractWineID($("title").text());
if(wineID && window.location.href.includes(wineID)) {
var wineTitle = getWineTitle(wineID);
if(wineTitle) {
var $h2 = $("h2[class^='Heading__StyledHeading'][class*='OfferHeroCard__StyledHeading']:first");
setWineTitle($h2, wineTitle); //may need to delay with setTimeout
} else if(fetchWine) {
//get wine title from a page-data.json request
var winePageDataURL = window.location.href.replace('www.vinomofo.com/','www.vinomofo.com/page-data/')+'page-data.json';
fetch(winePageDataURL, { method: 'get', mode: 'cors', credentials: 'include' })
.then((response) => response.json())
.then((json) => {
var originalName = json.result.pageContext.offer.sku.wines[0].originalName;
var $h2 = $("h2[class^='Heading__StyledHeading'][class*='OfferHeroCard__StyledHeading']:first");
setWineID(wineID, originalName);
setWineTitle($h2, originalName);
});
}
}
}
//set BM List Titles
$("a:contains('Black Market'),a:contains('#')").each(function() {
var wineID = extractWineID($(this).text());
if(wineID) {
var wineTitle = getWineTitle(wineID);
if(wineTitle)
setWineTitle($(this), wineTitle);
}
});
if(i < 5) //repeat setting titles for a while to deal with slow page loads
setTimeout(() => setWineTitles(i+1, false), i*500);
}
function extractWineID(wineText) {
var textSplit = wineText.split('#')[1];
if(textSplit)
return textSplit.split(' ')[0].trim();
return null;
}
function setWineTitle($target, originalname) {
$target.text(originalname);
}
function staleCache() {
var wines = getWines();
if(!wines || !wines.cacheDate)
return true;
var cacheDate = new Date(wines.cacheDate);
return cacheDate.setDate(cacheDate.getDate() + 1) < new Date();
}
// START Local storage functions
function getWines() {
var wines = localStorage.getItem("wines");
return wines ? JSON.parse(wines) : null;
}
function setWineID(wineID, wineTitle) {
if(!wineID)
return;
var wines = getWines();
wines['_'+wineID.trim()] = wineTitle;
console.log('set wine id \''+wineID.trim() + '\' to \'' + wineTitle + '\'');
localStorage.setItem("wines", JSON.stringify(wines));
}
function getWineTitle(wineID) {
var wines = getWines();
if(!(wines && wineID))
return null;
if(wines['v2_'+wineID.trim()])
return wines['v2_'+wineID.trim()].name;
else
return wines['_'+wineID.trim()];
}
window.findWine = function (search) {
var wines = getWines();
if(!(wines && search))
return null;
for (var key in wines) {
if(key.startsWith('v2_')) {
if(isNaN(search)) {
var wineName = wines[key].name.toLowerCase();
var terms = search.split(" ");
if(terms.every(t => wineName.includes(t.toLowerCase())))
console.log(wines[key].name + ' - '+ window.location.origin + wines[key].path);
} else {
if(key.substr(3) == search) {
console.log(wines[key].name + ' - '+ window.location.origin + wines[key].path);
}
}
}
}
}
// END Local storage functions
//This will listen for calls to page-data.json and see if it can extract wine titles
function setupXMLHttpRequestIntercept() {
const dummySend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function () {
const _onreadystatechange = this.onreadystatechange;
this.onreadystatechange = function () {
if(this.responseURL.endsWith('page-data.json')) {
if (this.readyState === 4) {
if (this.status === 200 || this.status === 1223) {
var j = JSON.parse(this.responseText);
if(j && j.result.pageContext.offer && j.result.pageContext.offer.sku && j.result.pageContext.offer.sku.wines && j.result.pageContext.offer.sku.wines[0]) {
var path = j.path;
var originalName = j.result.pageContext.offer.sku.wines[0].originalName;
var wineID = extractWineID(j.result.pageContext.offer.name);
if(wineID && !getWineTitle(wineID)) {
setWineID(wineID, originalName);
setWineTitle($("a[href='"+path+"']"), originalName);
}
}
}
}
}
if (_onreadystatechange) {
_onreadystatechange.apply(this, arguments);
}
}
dummySend.apply(this, arguments);
}
}
})();