// ==UserScript== // @name Flickr Cross-Recommendations // @namespace http://netcetera.org // @include http://www.flickr.com/photos/* // @include https://www.flickr.com/photos/* // @match http://www.flickr.com/photos/* // @match https://www.flickr.com/photos/* // @version 1.53e // @grant none // @author Simon Whitaker (http://www.flickr.com/people/chubbybat/) // @contributor Alesa Dam (http://www.flickr.com/people/alesadam/) // @contributor Darren Greaves (http://www.flickr.com/people/boncey/) // @contributor Martin Heimburger (http://www.flickr.com/people/Vispillo/) // @contributor Mark Boyd (https://www.flickr.com/people/mark_boyd/) // @description Adds a "People who faved this also faved..." panel to photos on Flickr // @downloadURL none // ==/UserScript== (function() { if (!document.location.href.match(/https?:\/\/www\.flickr\.com\/photos\/[^\/]+\/\d+.*/)) { return; } var MAX_IMGS = 6; // number of cross-recommendations to retrieve var MAX_RUNS = MAX_IMGS * 15; // if we don't have those random images by then, better quit var current_element; var prev_element; var target_element; var current_photo_id; var photo_count; var run_count; var photos_to_ignore; var testForElement = true; var pageURLCheckTimer = setInterval ( function () { if ( this.lastPathStr !== location.pathname || this.lastQueryStr !== location.search || this.lastPathStr === null || this.lastQueryStr === null ) { this.lastPathStr = location.pathname; this.lastQueryStr = location.search; gmMain (); } else if (testForElement) { current_element = document.getElementsByClassName('view sub-photo-fave-view')[0]; if (!current_element) { current_element = document.getElementsByClassName('fave-block')[0]; } if (!current_element) { current_element = document.getElementById('comments'); } if ((current_element != prev_element) && (current_element)) { prev_element = current_element; testForElement = false; FCR_add_panel(current_element); } } } , 200 ); function gmMain () { if (!document.location.href.match(/https?:\/\/www\.flickr\.com\/.*/)) { clearInterval(pageURLCheckTimer); } else { testForElement = document.location.href.match(/https?:\/\/www\.flickr\.com\/photos\/[^\/]+\/\d+.*/); } } var protocol = window.location.protocol; if (typeof(GM_log) == "undefined") { // Chrome GM_log = function(message) { console.info('FCR: ' + message); } } var getJSVariable = function (regex) { // Thanks to Vispillo for this compact code var retval; var scripts = document.getElementsByTagName('script'); for(var i = 0, len = scripts.length; i < len; ++i) { var script = scripts[i]; var html = script.innerHTML; try { retval = regex.exec(html)[1]; break; } catch (e) { } } return retval; } function pickRandomFavoriteFrom(people) { if (!people || people.length == 0) { GM_log("no people found"); return; } if (photo_count >= MAX_IMGS) { // sanity check return; } if (++run_count > MAX_RUNS) { GM_log("out of data"); return; } photos_to_ignore[current_photo_id] = 1; var personIdx = Math.floor(Math.random() * people.length); var nsid = people[personIdx].nsid; var listRequest = new XMLHttpRequest(); listRequest.onload = function(getPublicListResponse) { var listJson = listRequest.response; try { var data = JSON.parse(listJson); } catch (e) { try { data = eval('(' + listJson + ')'); } catch (f) { //GM_log("exception parsing list response: " + e); pickRandomFavoriteFrom(people); return; } } var photos = data.photos.photo; var photoIdx = Math.floor(Math.random() * photos.length); var photo = photos[photoIdx]; if (photos_to_ignore[photo.id]) { pickRandomFavoriteFrom(people); return; } photos_to_ignore[photo.id] = 1; var photo_url = protocol + '//farm' + photo.farm + '.static.flickr.com/' + photo.server + '/' + photo.id + '_' + photo.secret + '_s.jpg'; var page_url = protocol+'//www.flickr.com/photos/' + photo.owner + '/' + photo.id + '/'; var img = document.createElement('img'); img.setAttribute('src',photo_url); img.setAttribute('border', 0); var a = document.createElement('a'); a.setAttribute('href', page_url); a.setAttribute('target', "_blank"); a.setAttribute('title', photo.title); a.style.marginRight = '8px'; a.appendChild(img); document.getElementById('FCR_photos').appendChild(a); // Show the main div, in case it's still hidden document.getElementById('FCR_main').style.display = "block"; ++photo_count; pickRandomFavoriteFrom(people); }; listRequest.open('get', protocol+'//api.flickr.com/services/rest/' +'?method=flickr.favorites.getPublicList' +'&api_key=' + api_key +'&format=json&nojsoncallback=1' +'&user_id=' + nsid, true); listRequest.send(); } function FCR_add_panel(the_element) { try { photo_count = 0; run_count = 0; photos_to_ignore = new Array(); if (!the_element) { GM_log("element not found; aborting"); return; } current_photo_id = re.exec(document.location.href)[1]; var xrec_div = document.createElement('div'); xrec_div.setAttribute('id', 'FCR_main'); var xrec_photos = document.createElement('div'); xrec_photos.setAttribute('id', 'FCR_photos'); var xrec_header = document.createElement('h3'); xrec_header.innerHTML = 'People who faved this also faved...'; xrec_div.appendChild(xrec_header); xrec_div.appendChild(xrec_photos); the_element.parentNode.insertBefore(xrec_div, the_element); xrec_div.style.display = 'none'; var url = protocol+'//api.flickr.com/services/rest/' +'?method=flickr.photos.getFavorites' +'&api_key=' + api_key +'&format=json&nojsoncallback=1' +'&photo_id=' + current_photo_id; var favesRequest = new XMLHttpRequest(); favesRequest.onload = function(response) { var json = favesRequest.response; try { var data = JSON.parse(json); } catch (e) { try { data = eval('(' + json + ')'); } catch (f) { GM_log("exception parsing response: " + e); return; } } pickRandomFavoriteFrom(data.photo.person); }; favesRequest.open('get', url, true); favesRequest.send(); } catch (e) { GM_log("Exception occurred: " + e); } } var re = /flickr\.com\/photos\/[^\/]+\/(\d+).*/; var api_key = '45d5d4b7dff9bc653c8eb3e73271c10c'; })();