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>