Skip to content

Instantly share code, notes, and snippets.

@ybogdanov
Created June 2, 2015 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ybogdanov/9a171a22e644c6ead71a to your computer and use it in GitHub Desktop.
Save ybogdanov/9a171a22e644c6ead71a to your computer and use it in GitHub Desktop.
Makes OLX (slando) render large image previews
// ==UserScript==
// @name OLX Previews
// @namespace http://use.i.E.your.homepage/
// @version 0.1
// @description Makes OLX (slando) render large image previews
// @match http://kiev.ko.olx.ua/nedvizhimost*
// @copyright 2015+, Yuriy Bogdanov
// ==/UserScript==
;(function(){
var q = asyncQueue(loadThumb, 4),
timeout = 10000,
running = 0
setInterval(function(){
$('td.offer a.link').filter(":not([handled])").each(function(i, a) {
q.push({el: a, retryN: 0})
})
}, 1000)
// To restore console.log()
// var i = document.createElement('iframe');
// i.style.display = 'none';
// document.body.appendChild(i);
// window.console = i.contentWindow.console;
var interv = setInterval(function(){
if (q.running() + running + q.length() == 0) {
clearInterval(interv)
}
console.log("Running %d (within queue %d), queue length %d", running, q.running(), q.length())
}, 5000)
function loadThumb(task, callback) {
var a = $(task.el)
var wrapper = a.closest('tbody')
a.attr('handled', true)
var req = new XMLHttpRequest()
req.open("get", a.attr('href'), true)
running++
var makeThumbsContainer = function() {
wrapper.find('tr.super-thumbs').remove()
var thumbsContainer = $('<tr class="super-thumbs">')
var td = $("<td>").attr("colspan", wrapper.find('td').length).appendTo(thumbsContainer)
var div = $("<div>").appendTo(td)
thumbsContainer.appendTo(wrapper)
return div
}
var done = function() {
if (req.readyState != 0) { // not UNSENT
req.abort()
}
callback && callback()
running--
}
var t = setTimeout(function() {
req.onload = function(){}
if (task.retryN == 0) {
task.retryN++
loadThumb(task)
}
else {
var retryA = $('<a href="javascript:void(0)">').append("retry").click(function(){
loadThumb(task)
})
makeThumbsContainer().append("Timeout ").append(retryA)
}
done()
}, timeout)
var loadingTxt = task.retryN == 0 ? "Loading..." : "Loading (" + task.retryN + ") ..."
makeThumbsContainer().append(loadingTxt)
req.onload = function() {
if (t) clearTimeout(t)
var images = $(req.responseText).contents().find('#offerdescription .bigImage')
if (!images.length) {
wrapper.find('tr.super-thumbs').remove()
return done()
}
wrapper.find("td[width=120]").remove()
var thumbsDiv = makeThumbsContainer().css({
height: 350,
overflowY: "scroll",
whiteSpace: "nowrap"
})
images.each(function(i, v){
if (i > 5) return
var imgEl = $('<img>').attr('src', v.src).css({
height: 350
})
var aWrap = $('<a>').attr('href', a.attr('href')).append(imgEl)
thumbsDiv.append(aWrap)
})
done()
}
req.send()
}
function asyncQueue(worker, concurrency) {
if (concurrency === undefined) {
concurrency = 1;
}
var _isArray = Array.isArray || function (obj) {
return _toString.call(obj) === '[object Array]';
};
var _each = function (arr, iterator) {
if (arr.forEach) {
return arr.forEach(iterator);
}
for (var i = 0; i < arr.length; i += 1) {
iterator(arr[i], i, arr);
}
};
function only_once(fn) {
var called = false;
return function() {
if (called) throw new Error("Callback was already called.");
called = true;
fn.apply(window, arguments);
}
}
function _insert(q, data, pos, callback) {
if (!q.started){
q.started = true;
}
if (!_isArray(data)) {
data = [data];
}
if(data.length == 0) {
// call drain immediately if there are no tasks
return setTimeout(function() {
if (q.drain) {
q.drain();
}
}, 0);
}
_each(data, function(task) {
var item = {
data: task,
callback: typeof callback === 'function' ? callback : null
};
if (pos) {
q.tasks.unshift(item);
} else {
q.tasks.push(item);
}
if (q.saturated && q.tasks.length === q.concurrency) {
q.saturated();
}
setTimeout(q.process, 0);
});
}
var workers = 0;
var q = {
tasks: [],
concurrency: concurrency,
saturated: null,
empty: null,
drain: null,
started: false,
paused: false,
push: function (data, callback) {
_insert(q, data, false, callback);
},
kill: function () {
q.drain = null;
q.tasks = [];
},
unshift: function (data, callback) {
_insert(q, data, true, callback);
},
process: function () {
if (!q.paused && workers < q.concurrency && q.tasks.length) {
var task = q.tasks.shift();
if (q.empty && q.tasks.length === 0) {
q.empty();
}
workers += 1;
var next = function () {
workers -= 1;
if (task.callback) {
task.callback.apply(task, arguments);
}
if (q.drain && q.tasks.length + workers === 0) {
q.drain();
}
q.process();
};
var cb = only_once(next);
worker(task.data, cb);
}
},
length: function () {
return q.tasks.length;
},
running: function () {
return workers;
},
idle: function() {
return q.tasks.length + workers === 0;
},
pause: function () {
if (q.paused === true) { return; }
q.paused = true;
q.process();
},
resume: function () {
if (q.paused === false) { return; }
q.paused = false;
q.process();
}
};
return q;
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment