first request sid (so as to communicate Synology API)
python t2ds.py login -u <username> -p <password> [--otp 233333]
then create download task
python t2ds.py task <path_to_torrent_file> --sid <sid>
#!/usr/bin/env python | |
import argparse | |
import sys | |
import hashlib | |
import base64 | |
from typing import Optional | |
import bencodepy | |
import requests | |
DSM_HOST = "" | |
DSM_PORT = "" | |
DSM_SID = "" | |
def make_magnet_from_file(file: str) -> str: | |
"""steal from https://github.com/DanySK/torrent2magnet/blob/develop/torrent2magnet.py""" | |
metadata = bencodepy.decode_from_file(file) | |
subj = metadata[b"info"] | |
hashcontents = bencodepy.encode(subj) | |
digest = hashlib.sha1(hashcontents).digest() | |
b32hash = base64.b32encode(digest).decode() | |
link = ( | |
"magnet:?" | |
+ "xt=urn:btih:" | |
+ b32hash | |
+ "&dn=" | |
+ metadata[b"info"][b"name"].decode() | |
+ "&tr=" | |
+ metadata[b"announce"].decode() | |
) | |
try: | |
link += "&xl=" + str(metadata[b"info"][b"length"]) | |
except KeyError: | |
pass | |
return link | |
def request_sid(username: str, password: str, otp_code: Optional[str] = None) -> str: | |
url = f"https://{DSM_HOST}:{DSM_PORT}/webapi/auth.cgi" | |
params = { | |
"api": "SYNO.API.Auth", | |
"version": "3", | |
"method": "login", | |
"account": username, | |
"passwd": password, | |
"session": "DownloadStation", | |
"format": "sid", | |
} | |
if otp_code: | |
params["otp_code"] = otp_code | |
resp = requests.get(url, params=params, verify=False) | |
return resp.json()["data"]["sid"] | |
def create_download_station_task(magnet: str, sid: str) -> None: | |
url = f"https://{DSM_HOST}:{DSM_PORT}/webapi/DownloadStation/task.cgi" | |
params = { | |
"api": "SYNO.DownloadStation.Task", | |
"version": 3, | |
"method": "create", | |
"uri": magnet, | |
"_sid": sid, | |
} | |
resp = requests.get(url, params=params, verify=False) | |
return | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser( | |
prog="t2ds", description="Download torrent with Synology Download Station" | |
) | |
subparsers = parser.add_subparsers(dest="command") | |
login_parser = subparsers.add_parser("login") | |
login_parser.add_argument("-u", "--username", help="username") | |
login_parser.add_argument("-p", "--password", help="password") | |
login_parser.add_argument("--otp", help="2fa code") | |
task_parser = subparsers.add_parser("task") | |
task_parser.add_argument("torrent_file", help="path to torrent file") | |
task_parser.add_argument("--sid", default=DSM_SID) | |
args = parser.parse_args() | |
if args.command == "login": | |
sid = request_sid(args.username, args.password, args.otp) | |
print( | |
f"""\ | |
Here is your sid: | |
{sid} | |
""" | |
) | |
elif args.command == "task": | |
magnet = make_magnet_from_file(args.torrent_file) | |
create_download_station_task(magnet, args.sid) | |
print("created") | |
else: | |
parser.print_help() |
first request sid (so as to communicate Synology API)
python t2ds.py login -u <username> -p <password> [--otp 233333]
then create download task
python t2ds.py task <path_to_torrent_file> --sid <sid>