-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
114 lines (97 loc) · 3.81 KB
/
main.py
File metadata and controls
114 lines (97 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import gi, requests
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
RPC_URL = "http://localhost:6800/jsonrpc"
SECRET = "mysecret"
TOKEN = f"token:{SECRET}"
session = requests.Session() # 🚀 سریعتر از requests.post تکی
def aria2_request(method, params=None):
payload = {
"jsonrpc": "2.0", "id": "qwer",
"method": method, "params": [TOKEN, *(params or [])]
}
try:
r = session.post(RPC_URL, json=payload, timeout=2)
data = r.json()
return data.get("result", [])
except:
return []
def aria2_multicall(methods):
calls = [[m, [TOKEN, *p]] for m, p in methods]
try:
r = session.post(RPC_URL, json={
"jsonrpc":"2.0","id":"multi","method":"system.multicall","params":[calls]
}, timeout=2).json()
return r.get("result", [])
except:
return []
def percent(comp, total):
return f"{(comp * 100)//total}%" if total else "0%"
def human(n):
n = int(n)
if n <= 0: return "0"
for unit in ["B","KB","MB","GB","TB","PB"]:
if n < 1024:
return f"{n}{unit}"
n //= 1024
return f"{n}PB"
class AddDownloadWindow(Gtk.Window):
def __init__(self):
super().__init__(title="Aria2 Download Manager")
self.set_default_size(650, 400)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
self.add(vbox)
hbox = Gtk.Box(spacing=5)
self.url_entry = Gtk.Entry(placeholder_text="enter link...")
add_btn = Gtk.Button(label="add .")
add_btn.connect("clicked", self.add_download)
hbox.pack_start(self.url_entry, True, True, 0)
hbox.pack_start(add_btn, False, False, 0)
vbox.pack_start(hbox, False, False, 0)
self.liststore = Gtk.ListStore(str, str, str, str, str)
self.tree = Gtk.TreeView(model=self.liststore)
for i, col in enumerate(["GID","Status","Progress","Size","Speed"]):
self.tree.append_column(Gtk.TreeViewColumn(col, Gtk.CellRendererText(), text=i))
vbox.pack_start(self.tree, True, True, 0)
self.tree.connect("button-press-event", self.open_menu)
GLib.timeout_add_seconds(2, self.update_list)
def open_menu(self, widget, event):
if event.button == 3 and self.get_selected_gid():
menu = Gtk.Menu()
for label, method in [("stop","aria2.pause"),("delete","aria2.remove")]:
item = Gtk.MenuItem(label=label)
item.connect("activate", lambda w, m=method: aria2_request(m,[self.get_selected_gid()]))
menu.append(item)
menu.show_all(); menu.popup_at_pointer()
def get_selected_gid(self):
model, it = self.tree.get_selection().get_selected()
return model[it][0] if it else None
def add_download(self, widget):
url = self.url_entry.get_text().strip()
if url:
aria2_request("aria2.addUri", [[url]])
self.url_entry.set_text("")
def update_list(self):
self.liststore.clear()
result = aria2_multicall([
("aria2.tellActive", [0,100]),
("aria2.tellWaiting", [0,100]),
("aria2.tellStopped", [0,100])
])
for section in result:
for item in section.get("result", []):
comp = int(item.get("completedLength",0))
total = int(item.get("totalLength",0))
speed = human(item.get("downloadSpeed",0))
self.liststore.append([
item.get("gid","-"),
item.get("status","-"),
percent(comp, total),
human(total),
speed+"/s" if speed!="0" else "-"
])
return True
win = AddDownloadWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()