🏠 Home 

Auto mp3 downloader

Automatic download of multiple mp3s from https://www.emp3z.com. Just insert list of songs into textarea, push the button and wait till it finishes.


Install this script?
  1. // ==UserScript==
  2. // @name Auto mp3 downloader
  3. // @description Automatic download of multiple mp3s from https://www.emp3z.com. Just insert list of songs into textarea, push the button and wait till it finishes.
  4. // @author Bladito
  5. // @version 0.6.6
  6. // @homepageURL https://greasyfork.org/en/users/55159-bladito
  7. // @match *://www.emp3x.ws/*
  8. // @match *://www.emp3z.ws/*
  9. // @match *://www.emp3z.co/*
  10. // @match *://www.emp3z.com/*
  11. // @match *://www.emp3c.com/*
  12. // @match *://www.emp3s.co/*
  13. // @match *://www.emp3d.co/*
  14. // @match *://www.emp3c.co/*
  15. // @match *://www.emp3e.com/*
  16. // @match *://y-api.org/button/*
  17. // @namespace Bladito/auto-mp3-downloader
  18. // @require http://code.jquery.com/jquery-latest.js
  19. // @grant none
  20. // ==/UserScript==
  21. (function($) {
  22. 'use strict';
  23. // run this code in inner cross origin iframe
  24. if (isSubstringInURL('/button/')) {
  25. log('SCRIPT 2');
  26. rememberUrlForSong();
  27. return;
  28. }
  29. log('SCRIPT 1');
  30. window.addEventListener('message', receiveMessage, false);
  31. function receiveMessage(evt) {
  32. log('RECEIVED MESSAGE', evt);
  33. if (evt.data && evt.data.indexOf('Bladito_link:') === 0) {
  34. setFoundDataForCurrentSong($('.song-list ul:eq(0) li:eq(0) a b').text(), evt.data.replace('Bladito_link:', ''));
  35. findUrlForNextSong();
  36. }
  37. }
  38. // block annoying popups
  39. var openWindow = window.open;
  40. window.open = function() {
  41. console.log('[Bladito/auto-mp3-downloader] Blocked opening window');
  42. return;
  43. };
  44. detectAdditionInDOM($('body').get(0), function(mutation) {
  45. if (mutation.target.tagName === 'BODY' && mutation.addedNodes[0].tagName === 'A') {
  46. console.log('[Bladito/auto-mp3-downloader] Removing overlay');
  47. $(mutation.addedNodes[0]).remove();
  48. }
  49. });
  50. var storageName = 'Bladito_autoDownloader_toDL';
  51. var storageStateName = 'Bladito_autoDownloader_state';
  52. var storageNowFinding = 'Bladito_autoDownloader_nowFinding';
  53. var storageDebugName = 'Bladito_autoDownloader_isDebug';
  54. var artistAndSongOnSeparateLines = false;
  55. var STATE = {
  56. IDLE:'IDLE',
  57. FINDING_URLS:'FINDING_URLS',
  58. DOWNLOADING:'DOWNLOADING'
  59. };
  60. init();
  61. log('state=',getState(),window.location.pathname);
  62. if (getState() === STATE.IDLE || getState() === STATE.DOWNLOADING) {
  63. insertCustomHTMLElements();
  64. }
  65. if (getState() === STATE.IDLE) {
  66. printR###lts(true);
  67. }
  68. if (getState() === STATE.FINDING_URLS) {
  69. if (isR###ltsPage()) {
  70. log('song found');
  71. window.location.href = $('a[href^="/download"')[0].href;
  72. } else if (isDetailPage()) {
  73. log('remembering download url');
  74. $('#dl1').click(); // this will fetch another iframe
  75. //rememberUrlForSong();
  76. } else if (isNotFoundPage()) {
  77. log('song not found');
  78. setFoundDataForCurrentSong('N/A', undefined);
  79. findUrlForNextSong();
  80. } else if (isMainPage()) {
  81. addResetButton();
  82. }
  83. }
  84. if (getState() === STATE.DOWNLOADING) {
  85. downloadSongs();
  86. printR###lts();
  87. resetInitialState(true);
  88. }
  89. //------------------------------------------------------------------------------------------------------------------
  90. function init() {
  91. if (!getState()) {
  92. setState(STATE.IDLE);
  93. }
  94. if (getState() === STATE.FINDING_URLS && !getNextSongToFind()) {
  95. setState(STATE.DOWNLOADING);
  96. }
  97. }
  98. function findDownloadUrls() {
  99. var textAreaVal = $('#my-dl-list').val(),
  100. mp3List = prepareMp3List(textAreaVal);
  101. if (typeof mp3List === 'string') {
  102. showError(mp3List);
  103. return;
  104. }
  105. setMp3List(mp3List);
  106. setState(STATE.FINDING_URLS);
  107. log('to dl ', JSON.stringify(mp3List));
  108. findUrlForNextSong();
  109. }
  110. function findUrlForNextSong() {
  111. var nextSong = getNextSongToFind();
  112. if (nextSong) {
  113. log('gonna find ', nextSong.name);
  114. setNowFinding(nextSong.name);
  115. $('input[name="search"]', window.parent.document).val(nextSong.name);
  116. $('input[name="search"]', window.parent.document).parents('form').submit();
  117. //$('input[name="search"]').val(nextSong.name);
  118. //$('input[name="search"]').parents('form').submit();
  119. } else {
  120. location.href = 'https://www.emp3z.com/';
  121. }
  122. }
  123. function setFoundDataForCurrentSong(songName, songUrl) {
  124. var currentSong = getNowFinding(),
  125. list = getMp3List();
  126. for (var i=0; i<list.length; i+=1) {
  127. if (list[i].name === currentSong) {
  128. list[i].processed = true;
  129. list[i].url = songUrl;
  130. list[i].foundName = songName;
  131. log('SAVED URL ', songUrl, ' for song ', list[i].name);
  132. break;
  133. }
  134. }
  135. setMp3List(list);
  136. }
  137. function getNextSongToFind() {
  138. var list = getMp3List();
  139. for (var i=0; i<list.length; i+=1) {
  140. if (list[i].processed !== true) {
  141. return list[i];
  142. }
  143. }
  144. return undefined;
  145. }
  146. function prepareMp3List(mp3listString) {
  147. var i, list, r###lt = [];
  148. if (!mp3listString || mp3listString.length === 0) {
  149. return 'EMPTY_INPUT';
  150. }
  151. list = mp3listString.split('\n');
  152. if (artistAndSongOnSeparateLines) {
  153. if (list.length % 2 !== 0) {
  154. return 'ODD_NUMBER';
  155. }
  156. for (i=1; i<list.length; i+=2) {
  157. r###lt.push({
  158. name: list[i-1] + ' ' + list[i]
  159. });
  160. }
  161. } else {
  162. for (i=0; i<list.length; i+=1) {
  163. r###lt.push({
  164. name: list[i]
  165. });
  166. }
  167. }
  168. return r###lt;
  169. }
  170. function rememberUrlForSong() {
  171. /*
  172. var interval = setInterval(function() {
  173. log('finding link...');
  174. var link = $($('iframe')[0].contentWindow.document).find('#ytd')[0];
  175. if (link && link.href && link.href.length > 0) {
  176. window.clearInterval(interval);
  177. log('found link! ', link.href);
  178. setFoundDataForCurrentSong($('.song-list ul:eq(0) li:eq(0) a b').text(), link.href);
  179. findUrlForNextSong();
  180. }
  181. }, 1000);
  182. */
  183. var interval = setInterval(function() {
  184. log('finding link...');
  185. var link = $('#button a')[0];
  186. if (link && link.href === 'https://y-api.org/') {
  187. $('#progress').click();
  188. }
  189. if (link && link.href && link.href.length > 0 && link.href !== 'https://y-api.org/') {
  190. window.clearInterval(interval);
  191. log('found link! sending message', link.href);
  192. window.parent.parent.postMessage('Bladito_link:' + link.href, '*');
  193. }
  194. }, 1000);
  195. }
  196. function downloadSongs() {
  197. var list = getMp3List();
  198. for (var i=0; i<list.length; i+=1) {
  199. if (list[i].url) {
  200. openWindow(list[i].url, '_blank');
  201. }
  202. }
  203. }
  204. function resetInitialState(keepList) {
  205. setState(STATE.IDLE);
  206. setNowFinding(null);
  207. if (!keepList) {
  208. setMp3List([]);
  209. }
  210. }
  211. function insertCustomHTMLElements() {
  212. var customElements, searchForm = $('form[action^="/search"]');
  213. customElements =
  214. '<div class="input-group col-lg-8" style="padding-top: 15px;">' +
  215. '<textarea id="my-dl-list" class="form-control" style="height: 120px;" placeholder="Insert one or multiple songs separated by enter."/>' +
  216. '<span class="input-group-btn" style="vertical-align: top;">' +
  217. '<button id="my-btn" class="btn btn-primary" style="height: 100%; min-height: 120px; border: none; padding: 0 14px;">Auto Download</button>' +
  218. '</span>' +
  219. '</div>' +
  220. '<div class="input-group col-lg-8" style="text-align: left;">' +
  221. '<label><input type="checkbox" id="bladito-input-mode" style="margin: 0 2px 0 0; vertical-align: text-top;">Artist and song on separate lines</label>' +
  222. '</div>'
  223. ;
  224. searchForm.append(customElements);
  225. $('#my-btn').click(findDownloadUrls);
  226. $('#bladito-input-mode').click(function() {
  227. artistAndSongOnSeparateLines = $(this).is(':checked');
  228. });
  229. }
  230. function showError(errCode) {
  231. var searchForm = $('form[action^="/search"]');
  232. $('#bladito-error-message').remove();
  233. if (errCode === 'ODD_NUMBER') {
  234. searchForm.prepend('<div id="bladito-error-message" class="input-group col-lg-12" style="height: 50px; line-height: 50px; margin-top: 15px; margin-bottom: 15px; color: white; background-color: #d64747;">'+
  235. 'You inserted ODD number of lines. Unable to continue.</div>');
  236. } else if (errCode === 'EMPTY_INPUT') {
  237. searchForm.prepend('<div id="bladito-error-message" class="input-group col-lg-12" style="height: 50px; line-height: 50px; margin-top: 15px; margin-bottom: 15px; color: white; background-color: #d64747;">'+
  238. 'No songs inserted into textarea!</div>');
  239. }
  240. }
  241. function printR###lts(isOldR###lt) {
  242. var r###ltsHtml,
  243. r###ltsMessageHtml,
  244. list = getMp3List(),
  245. failedCounter = 0,
  246. searchForm = $('form[action^="/search"]'),
  247. r###ltColor = isOldR###lt ? '#008cba;' : '#71bf44;';
  248. r###ltsHtml = '<div class="input-group col-lg-12" style="padding: 15px; border: 1px solid '+r###ltColor+'"><table style="width: 100%;"><tbody><tr><th>Searched Song</th><th>Found Song</th><th></th><tr>';
  249. for (var i=0; i<list.length; i+=1) {
  250. r###ltsHtml += '<tr><td>' + list[i].name + '</td><td>' + list[i].foundName + '</td><td>';
  251. if (list[i].url) {
  252. r###ltsHtml += '<a href="' + list[i].url + '">Redownload</a>';
  253. } else {
  254. r###ltsHtml += 'Not found';
  255. failedCounter += 1;
  256. }
  257. r###ltsHtml += '</td></tr>';
  258. }
  259. setMp3List(list);
  260. r###ltsHtml += '</tbody></table></div>';
  261. r###ltsHtml = $(r###ltsHtml);
  262. if (isOldR###lt) {
  263. r###ltsMessageHtml = '<div class="input-group col-lg-12" style="height: 50px; line-height: 50px; margin-top: 15px; color: white; background-color: '+r###ltColor+'">Last time you searched for:';
  264. } else {
  265. r###ltsMessageHtml = '<div class="input-group col-lg-12" style="height: 50px; line-height: 50px; margin-top: 15px; color: white; background-color: '+r###ltColor+'">Found: ' + (list.length - failedCounter) + '/' + list.length + ' songs.';
  266. }
  267. searchForm.append(r###ltsHtml);
  268. r###ltsHtml.before(r###ltsMessageHtml);
  269. }
  270. function addResetButton() {
  271. var customElements, searchForm = $('form[action^="/search"]');
  272. customElements =
  273. '<div class="input-group col-lg-12" style="height: 50px; margin-top: 15px; color: white; background-color: #d9534f;">Oops, something went wrong :(.' +
  274. '<button id="my-reset-btn" type="button" class="btn btn-primary" style="margin-left: 15px;">Reset to initial state</button>' +
  275. '</div>'
  276. ;
  277. searchForm.append(customElements);
  278. $('#my-reset-btn').click(function() {
  279. resetInitialState();
  280. location.href = 'https://www.emp3z.com/';
  281. });
  282. }
  283. function isR###ltsPage() {
  284. return isSubstringInURL('/mp3/');
  285. }
  286. function isDetailPage() {
  287. return isSubstringInURL('/download/');
  288. }
  289. function isNotFoundPage() {
  290. return isSubstringInURL('/404.php');
  291. }
  292. function isMainPage() {
  293. return window.location.pathname === '/';
  294. }
  295. function isSubstringInURL(substring) {
  296. return window.location.pathname.substring(0, substring.length) === substring;
  297. }
  298. function log() {
  299. if (localStorage.getItem(storageDebugName) === 'true') {
  300. console.log.apply(console, arguments);
  301. }
  302. }
  303. function setState(state) {
  304. localStorage.setItem(storageStateName, state);
  305. }
  306. function getState() {
  307. return localStorage.getItem(storageStateName);
  308. }
  309. function setNowFinding(songName) {
  310. localStorage.setItem(storageNowFinding, songName);
  311. }
  312. function getNowFinding() {
  313. return localStorage.getItem(storageNowFinding);
  314. }
  315. function setMp3List(mp3list) {
  316. localStorage.setItem(storageName, JSON.stringify(mp3list));
  317. }
  318. function getMp3List() {
  319. return JSON.parse(localStorage.getItem(storageName));
  320. }
  321. function detectAdditionInDOM(node, callback) {
  322. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  323. if (node) {
  324. if (MutationObserver) {
  325. var obs = new MutationObserver(function(mutations, observer) {
  326. mutations.forEach(function(mutation) {
  327. if (mutation.addedNodes.length) {
  328. callback(mutation);
  329. }
  330. });
  331. });
  332. obs.observe(node, { childList:true, subtree:true });
  333. } else if (window.addEventListener) {
  334. node.addEventListener('DOMNodeInserted', callback, false);
  335. }
  336. }
  337. }
  338. })(jQuery);