From 1fcefa2195210a175030ee50eb87cb1b6fa0ad2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D1=80=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=A0=D0=BE?= =?UTF-8?q?=D0=BC=D0=B0=D0=BD?= Date: Tue, 7 May 2019 19:58:24 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=81=D1=91=20=D0=B2=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=8A=D0=B5=D0=BA=D1=82=D1=8B.=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D1=8C=20=D0=BE=D1=82=20tinybt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addon.xml | 1 + lib/pyrrent.py | 95 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 69 insertions(+), 27 deletions(-) diff --git a/addon.xml b/addon.xml index 578547d..6f8017f 100644 --- a/addon.xml +++ b/addon.xml @@ -3,6 +3,7 @@ + diff --git a/lib/pyrrent.py b/lib/pyrrent.py index eb8866b..bfc3aa2 100644 --- a/lib/pyrrent.py +++ b/lib/pyrrent.py @@ -1,6 +1,8 @@ import torrent_parser as tp import threading from math import ceil +from hashlib import sha1 +from datetime import datetime BUFFER_SIZE = 10 * 1024 * 1024 @@ -55,35 +57,74 @@ class Buffer(object): return [] class Piece(object): - def __init__(self, p_index, p_hash, payload): - self.index = p_index + def __init__(self, p_hash, payload=b''): self.hash = p_hash self.payload = payload + self.exist = False +class PieceRange(object): + def __init__(self, first_piece, first_piece_offset, last_piece, last_piece_size): + self.first = first_piece + self.first_offset = first_piece_offset + self.last = last_piece + self.last_size = last_piece_size +class TFile(object): + def __init__(self, path, length, piece_range): + self.path = path + self.name = path[-1] + self.length = length + self.pieace_range = piece_range +class Tracker(object): + def __init__(self, url): + self.url = url + self.next_announce = datetime.now() + self.reachable = True + @property + def can_announce(self): + return self.next_announce <= datetime.now() and self.reachable + +class Info(object): + def __init__(self, info, trackers): + trackers = list(set(trackers)) + self.hash = sha1(tp.BEncoder(info).encode()).hexdigest() + self.files = [] + self.trackers = list(map(Tracker, trackers)) + self.pieces = list(map(Piece, info['pieces'])) + self.piece_length = info['piece length'] + def piece_range_gen(start, next_at): + first_piece = start // self.piece_length + first_piece_offset = start % self.piece_length + tail = next_at % self.piece_length + last_piece = next_at // self.piece_length - int(not bool(tail)) + last_piece_size = self.piece_length if not tail else tail + return PieceRange(first_piece, first_piece_offset, last_piece, last_piece_size) + if 'files' in info: + addr_ptr = 0 + for i in range(len(info['files'])): + f = info['files'][i] + next_at = addr_ptr + f['length'] + pr = piece_range_gen(addr_ptr, next_at) + self.files.append(TFile(info['name'] + f['path'], f['length'], pr)) + addr_ptr += f['length'] + else: + pr = piece_range_gen(0, info['length']) + self.files.append(TFile([info['name']], info['length'], pr)) class Pyrrent(object): - multifile = False + shuttingdown = False + downloaded = 0 + uploaded = 0 + tracker_responce = {} + tracker_responce_ver = 0 def __init__(self, filepath): - self.data = tp.parse_torrent_file(filepath) - self.piece_length = self.data['info']['piece length'] - self.buffer = Buffer(self.piece_length) - self.pieces = self.data['info']['pieces'] - if 'files' in self.data['info'].keys(): - self.multifile = True - if not self.multifile: - self.file_addresses = [(0, self.piece_length)] - else: - self.file_addresses = [] - addr_ptr = 0 - for length in map(lambda x: x['length'], self.data['info']['files']): - next_at = addr_ptr + length - self.file_addresses.append((addr_ptr, next_at)) - addr_ptr += length - def piece_range(self, f_index): - start, next_at = self.file_addresses[f_index] - start_piece = start // self.piece_length - start_byte = start % self.piece_length - tail = next_at % self.piece_length - end_piece = next_at // self.piece_length - int(not bool(tail)) - end_byte = self.piece_length if not tail else tail - return [(start_piece, start_byte),(end_piece, end_byte)] - + data = tp.parse_torrent_file(filepath) + self.info = Info(data['info'], [data['announce']] + data['announce-list'] if 'announce-list' in data else []) + + def tracker_anouncer(self): + self.tracker_responce_ver += 1 + for i in range(len(self.info.trackers)): + tracker = self.info.trackers[i] + if tracker.can_announce: + thr = threading.Thread(target=self.announce, args=(tracker, i)) + thr.start() + def announce(self, tracker, index): + pass