Skip to content

Instantly share code, notes, and snippets.

@aa65535
Last active November 18, 2016 17:37
Show Gist options
  • Save aa65535/7891903 to your computer and use it in GitHub Desktop.
Save aa65535/7891903 to your computer and use it in GitHub Desktop.
一个使用Aria2下载迅雷离线的批处理, 使用前需要将BAT文件编码改为ANSI

注意:本批处理涉及到的文件全部为ANSI编码,其他编码会造成乱码或者无法运行!

本批处理需要两个外部命令:aria2c.exe wfr.exe

aria2c.exe 下载地址:http://sourceforge.net/projects/aria2/files/stable/

wfr.exe 下载地址:http://baiy.cn/utils/wfr/wfr.rar

首次使用需要对批处理和Aria2配置,按照提示输入即可,批处理有做默认配置,也可以直接一路回车跳过。

注:对本批处理来说,提示输入的时候直接回车表示跳过此项设置,有部分设置是不允许跳过的。

批处理功能配置部分:

  1. Aria2有限速功能,可以防止在下载的时候网络太卡,开启后每次打开批处理会提示输入限速值,直接回车跳过的话则使用配置文件中的default_speed值,若填0的话则表示不限速。

  2. 为了不需要每次都输入下载链接和文件名,可以使用下载列表,下载列表文件名默认为down.lst,下载列表内容格式为每行一个任务,文件名和下载链接使用\分割,如:filename.txt\http://example.com/path/file.txt\gdriveid,可以使用#来做注释,批处理会自动跳过#开头的行,下载文件的编码为ANSI,其他格式会报错。

  3. 指定时间段下载完成后关机功能,夜晚挂机下载可以使用此功能,在此时间段内下载完成全部任务后批处理会关闭计算机。时间段需要开始时间和结束时间,根据自己需要填写即可。

配置文件AdmX.ini可以在日后根据需要修改选项

Aria2配置部分:

  1. Aria2 v1.16后版本可以使用磁盘缓存功能,可以在一定程度上减少磁盘读写次数,这个可以根据下载速度填写,不建议设置过大,以免出错中断造成数据损失。

  2. 文件预分配功能就是指在下载开始之前预先在磁盘划出文件所需要的空间,可以有效减少磁盘碎片,缺点是需要消耗时间,NTFS格式磁盘可以使用falloc方式,速度比较快,FAT32格式磁盘预分配需要很长时间,建议使用none选项关闭此功能。

  3. 同一服务器连接数值和单文件最大线程数和连接相关配置,根据自己需要修改,一般默认即可。

配置完成后即可使用本批处理了。Aria2还有许多选项可以配置,一般使用的话默认足够。

详细的配置可以自行修改aria2.conf文件,参数可以参考aria2的manual :http://aria2.sourceforge.net/manual/en/html/aria2c.html

关于下载列表的使用:

你需要安装ThunderAssistant.user.js脚本对离线下载链接进行提取 ,点击右侧View Raw按钮即可安装,安装完成后离线页面会出现提取地址菜单,勾选需要下载的任务后,点击提取地址菜单即可输出合适的格式了,直接复制粘贴进下载列表即可。

右下角的保存为文件可以保存下载列表,但是注意此列表为UTF-8编码,需要转换为ANSI编码才能使用。

关于下载完成关机功能:

开启此功能后如果完成时间在“下载关机时间段结束时间”之后的话则直接退出,否则则会判断当前时间是否在“下载关机时间段”之内,如果早于此时间段则会等待5分钟后重新检查,直到在“下载关机时间段”之内,在启动关机命令之前有10秒钟的等待时间。

