Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Flickr Original Link
- // @namespace https://greasyfork.org/scripts/1190-flickr-original-link
- // @include /flickr\.com/
- // @version 6.0.1
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_addStyle
- // @grant GM_xmlhttpRequest
- // @require https://code.jquery.com/jquery-3.3.1.min.js
- // @description Show direct links to download biggest Flickr image available and some other sizes.
- // @downloadURL https://update.greasyfork.org/scripts/1190/Flickr%20Original%20Link.user.js
- // @updateURL https://update.greasyfork.org/scripts/1190/Flickr%20Original%20Link.meta.js
- // ==/UserScript==
- // THIS VERSION:
- // - bugfix: Replaces $.get() calls with GM_xmlhttpRequest to workaround the flickr.com CORS settings enforced by the browser. Now direct download links in albums are (more) reliable.
- // - user-interface: Removes the "DOWNLOAD" text from some pages, leaving only the image size text + colored background. TODO: two occurrences remaining, but I did not see them yet.
- // - enhancement: Moves the download links of the single-image page from down-below-hard-to-find up, below the image.
- // - dev: Code is formatted automatically by the Templatemonkey editor
- // - dev: Some comments and code cleanup while I was decyphering it. Far from clean, but it's approachable.
- var postfix = "_d.jpg";
- var prefix = "DOWNLOAD ";
- var isChecked_openLink = "";
- var isChecked_alwaysShow = "";
- var key_openLink = "flickr_openLink";
- var key_alwaysShow = "flickr_alwaysShow";
- var value_openLink = false;
- var value_alwaysShow = false;
- var imageSizeOrder = ["9k","8k","7k","6k","5k","4k","3k","2k","o", "k", "h", "l","b", "c", "z"];
- var globalObserver = null;
- function log(s) {
- console.log(s);
- }
- log("Begin flickr script");
- function getSetting() {
- log("Begin get settings");
- value_openLink = GM_getValue(key_openLink, false);
- value_alwaysShow = GM_getValue(key_alwaysShow, false);
- if (value_openLink) {
- postfix = ".";
- isChecked_openLink = ' checked="checked" ';
- prefix = "OPEN ";
- }
- else {
- postfix = "_d.";
- isChecked_openLink = "";
- prefix = "DOWNLOAD ";
- }
- if (value_alwaysShow) {
- isChecked_alwaysShow = ' checked="checked" ';
- }
- else {
- isChecked_alwaysShow = "";
- }
- }
- function checkAlwaysShow() {
- if (value_alwaysShow) {
- $('div.interaction-view').css('opacity', '1');
- }
- $('div.interaction-bar').css('bottom', '1.1em');
- }
- // Add extra functionality in the single-photo page.
- function action_single_page() {
- if ($('.commonButton').length > 0) {
- // The download links have already been added.
- return false;
- }
- var action = function (sourceCode) {
- var sizes = sourceCode.match(/modelExport: {.+?"sizes":{.+?}}/i);
- var mSize = sizes[0].match(/"width":"?\d+"?,"height":"?\d+"?,/ig);
- var mLink = sizes[0].match(/"displayUrl":"[^"]+"/ig);
- var length = mLink.length;
- for (var k = 0; k < length; k++) {
- mSize[k] = mSize[k].replace(/"width":(\d+),"height":(\d+),/i, "$1 x $2");
- mLink[k] = mLink[k].replace(/"displayUrl":"([^"]+)"/i, "$1").replace(/\\/g, "").replace(/(_[0-9a-z]+)\.([a-z]{3,4})/i, '$1' + postfix + '$2');
- }
- var str = '<div style="width:100%; text-align:center;">';
- for (k = Math.max(0, length - 7); k < length; k++) {
- var c = (k == length - 1) ? 'bigButton' : 'smallButton';
- str += '<a class="commonButton ' + c + '" href="' + mLink[k] + '">' + mSize[k] + ' px</a>';
- }
- str += '</div>';
- var e = document.createElement('div');
- e.innerHTML = str;
- var insertLocation = $('.sub-photo-container');
- insertLocation.prepend(e.firstChild);
- };
- $.get(document.URL, action);
- }
- function addDownloadLinksToAlbumPhotos(data) {
- if (data === null) {
- log("data is null");
- return;
- }
- var sizes = data.match(/"sizes":.+?}}/ig);
- if (sizes === null) {
- log("sizes is null");
- return;
- }
- var dates = data.match(/"datePosted":"\d+"/ig);
- if (dates == null) {
- log("cannot find any dates");
- }
- var e2;
- if (type == 'album') {
- e2 = $('div.photo-card-view div.foot');
- } else {
- e2 = $('div.photo-list-photo-view');
- }
- log("Number of photo in this page: "+e2.length);
- for (var index = 0; index < e2.length; index++) {
- var e = $(e2[index]);
- if (e.find('.myFuckingLink').filter(':first').length > 0) {
- // Already added.
- continue;
- }
- e.html(e.html() + '<a class="myFuckingLink"></a>');
- for (var i = 0; i < imageSizeOrder.length; ++i) {
- var photo = sizes[index].match(new RegExp('"' + imageSizeOrder[i] + '".*?:{"displayUrl":"([^"]+)","width":(\\d+),"height":(\\d+)', "i"));
- if (photo === null) continue;
- var b = e.find('.myFuckingLink');
- b.attr('href', photo[1].replace(/\\/g, "").replace(/(_[0-9a-z]+)\.([a-z]{3,4})/i, '$1' + postfix + '$2'));
- var timestamp = dates[index].match(/\d+/i);
- var t = new Date((new Number(timestamp)) * 1000);
- b.attr('title', prefix + photo[2] + " x " + photo[3] + " | Upload: " + t.toLocaleDateString());
- b.html(photo[2] + " x " + photo[3]);
- break;
- }
- }
- }
- function action_normal_page(theType) {
- var target = $('#content')[0];
- var config = {
- childList: true,
- subtree: true,
- };
- var prevUrl = "none";
- var prevThumbLength = 0;
- var sourceCode = null;
- var action = function (x) {
- log('#content changed ' + x);
- var e3;
- if (x == 'album') {
- e3 = $('div.photo-card-view');
- } else {
- e3 = $('div.photo-list-photo-view');
- }
- if (document.URL == prevUrl) {
- if (e3.length == prevThumbLength) return false; // number of thumbnail is not change, no need to process further
- checkAlwaysShow();
- prevThumbLength = e3.length;
- log("Number of thumb: " + prevThumbLength);
- addDownloadLinksToAlbumPhotos(sourceCode);
- } else {
- var e1 = e3.find('a').filter(':first');
- if (e1.length < 1) return false; // not found any link to valid single image page
- checkAlwaysShow();
- // get full source code for this page
- sourceCode = null;
- prevUrl = document.URL;
- var link1 = e1.attr('href');
- console.time("GetSource");
- $('#content').append('<div id="loadingIndicator" style="position:fixed;left:5px;bottom:2em;display:block;background-color:pink;border:solid;padding:3px">Getting original link<br>Please wait...</div>');
- log("Getting page of first photo: " + link1);
- GM_xmlhttpRequest({
- method: "GET",
- url: link1,
- onload: function(response) {
- log("Got page of first photo");
- // Processing single image page source to get entry-type link
- var link2 = 'https://flickr.com' + response.responseText.match(/<a\s+class=.+?entry-type.+?href='([^']+)/i)[1];
- link2 = link2.replace("/albums/", "/sets/");
- log("Begin get source 2: " + link2);
- GM_xmlhttpRequest({
- method: "GET",
- url: link2,
- onload: function(response) {
- // Processing page source to get image links
- log("Got final source: " + link2);
- console.timeEnd("GetSource");
- $('#loadingIndicator').remove();
- addDownloadLinksToAlbumPhotos(response.responseText);
- },
- onerror: function(response) {
- log("Failed getting second? page: " + response);
- },
- });
- },
- onerror: function(response) {
- log("Failed getting first photo page: " + response);
- },
- });
- }
- };
- action(theType);
- globalObserver = new MutationObserver(function (mutations, ob) {
- action(theType);
- });
- globalObserver.observe(target, config);
- }
- function flickr_mouseenter() {
- var e = $(this);
- if (e.find('.myFuckingLink').filter(':first').length > 0) {
- e.off('mouseenter');
- return false;
- }
- var url = e.find('a').filter(':first').attr('href');
- if (typeof url == "undefined" || url === null) return false;
- e.append('<a class="myFuckingLink">(Link loading...)</a>');
- $.get(url, function (data) {
- var photo = data.match(/"displayUrl":"([^"]+)","width":(\d+),"height":(\d+)[^}]+}}/i);
- var link = photo[1].replace(/\\/g, "").replace(/(_[0-9a-z]+)\.([a-z]{3,4})/i, '$1' + postfix + '$2');
- var text = prefix + photo[2] + " x " + photo[3] + " Upload: ";
- var b = e.find('.myFuckingLink');
- b.attr('href', link);
- b.attr('title', text);
- b.html(text);
- });
- }
- function action_hover_page() {
- var target = $('body')[0];
- var config = {
- childList: true,
- subtree: true,
- };
- var prevLength = 0;
- globalObserver = new MutationObserver(function (mutations, ob) {
- var e = $('div.photo-list-photo-view');
- if (e.length == prevLength) return false; // no new Thumbnail, don't do anything
- log("Number of thumb: " + e.length);
- prevLength = e.length;
- checkAlwaysShow();
- e.mouseenter(flickr_mouseenter);
- });
- globalObserver.observe(target, config);
- }
- function pageType() {
- var t = "none";
- var htmlClass = $('html').attr('class');
- console.log("HTML class: " + htmlClass);
- if (htmlClass.match(/html-photo-page.+scrappy-view/i) !== null) t = 'single';
- else if (htmlClass.match(/html-(search-photos-unified|group-pool)-page-view/i) !== null) t = 'hover';
- else if ($('div.photo-list-photo-view').filter(':first').length > 0) t = 'normal';
- else if ($('div.photo-list-view').filter(':first').length > 0) t = 'album';
- console.log("Page type: " + t);
- return t;
- }
- var prevType = "none";
- var type = "none";
- var oldUrl = "none";
- var count = 0;
- function kickStart() {
- oldUrl = document.URL;
- type = pageType();
- getSetting();
- checkAlwaysShow();
- var strCss = "";
- if (type == 'album') {
- strCss += ".myFuckingLink{position:absolute;z-index:999999;left:5px;bottom:0px;width:100%;display:block;background-color: lightgreen;border-radius: 2px;}";
- } else {
- strCss += ".myFuckingLink{position:absolute;z-index:999999;left:3px;bottom:0px;width:100%;display:block;background-color: lightgreen;color:white!important;}";
- }
- strCss += ".myFuckingLink:hover{background-color:rgba(100, 100, 255,0.65)!important}";
- strCss += ".commonButton{display: inline-block;border-radius: 0.5em;margin: 0.2em;padding: 0.5em;font-size: 90%;height: fit-content;}";
- strCss += ".bigButton{background-color: lightgreen}";
- strCss += ".smallButton{background-color:pink}";
- GM_addStyle(strCss);
- // Install the settings functionality at the top of the page.
- $('.myOptionBox').remove();
- $('ul.nav-menu:first').append('<li class="myOptionBox"><div style="color:pink;padding:1px"><input id="optionbox_openLink" type="checkbox"' + isChecked_openLink + 'style="margin:2px"/>Open image link in browser<br><input id="optionbox_alwaysShow" type="checkbox"' + isChecked_alwaysShow + 'style="margin:2px"/>Always show image information in Photostream</div></li>');
- $('#optionbox_openLink').change(function () {
- GM_setValue(key_openLink, $(this).prop('checked'));
- });
- $('#optionbox_alwaysShow').change(function () {
- GM_setValue(key_alwaysShow, $(this).prop('checked'));
- });
- // Change the page.
- if (type == 'single') action_single_page();
- else if (type == 'normal' || type == 'album') action_normal_page(type);
- else if (type == 'hover') action_hover_page();
- }
- log("Preparing to run kickStart(), which decides what shall be done");
- var timestamp = "1469473824";
- var number = new Number(timestamp);
- var t = new Date(number * 1000);
- log("Time number: " + t.toLocaleDateString('vi-VN'));
- kickStart();
- // Run kickStart whenever the URL changes.
- var target = $('html')[0];
- var config = {
- childList: false,
- attributes: true,
- };
- var observer = new MutationObserver(function (mutations, ob) {
- if (oldUrl == document.URL) {
- // We already kickStarted the current page.
- return;
- }
- if (globalObserver !== null) globalObserver.disconnect();
- kickStart();
- });
- observer.observe(target, config);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement