Skip to content

Instantly share code, notes, and snippets.

@sheepymeh
Last active March 4, 2022 06:11
Show Gist options
  • Save sheepymeh/7d166836ee1985a4e122b7f75fa16be2 to your computer and use it in GitHub Desktop.
Save sheepymeh/7d166836ee1985a4e122b7f75fa16be2 to your computer and use it in GitHub Desktop.
google-drive-restricted-download

Downloads restricted PDFs from Google Drive that cannot normally be downloaded. Uses A4 paper size and scales accordingly. Copy and paste script.js into the console and press Enter.

Ensure that your system has enough RAM before starting.
Thanks to this comment for zoom-in code.

const FULL_RES_EXPORT = true;
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function triggerMouseEvent(node, eventType) {
const clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent(eventType, true, true);
node.dispatchEvent(clickEvent);
}
(async () => {
const scrollParent = document.querySelector('textarea').nextSibling;
scrollParent.scrollTo(0, 0);
console.info('Loading pages');
let elements = document.querySelectorAll('img');
if (FULL_RES_EXPORT) {
for (let img of elements) {
if (/^blob:/.test(img.src)) img.parentNode.removeChild(img);
}
const zoomButton = document.querySelector('[aria-label="Zoom in"]');
for (let i = 0; i < 7; i++) {
triggerMouseEvent(zoomButton, 'mouseover');
triggerMouseEvent(zoomButton, 'mousedown');
triggerMouseEvent(zoomButton, 'mouseup');
}
}
for (let i = 0; i < scrollParent.scrollHeight; i += scrollParent.clientHeight) {
scrollParent.scrollTo(0, i);
await sleep(75);
}
let jspdf = document.createElement('script');
jspdf.addEventListener('load', async () => {
console.info('Collating pages');
const pdf = new jsPDF({
unit: 'pt',
compress: true
});
pdf.deletePage(1);
let pagesLoaded;
const totalPages = parseInt(document.querySelector('[aria-label^="Page "]').getAttribute('aria-label').split(' ')[3].replace(',', ''));
do {
elements = document.querySelectorAll('img');
pagesLoaded = 0;
for (let img of elements) {
if (/^blob:/.test(img.src)) pagesLoaded++;
}
await sleep(100);
} while (pagesLoaded < totalPages);
console.info('Creating PDF');
const startTime = new Date();
elements.forEach((img, idx) => {
if (!/^blob:/.test(img.src)) return;
const ratio = img.width / img.height;
if (ratio > 1) {
pdf.addPage('a4', 'l');
if (ratio < 842 / 595) pdf.addImage(img, 'png' , 0, 0, ratio * 595, 595);
else pdf.addImage(img, 'png' , 0, 0, 842, 842 / ratio);
}
else {
pdf.addPage('a4', 'p');
if (ratio < 595 / 842) pdf.addImage(img, 'png' , 0, 0, ratio * 842, 842);
else pdf.addImage(img, 'png' , 0, 0, 595, 595 / ratio);
}
console.info(`Processed page ${idx+1} of ${pagesLoaded}. ${Math.round((pagesLoaded-idx-1) * ((new Date()) - startTime) / 1000 / (idx+1))}s remaining.`);
});
console.info(`Took ${((new Date()) - startTime) / 1000}s`);
pdf.save(document.querySelector('[aria-label="PDF icon"]').nextSibling.innerText);
console.info(`Created PDF with ${pagesLoaded} pages`);
});
jspdf.src = 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js';
document.body.appendChild(jspdf);
})();
@TheoLeeCJ
Copy link

After inspecting the PDF Viewer, it seems that the zoom-in button does not have a meaningful click handler to zoom-in - this is instead done with mousedown, mouseup etc events...

function triggerMouseEvent (node, eventType) {
    var clickEvent = document.createEvent ('MouseEvents');
    clickEvent.initEvent (eventType, true, true);
    node.dispatchEvent (clickEvent);
}

targetNode = document.querySelector('[aria-label="Zoom in"]');
triggerMouseEvent (targetNode, "mouseover");
triggerMouseEvent (targetNode, "mousedown");
triggerMouseEvent (targetNode, "mouseup");
triggerMouseEvent (targetNode, "click");

For all your zooming-in needs!
Thanks: https://stackoverflow.com/questions/24025165/simulating-a-mousedown-click-mouseup-sequence-in-tampermonkey

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment