101arrowz 4 years ago committed by GitHub
commit 09a3f440b4

@ -0,0 +1,13 @@
Download a McGraw Hill Education eTextbook
---
If you purchase a textbook from McGraw Hill, the website to view it is clunky and only works on some devices.
You can't go to specific page numbers, the search is super slow, etc.
That's why I wrote this script to download the textbook as an ePub file for your own viewing.
Using this script is 100% legal. McGraw Hill publicly hosts their ebooks online in order for their web client to,
download it. Moreover, to use it, you must already have purchased the book you would like to download, so it is
legally yours to use as you please. **However, it IS illegal to use this for piracy purposes.DO NOT DISTRIBUTE
ANY TEXTBOOKS YOU DOWNLOAD USING THIS SCRIPT.**
## Instructions
1. Open your textbook in the McGraw-Hill Connect website (how you normally open it)
2.

@ -0,0 +1,41 @@
import('https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.2/jszip.min.js').then(async () => {
alert('This is the McGraw-Hill Education Textbook Downloader. Click OK to start downloading the files.');
const IMPORT_URL = (await (await fetch('https://player-api.mheducation.com/lti', { credentials: 'include' })).json()).custom_epub_url;
const epub = new JSZip();
const metaInf = epub.folder('META-INF');
metaInf.file('container.xml', await (await fetch(IMPORT_URL + 'META-INF/container.xml', { credentials: 'include' })).text());
const epubData = epub.folder('OPS');
const opfString = await (await fetch(IMPORT_URL + 'OPS/content.opf', { credentials: 'include' })).text();
epubData.file('content.opf', opfString);
const opf = new DOMParser().parseFromString(opfString, 'application/xml');
for (let item of opf.querySelector('manifest').children) {
const href = item.getAttribute('href');
try {
const data = await (await fetch(`${IMPORT_URL}OPS/${href}`, { credentials: 'include' })).arrayBuffer();
epubData.file(href, data);
console.log('Finished downloading', href);
} catch(e) {
throw `Failed to download ${href}: ${e}`;
}
}
alert('Finished downloading data! Click OK to start compression.');
window.__savedTextbook = epub;
let highestPercent = 0;
const data = await epub.generateInternalStream({ type: 'blob' }).accumulate(({ percent }) => {
const intPercent = Math.floor(percent);
if (intPercent > highestPercent) {
console.log(intPercent+'% complete');
highestPercent = intPercent
}
});
alert('Finished compressing textbook! Click OK to start download.');
window.__savedTextbookEpub = data;
const url = URL.createObjectURL(data);
const tmpLink = document.createElement('a');
tmpLink.href = url;
const possibleTitle = opf.querySelector('metadata title');
const titleString = possibleTitle ? possibleTitle.innerHTML : 'textbook';
tmpLink.download = titleString + '.epub';
tmpLink.click();
URL.revokeObjectURL(url);
}).catch(err => alert('Textbook download failed because an error occurred: '+err));
Loading…
Cancel
Save