Last active
November 8, 2021 01:05
-
-
Save MikeRawding/9826e5f736316e35b50b1b007209b7a5 to your computer and use it in GitHub Desktop.
Adds button to download all parts of an audio book from Overdrive.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Overdrive Audio Book Downloader | |
// @namespace https://gist.github.com/MikeRawding | |
// @version 0.4 | |
// @description Adds a button to download all parts of an audio book from listen.overdrive.com | |
// @author Mike Rawding | |
// @include *listen.overdrive.com* | |
// @icon https://www.overdrive.com/Content/img/icons/svg/overdrive-app-icon.svg | |
// @grant none | |
// ==/UserScript== | |
(() => { | |
'use strict'; | |
const GM_addStyle = (css) => { | |
const style = document.getElementById("GM_addStyleBy8626") || (function() { | |
const style = document.createElement('style'); | |
style.type = 'text/css'; | |
style.id = "GM_addStyleBy8626"; | |
document.head.appendChild(style); | |
return style; | |
})(); | |
const sheet = style.sheet; | |
sheet.insertRule(css, (sheet.rules || sheet.cssRules || []).length); | |
} | |
GM_addStyle(".download-icon { width: 40px; padding-top: 20px; margin-left: 6px; height: 32px; cursor: pointer;}"); | |
let downloadButton = null | |
const zeroPad = num => { | |
if (num < 10) { | |
return `0${num}` | |
} else { | |
return `${num}` | |
} | |
} | |
const download = async ({ filename, url }) => { | |
const response = await fetch(url) | |
if (response.status !== 200) { | |
throw new Error() | |
} | |
const blob = await response.blob() | |
const downloadUrl = await URL.createObjectURL(blob) | |
const link = document.createElement("a"); | |
link.href = downloadUrl; | |
link.download = filename; | |
document.body.appendChild(link); | |
link.click(); | |
document.body.removeChild(link); | |
} | |
const downloadAll = () => { | |
downloadButton.onclick = () => { } | |
window.bData.spine.forEach((part, index) => { | |
const url = `${window.location.origin}/${part.path}` | |
const filename = `${window.bData.title.main}-Part${zeroPad(index + 1)}` | |
download({ filename, url }) | |
}) | |
// Disable button for a moment so the user doesn't click twice | |
setTimeout(() => { | |
downloadButton.onclick = downloadAll | |
}, 2_000) | |
} | |
const createButton = () => { | |
const builderDiv = document.createElement('div') | |
builderDiv.innerHTML = | |
` | |
<div title="Download All Parts" class="menu-bar-shortcut menu-bar-shortcut-speedo" touch-action="none" style="touch-action: none;"> | |
<svg viewBox="0 0 384 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="download-icon"> | |
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |
<path d="M348.5 264l-148 148.5c-4.7 4.7-12.3 4.7-17 0L35.5 264c-4.7-4.7-4.7-12.3 0-17l7.1-7.1c4.7-4.7 12.3-4.7 17 0l115.4 116V44c0-6.6 5.4-12 12-12h10c6.6 0 12 5.4 12 12v311.9L324.4 240c4.7-4.7 12.3-4.7 17 0l7.1 7.1c4.7 4.6 4.7 12.2 0 16.9zM384 468v-8c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v8c0 6.6 5.4 12 12 12h360c6.6 0 12-5.4 12-12z" stroke="#000000" stroke-width="3" stroke-linecap="round" class="icon-solid"></path> | |
</g> | |
</svg> | |
</div> | |
`.trim() | |
downloadButton = builderDiv.firstChild | |
downloadButton.onclick = downloadAll | |
return downloadButton | |
} | |
/** | |
* Adds download button | |
* Might outrun the rest of the dom, | |
* so keep retrying until the container is ready | |
*/ | |
const addButton = () => { | |
const container = document.getElementsByClassName('nav-action-bar-right') | |
if (container && container[0]) { | |
container[0].appendChild(createButton()) | |
} else { | |
setTimeout(addButton, 10) | |
} | |
} | |
addButton() | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
v0.4