Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
anasty17
GitHub Repository: anasty17/mirror-leech-telegram-bot
Path: blob/master/bot/core/torrent_manager.py
1630 views
1
from aioaria2 import Aria2WebsocketClient
2
from aioqbt.client import create_client
3
from asyncio import gather, TimeoutError
4
from aiohttp import ClientError
5
from pathlib import Path
6
from inspect import iscoroutinefunction
7
from tenacity import (
8
retry,
9
stop_after_attempt,
10
wait_exponential,
11
retry_if_exception_type,
12
)
13
14
from .. import LOGGER, aria2_options
15
16
17
def wrap_with_retry(obj, max_retries=3):
18
for attr_name in dir(obj):
19
if attr_name.startswith("_"):
20
continue
21
22
attr = getattr(obj, attr_name)
23
if iscoroutinefunction(attr):
24
retry_policy = retry(
25
stop=stop_after_attempt(max_retries),
26
wait=wait_exponential(multiplier=1, min=1, max=5),
27
retry=retry_if_exception_type(
28
(ClientError, TimeoutError, RuntimeError)
29
),
30
)
31
wrapped = retry_policy(attr)
32
setattr(obj, attr_name, wrapped)
33
return obj
34
35
36
class TorrentManager:
37
aria2 = None
38
qbittorrent = None
39
40
@classmethod
41
async def initiate(cls):
42
cls.aria2, cls.qbittorrent = await gather(
43
Aria2WebsocketClient.new("http://localhost:6800/jsonrpc"),
44
create_client("http://localhost:8090/api/v2/"),
45
)
46
cls.qbittorrent = wrap_with_retry(cls.qbittorrent)
47
48
@classmethod
49
async def close_all(cls):
50
await gather(cls.aria2.close(), cls.qbittorrent.close())
51
52
@classmethod
53
async def aria2_remove(cls, download):
54
if download.get("status", "") in ["active", "paused", "waiting"]:
55
await cls.aria2.forceRemove(download.get("gid", ""))
56
else:
57
try:
58
await cls.aria2.removeDownloadResult(download.get("gid", ""))
59
except:
60
pass
61
62
@classmethod
63
async def remove_all(cls):
64
await cls.pause_all()
65
await gather(
66
cls.qbittorrent.torrents.delete("all", False),
67
cls.aria2.purgeDownloadResult(),
68
)
69
downloads = []
70
results = await gather(cls.aria2.tellActive(), cls.aria2.tellWaiting(0, 1000))
71
for res in results:
72
downloads.extend(res)
73
tasks = []
74
tasks.extend(
75
cls.aria2.forceRemove(download.get("gid")) for download in downloads
76
)
77
try:
78
await gather(*tasks)
79
except:
80
pass
81
82
@classmethod
83
async def overall_speed(cls):
84
s1, s2 = await gather(
85
cls.qbittorrent.transfer.info(), cls.aria2.getGlobalStat()
86
)
87
download_speed = s1.dl_info_speed + int(s2.get("downloadSpeed", "0"))
88
upload_speed = s1.up_info_speed + int(s2.get("uploadSpeed", "0"))
89
return download_speed, upload_speed
90
91
@classmethod
92
async def pause_all(cls):
93
await gather(cls.aria2.forcePauseAll(), cls.qbittorrent.torrents.stop("all"))
94
95
@classmethod
96
async def change_aria2_option(cls, key, value):
97
downloads = []
98
results = await gather(cls.aria2.tellActive(), cls.aria2.tellWaiting(0, 1000))
99
for res in results:
100
downloads.extend(res)
101
tasks = []
102
for download in downloads:
103
if download.get("status", "") != "complete":
104
tasks.append(cls.aria2.changeOption(download.get("gid"), {key: value}))
105
if tasks:
106
try:
107
await gather(*tasks)
108
except Exception as e:
109
LOGGER.error(e)
110
if key not in ["checksum", "index-out", "out", "pause", "select-file"]:
111
await cls.aria2.changeGlobalOption({key: value})
112
aria2_options[key] = value
113
114
115
def aria2_name(download_info):
116
if "bittorrent" in download_info and download_info["bittorrent"].get("info"):
117
return download_info["bittorrent"]["info"]["name"]
118
elif download_info.get("files"):
119
if download_info["files"][0]["path"].startswith("[METADATA]"):
120
return download_info["files"][0]["path"]
121
file_path = download_info["files"][0]["path"]
122
dir_path = download_info["dir"]
123
if file_path.startswith(dir_path):
124
return Path(file_path[len(dir_path) + 1 :]).parts[0]
125
else:
126
return ""
127
else:
128
return ""
129
130
131
def is_metadata(download_info):
132
return any(
133
f["path"].startswith("[METADATA]") for f in download_info.get("files", [])
134
)
135
136