NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @id decibelios-yadg // @name decibelios - YADG // @description This script provides integration with online description generator YADG (http://yadg.cc) // @version 1.0.0 // @namespace yadg // @grant GM_xmlhttpRequest // @require https://yadg.cc/static/js/jsandbox.min.js // @include http*://*decibelios.li/upload.php* // @include http*://*what.cd/requests.php* // @include http*://*what.cd/torrents.php* // @include http*://*waffles.fm/upload.php* // @include http*://*waffles.fm/requests.php* // ==/UserScript== // --------- USER SETTINGS START --------- /* Here you can set site specific default templates. You can find a list of available templates at: https://yadg.cc/api/v2/templates/ */ var defaultWhatFormat = 5, defaultDecibeliosFormat = 5, defaultWafflesFormat = 9; // --------- USER SETTINGS END --------- // --------- THIRD PARTY CODE AREA START --------- // // Creates an object which gives some helper methods to // Save/Load/Remove data to/from the localStorage // // Source from: https://github.com/gergob/localstoragewrapper // function LocalStorageWrapper (applicationPrefix) { "use strict"; if(applicationPrefix == undefined) { throw new Error('El parámetro applicationPrefix ha de ser definido.'); } var delimiter = '_'; //if the passed in value for prefix is not string, it should be converted var keyPrefix = typeof(applicationPrefix) === 'string' ? applicationPrefix : JSON.stringify(applicationPrefix); var localStorage = window.localStorage||unsafeWindow.localStorage; var isLocalStorageAvailable = function() { return typeof(localStorage) != undefined }; var getKeyPrefix = function() { return keyPrefix; }; // // validates if there is a prefix defined for the keys // and checks if the localStorage functionality is available or not // var makeChecks = function(key) { var prefix = getKeyPrefix(); if(prefix == undefined) { throw new Error('No hay prefijo definido, los datos no pueden ser guardados.'); } if(!isLocalStorageAvailable()) { throw new Error('Tu navegador no soporta el almacenamiento local, los datos no pueden ser guardados.'); } //keys are always strings var checkedKey = typeof(key) === 'string' ? key : JSON.stringify(key); return checkedKey; }; // // saves the value associated to the key into the localStorage // var addItem = function(key, value) { var that = this; try{ var checkedKey = makeChecks(key); var combinedKey = that.getKeyPrefix() + delimiter + checkedKey; localStorage.setItem(combinedKey, JSON.stringify(value)); } catch(error) { console.log(error); throw error; } }; // // gets the value of the object saved to the key passed as parameter // var getItem = function(key) { var that = this; var result = undefined; try{ var checkedKey = makeChecks(key); var combinedKey = that.getKeyPrefix() + delimiter + checkedKey; var resultAsJSON = localStorage.getItem(combinedKey); result = JSON.parse(resultAsJSON); } catch(error) { console.log(error); throw error; } return result; }; // // returns all the keys from the localStorage // var getAllKeys = function() { var prefix = getKeyPrefix(); var results = []; if(prefix == undefined) { throw new Error('No hay prefijo definido, los datos no pueden ser guardados.'); } if(!isLocalStorageAvailable()) { throw new Error('Tu navegador no soporta el almacenamiento local, los datos no pueden ser guardados.'); } for(var key in localStorage) { if(key.indexOf(prefix) == 0) { var keyParts = key.split(delimiter); results.push(keyParts[1]); } } return results; }; // // removes the value associated to the key from the localStorage // var removeItem = function(key) { var that = this; var result = false; try{ var checkedKey = makeChecks(key); var combinedKey = that.getKeyPrefix() + delimiter + checkedKey; localStorage.removeItem(combinedKey); result = true; } catch(error) { console.log(error); throw error; } return result; }; // // removes all the values from the localStorage // var removeAll = function() { var that = this; try{ var allKeys = that.getAllKeys(); for(var i=0; i < allKeys.length; ++i) { var checkedKey = makeChecks(allKeys[i]); var combinedKey = that.getKeyPrefix() + delimiter + checkedKey; localStorage.removeItem(combinedKey); } } catch(error) { console.log(error); throw error; } }; // make some of the functionalities public return { isLocalStorageAvailable : isLocalStorageAvailable, getKeyPrefix : getKeyPrefix, addItem : addItem, getItem : getItem, getAllKeys : getAllKeys, removeItem : removeItem, removeAll : removeAll } } // --------- THIRD PARTY CODE AREA END --------- var yadg_util = { exec : function exec(fn) { var script = document.createElement('script'); script.setAttribute("type", "application/javascript"); script.textContent = '(' + fn + ')();'; document.body.appendChild(script); // run the script document.body.removeChild(script); // clean up }, // handle for updating page css, taken from one of hateradio's scripts addCSS : function(style) { if(!this.style) { this.style = document.createElement('style'); this.style.type = 'text/css'; (document.head || document.getElementsByTagName('head')[0]).appendChild(this.style); } this.style.appendChild(document.createTextNode(style+'\n')); }, setValueIfSet: function(value,input,cond) { if (cond) { input.value = value; } else { input.value = ''; } }, // negative count will remove, positive count will add given number of artist boxes addRemoveArtistBoxes : function(count) { if (count != 0) { if (count < 0) { for (var i = 0; i < -count; i++) { yadg_util.exec(function() {RemoveArtistField()}); } } else { for (var i = 0; i < count; i++) { yadg_util.exec(function() {AddArtistField()}); } } } }, getOptionOffsets : function(select) { var option_offsets = {}; for (var j = 0; j < select.options.length; j++) { option_offsets[select.options[j].value] = select.options[j].index; } return option_offsets; }, storage : new LocalStorageWrapper("yadg"), settings : new LocalStorageWrapper("yadgSettings") }; // very simple wrapper for XmlHttpRequest function requester(url, method, callback, data, error_callback) { this.data = data; this.url = url; this.method = method; if (!error_callback) { error_callback = yadg.failed_callback; } this.send = function() { details = { url : this.url, method : this.method, onload : function(response) { if (response.status === 200) { callback(JSON.parse(response.responseText)); } else if (response.status === 401) { yadg.failed_authentication_callback(); } else { error_callback(); } }, onerror : error_callback }; if (method == "POST") { details.data = JSON.stringify(this.data); } var headers = { "Accept" : "application/json", "Content-Type" : "application/json" }; if (yadg_util.settings.getItem(factory.KEY_API_TOKEN)) { headers.Authorization = "Token " + yadg_util.settings.getItem(factory.KEY_API_TOKEN); } details.headers = headers; GM_xmlhttpRequest(details); }; } var yadg_sandbox = { KEY_LAST_WARNING : "templateLastWarning", init : function(callback) { GM_xmlhttpRequest({ method: 'GET', url: yadg.yadgHost + '/static/js/jsandbox-worker.js', onload: function(response) { var script, dataURL = null; if (response.status === 200) { script = response.responseText; var blob = new Blob([script], {type: 'application/javascript'}); var URL = window.webkitURL || window.URL; dataURL = URL.createObjectURL(blob); yadg_sandbox.initCallback(dataURL); yadg_sandbox.loadSwig(callback); } else { yadg_sandbox.initCallbackError(); } }, onerror: function() { yadg_sandbox.initCallbackError(); } }); }, loadSwig : function(callback) { // importScripts for the web worker will not work in Firefox with cross-domain requests // see: https://bugzilla.mozilla.org/show_bug.cgi?id=756589 // so download the Swig files manually with GM_xmlhttpRequest GM_xmlhttpRequest({ method: 'GET', url: yadg.yadgHost + "/static/js/swig.min.js", onload: function(response) { if (response.status === 200) { yadg_sandbox.swig_script = response.responseText; GM_xmlhttpRequest({ method: 'GET', url: yadg.yadgHost + "/static/js/swig.custom.js", onload: function(response) { if (response.status === 200) { yadg_sandbox.swig_custom_script = response.responseText; callback(); } } }); } } }); }, initializeSwig : function(dependencies) { if (!(this.swig_script && this.swig_custom_script)) { yadg.failed_callback(); return } yadg_sandbox.exec({data: this.swig_script, onerror: yadg.failed_callback}); yadg_sandbox.exec({data: this.swig_custom_script, onerror: yadg.failed_callback}); yadg_sandbox.exec({data: "var myswig = new swig.Swig({ loader: swig.loaders.memory(input.templates), autoescape: false }), i=0; yadg_filters.register_filters(myswig);", input: {templates: dependencies}}); }, renderTemplate : function(template, data, callback, error) { eval_string = "myswig.render(input.template, { locals: input.data, filename: 'scratchpad' + (i++) })"; this.eval({data: eval_string, callback: function(out) {callback(out);}, input: {template: template, data: data}, onerror: function(err){error(err);}}); }, initCallback : function(dataUrl) { JSandbox.url = dataUrl; this.jsandbox = new JSandbox(); this.initError = false; }, resetSandbox : function() { this.jsandbox.terminate(); this.jsandbox = new JSandbox(); }, load : function(options) { this.jsandbox.load(options); }, exec : function(options) { this.jsandbox.exec(options); }, eval : function(options) { this.jsandbox.eval(options); }, initCallbackError : function() { this.initError = true; var last_warning = yadg_util.storage.getItem(this.KEY_LAST_WARNING), now = new Date(); if (last_warning === null || now.getTime() - (new Date(last_warning)).getTime() > factory.CACHE_TIMEOUT) { alert("No se han podido cargar los ficheros necesarios para ejecutar YADG. Si el error persiste puede que necesites actualizar el script. Solo recivirás este mensaje una vez al día."); yadg_util.storage.addItem(this.KEY_LAST_WARNING, now); } } }; var factory = { // storage keys for cache KEY_LAST_CHECKED : "lastChecked", KEY_SCRAPER_LIST : "scraperList", KEY_FORMAT_LIST : "formatList", // storage keys for settings KEY_API_TOKEN : "apiToken", KEY_DEFAULT_TEMPLATE : "defaultTemplate", KEY_DEFAULT_SCRAPER : "defaultScraper", CACHE_TIMEOUT : 1000*60*60*24, // 24 hours UPDATE_PROGRESS : 0, locations : new Array( { name : 'whatcd_upload', regex : /http(s)?\:\/\/(.*\.)?what\.cd\/upload\.php.*/i }, { name : 'whatcd_edit', regex : /http(s)?\:\/\/(.*\.)?what\.cd\/torrents\.php\?action=editgroup&groupid=.*/i }, { name : 'whatcd_request', regex : /http(s)?\:\/\/(.*\.)?what\.cd\/requests\.php\?action=new/i }, { name : 'whatcd_torrent_overview', regex : /http(s)?\:\/\/(.*\.)?what\.cd\/torrents\.php\?id=.*/i }, { name : 'decibeliosli_upload', regex : /http(s)?\:\/\/(.*\.)?decibelios\.li\/upload\.php.*/i }, { name : 'decibeliosli_edit', regex : /http(s)?\:\/\/(.*\.)?decibelios\.li\/torrents\.php\?action=editgroup&groupid=.*/i }, { name : 'decibeliosli_request', regex : /http(s)?\:\/\/(.*\.)?decibelios\.li\/requests\.php\?action=new/i }, { name : 'decibeliosli_torrent_overview', regex : /http(s)?\:\/\/(.*\.)?decibelios\.li\/torrents\.php\?id=.*/i }, { name : 'waffles_upload', regex : /http(s)?\:\/\/(.*\.)?waffles\.fm\/upload\.php.*/i }, { name : 'waffles_request', regex : /http(s)?\:\/\/(.*\.)?waffles\.fm\/requests\.php\?do=add/i } ), determineLocation : function(uri) { for (var i = 0; i < this.locations.length; i++) { if (this.locations[i].regex.test(uri)) { return this.locations[i].name; } } return ""; }, init : function() { this.currentLocation = this.determineLocation(document.URL); this.insertIntoPage(this.getInputElements()); // set the necessary styles this.setStyles(); // populate settings inputs this.populateSettings(); // add the appropriate action for the button var button = document.getElementById('yadg_submit'); button.addEventListener('click',function(e) { e.preventDefault(); yadg.makeRequest();},false); // add the action for the options toggle var toggleLink = document.getElementById('yadg_toggle_options'); if (toggleLink !== null) { toggleLink.addEventListener('click', function(e) { e.preventDefault(); var optionsDiv = document.getElementById('yadg_options'), display = optionsDiv.style.display; if (display == 'none' || display == '') { optionsDiv.style.display = 'block'; } else { optionsDiv.style.display = 'none'; } }); } // add the action for the template select var formatSelect = this.getFormatSelect(); if (formatSelect !== null) { formatSelect.addEventListener('change', function(e) { if (yadg_renderer.hasCached()) { yadg_renderer.renderCached(this.value, factory.setDescriptionBoxValue, factory.setDescriptionBoxValue); } }); } // add the action to the save settings link var saveSettingsLink = document.getElementById('yadg_save_settings'); if (saveSettingsLink !== null) { saveSettingsLink.addEventListener('click', function(e) { e.preventDefault(); factory.saveSettings(); alert("Preferencias guardadas correctamente."); }); } // add the action to the clear cache link var clearCacheLink = document.getElementById('yadg_clear_cache'); if (clearCacheLink !== null) { clearCacheLink.addEventListener('click', function(e) { e.preventDefault(); yadg_util.storage.removeAll(); alert("Caché borrada. Por favor refresca la página para que haga efecto."); }); } var last_checked = yadg_util.storage.getItem(factory.KEY_LAST_CHECKED); if (last_checked === null || (new Date()).getTime() - (new Date(last_checked)).getTime() > factory.CACHE_TIMEOUT) { // update the scraper and formats list factory.UPDATE_PROGRESS = 1; yadg.getScraperList(factory.setScraperSelect); yadg.getFormatsList(factory.setFormatSelect); } else { factory.setScraperSelect(yadg_util.storage.getItem(factory.KEY_SCRAPER_LIST)); factory.setFormatSelect(yadg_util.storage.getItem(factory.KEY_FORMAT_LIST)); } }, getApiTokenInput : function() { return document.getElementById('yadg_api_token'); }, populateSettings : function() { var api_token = yadg_util.settings.getItem(factory.KEY_API_TOKEN); if (api_token) { var api_token_input = factory.getApiTokenInput(); api_token_input.value = api_token; } }, saveSettings : function() { var scraper_select = factory.getScraperSelect(), template_select = factory.getFormatSelect(), api_token_input = factory.getApiTokenInput(); var current_scraper = null, current_template = null, api_token = api_token_input.value.trim(); if (scraper_select.options.length > 0) { current_scraper = scraper_select.options[scraper_select.selectedIndex].value; } if (template_select.options.length > 0) { current_template = template_select.options[template_select.selectedIndex].value; } if (current_scraper !== null) { yadg_util.settings.addItem(factory.KEY_DEFAULT_SCRAPER, current_scraper); } if (current_template !== null) { yadg_util.settings.addItem(factory.KEY_DEFAULT_TEMPLATE, current_template); } if (api_token !== "") { yadg_util.settings.addItem(factory.KEY_API_TOKEN, api_token); } else { yadg_util.settings.removeItem(factory.KEY_API_TOKEN); } }, setDescriptionBoxValue : function(value) { var desc_box = factory.getDescriptionBox(); if (desc_box !== null) { desc_box.value = value; } }, getFormatSelect : function() { return document.getElementById('yadg_format'); }, setDefaultFormat : function() { var format_select = factory.getFormatSelect(); var format_offsets = yadg_util.getOptionOffsets(format_select); var default_format = yadg_util.settings.getItem(factory.KEY_DEFAULT_TEMPLATE); if (default_format !== null && default_format in format_offsets) { format_select.selectedIndex = format_offsets[default_format]; } else { // we have no settings so fall back to the hard coded defaults switch (this.currentLocation) { case "waffles_upload": format_select.selectedIndex = format_offsets[defaultWafflesFormat]; break; case "waffles_request": format_select.selectedIndex = format_offsets[defaultWafflesFormat]; break; default: format_select.selectedIndex = format_offsets[defaultWhatFormat]; break; } } }, getScraperSelect : function() { return document.getElementById("yadg_scraper"); }, setDefaultScraper : function() { var default_scraper = yadg_util.settings.getItem(factory.KEY_DEFAULT_SCRAPER); if (default_scraper !== null) { var scraper_select = factory.getScraperSelect(); var scraper_offsets = yadg_util.getOptionOffsets(scraper_select); if (default_scraper in scraper_offsets) { scraper_select.selectedIndex = scraper_offsets[default_scraper]; } } }, setScraperSelect : function(scrapers) { var scraper_select = factory.getScraperSelect(); factory.setSelect(scraper_select, scrapers); factory.setDefaultScraper(); if (factory.UPDATE_PROGRESS > 0) { yadg_util.storage.addItem(factory.KEY_SCRAPER_LIST, scrapers); factory.UPDATE_PROGRESS |= 1<<1; if (factory.UPDATE_PROGRESS === 7) { yadg_util.storage.addItem(factory.KEY_LAST_CHECKED, new Date()); } } }, setFormatSelect : function(templates) { var format_select = factory.getFormatSelect(); var non_utility = []; var save_templates = []; for (var i = 0; i < templates.length; i++) { if (factory.UPDATE_PROGRESS > 0) { yadg_templates.addTemplate(templates[i]); save_templates.push({ id : templates[i]['id'], url : templates[i]['url'], name : templates[i]['name'], owner : templates[i]['owner'], default : templates[i]['default'], isUtility : templates[i]['isUtility'] }); } else { yadg_templates.addTemplateUrl(templates[i]['id'], templates[i]['url']); } if (!templates[i]['isUtility']) { non_utility.push(templates[i]); } } factory.setSelect(format_select, non_utility); factory.setDefaultFormat(); if (factory.UPDATE_PROGRESS > 0) { yadg_util.storage.addItem(factory.KEY_FORMAT_LIST, save_templates); factory.UPDATE_PROGRESS |= 1<<2; if (factory.UPDATE_PROGRESS === 7) { yadg_util.storage.addItem(factory.KEY_LAST_CHECKED, new Date()); } } }, setSelect : function(select, data) { select.options.length = data.length; for (var i = 0; i < data.length; i++) { // we are not using the javascript constructor to create an Option instance because this will create an // incompatibility with jQuery in Chrome which will make it impossible to add a new artist field on What.cd var o = document.createElement("option"); if ('owner' in data[i]) { o.text = data[i]['name'] + " [" + data[i]['owner'] + "]"; } else { o.text = data[i]['name']; } o.value = data[i]['value'] || data[i]['id']; o.selected = data[i]['default']; select.options[i] = o; if (data[i]['default']) { select.selectedIndex = i; } if (data[i]['url']) { o.setAttribute('data-url', data[i]['url']); } } }, setStyles : function() { // general styles yadg_util.addCSS('div#yadg_options{ display:none; margin-top:3px; } input#yadg_input,input#yadg_submit,label#yadg_format_label,a#yadg_scraper_info { margin-right: 5px } div#yadg_response { margin-top:3px; } select#yadg_scraper { margin-right: 2px } #yadg_options_template,#yadg_options_api_token { margin-bottom: 3px; }'); // location specific styles will go here switch(this.currentLocation) { case "waffles_upload": yadg_util.addCSS('div#yadg_response ul { margin-left: 0 !important; padding-left: 0 !important; }'); break; case "waffles_request": yadg_util.addCSS('div#yadg_response ul { margin-left: 0 !important; padding-left: 0 !important; }'); break; default: break; } }, getInputElements : function() { var buttonHTML = '<input type="submit" value="Buscar" id="yadg_submit"/>', scraperSelectHTML = '<select name="yadg_scraper" id="yadg_scraper"></select>', optionsHTML = '<div id="yadg_options"><div id="yadg_options_template"><label for="yadg_format" id="yadg_format_label">Plantilla:</label><select name="yadg_format" id="yadg_format"></select></div><div id="yadg_options_api_token"><label for="yadg_api_token" id="yadg_api_token_label">API token (<a href="https://yadg.cc/api/token" target="_blank">Obtén uno aquí</a>):</label> <input type="text" name="yadg_api_token" id="yadg_api_token" size="50" /></div><div id="yadg_options_links"><a id="yadg_save_settings" href="#" title="Guardar el scraper escogido y la plantilla como por defecto para este sitio y guarda el token de la API.">Guardar preferencias</a> <span class="yadg_separator">|</span> <a id="yadg_clear_cache" href="#">Borrar caché</a></div></div>', inputHTML = '<input type="text" name="yadg_input" id="yadg_input" size="60" />', responseDivHTML = '<div id="yadg_response"></div>', toggleOptionsLinkHTML = '<a id="yadg_toggle_options" href="#">Mostrar las preferencias</a>', scraperInfoLink = '<a id="yadg_scraper_info" href="https://yadg.cc/available-scrapers" target="_blank" title="Obtén información adicional sobre las opciones disponibles (en inglés)">[?]</a>'; switch (this.currentLocation) { case "whatcd_upload": var tr = document.createElement('tr'); tr.className = "yadg_tr"; tr.innerHTML = '<td class="label">YADG:</td><td>' + inputHTML + scraperSelectHTML + scraperInfoLink + buttonHTML + toggleOptionsLinkHTML + optionsHTML + responseDivHTML + '</td>'; return tr; case "whatcd_edit": var div = document.createElement('div'); div.className = "yadg_div"; div.innerHTML = '<h3 class="label">YADG</h3>' + inputHTML + scraperSelectHTML + scraperInfoLink + buttonHTML + toggleOptionsLinkHTML + optionsHTML + responseDivHTML; return div; case "whatcd_torrent_overview": var div = document.createElement('div'); div.className = "yadg_div"; div.innerHTML = '<h3 class="label">YADG</h3>' + '<input type="text" name="yadg_input" id="yadg_input" />' + scraperSelectHTML + scraperInfoLink + buttonHTML + optionsHTML + responseDivHTML; return div; case "whatcd_request": var tr = document.createElement('tr'); tr.className = "yadg_tr"; tr.innerHTML = '<td class="label">YADG:</td><td>' + inputHTML + scraperSelectHTML + scraperInfoLink + buttonHTML + toggleOptionsLinkHTML + optionsHTML + responseDivHTML + '</td>'; return tr; case "decibeliosli_upload": var tr = document.createElement('tr'); tr.className = "yadg_tr"; tr.innerHTML = '<td class="label">YADG:</td><td>' + inputHTML + scraperSelectHTML + scraperInfoLink + buttonHTML + toggleOptionsLinkHTML + optionsHTML + responseDivHTML + '</td>'; return tr; case "decibeliosli_edit": var div = document.createElement('div'); div.className = "yadg_div"; div.innerHTML = '<h3 class="label">YADG</h3>' + inputHTML + scraperSelectHTML + scraperInfoLink + buttonHTML + toggleOptionsLinkHTML + optionsHTML + responseDivHTML; return div; case "decibeliosli_torrent_overview": var div = document.createElement('div'); div.className = "yadg_div"; div.innerHTML = '<h3 class="label">YADG</h3>' + '<input type="text" name="yadg_input" id="yadg_input" />' + scraperSelectHTML + scraperInfoLink + buttonHTML + optionsHTML + responseDivHTML; return div; case "decibeliosli_request": var tr = document.createElement('tr'); tr.className = "yadg_tr"; tr.innerHTML = '<td class="label">YADG:</td><td>' + inputHTML + scraperSelectHTML + scraperInfoLink + buttonHTML + toggleOptionsLinkHTML + optionsHTML + responseDivHTML + '</td>'; return tr; case "waffles_upload": var tr = document.createElement('tr'); tr.className = "yadg_tr"; tr.innerHTML = '<td class="heading" valign="top" align="right"><label for="yadg_input">YADG:</label></td><td>' + inputHTML + scraperSelectHTML + scraperInfoLink + buttonHTML + toggleOptionsLinkHTML + optionsHTML + responseDivHTML + '</td>'; return tr; case "waffles_request": var tr = document.createElement('tr'); tr.className = "yadg_tr"; tr.innerHTML = '<td style="text-align:left;width:100px;">YADG:</td><td style="text-align:left;">' + inputHTML + scraperSelectHTML + scraperInfoLink + buttonHTML + toggleOptionsLinkHTML + optionsHTML + responseDivHTML + '</td>'; return tr; default: // that should actually never happen return document.createElement('div'); } }, insertIntoPage : function(element) { switch (this.currentLocation) { case "whatcd_upload": var year_tr = document.getElementById('year_tr'); year_tr.parentNode.insertBefore(element,year_tr); break; case "whatcd_edit": var summary_input = document.getElementsByName('summary')[0]; summary_input.parentNode.insertBefore(element,summary_input.nextSibling.nextSibling); break; case "whatcd_torrent_overview": var add_artists_box = document.getElementsByClassName("box_addartists")[0]; add_artists_box.appendChild(element); break; case "whatcd_request": var artist_tr = document.getElementById('artist_tr'); artist_tr.parentNode.insertBefore(element,artist_tr); break; case "decibeliosli_upload": var year_tr = document.getElementById('year_tr'); year_tr.parentNode.insertBefore(element,year_tr); break; case "decibeliosli_edit": var summary_input = document.getElementsByName('summary')[0]; summary_input.parentNode.insertBefore(element,summary_input.nextSibling.nextSibling); break; case "decibeliosli_torrent_overview": var add_artists_box = document.getElementsByClassName("box_addartists")[0]; add_artists_box.appendChild(element); break; case "decibeliosli_request": var artist_tr = document.getElementById('artist_tr'); artist_tr.parentNode.insertBefore(element,artist_tr); break; case "waffles_upload": var submit_button = document.getElementsByName('submit')[0]; submit_button.parentNode.parentNode.parentNode.insertBefore(element,submit_button.parentNode.parentNode); break; case "waffles_request": var category_select = document.getElementsByName('category')[0]; category_select.parentNode.parentNode.parentNode.insertBefore(element,category_select.parentNode.parentNode); break; default: break; } }, getDescriptionBox : function() { switch (this.currentLocation) { case "whatcd_upload": return document.getElementById('album_desc'); case "whatcd_edit": return document.getElementsByName('body')[0]; case "whatcd_torrent_overview": if (!this.hasOwnProperty("dummybox")) { this.dummybox = document.createElement('div'); } return this.dummybox; case "whatcd_request": return document.getElementsByName('description')[0]; case "decibeliosli_upload": return document.getElementById('album_desc'); case "decibeliosli_edit": return document.getElementsByName('body')[0]; case "decibeliosli_torrent_overview": if (!this.hasOwnProperty("dummybox")) { this.dummybox = document.createElement('div'); } return this.dummybox; case "decibeliosli_request": return document.getElementsByName('description')[0]; case "waffles_upload": return document.getElementById('descr'); case "waffles_request": return document.getElementsByName('information')[0]; default: // that should actually never happen return document.createElement('div'); } }, getFormFillFunction : function() { switch (this.currentLocation) { case "whatcd_upload": var f = function(rawData) { var artist_inputs = document.getElementsByName("artists[]"), album_title_input = document.getElementById("title"), year_input = document.getElementById("year"), label_input = document.getElementById("record_label"), catalog_input = document.getElementById("catalogue_number"), tags_input = document.getElementById("tags"), data = yadg.prepareRawResponse(rawData); if (data.artists != false) { yadg_util.addRemoveArtistBoxes(data.artists_length - artist_inputs.length); artist_inputs = document.getElementsByName("artists[]"); for (var i = 0; i < artist_inputs.length; i++) { var artist_input = artist_inputs[i], type_select = artist_input.nextSibling; while (type_select.tagName != 'SELECT') { type_select = type_select.nextSibling; } artist_input.value = data.artist_keys[i]; option_offsets = yadg_util.getOptionOffsets(type_select); // an artist can have multiple types, we only take one of them into account though // with this priority: Main > Guest > Remixer if (data.artists[data.artist_keys[i]].indexOf("main") != -1) { type_select.selectedIndex = option_offsets[1]; } else if (data.artists[data.artist_keys[i]].indexOf("guest") != -1) { type_select.selectedIndex = option_offsets[2]; } else if (data.artists[data.artist_keys[i]].indexOf("remixer") != -1) { type_select.selectedIndex = option_offsets[3]; } else { type_select.selectedIndex = option_offsets[1]; } } } else { for (var i = 0; i < artist_inputs.length; i++) { artist_inputs[i].value = ''; } } if (data.tags != false) { tags_input.value = data.tag_string.toLowerCase(); } else { tags_input.value = ''; } yadg_util.setValueIfSet(data.year,year_input,data.year != false); yadg_util.setValueIfSet(data.title,album_title_input,data.title != false); yadg_util.setValueIfSet(data.label,label_input,data.label != false); yadg_util.setValueIfSet(data.catalog,catalog_input,data.catalog != false); }; return f; case "whatcd_edit": f = function(rawData) { var year_input = document.getElementsByName("year")[0], label_input = document.getElementsByName("record_label")[0], catalog_input = document.getElementsByName("catalogue_number")[0], data = yadg.prepareRawResponse(rawData); yadg_util.setValueIfSet(data.year,year_input,data.year != false); yadg_util.setValueIfSet(data.label,label_input,data.label != false); yadg_util.setValueIfSet(data.catalog,catalog_input,data.catalog != false); }; return f; case "whatcd_torrent_overview": f = function(rawData) { var artist_inputs = document.getElementsByName("aliasname[]"), data = yadg.prepareRawResponse(rawData); if (data.artists != false) { yadg_util.addRemoveArtistBoxes(data.artists_length - artist_inputs.length); artist_inputs = document.getElementsByName("aliasname[]"); for (var i = 0; i < artist_inputs.length; i++) { var artist_input = artist_inputs[i], type_select = artist_input.nextSibling; while (type_select.tagName != 'SELECT') { type_select = type_select.nextSibling; } artist_input.value = data.artist_keys[i]; option_offsets = yadg_util.getOptionOffsets(type_select); // an artist can have multiple types, we only take one of them into account though // with this priority: Main > Guest > Remixer if (data.artists[data.artist_keys[i]].indexOf("main") != -1) { type_select.selectedIndex = option_offsets[1]; } else if (data.artists[data.artist_keys[i]].indexOf("guest") != -1) { type_select.selectedIndex = option_offsets[2]; } else if (data.artists[data.artist_keys[i]].indexOf("remixer") != -1) { type_select.selectedIndex = option_offsets[3]; } else { type_select.selectedIndex = option_offsets[1]; } } } else { for (var i = 0; i < artist_inputs.length; i++) { artist_inputs[i].value = ''; } } }; return f; case "whatcd_request": var f = function(rawData) { var artist_inputs = document.getElementsByName("artists[]"), album_title_input = document.getElementsByName("title")[0], year_input = document.getElementsByName("year")[0], label_input = document.getElementsByName("recordlabel")[0], catalog_input = document.getElementsByName("cataloguenumber")[0], tags_input = document.getElementById("tags"), data = yadg.prepareRawResponse(rawData); if (data.artists != false) { yadg_util.addRemoveArtistBoxes(data.artists_length - artist_inputs.length); artist_inputs = document.getElementsByName("artists[]"); for (var i = 0; i < artist_inputs.length; i++) { var artist_input = artist_inputs[i], type_select = artist_input.nextSibling; while (type_select.tagName != 'SELECT') { type_select = type_select.nextSibling; } artist_input.value = data.artist_keys[i]; option_offsets = yadg_util.getOptionOffsets(type_select); // an artist can have multiple types, we only take one of them into account though // with this priority: Main > Guest > Remixer if (data.artists[data.artist_keys[i]].indexOf("main") != -1) { type_select.selectedIndex = option_offsets[1]; } else if (data.artists[data.artist_keys[i]].indexOf("guest") != -1) { type_select.selectedIndex = option_offsets[2]; } else if (data.artists[data.artist_keys[i]].indexOf("remixer") != -1) { type_select.selectedIndex = option_offsets[3]; } else { type_select.selectedIndex = option_offsets[1]; } } } else { for (var i = 0; i < artist_inputs.length; i++) { artist_inputs[i].value = ''; } } if (data.tags != false) { tags_input.value = data.tag_string.toLowerCase(); } else { tags_input.value = ''; } yadg_util.setValueIfSet(data.year,year_input,data.year != false); yadg_util.setValueIfSet(data.title,album_title_input,data.title != false); yadg_util.setValueIfSet(data.label,label_input,data.label != false); yadg_util.setValueIfSet(data.catalog,catalog_input,data.catalog != false); }; return f; case "decibeliosli_upload": var f = function(rawData) { var artist_inputs = document.getElementsByName("artists[]"), album_title_input = document.getElementById("title"), year_input = document.getElementById("year"), label_input = document.getElementById("record_label"), catalog_input = document.getElementById("catalogue_number"), tags_input = document.getElementById("tags"), data = yadg.prepareRawResponse(rawData); if (data.artists != false) { yadg_util.addRemoveArtistBoxes(data.artists_length - artist_inputs.length); artist_inputs = document.getElementsByName("artists[]"); for (var i = 0; i < artist_inputs.length; i++) { var artist_input = artist_inputs[i], type_select = artist_input.nextSibling; while (type_select.tagName != 'SELECT') { type_select = type_select.nextSibling; } artist_input.value = data.artist_keys[i]; option_offsets = yadg_util.getOptionOffsets(type_select); // an artist can have multiple types, we only take one of them into account though // with this priority: Main > Guest > Remixer if (data.artists[data.artist_keys[i]].indexOf("main") != -1) { type_select.selectedIndex = option_offsets[1]; } else if (data.artists[data.artist_keys[i]].indexOf("guest") != -1) { type_select.selectedIndex = option_offsets[2]; } else if (data.artists[data.artist_keys[i]].indexOf("remixer") != -1) { type_select.selectedIndex = option_offsets[3]; } else { type_select.selectedIndex = option_offsets[1]; } } } else { for (var i = 0; i < artist_inputs.length; i++) { artist_inputs[i].value = ''; } } if (data.tags != false) { tags_input.value = data.tag_string.toLowerCase(); } else { tags_input.value = ''; } yadg_util.setValueIfSet(data.year,year_input,data.year != false); yadg_util.setValueIfSet(data.title,album_title_input,data.title != false); yadg_util.setValueIfSet(data.label,label_input,data.label != false); yadg_util.setValueIfSet(data.catalog,catalog_input,data.catalog != false); }; return f; case "decibeliosli_edit": f = function(rawData) { var year_input = document.getElementsByName("year")[0], label_input = document.getElementsByName("record_label")[0], catalog_input = document.getElementsByName("catalogue_number")[0], data = yadg.prepareRawResponse(rawData); yadg_util.setValueIfSet(data.year,year_input,data.year != false); yadg_util.setValueIfSet(data.label,label_input,data.label != false); yadg_util.setValueIfSet(data.catalog,catalog_input,data.catalog != false); }; return f; case "decibeliosli_torrent_overview": f = function(rawData) { var artist_inputs = document.getElementsByName("aliasname[]"), data = yadg.prepareRawResponse(rawData); if (data.artists != false) { yadg_util.addRemoveArtistBoxes(data.artists_length - artist_inputs.length); artist_inputs = document.getElementsByName("aliasname[]"); for (var i = 0; i < artist_inputs.length; i++) { var artist_input = artist_inputs[i], type_select = artist_input.nextSibling; while (type_select.tagName != 'SELECT') { type_select = type_select.nextSibling; } artist_input.value = data.artist_keys[i]; option_offsets = yadg_util.getOptionOffsets(type_select); // an artist can have multiple types, we only take one of them into account though // with this priority: Main > Guest > Remixer if (data.artists[data.artist_keys[i]].indexOf("main") != -1) { type_select.selectedIndex = option_offsets[1]; } else if (data.artists[data.artist_keys[i]].indexOf("guest") != -1) { type_select.selectedIndex = option_offsets[2]; } else if (data.artists[data.artist_keys[i]].indexOf("remixer") != -1) { type_select.selectedIndex = option_offsets[3]; } else { type_select.selectedIndex = option_offsets[1]; } } } else { for (var i = 0; i < artist_inputs.length; i++) { artist_inputs[i].value = ''; } } }; return f; case "decibeliosli_request": var f = function(rawData) { var artist_inputs = document.getElementsByName("artists[]"), album_title_input = document.getElementsByName("title")[0], year_input = document.getElementsByName("year")[0], label_input = document.getElementsByName("recordlabel")[0], catalog_input = document.getElementsByName("cataloguenumber")[0], tags_input = document.getElementById("tags"), data = yadg.prepareRawResponse(rawData); if (data.artists != false) { yadg_util.addRemoveArtistBoxes(data.artists_length - artist_inputs.length); artist_inputs = document.getElementsByName("artists[]"); for (var i = 0; i < artist_inputs.length; i++) { var artist_input = artist_inputs[i], type_select = artist_input.nextSibling; while (type_select.tagName != 'SELECT') { type_select = type_select.nextSibling; } artist_input.value = data.artist_keys[i]; option_offsets = yadg_util.getOptionOffsets(type_select); // an artist can have multiple types, we only take one of them into account though // with this priority: Main > Guest > Remixer if (data.artists[data.artist_keys[i]].indexOf("main") != -1) { type_select.selectedIndex = option_offsets[1]; } else if (data.artists[data.artist_keys[i]].indexOf("guest") != -1) { type_select.selectedIndex = option_offsets[2]; } else if (data.artists[data.artist_keys[i]].indexOf("remixer") != -1) { type_select.selectedIndex = option_offsets[3]; } else { type_select.selectedIndex = option_offsets[1]; } } } else { for (var i = 0; i < artist_inputs.length; i++) { artist_inputs[i].value = ''; } } if (data.tags != false) { tags_input.value = data.tag_string.toLowerCase(); } else { tags_input.value = ''; } yadg_util.setValueIfSet(data.year,year_input,data.year != false); yadg_util.setValueIfSet(data.title,album_title_input,data.title != false); yadg_util.setValueIfSet(data.label,label_input,data.label != false); yadg_util.setValueIfSet(data.catalog,catalog_input,data.catalog != false); }; return f; case "waffles_upload": var f = function(rawData) { var artist_input = document.getElementsByName("artist")[0], album_title_input = document.getElementsByName("album")[0], year_input = document.getElementsByName("year")[0], va_checkbox = document.getElementById("va"), tags_input = document.getElementById("tags"), data = yadg.prepareRawResponse(rawData); if (data.artists != false) { if (data.is_various) { artist_input.value = ""; va_checkbox.checked = true; } else { va_checkbox.checked = false; var artist_string = ""; for (var i = 0; i < data.artists_length; i++) { if (data.artists[data.artist_keys[i]].indexOf("main") != -1) { if (artist_string != "" && i < data.artists_length - 1) { artist_string = artist_string + ", "; } else if (artist_string != "" && i == data.artists_length - 1) { artist_string = artist_string + " & "; } artist_string = artist_string + data.artist_keys[i]; } } artist_input.value = artist_string; } } else { va_checkbox.checked = false; artist_input.value = ""; } yadg_util.setValueIfSet(data.year,year_input,data.year != false); yadg_util.setValueIfSet(data.title,album_title_input,data.title != false); if (data.tags != false) { tags_input.value = data.tag_string_nodots.toLowerCase(); } else { tags_input.value = ''; } yadg_util.exec(function() {formatName()}); }; return f; case "waffles_request": var f = function(rawData) { var artist_input = document.getElementsByName("artist")[0], album_title_input = document.getElementsByName("title")[0], year_input = document.getElementsByName("year")[0], data = yadg.prepareRawResponse(rawData); if (data.artists != false) { if (data.is_various) { artist_input.value = "Various Artists"; } else { var artist_string = ""; for (var i = 0; i < data.artists_length; i++) { if (data.artists[data.artist_keys[i]].indexOf("main") != -1) { if (artist_string != "" && i < data.artists_length - 1) { artist_string = artist_string + ", "; } else if (artist_string != "" && i == data.artists_length - 1) { artist_string = artist_string + " & "; } artist_string = artist_string + data.artist_keys[i]; } } artist_input.value = artist_string; } } else { artist_input.value = ""; } yadg_util.setValueIfSet(data.year,year_input,data.year != false); yadg_util.setValueIfSet(data.title,album_title_input,data.title != false); }; return f; default: // that should actually never happen return function(data) {}; } } }; var yadg_templates = { _templates : {}, _template_urls : {}, getTemplate : function(id, callback) { if (id in this._templates) { callback(this._templates[id]); } else if (id in this._template_urls) { var request = new requester(this._template_urls[id], 'GET', function(template) { yadg_templates.addTemplate(template); callback(template); }, null, yadg_templates.errorTemplate); request.send(); } else { this.errorTemplate(); } }, addTemplate : function(template) { this._templates[template.id] = template; }, addTemplateUrl : function(id, url) { this._template_urls[id] = url; }, errorTemplate : function() { yadg.printError("No se ha podido obtener la plantilla. Por favor elige otra.", true); } }; var yadg_renderer = { _last_data : null, _last_template_id : null, render : function(template_id, data, callback, error_callback) { this._last_data = data; var new_template = this._last_template_id !== template_id; this._last_template_id = template_id; yadg_templates.getTemplate(template_id, function(template) { // the new template might have different dependencies, so initialize Swig with those if (new_template) { yadg_sandbox.resetSandbox(); yadg_sandbox.initializeSwig(template.dependencies); } yadg_sandbox.renderTemplate(template.code, data, callback, error_callback); }); }, renderCached : function(template_id, callback, error_callback) { if (this.hasCached()) { this.render(template_id, this._last_data, callback, error_callback); } }, hasCached : function() { return this._last_data !== null; }, clearCached : function() { this._last_data = null; } }; var yadg = { yadgHost : "https://yadg.cc", baseURI : "/api/v2/", standardError : "Lo sentimos, ha ocurrido un error. Por favor prueba de nuevo. Si el error persiste, puede que el script necesite ser actualizado.", authenticationError : "Tu token de la API no es válido. Por favor proporciona un token de la API válido.", lastStateError : false, isBusy : false, init : function() { this.scraperSelect = document.getElementById('yadg_scraper'); this.formatSelect = document.getElementById('yadg_format'); this.input = document.getElementById('yadg_input'); this.responseDiv = document.getElementById('yadg_response'); this.button = document.getElementById('yadg_submit'); }, getBaseURL : function() { return this.yadgHost + this.baseURI; }, getScraperList : function(callback) { var url = this.getBaseURL() + "scrapers/"; var request = new requester(url, 'GET', callback); request.send(); }, getFormatsList : function(callback) { var url = this.getBaseURL() + "templates/"; this.getTemplates(url, [], callback); }, getTemplates : function(url, templates, callback) { var request = new requester(url, 'GET', function(data) { for (var i = 0; i < data.results.length; i++) { templates.push(data.results[i]); } if (data.next !== null) { yadg.getTemplates(data.next, templates, callback); } else { callback(templates); } }); request.send(); }, makeRequest : function(params) { if (this.isBusy) return; if (params) { var data = params; } else { var data = { scraper: this.scraperSelect.options[this.scraperSelect.selectedIndex].value, input: this.input.value }; } var url = this.getBaseURL() + 'query/'; if (data.input !== '') { var request = new requester(url, 'POST', function(result) { yadg.getResult(result.url); }, data); this.busyStart(); request.send(); } }, getResult : function(result_url) { var request = new requester(result_url, 'GET', function(response) { if (response.status == "done") { if (response.data.type == 'ReleaseResult') { var template_id = yadg.formatSelect.options[yadg.formatSelect.selectedIndex].value; yadg_renderer.render(template_id, response, factory.setDescriptionBoxValue, factory.setDescriptionBoxValue); if (yadg.lastStateError == true) { yadg.responseDiv.innerHTML = ""; yadg.lastStateError = false; } fillFunc = factory.getFormFillFunction(); fillFunc(response.data); } else if (response.data.type == 'ListResult') { var ul = document.createElement('ul'); ul.id = "yadg_release_list"; var release_list = response.data.items; for (var i = 0; i < release_list.length;i++) { var name = release_list[i]['name'], info = release_list[i]['info'], query_params = release_list[i]['queryParams'], release_url = release_list[i]['url']; var li = document.createElement('li'), a = document.createElement('a'); a.textContent = name; a.params = query_params; a.href = release_url; a.addEventListener('click',function(e) { e.preventDefault(); yadg.makeRequest(this.params);},false); li.appendChild(a); li.appendChild(document.createElement('br')); li.appendChild(document.createTextNode(info)); ul.appendChild(li); } if (ul.childNodes.length != 0) { yadg.responseDiv.innerHTML = ""; yadg.responseDiv.appendChild(ul); yadg.lastStateError = false; // we got a ListResult so clear the last ReleaseResult from the render cache yadg_renderer.clearCached(); } else { yadg.printError('Lo sentimos, no hay coincidencias.'); } } else if (response.data.type == 'NotFoundResult') { yadg.printError('No he conseguido obtener el release con esta ID. Puede que quieras probar de nuevo con otra diferente.'); } else { yadg.printError('Algo raro ha ocurrido. Por favor prueba de nuevo'); } yadg.busyStop(); } else if (response.status == 'failed') { yadg.failed_callback(); } else { var delay = function() { yadg.getResult(response.url); }; window.setTimeout(delay, 1000); } }); request.send(); }, printError : function(message, template_error) { this.responseDiv.innerHTML = ""; this.responseDiv.appendChild(document.createTextNode(message)); if (!template_error) { this.lastStateError = true; // there was a non template related error, so for consistencies sake clear the last ReleaseResult from the // render cache yadg_renderer.clearCached(); } }, failed_callback : function() { yadg.printError(yadg.standardError); yadg.busyStop(); }, failed_authentication_callback : function() { yadg.printError(yadg.authenticationError); yadg.busyStop(); }, busyStart : function() { this.isBusy = true; this.button.setAttribute('disabled',true); this.button.value = "Por favor espere..."; this.input.setAttribute('disabled',true); this.scraperSelect.setAttribute('disabled',true); this.formatSelect.setAttribute('disabled',true); }, busyStop : function() { this.button.removeAttribute('disabled'); this.button.value = "Recoger"; this.input.removeAttribute('disabled'); this.scraperSelect.removeAttribute('disabled'); this.formatSelect.removeAttribute('disabled'); this.isBusy = false; }, prepareRawResponse : function(rawData) { var result = {}; result.artists = false; result.year = false; result.title = false; result.label = false; result.catalog = false; result.genre = false; result.style = false; result.tags = false; result.is_various = false; if (rawData.artists.length > 0) { result.artists = {}; for (var i = 0; i < rawData.artists.length; i++) { var artist = rawData.artists[i]; if (!artist["isVarious"]) { result.artists[artist["name"]] = artist["types"]; } else { result.is_various = true; } } } if (rawData.discs.length > 0) { for (var k = 0; k < rawData.discs.length; k++) { var disc = rawData.discs[k]; for (var l = 0; l < disc["tracks"].length; l++) { var track = disc["tracks"][l]; for (var m = 0; m < track["artists"].length; m++) { var name = track["artists"][m]["name"], type = track["artists"][m]["types"]; var newTypes = null; if (name in result.artists) { newTypes = result.artists[name].concat(type); // deduplicate new types array for(var i = 0; i < newTypes.length; ++i) { for(var j = i+1; j < newTypes.length; ++j) { if(newTypes[i] === newTypes[j]) newTypes.splice(j--, 1); } } } else { newTypes = type; } result.artists[name] = newTypes; } } } } for (var i = 0; i < rawData['releaseEvents'].length; i++) { var event = rawData['releaseEvents'][i]; result.year = event.date.match(/\d{4}/)[0]; if (result.year.length != 4) { result.year = false; } else { break; } } if (rawData.title) { result.title = rawData.title; } if (rawData.labelIds.length > 0) { var labelId = rawData['labelIds'][0]; if (labelId.label) { result.label = labelId.label; } if (labelId.catalogueNrs.length > 0) { result.catalog = labelId.catalogueNrs[0]; } } if (rawData.genres.length > 0) { result.genre = rawData.genres; } if (rawData.styles.length > 0) { result.style = rawData.styles; } if (result.genre != false && result.style != false) { result.tags = rawData.genres.concat(rawData.styles); } else if (result.genre != false) { result.tags = rawData.genres; } else if (result.style != false) { result.tags = rawData.styles; } if (result.tags != false) { result.tag_string = ""; result.tag_string_nodots = ""; for (var i = 0; i < result.tags.length; i++) { result.tag_string = result.tag_string + result.tags[i].replace(/\s+/g,'.'); result.tag_string_nodots = result.tag_string_nodots + result.tags[i].replace(/\s+/g,' '); if (i != result.tags.length-1) { result.tag_string = result.tag_string + ', '; result.tag_string_nodots = result.tag_string_nodots + ', '; } } } if (result.artists != false) { // count the artists result.artists_length = 0; result.artist_keys = []; for (var i in result.artists) { if (result.artists.hasOwnProperty(i)) { result.artists_length++; result.artist_keys.push(i); } } } if (result.artists_length == 0) { result.artists = false; } return result; } }; yadg_sandbox.init(function() { factory.init(); yadg.init(); });