Skip to content

Instantly share code, notes, and snippets.

@bradchoate
Last active May 19, 2023 05:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradchoate/c83b4b5db9f80abdd2c4d426f9fa2965 to your computer and use it in GitHub Desktop.
Save bradchoate/c83b4b5db9f80abdd2c4d426f9fa2965 to your computer and use it in GitHub Desktop.
MLTSHP Bookmarklet for a random post
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`})();})();
// 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`;
}
})();
(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