Skip to content

Instantly share code, notes, and snippets.

@miere43
Created February 25, 2017 21:29
Show Gist options
  • Save miere43/9d60fe6701b7d878d59763469e64bcad to your computer and use it in GitHub Desktop.
Save miere43/9d60fe6701b7d878d59763469e64bcad to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Jisho Audio Downloader
// @namespace http://miere.ru/
// @version 0.1
// @description Adds download audio button to Jisho.org pages which downloads word audio clips.
// @author Vladislav <miere> Vorobiev
// @match http://jisho.org/search/*
// @match http://jisho.org/word/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
function getWordNameFromAudioID(audioID) {
if (!audioID || audioID.length < 7) return "unknown";
var result = "";
for (var i = 6; i < audioID.length && audioID[i] !== ':'; ++i) {
result = result + audioID[i];
}
return result;
}
function getFileExtension(file) {
if (!file || file.length === 0) return "";
var extension = [];
var seperatorFound = false;
for (var i = file.length - 1; i > 0; --i) {
if (file[i] === '.') {
extension.add(file[i]);
extension.reverse();
break;
} else {
extension.add(file[i]);
}
}
return extension.join('');
}
function insertNodeAfter(insertNode, afterNode) {
afterNode.parentNode.insertBefore(insertNode, afterNode.nextSibling);
}
function downloadFileWithFileName(url, fileName) {
var URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest(),
a = document.createElement('a'), file;
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onerror = function() {
a.href = url;
a.download = fileName;
a.click();
};
xhr.onload = function() {
file = new Blob([xhr.response], { type : 'application/octet-stream' });
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
};
xhr.send();
}
var audioElements = document.getElementsByTagName('audio');
for (var i = 0; i < audioElements.length; ++i) {
var audioElement = audioElements[i];
var audioID = audioElement.id;
var audioLinkElement = audioElement.nextElementSibling;
if (!audioLinkElement || !audioLinkElement.dataset || audioLinkElement.dataset.id != audioID) {
continue; // @TODO: Site layout has changed, skip this or show alert?
}
var downloadAudioElement = document.createElement('a');
downloadAudioElement.className = 'concept_light-status_link';
downloadAudioElement.dataset.href = audioElement.children[0].src;
downloadAudioElement.dataset.download = getWordNameFromAudioID(audioID) + getFileExtension(downloadAudioElement.dataset.href);
downloadAudioElement.innerText = 'Download audio';
downloadAudioElement.addEventListener('click', function(ev) {
downloadFileWithFileName(ev.target.dataset.href, ev.target.dataset.download);
});
insertNodeAfter(downloadAudioElement, audioLinkElement);
}
})();
@robjweiss
Copy link

Thanks for writing this script. I was about to create my own and was glad to see that someone had already taken care of it. It's been a while since you wrote this, but I could not get the current version of the script to work on Chrome Version 73.0.3683.103. The CORS policy does not allow for the response to load. I created a fork that uses a proxy server that appends the necessary CORS header to the response so that the browser will load it. Feel free to pull those changes if you find them useful.

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