Skip to content

Instantly share code, notes, and snippets.

@cdpath
Last active September 7, 2022 16:37
Show Gist options
  • Save cdpath/3d7dccab7b6ff9b3c41149ce0f557670 to your computer and use it in GitHub Desktop.
Save cdpath/3d7dccab7b6ff9b3c41149ce0f557670 to your computer and use it in GitHub Desktop.
Torrent2DS
#!/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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment