Last active
July 10, 2019 04:20
-
-
Save Sasquire/684ba83c22137e08a4b1f81a328b6f2f to your computer and use it in GitHub Desktop.
A quick something to compare posts with an elo rating to try and find what your favorite is.
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
// ==UserScript== | |
// @name e621 elo compare | |
// @namespace http://tampermonkey.net/ | |
// @version 1.00001 | |
// @description try to take over the world! | |
// @author Sasquire | |
// @match https://e621.net/extensions/post_elo | |
// @match http://e621.net/extensions/post_elo | |
// @grant GM_addStyle | |
// ==/UserScript== | |
const starting_elo = 1000; | |
const elo_k = 30; | |
// Clears the page | |
(() => { | |
function clear_node(node){ | |
while(node.children.length > 0){ | |
node.removeChild(node.children[0]); | |
} | |
} | |
function remove_toJSON(){ | |
// This gave me a lot of greif. e621 changes the toJSON | |
// methods and creates not optimal JSON. | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify | |
delete Object.prototype.toJSON; | |
delete Date.prototype.toJSON; | |
delete String.prototype.toJSON; | |
delete Array.prototype.toJSON; | |
delete Number.prototype.toJSON; | |
// Kira I don't know what this did, but it gave me errors. So I removed it. | |
jQuery.event.dispatch = () => ''; | |
} | |
clear_node(document.head); | |
clear_node(document.body); | |
remove_toJSON(); | |
document.body.innerHTML = ` | |
<div id="main"> | |
<div id="header"><button id="export">Export</button></div> | |
<div id="leftpost"></div> | |
<div id="rightpost"></div> | |
</div> | |
`; | |
GM_addStyle(` | |
#main { | |
height: 100vh; | |
display: grid; | |
grid-template-columns: auto 20px auto; | |
grid-template-rows: 75px auto; | |
} | |
#header { | |
grid-column: 1 / 3; | |
grid-rows: 1 / 1; | |
} | |
#leftpost { | |
grid-column: 1 / 1; | |
grid-rows: 2 / 2; | |
} | |
#rightpost { | |
grid-column: 3 / 3; | |
grid-rows: 2 / 2; | |
} | |
#leftpost > *, #rightpost > * { | |
max-width: 90%; | |
max-height: 90%; | |
margin: auto; | |
align-self: center; | |
} | |
`); | |
})(); | |
async function get_all_posts(query){ | |
const posts = {} | |
for(let page = 1; true; page++){ | |
const data = await get_search_results(query, page); | |
data.forEach(e => (e.elo = starting_elo)); | |
data.forEach(e => (e.hit = 0)); | |
data.forEach(e => (posts[e.id] = e)); | |
if(data.length != 320){ | |
console.log('Posts loaded') | |
return posts; | |
} | |
} | |
} | |
async function get_search_results(query, page){ | |
console.log(`Getting page ${page} for [${query}]\nThis could take a while`); | |
const url = new URL('https://e621.net/post/index.json'); | |
url.searchParams.set('tags', query); | |
url.searchParams.set('page', page); | |
url.searchParams.set('limit', 320); | |
const res = await fetch(new Request(url)); | |
const text = await res.text(); | |
if(res.status != 200){ | |
console.log(`Bad status code ${res.status}\n${text}`); | |
throw new Error(`Bad status code ${res.status}\n${text}`); | |
} else { | |
const data = JSON.parse(text); | |
return data; | |
} | |
} | |
function set(id, post){ | |
const golder = document.getElementById(id); | |
// I know its not safe. this is something quick | |
if(post.file_ext == 'webm'){ | |
golder.innerHTML = ` | |
<video | |
poster="${post.sample_url}" | |
id="webm-container" | |
controls | |
loop="true" | |
> | |
<source src="${post.file_url}" type="video/webm" /> | |
</video>`; | |
} else if(post.file_ext == 'swf') { | |
golder.innerHTML = ` | |
<object> | |
<param name="movie" value="${post.file_url}"> | |
<embed | |
type="application/x-shockwave-flash" | |
src="${post.file_url}" | |
allowscriptaccess="never" | |
> | |
</object>`; | |
} else { | |
golder.innerHTML = `<img src="${post.file_url}">`; | |
} | |
} | |
function compare_two(post1, post2){ | |
set('leftpost', post1); | |
set('rightpost', post2); | |
document.getElementById('leftpost').setAttribute('data-id', post1.id); | |
document.getElementById('rightpost').setAttribute('data-id', post2.id); | |
} | |
function do_elo(rating1, rating2, winner){ | |
function probability(r1, r2){ | |
return 1 / (1 + Math.pow(10, (r1 - r2) / 400)); | |
} | |
const p1 = probability(rating2, rating1); // Probability p1 wins | |
const p2 = probability(rating1, rating2); | |
if(winner == 1){ | |
const nr1 = rating1 + elo_k * (1 - p1); | |
const nr2 = rating2 + elo_k * (0 - p2); | |
return [nr1, nr2] | |
} else { | |
const nr1 = rating1 + elo_k * (0 - p1); | |
const nr2 = rating2 + elo_k * (1 - p2); | |
return [nr1, nr2]; | |
} | |
} | |
function select2(posts){ | |
const all_posts = Object.values(posts).sort((a, b) => { | |
const hd = a.hit - b.hit; | |
if(hd != 0){ return hd; } | |
const ed = a.elo - b.elo; | |
if(ed != 0){ return ed; } | |
return Math.random() > 0.5 ? -1 : 1 | |
}); | |
compare_two(all_posts[0], all_posts[1]); | |
} | |
get_all_posts('').then(posts => { | |
select2(posts); | |
document.addEventListener('keydown', e => { | |
if(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Space'].includes(e.key) == false){ return; } | |
const get = id => parseInt(document.getElementById(id).getAttribute('data-id'), 10); | |
const left_id = get('leftpost'); | |
const right_id = get('rightpost'); | |
let r1 = posts[left_id].elo; | |
let r2 = posts[right_id].elo; | |
if(e.key == 'ArrowLeft'){ | |
[r1, r2] = do_elo(r1, r2, 1); | |
} else if(e.key == 'ArrowRight'){ | |
[r1, r2] = do_elo(r1, r2, 2); | |
} else if(e.key == 'ArrowUp'){ | |
// Both win | |
let _ = null; | |
[r1, _] = do_elo(r1, r2, 1); | |
[_, r2] = do_elo(r1, r2, 2); | |
} else if(e.key == 'ArrowDown'){ | |
// Both lose | |
let _ = null; | |
[r1, _] = do_elo(r1, r2, 2); | |
[_, r2] = do_elo(r1, r2, 1); | |
} else if(e.key == 'Space'){ | |
} | |
posts[left_id].elo = r1; | |
posts[right_id].elo = r2; | |
posts[left_id].hit++; | |
posts[right_id].hit++; | |
select2(posts); | |
}); | |
document.getElementById('export').addEventListener('click', () => { | |
console.log(Object.values(posts).map(e => ({ | |
post_id: e.id, | |
elo: e.elo | |
})).map(e => `${e.post_id} ${e.elo}`)) | |
}); | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment