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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
#!/usr/bin/python3
from sys import path, argv
path.append("..")
from travnik import Torrent
import inotify.adapters
from threading import Thread
from random import randrange
from os import stat, path
from time import sleep
from pydub import AudioSegment
from pydub.playback import play
from socket import socket, AF_UNIX, AF_INET, SOCK_STREAM
import libtorrent
def random_file(torrent, save_path, endung=".flac"):
def get_index_from_endung(chosen):
for i in range(torrent.torrent_file().files().num_files()):
if (torrent.torrent_file().files().file_path(i).endswith(endung)):
if chosen == 0:
return i
break
chosen -= 1
prios = []
for i in torrent.get_file_priorities():
prios.append(0)
endungs = 0
for i in range(torrent.torrent_file().files().num_files()):
if (torrent.torrent_file().files().file_path(i).endswith(endung)):
endungs += 1
if endungs == 0:
print("no more endungs")
return False
chosen = randrange(endungs)
tries_left = endungs
print(f"there are {endungs} {endung} files")
while True:
if tries_left == 0:
print("no more tries")
return False
tries_left -= 1
try:
p = save_path + "/" + torrent.torrent_file().files().file_path(get_index_from_endung(chosen))
print(f"trying path {p} with stat")
stat(p)
except FileNotFoundError:
break
else:
chosen = (chosen + 1) % endungs;
continue
prios[get_index_from_endung(chosen)] = 4
torrent.prioritize_files(prios)
print(f"random file {torrent.torrent_file().files().file_path(get_index_from_endung(chosen))} chosen to download")
return True
def watcher(session, torrents, s, d, active_torrents=10):
i = inotify.adapters.Inotify()
i.add_watch(d)
for event in i.event_gen(yield_nones=False):
(_, type_names, path, filename) = event
if ("IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names) and filename.endswith(".torrent"):
t = Torrent()
t.file(path + filename)
for pth, size in t.paths():
if pth[-1].endswith(b'.flac'):
info = libtorrent.torrent_info(path + filename)
torr = session.add_torrent({"ti": info, "save_path": s})
random_file(torr, save_path=s);
torrents.append(torr)
if len(torrents) > active_torrents:
session.remove_torrent(torrents[0])
del torrents[0]
break
def alerts(session, playstack, save_path, torrents):
while True:
session.wait_for_alert(86400*1000*21)
for a in session.pop_alerts():
if a.category() & libtorrent.alert.category_t.error_notification:
print(f"error notification alert from libtorrent: {a}")
if type(a) == libtorrent.file_completed_alert:
if a.handle.get_file_priorities()[a.index] != 4:
continue
playstack.append(a.handle.torrent_file().files().file_path(a.index))
if not random_file(a.handle, save_path):
session.remove_torrent(a.handle)
torrents.remove(a.handle)
continue
else:
a.handle.resume()
if type(a) in [libtorrent.external_ip_alert, libtorrent.listen_succeeded_alert, libtorrent.dht_get_peers_alert, libtorrent.dht_outgoing_get_peers_alert, libtorrent.dht_reply_alert, libtorrent.torrent_added_alert, libtorrent.state_changed_alert, libtorrent.torrent_resumed_alert, libtorrent.stats_alert, libtorrent.torrent_checked_alert, libtorrent.peer_connect_alert, libtorrent.alert, libtorrent.peer_disconnected_alert, libtorrent.incoming_connection_alert, libtorrent.block_downloading_alert, libtorrent.dht_bootstrap_alert, libtorrent.dht_announce_alert, libtorrent.block_finished_alert, libtorrent.piece_finished_alert, libtorrent.peer_unsnubbed_alert, libtorrent.peer_snubbed_alert, libtorrent.portmap_error_alert, libtorrent.block_timeout_alert, libtorrent.block_uploaded_alert, libtorrent.performance_alert, libtorrent.cache_flushed_alert, libtorrent.dht_log_alert, libtorrent.portmap_log_alert, libtorrent.dht_pkt_alert, libtorrent.log_alert, libtorrent.peer_log_alert, libtorrent.picker_log_alert, libtorrent.torrent_log_alert]:
continue
print(f"{type(a)} | {a}")
def stream(playstack, unix=None):
if type(unix) is str:
while True:
# sock = socket(AF_INET, SOCK_STREAM)
# sock.connect("tranzistor", 1234)
sock = socket(AF_UNIX, SOCK_STREAM)
sock.connect("/tmp/ls")
sock.sendall(b"request.alive\r\n")
sleep(1)
data = sock.recv(256)
a = data.split(b"\r")[0]
if a == b"":
sock.sendall(b"request.push " + bytes(playstack.pop(), encoding="utf-8"))
sleep(1)
else:
while True:
if len(playstack) == 0:
sleep(1)
continue
song = AudioSegment.from_file(path.abspath(playstack.pop()), "flac")
play(song)
sleep(1)
def progress(session, torrents):
while True:
for torr in torrents:
s = torr.status()
print(torr.torrent_file().name() + '\t%.2f%% complete (down: %.1f kB/s up: %.1f kB/s peers: %d) %s' % (s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, s.num_peers, s.state))
sleep(1)
if __name__ == "__main__":
session = libtorrent.session({"alert_mask": libtorrent.alert.category_t.all_categories});
torrents = []
playstack = []
save_path = "."
torrents_path = "."
unix = None
if len(argv) > 1:
save_path = argv[1]
if len(argv) > 2:
torrents_path = argv[2]
if len(argv) > 3:
unix = argv[3]
w = Thread(target=watcher, args=(session, torrents, save_path, torrents_path))
a = Thread(target=alerts, args=(session, playstack, save_path, torrents))
p = Thread(target=progress, args=(session, torrents))
s = Thread(target=stream, args=(playstack, unix))
w.start()
a.start()
p.start()
s.start()
w.join()
a.join()
p.join()
s.join()
|