Skip to content

Instantly share code, notes, and snippets.

@dvingerh
Last active April 21, 2018 14:51
Show Gist options
  • Save dvingerh/118208296fcdee614967c3880ba8f0fc to your computer and use it in GitHub Desktop.
Save dvingerh/118208296fcdee614967c3880ba8f0fc to your computer and use it in GitHub Desktop.
Add download links and a batch download button for PixHost on Picturepub. Useful if the photos aren't added to an album.
// ==UserScript==
// @name PicturePub Batch Downloader
// @namespace http://tampermonkey.net/
// @version 0.2
// @description Add download links and a batch download button for PixHost on Picturepub. Useful if the photos aren't added to an album.
// @author You
// @require https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
// @include *picturepub.net/index.php?threads*
// @grant GM_xmlhttpRequest
// @grant GM_download
// @run-at document-idle
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
(function() {
'use strict';
$("blockquote[class^='messageText']").each(function()
{
var count = 0;
var contains = false;
var width, widthHalf, dlButton;
$(this).find('a').each(function(){
$(this).find('img').each(function(a){
var src = $(this).attr('src');
if (src.indexOf("pixhost") !== -1)
{
contains = true;
src = src.replace("/thumbs/", "/images/").replace("//t", "//img");
width = $(this).width() - 25;
widthHalf = (width / 2) + 3;
dlButton = '<a target="_blank" class="dlPixHost" href="' + src + '" style="position: relative; margin-left: -' + (width + 25) + 'px; margin-right: 0px; padding-left: ' + widthHalf + 'px; padding-right:' + (widthHalf + 1) + 'px; background-color: rgba(0,0,0,0.7); font-weight: bold;" download>DL</a>';
$(this).parent().after(dlButton);
count++;
}
});
});
if (contains) {
$(this).parent().parent().parent().find("div.privateControls").after('<a style="margin-left: 5px;" href="javascript:void()" class="BatchDl OverlayTrigger item control" data-cacheoverlay="false" style=""><span></span>Batch Download PixHost (' + count + ' Pictures)</a>');
}
});
$("a[class^='BatchDl']").click( function(e) {e.preventDefault(); BatchDownload(this); return false; } );
var img_arr = [];
var cancelled = false;
var downloading = false;
function BatchDownload(button)
{
if (!downloading) {
if (img_arr.length > 0) { img_arr = []; }
$($(button).parent().prev().prev().find('a.dlPixHost')).each(function(){
var image_url = $(this).attr('href');
img_arr.push(image_url);
});
$(button).text("Starting download... expect stuttering in this tab during downloading.");
downloading = true;
setTimeout(function() { downloadFiles($(button), 0); }, 3000);
}
else {
cancelled = true;
}
}
function downloadFiles(button, iteration) {
if(!cancelled) {
if (iteration != img_arr.length) {
var downloader = GM_xmlhttpRequest ( {
method: 'GET',
url: img_arr[iteration],
synchronous: false,
onload: respDetails => {
var binResp = customBase64Encode (respDetails.responseText);
var base64_img = 'data:image/png;base64,' + binResp;
var contentType = 'image/png';
var blob = b64toBlob(binResp, contentType);
var blobUrl = URL.createObjectURL(blob);
saveFile(blob, img_arr[iteration].split('/').pop());
iteration++;
$(button).text("Downloaded " + iteration + " of " + img_arr.length + " pictures... Click to cancel.");
downloadFiles($(button), iteration);
},
overrideMimeType: 'text/plain; charset=x-user-defined'
} );
} else {
$(button).text("Downloaded all " + img_arr.length + " pictures.");
setTimeout(function() { $(button).text("Batch Download PixHost (" + img_arr.length + " Pictures)"); }, 5000);
}
}
else {
$(button).text("Download cancelled. Downloaded " + iteration + " pictures.");
cancelled = false;
downloading = false;
setTimeout(function() { $(button).text("Batch Download PixHost (" + img_arr.length + " Pictures)"); }, 5000);
}
}
function showSplashscreen() {
let splashscreen = document.body.appendChild(document.createElement('div'));
splashscreen.classList.add('mgisga_splashscreen');
splashscreen.style = `
background: black;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 666;
opacity: 0.7;
`;
let spinner = splashscreen.appendChild(document.createElement('img'));
spinner.src = 'http://svgur.com/i/6Mk.svg';
spinner.style = `
position: fixed;
left: calc(50% - 100px);
top: calc(50% - 100px);
filter: invert();
`;
}
function saveFile(blob, filename) {
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
const a = document.createElement('a');
document.body.appendChild(a);
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}, 0);
}
}
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function customBase64Encode (inputStr) {
var
bbLen = 3,
enCharLen = 4,
inpLen = inputStr.length,
inx = 0,
jnx,
keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
output = "",
paddingBytes = 0;
var
bytebuffer = new Array (bbLen),
encodedCharIndexes = new Array (enCharLen);
while (inx < inpLen) {
for (jnx = 0; jnx < bbLen; ++jnx) {
if (inx < inpLen)
bytebuffer[jnx] = inputStr.charCodeAt (inx++) & 0xff;
else
bytebuffer[jnx] = 0;
}
encodedCharIndexes[0] = bytebuffer[0] >> 2;
encodedCharIndexes[1] = ( (bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4);
encodedCharIndexes[2] = ( (bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6);
encodedCharIndexes[3] = bytebuffer[2] & 0x3f;
paddingBytes = inx - (inpLen - 1);
switch (paddingBytes) {
case 1:
encodedCharIndexes[3] = 64;
break;
case 2:
encodedCharIndexes[3] = 64;
encodedCharIndexes[2] = 64;
break;
default:
break;
}
for (jnx = 0; jnx < enCharLen; ++jnx)
output += keyStr.charAt ( encodedCharIndexes[jnx] );
}
return output;
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment