您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automatically download anime torrents from Nyaa
当前为
// ==UserScript== // @name Nyaa.se AutoDownloader // @namespace Autodownload // @author Victorique // @description Automatically download anime torrents from Nyaa // @include http://www.nyaa.se/?page=search&cats=*&filter=*&term=*&user=* // @include http://www.nyaa.se/?page=search&filter=*&term=*&user=* // @include http://www.nyaa.se/?page=search&term=*&user=* // @version 4.1.2 // @license MIT // @run-at document-start // @grant none // @require https://code.jquery.com/jquery-2.1.4.min.js // ==/UserScript== /* var e = document.createElement("script"); e.src = 'http://localhost/userScripts/AutoDownloader.user.js'; e.type = "text/javascript"; document.getElementsByTagName("head")[0].appendChild(e); */ "use strict"; /* OBJECT CREATION START */ var Episode = (function () { /** * An Episode represents an table row in the current page * @param {Number} res The resolution used for this episode * @param {String} downloadLink The download link for this episode * @param {Number} seeds The seed count for this episode * @param {Number} leechers The leech count for this episode * @param {String} uid The ID of this episode * @param {Number} resides The page that this Episode resides in * @returns {Object} the proto of itself */ function Episode(res, downloadLink, seeds, leechers, uid, resides) { if (typeof res !== "number") { throw "res must be a number"; } if (typeof downloadLink !== "string") { throw "downloadLink must be a string"; } if (typeof seeds !== "number") { throw "seeds must be a number"; } if (typeof leechers !== "number") { throw "leechers must be a number"; } if (typeof uid !== "string") { throw "uid must be a string"; } if (typeof resides !== "number") { throw "resides must be a number"; } var _res = res; var _downloadLink = downloadLink; var _seeds = seeds; var _leechers = leechers; var _uid = uid; var _resides = resides; this.getRes = function () { return _res; }; this.getDownloadLink = function () { return _downloadLink; }; this.getSeeds = function () { return _seeds; }; this.getLeechers = function () { return _leechers; }; this.getUid = function () { return _uid; }; this.getResides = function () { return _resides; }; return this; } Episode.prototype = { constructor: Episode } return Episode; }()); var Anime = (function () { var currentAnime = null; var currentSubber = null; /** * Array of Episode Objects */ var eps = []; /** * Set the current Anime name * @param {String} anime The of the Anime */ var setCurrentAnime = function (anime) { currentAnime = anime; }; /** * Set the name of the current subber * @param {String} sub Name of the current subber */ var setCurrentSubber = function (sub) { currentSubber = sub; }; /** * Get the current Subber * @returns {String} The name of the Subber for this anime */ var getCurrentSubber = function () { return currentSubber; }; /** * Get the current anime name * @returns {String} Name of the anime */ var getCurrentAnime = function () { return currentAnime; }; /** * Get the avrage seeds for a specified res * @param {Number} res The res to get the avg seeds for * @returns {Number} The avg seeds */ var avgSeedsForRes = function (res) { if (typeof res !== "number") { throw "res Must be an int"; } var seedCount = 0; if (getamountOfEpsFromRes(res) === 0) { return 0; } for (var i = 0; i < eps.length; i++) { var currentEp = eps[i]; if (currentEp.getRes() === res) { seedCount += currentEp.getSeeds(); } } return Math.round(seedCount = seedCount / getamountOfEpsFromRes(res)); }; /** * Get the avrage leechers for a specified res * @param {Number} res The res to get the avg seeds for * @returns {Number} The avg leechers */ var avgPeersForRes = function (res) { if (typeof res !== "number") { throw "res Must be an int"; } var leechCount = 0; if (getamountOfEpsFromRes(res) === 0) { return 0; } for (var i = 0; i < eps.length; i++) { var currentEp = eps[i]; if (currentEp.getRes() === res) { leechCount += currentEp.getLeechers(); } } return Math.round(leechCount = leechCount / getamountOfEpsFromRes(res)); }; /** * Get the total amount of eps for a res * @param {Number} res res * @returns {Number} The amount of eps for the res */ var getamountOfEpsFromRes = function (res) { if (typeof res !== "number") { throw "res must be of type 'number'"; } return getEpsForRes(res).length; }; var _isjQueryObject = function (obj) { if (obj instanceof jQuery || 'jquery' in Object(obj)) { return true; } else { return false; } }; /** * Add Episodes to the array * @param {Episode} ep The Anime object to add */ var addEps = function (ep) { if (typeof ep !== "object" && !ep instanceof Episode) { throw "addEps must take an Episode object"; } eps.push(ep); }; /** * Add an array of Episode object to the Anime object * @param {Array} episode Array of Episode objects to add */ var addAllEps = function (episode) { for (var i = 0; i < episode.length; i++) { var currEp = episode[i]; if (typeof currEp !== "object" && !currEp instanceof Episode) { throw "addEps must take an Episode object"; } eps.push(currEp); } }; /** * Get the Anime objects for a specified res * @param {Number} res res to use * @returns {Episode} Array of Episodes that match the specified res */ var getEpsForRes = function (res) { if (typeof res !== "number") { throw "res Must be an int"; } var arrayOfEps = []; for (var i = 0; i < eps.length; i++) { var currentEp = eps[i]; if (currentEp.getRes() === res) { arrayOfEps.push(currentEp); } } return arrayOfEps; }; /** * Given a JQuery object that represents a "tr" of the table, this will return that Episode's UID * @param {Object} obj The Jquery representation of a tr (table row) * @returns {String} The UID of that Episode */ var getUidFromJqueryObject = function (obj) { if (!_isjQueryObject(obj)) { throw "Object must be of type 'Jquery'"; } if (obj.is("tr")) { var anchor = (function () { var tableRows = obj.find("td.tlistdownload > a"); if (tableRows.length > 1) { throw "Object must be unique"; } return _getUidFromAnchor(tableRows.get(0)) }()); } else { return null; } return anchor; }; /** * Get the Episode from a given anchor tag * @param {Object} anchor Jquery or pure JS anchor dom element * @returns {Episode} The eipside that matches the Anchor */ var getEpisodeFromAnchor = function (anchor) { var link = (function () { if (_isjQueryObject(anchor)) { return anchor.get(0); } return anchor; }()); var uid = _getUidFromAnchor(link); return getEpisodeFromUid(uid); }; /** * Get the Episode object given a UID * @param {String} uid The Episode UID * @returns {Episode} The Episode that matches the UID */ var getEpisodeFromUid = function (uid) { if (typeof uid !== "string") { throw "uid must be of type String"; } for (var i = 0; i < eps.length; i++) { var currentEp = eps[i]; if (currentEp.getUid() === uid) { return currentEp; } } return null; }; /** * Get an array of Episodes that from the page that it came from * @param {Number} resides The page where the Episode originated from * @param {Boolean} exclude Match this page only, or exculde this page and return all other objects. if true, will return all Episodes that are not of the passed in page * @returns {Episode} Array of Episodes */ var getEpisodesFromResidence = function (resides, exclude) { if (typeof resides !== "number") { throw "resides must be a number"; } var arrayOfEps = []; for (var i = 0; i < eps.length; i++) { var currentEp = eps[i]; if (exclude === true) { if (currentEp.getResides() !== resides) { arrayOfEps.push(currentEp); } } else { if (currentEp.getResides() === resides) { arrayOfEps.push(currentEp); } } } return arrayOfEps; }; /** * Get the UID from an anchor tag * @param {Object} anchor Dom element of an Anchor * @returns {String} The UID */ var _getUidFromAnchor = function (anchor) { return anchor.href.split("=").pop(); }; /** * Remove an object from an array * @param {Array} arr Array to search in * @param {Object} obj Object to remove */ var _removeObjectFromArray = function (arr, obj) { var i = arr.length; while (i--) { if (arr[i] === obj) { arr.splice(i, 1); } } } /** * Get an array of all the pages avalible in the Anime (tables) * @returns {Array} Array of URLS */ var getPageUrls = function () { var urls = []; $.each($('div.pages').filter(function (i) { return i === 0; }).find('a'), function (k, v) { urls.push(this.href); }); return urls; }; /** * Remove an episode from the Episode array based on UI * @param {String} uid the UID */ var removeEpisodesFromUid = function (uid) { var episodes = getEpisodeFromUid(uid); for (var i = 0; i < episodes.length; i++) { var currentEp = episodes[i]; _removeObjectFromArray(eps, currentEp); } }; /** * Remove all episodes that match a page number * @param {Number} resides The page number * @param {Boolean} exclude if true, this will remove all Episode objects that do not match the passed in page number. if false, removes all episodes that match the passed in page number */ var removeEpisodesFromResidence = function (resides, exclude) { if (typeof exclude !== "boolean") { throw "excluse must be true or false"; } var episodes = getEpisodesFromResidence(resides, exclude); for (var i = 0; i < episodes.length; i++) { var currentEp = episodes[i]; _removeObjectFromArray(eps, currentEp); } }; var getAmountOfEps = function () { return eps.length; }; return { setCurrentAnime: setCurrentAnime, getCurrentAnime: getCurrentAnime, addEps: addEps, getEpsForRes: getEpsForRes, getamountOfEpsFromRes: getamountOfEpsFromRes, setCurrentSubber: setCurrentSubber, getCurrentSubber: getCurrentSubber, avgSeedsForRes: avgSeedsForRes, getUidFromJqueryObject: getUidFromJqueryObject, getEpisodeFromUid: getEpisodeFromUid, getEpisodeFromAnchor: getEpisodeFromAnchor, getPageUrls: getPageUrls, addAllEps: addAllEps, getEpisodesFromResidence: getEpisodesFromResidence, removeEpisodesFromUid: removeEpisodesFromUid, removeEpisodesFromResidence: removeEpisodesFromResidence, avgPeersForRes: avgPeersForRes, getAmountOfEps: getAmountOfEps }; }()); /** Utility functions ***/ var Utils = (function () { /** * Display a message to the use (built in alert) * @param {String} message Message to show * @param {Boolean} confirmMsg If true, message will be a confirm alert (yes or no) * @returns {Boolean} Returns true if confirmMsg is false, else returns true or false depending on the user selection */ var displayMessage = function (message, confirmMsg) { if (typeof confirmMsg === "boolean") { if (confirmMsg === true) { return confirm(message); } } alert(message); return true; }; /** * Disable the given button * @param {Object} button Jquery object of the button */ var disableButton = function (button) { button.prop('disabled', true); }; /** * Enable the given button * @param {Object} button Jquery object of the button */ var enableButton = function (button) { button.prop('disabled', false); }; /** * Do the downloads * @param {Object} event The event to decide if it is a download all or a downlaod selection (to make this method more abstract) */ var doDownloads = function (event) { var type = $(event.target).data("type"); var amountOfAnime; var collectionOfAnime; var userSelect; var _minSeeds = Options.Seeds.minSeeds === -1 ? 0 : Options.Seeds.minSeeds; if (type === "downloadAll") { var selectedRes = parseInt($("#downloadRes").val()); amountOfAnime = Anime.getamountOfEpsFromRes(selectedRes); collectionOfAnime = Anime.getEpsForRes(selectedRes); userSelect = displayMessage("You are about to download " + amountOfAnime + " eps.\n\ This will cause " + amountOfAnime + " download pop-ups\nAre you sure you want to continue?\nIf there are a lot of eps, your browser might stop responding for a while.\ This is normal\nIf you are on Google Chrome, it will ask you to allow multiple-downloads\n\nYour min seeds restriction is: " + _minSeeds + "\ This will not be reflected in this message download count, but all episodes with this restriction will be skipped", true); } else if (type === "downloadSelected") { amountOfAnime = $(".checkboxes:checked").length; collectionOfAnime = []; $.each($('.checkboxes:checked').prev('a'), function (k, v) { var episode = Anime.getEpisodeFromAnchor(this); collectionOfAnime.push(episode); }); userSelect = displayMessage("You are about to download " + amountOfAnime + " items. if there are a lot of itmes, it might make your browser stop responding for a while This is normal\n\ Chrome will ask you to accept multiple downloads ", true); } else { throw "Unexpected Error"; } if (userSelect === false) { return; } for (var i = 0; i < collectionOfAnime.length; i++) { var currentEp = collectionOfAnime[i]; if (_minSeedsSet() && type !== "downloadSelected") { if (currentEp.getSeeds() < _minSeeds) { continue; } } var currentDownloadLink = currentEp.getDownloadLink(); var link = document.createElement("a"); link.download = ""; link.href = currentDownloadLink; link.click(); } }; /** * Returns if the checkbox is checked * @param {Object} checkbox The checkbox * @returns {Boolean} If ehcked or not */ var checkBoxValid = function (checkbox) { return checkbox.is(":checked"); }; var _minSeedsSet = function () { return Options.Seeds.minSeeds !== -1 ? true : false; //(typeof Options.Seeds.minSeeds !== "undefined") ? 0: Options.Seeds.minSeeds; } /** * Build the download infomation table * @returns {String} The html of the built table */ var buildTable = function () { var html = ""; html += "<table style='width: 100%' id='info'>"; html += "<caption>Download infomation</caption>"; html += "<tr>"; html += "<th>resolution</th>"; html += "<th>Episode count</th>"; html += "<th>Average seeds</th>"; html += "<th>Average leechers</th>"; html += "</tr>"; html += "<tr>"; html += "<td>1080p</td>"; html += "<td>" + Anime.getamountOfEpsFromRes(1080) + "</td>"; html += "<td>" + Anime.avgSeedsForRes(1080) + "</td>"; html += "<td>" + Anime.avgPeersForRes(1080) + "</td>"; html += "</tr>"; html += "<tr>"; html += "<td>720p</td>"; html += "<td>" + Anime.getamountOfEpsFromRes(720) + "</td>"; html += "<td>" + Anime.avgSeedsForRes(720) + "</td>"; html += "<td>" + Anime.avgPeersForRes(720) + "</td>"; html += "</tr>"; html += "<tr>"; html += "<td>480p</td>"; html += "<td>" + Anime.getamountOfEpsFromRes(480) + "</td>"; html += "<td>" + Anime.avgSeedsForRes(480) + "</td>"; html += "<td>" + Anime.avgPeersForRes(480) + "</td>"; html += "</tr>"; html += "<tr>"; html += "<td>360p</td>"; html += "<td>" + Anime.getamountOfEpsFromRes(360) + "</td>"; html += "<td>" + Anime.avgSeedsForRes(360) + "</td>"; html += "<td>" + Anime.avgPeersForRes(360) + "</td>"; html += "</tr>"; html += "</table>"; return html; }; /** * Return the current page offset (what table page you are on) * @returns {Number} The offset */ var getCurrentPageOffset = function () { return parseInt((typeof QueryString.offset === "undefined") ? 1 : QueryString.offset); }; /** * Returns true of false if you can support HTML5 storeag * @returns {Boolean} */ var html5StoreSupport = function () { try { return 'localStorage' in window && window['localStorage'] !== null; } catch (e) { return false; } }; var injectCss = function (css) { if (_isUrl(css)) { $("<link>").prop({ "type": "text/css", "rel": "stylesheet" }).attr("href", css).appendTo("head"); } else { $("<style>").prop("type", "text/css").html(css).appendTo("head"); } }; var _isUrl = function (url) { var matcher = new RegExp(/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/); return matcher.test(url); }; return { displayMessage: displayMessage, disableButton: disableButton, enableButton: enableButton, doDownloads: doDownloads, checkBoxValid: checkBoxValid, buildTable: buildTable, getCurrentPageOffset: getCurrentPageOffset, html5StoreSupport: html5StoreSupport, injectCss: injectCss }; }()); var DataParser = (function () { /**l * Parses a table and returns an array of Episodes from it * @param {Object} table Jquery representation of the anime table * @returns {Episode} Array of Episodes */ var parseTable = function (table, currentPage) { var trRow = table.find("img[src='http://files.nyaa.se/www-37.png']").closest("tr"); var eps = []; $(trRow).filter(function (e) { return ($(this).children('td:nth-child(2)').text().indexOf('1080p') > -1 || $(this).children('td:nth-child(2)').text().indexOf('1920x1080') > -1); }).each(function (k, v) { var currentDownloadLink = $(this).find('td:nth-child(3) >a').attr('href'); var seeds = (isNaN(parseInt($(this).find("td.tlistsn").text()))) ? 0 : parseInt($(this).find("td.tlistsn").text()); var leech = (isNaN(parseInt($(this).find("td.tlistln").text()))) ? 0 : parseInt($(this).find("td.tlistln").text()); var uid = Anime.getUidFromJqueryObject($(this)); eps.push(new Episode(1080, currentDownloadLink, seeds, leech, uid, currentPage)); }); $(trRow).filter(function (e) { return ($(this).children("td:nth-child(2)").text().indexOf("720p") > -1 || $(this).children("td:nth-child(2)").text().indexOf("1280x720")) > -1; }).each(function (k, v) { var currentDownloadLink = $(this).find('td:nth-child(3) >a').attr('href'); var seeds = (isNaN(parseInt($(this).find("td.tlistsn").text()))) ? 0 : parseInt($(this).find("td.tlistsn").text()); var leech = (isNaN(parseInt($(this).find("td.tlistln").text()))) ? 0 : parseInt($(this).find("td.tlistln").text()); var uid = Anime.getUidFromJqueryObject($(this)); eps.push(new Episode(720, currentDownloadLink, seeds, leech, uid, currentPage)); }); $(trRow).filter(function (e) { return ($(this).children("td:nth-child(2)").text().indexOf("480p") > -1 || $(this).children("td:nth-child(2)").text().indexOf("640x480") > -1); }).each(function (k, v) { var currentDownloadLink = $(this).find('td:nth-child(3) >a').attr('href'); var seeds = (isNaN(parseInt($(this).find("td.tlistsn").text()))) ? 0 : parseInt($(this).find("td.tlistsn").text()); var leech = (isNaN(parseInt($(this).find("td.tlistln").text()))) ? 0 : parseInt($(this).find("td.tlistln").text()); var uid = Anime.getUidFromJqueryObject($(this)); eps.push(new Episode(480, currentDownloadLink, seeds, leech, uid, currentPage)); }); $(trRow).filter(function (e) { return ($(this).children("td:nth-child(2)").text().indexOf("360p") > -1 || $(this).children("td:nth-child(2)").text().indexOf("640×360") > -1); }).each(function (k, v) { var currentDownloadLink = $(this).find('td:nth-child(3) >a').attr('href'); var seeds = (isNaN(parseInt($(this).find("td.tlistsn").text()))) ? 0 : parseInt($(this).find("td.tlistsn").text()); var leech = (isNaN(parseInt($(this).find("td.tlistln").text()))) ? 0 : parseInt($(this).find("td.tlistln").text()); var uid = Anime.getUidFromJqueryObject($(this)); eps.push(new Episode(360, currentDownloadLink, seeds, leech, uid, currentPage)); }); return eps; }; return { parseTable: parseTable, }; }()); var QueryString = function () { var query_string = {}; var query = window.location.search.substring(1); var vars = query.split('&'); for (var i = 0; i < vars.length; i++) { var pair = vars[i].split('='); if (typeof query_string[pair[0]] === 'undefined') { query_string[pair[0]] = pair[1]; } else if (typeof query_string[pair[0]] === 'string') { var arr = [ query_string[pair[0]], pair[1] ]; query_string[pair[0]] = arr; } else { query_string[pair[0]].push(pair[1]); } } return query_string; }(); var Options = (function () { var Seeds = {}; Object.defineProperty(Seeds, "minSeeds", { enumerable: true, set: function (seeds) { if (typeof seeds !== "number") { throw "seeds must be a number"; } this._minSeeds = seeds; if (Utils.html5StoreSupport() === true) { // also set it on the local DB if (this._minSeeds === -1) { Localstore.removeMinSeedsFromStore(); } else { Localstore.setMinSeedsFromStore(this._minSeeds); } } }, get: function () { return typeof this._minSeeds === "undefined" ? -1 : this._minSeeds; } }); return { Seeds: Seeds } }()); //Local storeage object var Localstore = { getMinSeedsFromStore: function () { return localStorage.getItem("minSeeds"); }, setMinSeedsFromStore: function (seeds) { localStorage.setItem('minSeeds', seeds); }, removeMinSeedsFromStore: function () { localStorage.removeItem("minSeeds"); } }; // Download fix for firefox HTMLElement.prototype.click = function () { var evt = this.ownerDocument.createEvent('MouseEvents'); evt.initMouseEvent('click', true, true, this.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null); this.dispatchEvent(evt); }; /* OBJECT CREATION END */ $(document).ready(function () { init(); // init the pannel and set up objects and listeners if (Utils.checkBoxValid($(".checkboxes"))) { // TODO: Refactor this statement! Utils.enableButton($("#downloadCustomButton")); } else { Utils.disableButton($("#downloadCustomButton")); } }); function init() { var doDownload = true; setAnimeObj(); buildUi(); bindListeners(); if (Utils.html5StoreSupport()) { setOptionsFromLocalStor(); } function setAnimeObj() { // Set currentAnime if (QueryString.term !== "") { Anime.setCurrentAnime(decodeURIComponent(QueryString.term).split("+").join(" ")); } else { Anime.setCurrentAnime("Unknown"); } // set subber Anime.setCurrentSubber($(".notice > a > span").html()); // Set eps var eps = DataParser.parseTable($("table.tlist"), Utils.getCurrentPageOffset()); Anime.addAllEps(eps); } function buildUi() { makeStyles(); buildPanel(); makeCheckBoxes(); function makeStyles() { var styles = ""; styles += ".panel{background-color: #fff; border: 1px solid transparent; border-radius: 4px; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); margin-bottom: 20px;}"; styles += ".panel-success {border-color: #d6e9c6;}"; styles += ".panel-heading{ border-bottom: 1px solid transparent; border-top-left-radius: 3px; border-top-right-radius: 3px; padding: 4px 15px; text-align:center}"; styles += ".panel-success > .panel-heading {background-color: #dff0d8; border-color: #d6e9c6; color: #3c763d;}"; styles += ".panel-success > .panel-footer + .panel-collapse > .panel-body {border-bottom-color: #d6e9c6;}"; styles += ".panel-footer {background-color: #f5f5f5; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top: 1px solid #ddd; padding: 10px 15px;}"; styles += ".panel-title {color: inherit; margin-bottom: 0; margin-top: 0; padding: 6px;}"; styles += ".panel-body {padding: 15px;}"; styles += ".avgSeeds{floar:left; padding-right:10px; color:#3c763d;}"; styles += ".checkboxes{left:1px; margin:0; padding:0; position: relative; top: 1px;}"; styles += "#info, #info th, #info td {border: 1px solid black;border-collapse: collapse;}"; styles += "#info th, #info td {padding: 5px;text-align: left;}"; styles += "label[for='MinSeeds']{ display: block; margin-top: 10px;}"; styles += "#SaveMinSeeds{margin-left:5px;}" styles += "#downloadCustomButton{float:right;}"; Utils.injectCss(styles); } function buildPanel() { var html = ""; html += '<div class="panel panel-success" style="margin-left: 9px; margin-top: 19px; width: 851px;">'; html += '<div class="panel-heading">'; html += '<h3 id="panel-title" class="panel-title"></h3>'; html += "</div>"; html += '<div class="panel-body" id="pannelContent"></div>'; html += '<div class="panel-footer" id="panelFooter">'; html += '</div>'; html += '</div>'; $(".content > .notice").after(html); buildPanelContent(); function buildPanelContent() { var html = ""; html += "<div>"; $("#panel-title").html("<span> Download \"" + Anime.getCurrentAnime() + " (" + Anime.getCurrentSubber() + ")\"</span>"); if (Anime.getAmountOfEps() === 0) { html += "<span> No translated anime found or error occured</span>"; html += "</div>"; $("#pannelContent").html(html); doDownload = false; return; } html += "<span>Pick a resolution: </span>"; html += "<select style=\"margin-right:5px;\" id=\"downloadRes\">"; if (Anime.getamountOfEpsFromRes(1080) >= 1) { html += "<option value=\"1080\">1080p</option>"; } if (Anime.getamountOfEpsFromRes(720) >= 1) { html += "<option value=\"720\">720p</option>"; } if (Anime.getamountOfEpsFromRes(480) >= 1) { html += "<option value=\"480\">480p</option>"; } if (Anime.getamountOfEpsFromRes(360) >= 1) { html += "<option value=\"360\">360p</option>"; } html += "</select>"; html += "<button type=\"button\" data-type='downloadAll' id=\"downloadAll\">Download all</button>"; html += "<button type='button' id='downloadCustomButton' data-type='downloadSelected' >download your selected items</button>"; html += "</div>"; html += "<div id='options'>"; html += "<label for='crossPage'> include Cross pages</label>"; html += "<input type='checkbox' id='crossPage' /> "; html += "<label for='MinSeeds'>Minimum seeders:</label>"; html += "<input type='number' min='0' id='MinSeeds' title='Any episode that is below this limit will be excluded from the download but not the infomation table (coming soon).'/>"; html += "<button type='button' id='SaveMinSeeds'>Save</button>"; html += "</div>"; html += "<div id='tableInfo'>"; html += Utils.buildTable(); html += "</div>"; $("#pannelContent").html(html); } } function makeCheckBoxes() { $(".tlistdownload > a").after("<input class='checkboxes' type='checkbox'/>"); } } function bindListeners() { $("#downloadAll").on("click", function (e) { if (doDownload === true) { Utils.doDownloads(e); } }); $("#downloadCustomButton").on("click", function (e) { if (doDownload === true) { Utils.doDownloads(e); } }); $(".checkboxes").on("click", function (e) { if (Utils.checkBoxValid($(".checkboxes"))) { Utils.enableButton($("#downloadCustomButton")); } else { Utils.disableButton($("#downloadCustomButton")); } }); $("#crossPage").on("click", function (e) { if (Utils.checkBoxValid($("#crossPage"))) { $("#tableInfo").html("<p>Please wait while we parse each page...</p>"); $("#crossPage").prop("disabled", true); Anime.getPageUrls().reduce(function (prev, cur, index) { return prev.then(function (data) { return $.ajax(cur).then(function (data) { var currentPage = cur.split("=").pop(); if (cur.indexOf("offset") === -1) { currentPage = 1; } var table = $(data).find("table.tlist"); Anime.addAllEps(DataParser.parseTable(table, parseInt(currentPage))); $("#tableInfo").append("<div>Page " + currentPage + " Done </div>") }); }) }, $().promise()).done(function () { $("#tableInfo").html(Utils.buildTable()); $("#crossPage").prop("disabled", false); }); } else { // when un-chekced, clear the Episodes of all eps that are not of the current page $("#tableInfo").html("<p>Please wait while we re-calculate the Episodes</p>"); var currentPage = Utils.getCurrentPageOffset(); Anime.removeEpisodesFromResidence(currentPage, true); $("#tableInfo").html(Utils.buildTable()); } }); $("#SaveMinSeeds").on("click", function (e) { if (parseInt($("#MinSeeds").val()) < 0) { alert("number cannot be negative"); return; } var value = parseInt($("#MinSeeds").val() === "" ? -1 : $("#MinSeeds").val()); Options.Seeds.minSeeds = value; if (value === -1) { alert("Minimum seeds have been cleared"); } else { alert("Minimum seeds now set to: " + value); } }); } function setOptionsFromLocalStor() { // Min seeds if (Localstore.getMinSeedsFromStore() !== null) { var minSeeds = parseInt(Localstore.getMinSeedsFromStore()); Options.Seeds.minSeeds = minSeeds; $("#MinSeeds").val(minSeeds); } } }