最近树莓派更新了最新版本,pi4,终于换上了千兆网卡还有双USB3.0(据说是一个hub?好在我只用一个口)。终于可以尝试做一个像样的NAS了。因为已经有小白智家可以同步手机内容到百度云,所以,这次的目标很简答, 使用pi4搭aria2+samba,以实现自动下载,电视直接播放的功能。同时还可以兼职备份电脑上的文件。
----------------------------------------分割线,以下正文-----------------------------------------------------------------------------
首先,jsonrpc是http调用,完全可以用postman或者火狐自带插件进行调试,跟普通restful接口差不多。但调试过程中,苦于不了解aria2的jsonrpc结构,总是报一些奇怪的错误,其中,最常见的如下:
{"id":null,"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid Request."}}
这种一般使用了错误的httpMethod,aria2的jsonrpc需使用HttpMethod="POST"
{"id":null,"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error."}}
这种错误源于1- Content-Type不正确,正确的Content-Type应该是application/json,2-传入的json结构不正确,3-Content-Length不正确,如果用火狐调试,请每次删除Content-Length的header,由火狐自动生成
在网上找到了正确的JSON结构如:
{"jsonrpc": "2.0", "id": "qwer",
"method": "aria2.addUri",
"params": [["http://www.baidu.com"],{"out":"index.html" ,"dir":"/home/"}]
}
POST过去,仍旧有问题,提示
{"id":"qwer","jsonrpc":"2.0","error":{"code":1,"message":"Unauthorized"}}
看上去,应该是我设置了token的原因,查看aria2官方文档,文档上只说使用http调用jsonrpc,需要保留basic认证,但他们会慢慢去除。通过百度basic认证原理,需要在header中加入Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxx(xxxxx是base64encode之后的username:password),password好说,可以理解为token值,但username是什么?我尝试了token、username或者aria2的实例名,都不正确,仍旧提示Unauthorized,看来这个不靠谱。
走投无路的我,看上去只能曲线救国了,因为大学期间学过一段时间python,再百度一下python操作aria2的类库,最后找到了pyaria2,通过网上的例子(如下),仍旧崩盘,还是提示Unauthorized。
from pyaria2 import Aria2RPC jsonrpc = Aria2RPC()
set_dir = os.path.dirname('/home/pi/movie/')
options = {"dir": set_dir, "out": '追龙Ⅱ.mkv' }
res = jsonrpc.addUri(['magnet:?xt=urn:btih:a9d9cf513b2ddef1b09ec8c7d32847a8aa089463&dn=[电影天堂www.dy2018.com]追龙ⅡHD高清国语中字.mkv'], options = options)
既然python有类库操作aria2,肯定应该考虑到了token的情景,所以问题应该出在例子本身。查看pyaria2的源码,发现两段关键代码
def __init__(self, url="http://localhost:6800/rpc", token=None): self._url = url if token: self._token = 'token:' + token
else: self._token = token self._client = ServerProxy(self._url) def addUri(self,uris,options): params = [urls, options] if self._token: params.insert(0.self._token)
return self._client.aria2.addUri(*params)
可以看到,Jsonrpc对象在初始化的时候,是可以指定token的,同时,初始化的时候,token增加了“token:”的头,比如我的token是secret,最终token的值是“token:secret”,同时,token在发送的时候,被放入了params的第一位。
修改一下我们的python代码
from pyaria2 import Aria2RPC jsonrpc = Aria2RPC(token="secret")
set_dir = os.path.dirname('/home/pi/movie/')
options = {"dir": set_dir, "out": '追龙Ⅱ.mkv' }
res = jsonrpc.addUri(['magnet:?xt=urn:btih:a9d9cf513b2ddef1b09ec8c7d32847a8aa089463&dn=[电影天堂www.dy2018.com]追龙ⅡHD高清国语中字.mkv'], options = options)
print(res)
终于成功,接下来,我们根据python结果,调整一下http调用jsonrpc的结构
{"jsonrpc": "2.0", "id": "qwer", "method": "aria2.addUri", "params": ["token:secret",["http://www.baidu.com"],{"out":"index.html" ,"dir":"/home/"}] }
同样成功!yes,终于搞定了aria2的jsonrpc调用。