Last active
May 19, 2023 05:10
-
-
Save bradchoate/c83b4b5db9f80abdd2c4d426f9fa2965 to your computer and use it in GitHub Desktop.
MLTSHP Bookmarklet for a random post
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
javascript:(function(){(async()=%3E{let%20e=%22https://mltshp.com/%22;0!==location%3F.href%3F.indexOf(e)%26%26(alert(%22First,%20navigating%20to%20MLTSHP...%20then,%20run%20this%20again!%22),location.href=e);let%20t=%22latestImageSharekey%22,n=localStorage,r=JSON.parse(n.getItem(t)||%22{}%22),i=Date.now(),l=i-864e5;if(r%3F.t%3Cl%26%26(r={}),r%3F.k||await%20fetch(`${e}incoming`).then(e=%3Ee.text()).then(e=%3E{let%20l=new%20DOMParser;r={k:l.parseFromString(e,%22text/html%22).querySelector(%22.inline-meta%20a%22).getAttribute(%22href%22).split(%22/%22)[2],t:i},n.setItem(t,JSON.stringify(r))}),r%3F.k){let%20a=%220123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ%22,g=e=%3E{let%20t=a.length,n=0;for(let%20r=0;r%3Ce.length;r++){let%20i=e.length-r-1,l=a.indexOf(e[r]);n+=l*Math.pow(t,i)}return%20n},h=g(r.k),o=e=%3E{let%20t=a.length,n=%22%22;for(;0!==e;){let[r,i]=[Math.floor(e/t),e%25t];e=r,n=a[i]+n}return%20n};for(;;){let%20s=Math.floor(Math.random()*h),f=o(s),$=`${e}p/${f}`;await%20fetch($).then(e=%3E{200===e.status%26%26(location.href=$)})}}else%20alert(%22Error%20retrieving%20Incoming!%20page.%20Are%20you%20signed%20in%3F%22),location.href=`${e}/sign-in`})();})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Minified using https://www.toptal.com/developers/javascript-minifier | |
// Bookmarkletized using http://jpillora.com/bookmarkleter/ | |
(async () => { | |
// This function returns a URL to a random post on MLTSHP. If | |
// it doesn't, then presumes the user isn't signed in, | |
// in which case the user is sent to the MLTSHP sign in page. | |
const MS = 'https://mltshp.com/'; | |
if (location?.href?.indexOf(MS) !== 0) { | |
// User is not on a MLTSHP page, so any fetch calls made | |
// to the site will fail. | |
alert('First, navigating to MLTSHP... then, run this again!'); | |
location.href = MS; | |
} | |
// Local storage key for saving image share key and timestamp | |
const LSK = 'latestImageSharekey'; | |
// Parse available share key from local storage | |
const ls = localStorage; | |
let sk = JSON.parse(ls.getItem(LSK) || '{}'); | |
const today = Date.now(); | |
// Latest image share key metadata is stored for 24 hours | |
const yesterday = today - 1000 * 60 * 60 * 24; | |
// check for expiration in sk.t (timestamp) | |
if (sk?.t < yesterday) { | |
sk = {}; | |
} | |
// Sharekey metadata isn't available or expired, so fetch | |
// the Incoming! page to determine the latest image. | |
if (!sk?.k) { | |
await fetch(`${MS}incoming`) | |
.then((response) => response.text()) | |
.then((html) => { | |
const parser = new DOMParser(); | |
// We're looking for the link to the first post on | |
// the incoming page, which should be the latest image. | |
// Selector is '.inline-meta a'. The link for that a tag | |
// will look like https://mltshp.com/p/1ABCDEF | |
sk = { | |
k: parser | |
.parseFromString(html, 'text/html') | |
.querySelector('.inline-meta a') | |
.getAttribute('href') | |
.split('/')[2], | |
t: today, | |
}; | |
ls.setItem(LSK, JSON.stringify(sk)); | |
}); | |
} | |
if (sk?.k) { | |
// With a valid sharekey in sk.k, we can decode it to a number, | |
// generate a random number from 1-n, then encode that to create | |
// the URL for the post. | |
const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; | |
const base36decode = (key) => { | |
// base36 alphabet | |
let len = alphabet.length, | |
decoded = 0; | |
// decode the base36 value in key | |
for (let i = 0; i < key.length; i++) { | |
const power = key.length - i - 1; | |
const value = alphabet.indexOf(key[i]); | |
decoded += value * Math.pow(len, power); | |
} | |
return decoded; | |
}; | |
const maxId = base36decode(sk.k); | |
const base36encode = (value) => { | |
let len = alphabet.length, | |
encoded = ''; | |
// encode the random number to base36 and | |
// return the resulting string | |
while (value !== 0) { | |
const [quotient, remainder] = [Math.floor(value / len), value % len]; | |
value = quotient; | |
encoded = alphabet[remainder] + encoded; | |
} | |
return encoded; | |
}; | |
while (true) { | |
// Construct a URL to a random post. The function inlined | |
// below will decode the sharekey in sk.k, generate a random | |
// number from 1 to that number, then encode that number to | |
// create the URL for the post. | |
const randomNum = Math.floor(Math.random() * maxId); | |
const randomKey = base36encode(randomNum); | |
let url = `${MS}p/${randomKey}`; | |
// Attempt to fetch the URL. If it returns a 404, then | |
// the post doesn't exist, so we'll try again. We should | |
// find a valid post before long. | |
await fetch(url).then((response) => { | |
if (response.status === 200) { | |
// Navigate to the post; this terminates the bookmarklet | |
location.href = url; | |
} | |
}); | |
} | |
} else { | |
alert('Error retrieving Incoming! page. Are you signed in?'); | |
location.href = `${MS}/sign-in`; | |
} | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(async()=>{let e="https://mltshp.com/";0!==location?.href?.indexOf(e)&&(alert("First, navigating to MLTSHP... then, run this again!"),location.href=e);let t="latestImageSharekey",n=localStorage,r=JSON.parse(n.getItem(t)||"{}"),i=Date.now(),l=i-864e5;if(r?.t<l&&(r={}),r?.k||await fetch(`${e}incoming`).then(e=>e.text()).then(e=>{let l=new DOMParser;r={k:l.parseFromString(e,"text/html").querySelector(".inline-meta a").getAttribute("href").split("/")[2],t:i},n.setItem(t,JSON.stringify(r))}),r?.k){let a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",g=e=>{let t=a.length,n=0;for(let r=0;r<e.length;r++){let i=e.length-r-1,l=a.indexOf(e[r]);n+=l*Math.pow(t,i)}return n},h=g(r.k),o=e=>{let t=a.length,n="";for(;0!==e;){let[r,i]=[Math.floor(e/t),e%t];e=r,n=a[i]+n}return n};for(;;){let s=Math.floor(Math.random()*h),f=o(s),$=`${e}p/${f}`;await fetch($).then(e=>{200===e.status&&(location.href=$)})}}else alert("Error retrieving Incoming! page. Are you signed in?"),location.href=`${e}/sign-in`})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment