// ==UserScript== // @name FTNPlus // @namespace https://feedthe.net/ // @description Displays iMDB information for movies on FTN. A modified version from FTN+ // @include https://feedthe.net/details.php* // ==/UserScript== function getInsertionPoint() { return evalXPath(document, '//table[@id="detailtable"]/tbody/tr').snapshotItem(1); } function evalXPath(dom, XPath) { return document.evaluate(XPath, dom, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null, null); } function getPureRating(dom) { var result = evalXPath(dom, "div[@id='wrapper']/div[@id='root']/div[@id='tn15']/div[@id='tn15main']/div[@id='tn15content']/div[@id='tn15rating']/div[2]/b[2]"); if (result.snapshotLength > 0) { var rating = result.snapshotItem(0).innerHTML; return rating.substring(0,rating.length - 3); } else { return null; } } function IMDbVotes(dom) { return evalXPath(dom, "div[@id='wrapper']/div[@id='root']/div[@id='tn15']/div[@id='tn15main']/div[@id='tn15content']/div[@id='tn15rating']/div[2]/small").snapshotItem(0).textContent; } function createTr(title, content) { var contentTr = document.createElement("tr"); var name = document.createElement("td"); name.innerHTML = "" + title + ""; contentTr.insertBefore(name, null); contentTr.insertBefore(content, null); return contentTr; } /* FIXME: Rewrite the next two methods */ function IMDbScore(dom) { var content = document.createElement("td"); var votes = IMDbVotes(dom); if (votes.search(/awaiting 5 votes/) == -1) { var rating = getPureRating(dom); if (rating) { var tmpDiv = document.createElement("span"); tmpDiv.innerHTML = "(" + rating + "/10) " + IMDbVotes(dom); var starsDiv = IMDbScoreStars(rating); content.insertBefore(starsDiv, null); content.insertBefore(tmpDiv, null); } } else { content.innerHTML = "Not enough votes."; } return createTr("Rating", content); } function IMDbScoreStars(rating) { var tmpDiv = document.createElement("span"); tmpDiv.setAttribute("style", "float: left;"); var style = document.createElement("style"); style.setAttribute("type", "text/css"); /* [XXX] Need a better image, transparent and preferrably with FTN icons */ style.innerHTML = ".starbar {display: inline; height: 20px; width: 200px; }.starbar .outer, .starbar .inner { background: transparent url('http://i.media-imdb.com/images/SFae751da69684847117d205d2cbc0ae90/tn15/stars.gif') no-repeat scroll 0px 0px; } .starbar .outer {height:20px;width:200px;}.starbar .inner { background-position: 0px -20px; height: 20px; width: 0pt; }"; tmpDiv.insertBefore(style, null); var width = rating * 20; var starbar = document.createElement("span"); starbar.innerHTML = "
"; starbar.setAttribute("class", "starbar"); tmpDiv.insertBefore(starbar, null); return tmpDiv; } function IMDbGenres(dom) { var content = document.createElement("td"); var genres = evalXPath(dom, "div[@id='wrapper']/div[@id='root']/div[@id='tn15']/div[@id='tn15main']/div[@id='tn15content']/div[6]/a"); if(genres.snapshotLength == 0) { content.innerHTML += "No genres."; } else { for (var i = 0; i < genres.snapshotLength - 1; i++) { content.innerHTML += genres.snapshotItem(i).innerHTML; if (i + 1 < genres.snapshotLength - 1) { content.innerHTML += " / "; } } } return createTr("Genres", content); } function IMDbPoster(dom) { var content = document.createElement("td"); var images = evalXPath(dom, "div[@id='wrapper']/div[@id='root']/div[@id='tn15']/div[@id='tn15lhs']/div/a/img/@src"); var tmpImg = document.createElement("img"); tmpImg.setAttribute("src", images.snapshotItem(0).textContent); content.insertBefore(tmpImg, null); return createTr("Poster", content); } function IMDbImages(dom) { var content = document.createElement("td"); var style = document.createElement("style"); style.innerHTML = ".imdbimages { float: left; margin-right: 5px; border: 1px solid #000; }"; content.insertBefore(style, null); var images = evalXPath(dom, "div[@id='wrapper']/div[@id='root']/div[@id='tn15']/div[@id='tn15main']/div[@id='tn15content']/table[1]/tbody/tr[2]/td/div/a/img/@src"); if ( images.snapshotLength == 0 ) { content.innerHTML += "No images."; } else { for (var i = 0; i < images.snapshotLength; i++) { var tmpImg = document.createElement("img"); tmpImg.setAttribute("src", images.snapshotItem(i).textContent); tmpImg.setAttribute("class", "imdbimages"); content.insertBefore(tmpImg, null); } } return createTr("Images", content); } function IMDbRelease(dom) { var content = document.createElement("td"); var release = evalXPath(dom, "div[@id='wrapper']/div[@id='root']/div[@id='tn15']/div[@id='tn15main']/div[@id='tn15content']/div[5]/text()[2]").snapshotItem(0).textContent; if(release && !(hasWhiteSpace(release))) { content.innerHTML = release; } else { content.innerHTML = "No release date listed."; } return createTr("Release Date", content); } function IMDbOutline(dom) { var content = document.createElement("td"); var text = dom.innerHTML; var re = /
Plot (?:Summary|Outline):<\/h5>\s*([^<]*)/i; var outline = text.match(re); if ( outline ) { content.innerHTML = outline[1]; } else { content.innerHTML = "Plot outline not available."; } return createTr("Plot Outline", content); } function IMDbRuntime(dom) { var content = document.createElement("td"); var text = dom.innerHTML; var re = /(
Runtime:<\/h5>)\s*([^<]*)/; var runtime = text.match(re); if( runtime && runtime.length > 0 && !hasWhiteSpace(runtime) ) { content.innerHTML = runtime[2]; } else { content.innerHTML = "Runtime not available."; } return createTr("Runtime", content); } function hasWhiteSpace(s) { reWhiteSpace = new RegExp(/^(\s|\b)+$/); if ( reWhiteSpace.test(s) ) { return true; } else { return false; } } function createDOM(text) { var tmpDiv = document.createElement("div"); tmpDiv.innerHTML = text; return tmpDiv; } function insert(destination, content) { destination.insertBefore(content, null); } function FTNPlusInsert(responseDetails) { if (responseDetails.status == "200") { var IMDBfetch = createDOM(responseDetails.responseText); var trFtnplus = document.createElement("tr"); trFtnplus.setAttribute("id", "tr_ftnplus"); var tdName = document.createElement("td"); tdName.innerHTML = "iMDB"; tdName.style.textAlign = "right"; tdName.style.verticalAlign = "top"; var tdContent = document.createElement("td"); var style = document.createElement("style"); style.innerHTML = "table#ftnplus td, table#ftnplus { border-width: 0px; } table#ftnplus td { vertical-align: top; } table#ftnplus td b { display: block; width: 80px; text-align: right; }"; tdContent.insertBefore(style, null); var ftnplusTable = document.createElement("table"); ftnplusTable.setAttribute("id", "ftnplus"); ftnplusTable.setAttribute("cellpadding", "3"); insert(ftnplusTable, IMDbScore(IMDBfetch)); insert(ftnplusTable, IMDbPoster(IMDBfetch)); insert(ftnplusTable, IMDbRelease(IMDBfetch)); insert(ftnplusTable, IMDbGenres(IMDBfetch)); insert(ftnplusTable, IMDbOutline(IMDBfetch)); insert(ftnplusTable, IMDbRuntime(IMDBfetch)); insert(ftnplusTable, IMDbImages(IMDBfetch)); insert(tdContent, ftnplusTable); insert(trFtnplus, tdName); insert(trFtnplus, tdContent); var insertion = getInsertionPoint(); insertion.parentNode.insertBefore(trFtnplus, insertion.nextSibling); } } function fetch(imdblink) { GM_xmlhttpRequest({ method: 'GET', url: imdblink, headers: { 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey', 'Accept': 'application/atom+xml,application/xml,text/xml', 'Referer': imdblink, }, onload: FTNPlusInsert }); } function getIMDbLink(text) { var re = /http:\/\/([^\.]*\.)?imdb.com\/title\/tt[0-9]{7}(\/)?/i; var arr = text.match(re); if (arr) { return arr[0]; } else { return arr; } } function displayFTNPlus() { var category = evalXPath(document, '//table[@id="detailtable"]/tbody/tr/td[.="Type"]/following-sibling::td[1]').snapshotItem(0).innerHTML.split("/")[0]; if (!( category == "Movies" )) { return; } var desc = evalXPath(document, '//table[@id="detailtable"]/tbody/tr/td[.="Description"]/ancestor::tr[1]/td[2]').snapshotItem(0).textContent; var imdb = getIMDbLink(desc); if ( imdb == null ) { /* Do nothing */ } else { fetch(imdb); } } displayFTNPlus();