-
Notifications
You must be signed in to change notification settings - Fork 87
/
main.py
108 lines (79 loc) · 3.56 KB
/
main.py
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
import sys
from block import State
__author__ = 'alexisgallepe'
import time
import peers_manager
import pieces_manager
import torrent
import tracker
import logging
import os
import message
class Run(object):
percentage_completed = -1
last_log_line = ""
def __init__(self):
try:
torrent_file = sys.argv[1]
except IndexError:
logging.error("No torrent file provided!")
sys.exit(0)
self.torrent = torrent.Torrent().load_from_path(torrent_file)
self.tracker = tracker.Tracker(self.torrent)
self.pieces_manager = pieces_manager.PiecesManager(self.torrent)
self.peers_manager = peers_manager.PeersManager(self.torrent, self.pieces_manager)
self.peers_manager.start()
logging.info("PeersManager Started")
logging.info("PiecesManager Started")
def start(self):
peers_dict = self.tracker.get_peers_from_trackers()
self.peers_manager.add_peers(peers_dict.values())
while not self.pieces_manager.all_pieces_completed():
if not self.peers_manager.has_unchoked_peers():
time.sleep(1)
logging.info("No unchocked peers")
continue
for piece in self.pieces_manager.pieces:
index = piece.piece_index
if self.pieces_manager.pieces[index].is_full:
continue
peer = self.peers_manager.get_random_peer_having_piece(index)
if not peer:
continue
self.pieces_manager.pieces[index].update_block_status()
data = self.pieces_manager.pieces[index].get_empty_block()
if not data:
continue
piece_index, block_offset, block_length = data
piece_data = message.Request(piece_index, block_offset, block_length).to_bytes()
peer.send_to_peer(piece_data)
self.display_progression()
time.sleep(0.1)
logging.info("File(s) downloaded successfully.")
self.display_progression()
self._exit_threads()
def display_progression(self):
new_progression = 0
for i in range(self.pieces_manager.number_of_pieces):
for j in range(self.pieces_manager.pieces[i].number_of_blocks):
if self.pieces_manager.pieces[i].blocks[j].state == State.FULL:
new_progression += len(self.pieces_manager.pieces[i].blocks[j].data)
if new_progression == self.percentage_completed:
return
number_of_peers = self.peers_manager.unchoked_peers_count()
percentage_completed = float((float(new_progression) / self.torrent.total_length) * 100)
current_log_line = "Connected peers: {} - {}% completed | {}/{} pieces".format(number_of_peers,
round(percentage_completed, 2),
self.pieces_manager.complete_pieces,
self.pieces_manager.number_of_pieces)
if current_log_line != self.last_log_line:
print(current_log_line)
self.last_log_line = current_log_line
self.percentage_completed = new_progression
def _exit_threads(self):
self.peers_manager.is_active = False
os._exit(0)
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
run = Run()
run.start()