让 Aria2 启动后自动继续未完成的下载 并清理已删除任务的文件

这个假期,我做的最有趣的一件事就是将路由器改造成了一台稳定的 NAS,其中由 Aria2 实现的离线下载服务器是作为 NAS 的一个核心功能。用着非常方便,然而却有以下几个问题:

  1. 重启机器后,Aria2 在重启后并不会自动继续之前的下载。虽然保存了 sessions,但 Aria2 重启之后会自动将所有任务暂停。这就没法实现挂机下载了。
  2. 删除 Aria2 建立的下载任务后,并不会删除硬盘中对应的文件(包括只下载到一半的破损文件),这很不方便。


重要补充说明

我的代码依赖于 Aria2 编译时的 XML 库依赖,而在某些版本中是不带这个依赖的。所以本篇文章不一定适用于所有情况。

为了解决这 2 个问题,我编写了一个 Python 脚本,完美地解决了困扰。

脚本在 Python3 下运行正常,未对 Python2 测试。不依赖第三方模块。
为了实现 “让暂停的任务继续下载”,需要按照 Aria2 文档来调用 RPC,所以 需要在代码内修改相关的连接地址、密码等信息。

脚本同时会自动读取任务列表,并在下载目录找到所有不属于任务列表中的文件,删除之。
你也可以在 fileWhiteList 变量中设置不想要删除的文件的白名单。

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 1. start all paused tasks
# 2. delete other files on disk

# API: https://aria2.github.io/manual/en/html/aria2c.html#rpc-interface

from xmlrpc import client as xmlc
import os

rpcUrl = 'http://127.0.0.1:6800/rpc'
rpcToken = 'token:PASSWORD'
downloadPath = '/root/usb/nas/download/'  # same to aria2 config
fileWhiteList = ['/bypy', '/PROTECTED']   # while list for delete


s = xmlc.ServerProxy(rpcUrl)
api = s.aria2
# start all tasks
api.unpauseAll(rpcToken)


tasks = api.tellActive(rpcToken)
tasks += api.tellStopped(rpcToken, 0, 99)
tasks += api.tellWaiting(rpcToken, 0, 99)

for task in tasks:
    # started BT tasks
    if ('bittorrent' in task) and ('info' in task['bittorrent']):
        filename = task['bittorrent']['info']['name']
        fileWhiteList.append(filename)
    # other tasks
    else:
        for file in task['files']:
            path = file['path']
            if path.startswith('[METADATA]'):
                path = path.replace('[METADATA]', '')
            else:
                path = os.path.basename(path)

            fileWhiteList.append(path)

# del same items
fileWhiteList = set(fileWhiteList)

print('fileWhiteList', fileWhiteList)


def isStrContainItemInList(str, list):
    for item in list:
        if item in str:
            return True
    return False


for parent, dirnames, filenames in os.walk(downloadPath, topdown=False):
    for filename in filenames:
        path = os.path.join(parent, filename)
        if not isStrContainItemInList(path, fileWhiteList):
            os.remove(path)
            print('del file: ', filename)
    for dirname in dirnames:
        path = os.path.join(parent, dirname)
        if not isStrContainItemInList(path, fileWhiteList):
            try:
                os.rmdir(path)
                print('del dir:  ', dirname)
            finally:
                pass

一般来说,我们需要这段脚本在开机后自动运行,加入至 /etc/rc.local 即可:

sleep 1m && python /root/aria2/afterRun.py > /var/log/aria2.afterRun.log &

相关推荐

Aria2 bt-tracker 跟踪服务器列表自动更新:https://www.feng.ee/aria2-trackers-auto-update.html

1 条评论
  1. 挖槽终于找到你了,很关键兄弟,收下了

发表一条评论