select / 1337x Top 100 Movies IMDb

// ==UserScript==
// @name         1337x Top 100 Movies IMDb
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Add imdb ratings to 1337x top 100 movies
// @author       s3lect
// @match        https://1337x.to/top-100-movies
// @grant        GM_xmlhttpRequest
// @license      MIT
// @copyright   2020, select (https://openuserjs.org/users/select)
// ==/UserScript==

const apiKey = 'XXXXXX'; // please create your api key at http://www.omdbapi.com/
const movieTitleRexEx = /(www\.[^ ]+ -)?(\[\w+\] )*([^(]*)( \()?(\d{4})[^p]/;
const movie_db = initDatabase();

function getImdbInfo(title, year) {
	return new Promise((resolve, reject) => {
		if (title in movie_db) resolve(movie_db[title]);
		let url = `http://www.omdbapi.com/?apiKey=${apiKey}&i=&t=${encodeURIComponent(title)}`;
		if (year) url += `&y=${year}`;
		GM_xmlhttpRequest({
			method: 'GET',
			url,
			onload: (response) => {
				const data = JSON.parse(response.responseText);
				if (data.Response === 'False') {
					movie_db[title] = false;
					reject();
				} else {
					movie_db[title] = data;
					resolve(data);
				}
				localStorage.movie_db = JSON.stringify(movie_db);
			},
			onerror: () => {
				console.warn('request failed: http://www.omdbapi.com/?t=' + title);
				reject();
			},
		});
	});
}

function initDatabase() {
	const c = localStorage.getItem('movie_db');
	return !c ? {} : JSON.parse(c);
}

async function run() {
	'use strict';
	document.body.innerHTML += `<style>
.lsdfkljsdflkj {display: flex; justify-content: space-between; }
.lsdfkljsdflkj .info { width: 3.1rem; margin-right: 1rem;}
.lsdfkljsdflkj a[href^="/torrent/"] { flex: 1; }
.lsdfkljsdflkj .votes { width: 100%; display: flex; justify-content: space-between;}
.lsdfkljsdflkj .title { display: flex; justify-content: space-between;}
</style>`;

	const tableEntries = [...document.querySelectorAll('.table tbody tr')];
	const entries = await Promise.all(tableEntries.map(async ($el) => {
			const $firstField = $el.querySelector('.name');
			const $title = $firstField.querySelector('a[href^="/torrent/"]')
			$title.classList.add = 'title'
			const rawTitle = $title.textContent;
			const match = movieTitleRexEx.exec(rawTitle);
			const cleanTitle = match ? match[3].replace(/\./g, ' ').trim() : '';
			const year = match ? match[5] : '';
			
			let imdbInfo = false;
			try {
				imdbInfo = match ? await getImdbInfo(cleanTitle, year) : false;
			} catch (error) {
				console.error('getImdbInfo Errro', error)
			}
			let rating = imdbInfo ? parseFloat(imdbInfo.imdbRating) : 0;
			if (isNaN(rating)) rating = -1;
			
			const $info = document.createElement('div')
			$info.classList.add('info')
			const imdbQuery = (t) =>
				`<a href="http://www.imdb.com/find?ref_=nv_sr_fn&q=${t}&s=all" target="_blank">🔎</a>`;
			if (!(match && match.length)) {
				$info.innerHTML = imdbQuery(rawTitle);
			} else if (!imdbInfo) {
				$info.innerHTML = imdbQuery(cleanTitle);
			} else {
				$info.innerHTML = `<a class="votes" href="http://www.imdb.com/title/${imdbInfo.imdbID}" target="_blank" title="${imdbInfo.imdbVotes} votes"> <span>${imdbInfo.imdbRating}</span><span>${imdbInfo.imdbVotes}</span>  </a>`;
				if (rating > 7.5) $firstField.style.fontWeight = `bold`;
				$title.innerHTML = `<span>${$title.innerHTML}</span><span style="color: #666; margin-left: 1rem">${imdbInfo.Genre}</span>`;
				if (rating < 7.0 && rating > 0) $el.style.opacity = 0.7;
			}
			$firstField.prepend($info); 
			$firstField.innerHTML = `<div class="lsdfkljsdflkj">${$firstField.innerHTML}</div>`
			return {
				$el,
				rating,
			};
		})
	);
	entries.sort((a, b) => (a.rating >= b.rating ? -1 : 1));
	const $parent = document.querySelector('.table tbody');
	$parent.innerHTML = entries.map(({ $el }) => $el.outerHTML).join(' ');
}

(function () {
	run().then(() => console.log('The End'));
})();