:: AdmX - Aria2 Download Manager for Xunlei
:: Release by aa65535
:: Time: 2013-12-13 03:08:57
:: External Command: aria2c.exe, wfr.exe
@echo off
title Aria2& color f3& mode con: cols=80 lines=8& setlocal enabledelayedexpansion
:: 检查Aria2是否可用
aria2c& cls
if !errorlevel! gtr 1 echo aria2c.exe not found!& pause>nul& exit
:: 检查配置文件和下载目录
if not exist AdmX.ini call :admxini
if not exist aria2.conf call :aria2conf
if not exist Aria2Data mkdir Aria2Data
:: 载入配置
:init
for /f "eol=# delims=" %%i in (AdmX.ini) do set "%%i"
:: 限速设置
set "dml=--max-download-limit=!default_speed!"
if !speed_limit! equ 1 (
cls& set /p "default_speed=限速值KB/s:"& set /a "default_speed=!default_speed!"
if !default_speed! gtr 0 (set "dml=--max-download-limit=!default_speed!K")
)
:: 下载列表判断
if "%~1"=="" (
if exist "!list_file!" (set "lst=!list_file!") else (echo 下载列表没有找到!& pause>nul& exit)
) else (
set "lst=%~1"
)
:: 处理文件名中的"!"
wfr %lst% -f:"^!" -t:"!"
:: 读取下载列表并启动下载
for /f "usebackq eol=# tokens=1,2,3 delims=\" %%i in ("!lst!") do (
set "fnm=%%i"& set "url=%%j"& set "gid=%%k"& set "header="
cls& if !default_speed!==0 (title Aria2:!fnm!) else (title [LMT:!default_speed!KB] Aria2:!fnm!)
if defined gid (set "header=--header="Cookie: !gid!"")
cls& aria2c --conf-path=aria2.conf !header! !dml! -o "Aria2Data/!fnm!" "!url!"
if !errorlevel! equ 0 (wfr !lst! -f:"%%i" -t:"#%%i")
if !errorlevel! equ 7 goto init
)
:: 若下载列表中URI不可用则退出
if not defined url (echo 下载列表任务为空!& pause>nul& exit)
goto shut
:: 完成关机功能
:shut
set /a hh=!time:~0,2!
if !shut! equ 1 (
if !hh! leq !period_end! (
if !hh! geq !period_start! (
cls& choice /c YN /t 10 /d Y /m 是否关闭计算机& if !errorlevel! equ 1 (shutdown -s -t 30)
) else (
timeout /t 300 /nobreak& goto shut
)
)
)
exit
:: 批处理配置
:admxini
echo 请按任意键开始配置本批处理. . .& pause>nul
cls& set /p speed_limit=是否开启限速功能[0.不开启,1.开启,默认1]:
if not defined speed_limit set speed_limit=1
cls& set /p list_file=输入默认下载列表文件名[默认down.lst]:
if not defined list_file set list_file=down.lst
echo #使用ANSI编码保存, 格式: 文件名\下载链接\gdriveid>>!list_file!
cls& set /p shut=是否开启指定时间段下载完成后关机功能[0.不开启,1.开启,默认1]:
if not defined shut set shut=1
cls& (
echo #是否开启限速功能[0.不开启, 1.开启]
echo speed_limit=!speed_limit!
echo #默认限速值, 当提示输入限速值时回车跳过则使用该值[单位: KB/s, 0为不限制]
echo default_speed=^0
echo #默认下载列表文件名
echo list_file=!list_file!
echo #是否开启指定时间段下载完成后关机功能[0.不开启,1.开启]
echo shut=!shut!
)>AdmX.ini|| goto admxini
if !shut!==1 (
echo 下载完成后关机功能已开启!请分别输入作用时段的开始和结束时间。
echo 如在3点到6点之间使用下载完成关机功能,分别在开始时间输入3、结束时间输入6即可。
set /p period_start=输入下载关机时间段开始时间[数字,默认3]:
if not defined period_start set period_start=3
set /p period_end=输入下载关机时间段结束时间[数字,默认6]:
if not defined period_end set period_end=6
(
echo #下载关机时间段开始时间
echo period_start=!period_start!
echo #下载关机时间段结束时间
echo period_end=!period_end!
)>>AdmX.ini|| goto admxini
)
cls& goto :eof
:: Aria2配置
:aria2conf
echo 请按任意键开始配置Aria2. . .& pause>nul
cls& set /p disk-cache=设置磁盘缓存[单位MB,填数字,默认16]:
if not defined disk-cache set disk-cache=16
chkntfs %~d0|find "NTFS"&& (cls& set type=falloc)|| (cls& set type=none)
cls& set /p file-allocation=文件预分配[速度: none ^> falloc ^> prealloc,默认!type!]:
if not defined file-allocation set file-allocation=!type!
cls& set /p max-connection-per-server=同一服务器连接数[数字,默认2]:
if not defined max-connection-per-server set max-connection-per-server=2
cls& set /p split=单文件最大线程数[数字,默认2]:
if not defined split set split=2
(
echo #磁盘缓存, 需要1.16及以上版本
echo disk-cache=!disk-cache!M
echo #文件预分配, 能有效降低磁盘碎片, 缺点是需要消耗时间, 所需时间 none ^< falloc ^< prealloc, falloc和trunc则需要文件系统和内核支持
echo file-allocation=!file-allocation!
echo #断点续传
echo continue=true
echo #同服务器连接数
echo max-connection-per-server=!max-connection-per-server!
echo #单文件最大线程数
echo split=!split!
echo #最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要
echo min-split-size=2M
)>aria2.conf|| goto aria2conf
cls& goto :eof
// ==UserScript==
// @name ThunderAssistant
// @namespace https://gist.github.com/aa65535/7891903
// @run-at document-end
// @noframes yes
// @include http://dynamic.cloud.vip.xunlei.com/*
// @version 1.03
// ==/UserScript==
//
// For Firefox & Chrome & Safari
// Author By eminarcissus
// Source Code: http://userscripts.org/scripts/review/111748
// Modified By aa65535
var XL = function() {
this.init();
};
XL.prototype = {
init: function() {
var o = this;
this.auto_select = this.getAutoSelect();
o.batchContent = [];
o.links = {};
o.links.normal = {};
o.links.bt = {};
o.nowType = null;
// Rule only accept 5 variable: $name $url $dir $cookie $gdrive
// Default Rule: $name\$url\$gdrive
// IDM Rule: <\n$url\ncookie: $cookie\n>
o.outputRule = localStorage.getItem('outputRule');
o.outputRule = o.outputRule || '$name\\$url\\$gdrive';
o.returnData = [];
o.showButton = $('.saveside:first').clone().attr('id', 'showAddr')
.css('clear', 'both').html('<a></a>').find('a').attr('href', '#')
.html('<em class="ic_sf ic_ziyuan"></em>提取地址').end();
o.buttonPoint = $('.saveside:last').parent();
o.buttonPoint.append(o.showButton);
$('#showAddr a').click(function() {
o.showCheckedLinks();
});
// Fetch download links at current page
o.fetchAll();
},
fetchAll: function() {
var o = this;
// Trigger stands for BT Folder to be parsed.
// Normal stands for Emule/http links which had already been parsed.
o.triggers = $('a[onclick*=bt_list_show]');
o.normals = $('input[value*=gdl][id*=dl]');
o.normals.each(function(i, down) {
var tid = down.id.split('dl_url');
tid = tid ? tid[1] : null;
if (tid) {
var fname = $(down).siblings('input[id^=durl]')[0].value;
var furl = down.value;
o.links.normal[tid] = {
'url': furl,
'name': fname
};
}
});
o.triggers.each(function(i, link) {
var args = $(link).attr('onclick').toString().match(/bt_list_show\((.*)\)/)[1].split(',');
var infoid = args[0].trim();
var tid = args[1].match(/\d+/)[0].trim();
var G_section = unsafeWindow.G_section || $('html').html().match(/G_section = (.*?);/)[1];
var G_USERID = unsafeWindow.G_USERID || location.href.match(/userid=(\d+)/)[1];
var req = "/interface/fill_bt_list?callback=bt_task_down_resp&tid=" +
tid + "&infoid=" + infoid + "&g_net=" + G_section + "&p=0&uid=" + G_USERID + "&t=" + new Date();
$.get(req, function(data) {
if (data) {
o.pushData(data, tid);
}
});
});
},
isBt: function(tid) {
return this.links.bt.hasOwnProperty(tid);
},
isNormal: function(tid) {
return this.links.normal.hasOwnProperty(tid);
},
parseArgs: function(archor) {
var args = $(archor).attr('onclick').toString().match(/bt_task_down\((.*)\)/)[1].split(',');
var infoid = args[0].trim();
var tid = args[1].trim();
return {
'infoid': infoid,
'tid': tid
};
},
getLinkByTid: function(tid) {
if (this.links.bt.hasOwnProperty(tid)) {
return this.links.bt[tid];
}
},
showAddress: function(addrString, type, callback) {
var o = this;
if (type == 'normal') {
this.nowType = 'normal';
this.addrBox = $('<div id="batchPublish"></div>')
.append('<div id="batchHeader"></div>')
.append('<div id="batchContent" style="float:left;clear:both"></div>')
.append('<div id="batchFooter" style="flolat:left;clear:both"></div>');
this.addrBox.find('.mcTab').css('display', 'none');
this.addrBox.find('#batchHeader')
.append('<a style="margin-left:8px;float:left" id="linkpage" href="javascript:;">输出Linkpage</a>')
.append('<a style="float:right;margin-right:8px" id="close_btn" href="javascript:;">关闭</a>')
.append('<a style="float:right;margin-right:12px" id="reset" href="javascript:;">重置格式</a>')
.append('<a style="float:right;margin-right:8px" id="reform" href="javascript:;">修改格式</a>')
.append('<a style="float:right;margin-right:8px" id="reverse" href="javascript:;">转序</a>');
this.addrBox.find('#batchFooter')
.append('<label style="margin-left:8px;float:left"><input id="auto_select" type="checkbox"/>点击自动全选</label>')
.append('<a style="float:right;margin-right:8px" id="output_cmd" href="javascript:;" download="down.lst">保存为文件</a>');
var batchContent = this.addrBox.find('#batchContent').append('<pre id="batchedlink"></pre>');
this.addrBox.find('#batchedlink').css({
width: '750px',
height: '410px',
overflow: 'scroll'
}).html(addrString);
$.blockUI({
message: this.addrBox,
css: {
width: '770px',
height: '450px'
}
});
$('#batchPublish').get(0).onclick = function(e) {
switch (e.target.id) {
case 'auto_select':
o.changeAutoSelect();
break;
case 'batchedlink':
if (o.auto_select) {
o.selectNode(e.target);
}
break;
case 'close_btn':
o.closeBox();
break;
case 'output_cmd':
o.outputCMD();
break;
case 'linkpage':
o.showLinkPage();
break;
case 'reform':
o.promptForRule();
break;
case 'reset':
if (confirm('重置导出格式?')) {
o.resetRule();
}
break;
case 'reverse':
o.reverseResult();
break;
}
};
}
this.outputCMD();
$('#auto_select').attr('checked', this.auto_select);
if (typeof callback === 'function') {
callback();
}
},
updateDownURL: function(text, urlId) {
var uriContent = "data:application/octet-stream," +
encodeURIComponent(text).replace(/%26amp%3B/g, '%26');
document.getElementById(urlId).href = uriContent;
},
outputCMD: function() {
this.updateDownURL($('#batchedlink').html(), 'output_cmd');
},
closeBox: function() {
$.unblockUI();
this.nowType = null;
},
restartBox: function() {
this.closeBox();
this.showCheckedLinks();
},
getCheckedArchors: function() {
var o = this;
var returnLinks = [];
$(':checked').each(function(i, cb) {
var tid = cb.value;
var flag = o.isBt(tid);
if (flag) {
var dlinks = o.getLinkByTid(tid);
$.each(dlinks, function(i, link) {
returnLinks.push(link);
});
} else {
if (o.isNormal(tid)) {
returnLinks.push(o.links.normal[tid]);
}
}
});
return returnLinks;
},
showCheckedLinks: function() {
var returnLinks = this.getCheckedArchors();
var linkString = this.getLinkDetail(returnLinks);
this.showAddress(linkString, 'normal');
},
pushData: function(data, tid) {
data = data.match(/bt_task_down_resp\((.*)\)/);
var rt = JSON.parse(data[1]);
this.returnData.push(data);
var tempArray = [];
$.each(rt.Result, function(i, down) {
var fname = down.title;
var furl = (/^\/download/.test(down.downurl) ?
'http://gdl.lixian.vip.xunlei.com' : '') + down.downurl;
tempArray.push({
'name': fname,
'url': furl
});
});
this.links.bt[tid] = tempArray;
},
getLinkDetail: function(links) {
var o = this;
var returnArray = [];
if (o.outputRule == 'json') {
$.each(links, function(i, link) {
returnArray.push({
'uri': link.url,
'option': {
'out': link.name
}
});
});
return JSON.stringify(returnArray);
}
$.each(links, function(i, link) {
var name = link.name.split('\\\*');
var filename = name.pop();
var dir = name.length == 0 ? '/': +'/' + name.join('/');
var tempString = o.outputRule
.replace(/\\n/g, '\n')
.replace(/&amp;/g, '&')
.replace(/\$name/g, filename)
.replace(/\$dir/g, dir)
.replace(/\$cookie/g, document.cookie)
.replace(/\$gdrive/g, document.cookie.match(/(gdriveid=[0-9A-F]*?);/)[1])
.replace(/\$url/g, link.url);
returnArray.push(tempString);
});
o.batchContent = returnArray;
return returnArray.join('\n');
},
getPureAddress: function(links) {
var tempString = '';
$.each(links, function(i, link) {
tempString += link.url + "\n";
});
return tempString;
},
getLinkPage: function() {
var o = this;
var returnLinks = o.getCheckedArchors();
var content = $('<div id="main"></div>');
content.append('<h1>Link Page</h1>');
content.append('<style type="text/css">a{display:block;text-decoration:none}</style>');
$.each(returnLinks, function(i, link) {
var archor = $('<a></a>');
archor.html(link.name).attr('href', link.url);
content.append(archor).append('<br/>');
});
return content.html();
},
showLinkPage: function() {
var content = this.getLinkPage();
var my_window = window.open('', '_BLANK');
my_window.document.write(content);
},
promptForRule: function() {
var lastRule = localStorage.getItem('outputRule');
var rule = prompt('输入您的自定义规则:', this.outputRule);
rule = rule || (lastRule || '$name\\$url\\$gdrive');
localStorage.setItem('outputRule', rule);
this.outputRule = rule;
this.restartBox();
},
resetRule: function() {
this.outputRule = '$name\\$url\\$gdrive';
localStorage.setItem('outputRule', this.outputRule);
alert('输出规则已被重置。');
this.restartBox();
},
changeAutoSelect: function() {
var flag = localStorage.getItem('auto_select') === 'true';
localStorage.setItem('auto_select', !flag);
this.auto_select = !flag;
$('#auto_select').attr('checked', this.auto_select);
},
getAutoSelect: function() {
var flag = localStorage.getItem('auto_select');
if (flag === null) {
localStorage.setItem('auto_select', true);
return true;
}
return flag === 'true';
},
reverseResult: function() {
$('#batchedlink').html(this.batchContent.reverse().join('\r\n'));
},
selectNode: function(node) {
// This is a third party function written by Martin Honnen
// In comp.lang.javascript
var selection, range, doc, win;
selection = window.getSelection();
doc = node.ownerDocument;
win = doc.defaultView;
if (doc && doc.createRange !== undefined &&
win && win.getSelection !== undefined &&
selection && selection.removeAllRanges !== undefined) {
range = doc.createRange();
range.selectNode(node);
selection.removeAllRanges();
selection.addRange(range);
} else if (document.body && document.body.createTextRange !== undefined) {
range = document.body.createTextRange();
if (range) {
range.moveToElementText(node);
range.select();
}
}
}
};
function XLInit() {
if (unsafeWindow.jQuery === undefined) {
setTimeout(XLInit, 1e3);
return;
}
jQuery = unsafeWindow.jQuery;
$ = jQuery;
(function($) {
$.fn.shiftClick = function() {
var lastSelected;
var checkBoxes = $(this);
this.each(function() {
$(this).click(function(ev) {
if (ev.shiftKey) {
var last = checkBoxes.index(lastSelected);
var first = checkBoxes.index(this);
var start = Math.min(first, last);
var end = Math.max(first, last);
var chk = lastSelected.checked;
for (var i = start; i < end; i++) {
checkBoxes[i].checked = chk;
}
} else {
lastSelected = this;
}
});
});
};
var blockMsg = $('<div class="blockUI blockMsg"></div>');
var blockOverlay = $('<div class="blockUI blockOverlay"></div>');
blockMsg.css({
backgroundColor: '#eee',
border: '3px solid #aaa',
color: '#000',
margin: 0,
padding: 0,
position: 'fixed',
// textAlign: 'center',
'z-index': 101
});
blockOverlay.css({
backgroundColor: '#333',
border: 0,
height: '100%',
left: 0,
margin: 0,
opacity: 0.5,
padding: 0,
position: 'fixed',
top: 0,
width: '100%',
'z-index': 100
});
$.blockUI = function(opts) {
blockMsg.html(opts.message).css(opts.css);
$('body').append(blockOverlay).append(blockMsg);
blockMsg.css({
left: ($(window).width() - blockMsg.width()) / 2,
top: ($(window).height() - blockMsg.height()) / 2.2
});
};
$.unblockUI = function(opts) {
blockMsg.remove();
blockOverlay.remove();
};
} (jQuery));
$('.in_ztclick').shiftClick();
unsafeWindow.XL = new XL();
}
XLInit();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment