Всё в объекты. Добавлена зависимость от tinybt
parent
d7f41a2f07
commit
1fcefa2195
|
@ -3,6 +3,7 @@
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.25.0"/>
|
<import addon="xbmc.python" version="2.25.0"/>
|
||||||
<import addon="script.module.torrent_parser" version="0.3.0"/>
|
<import addon="script.module.torrent_parser" version="0.3.0"/>
|
||||||
|
<import addon="script.module.tinybt" version="0.9.0"/>
|
||||||
</requires>
|
</requires>
|
||||||
<extension point="xbmc.python.module" library="lib"/>
|
<extension point="xbmc.python.module" library="lib"/>
|
||||||
<extension point="xbmc.addon.metadata">
|
<extension point="xbmc.addon.metadata">
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import torrent_parser as tp
|
import torrent_parser as tp
|
||||||
import threading
|
import threading
|
||||||
from math import ceil
|
from math import ceil
|
||||||
|
from hashlib import sha1
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
BUFFER_SIZE = 10 * 1024 * 1024
|
BUFFER_SIZE = 10 * 1024 * 1024
|
||||||
|
|
||||||
|
@ -55,35 +57,74 @@ class Buffer(object):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
class Piece(object):
|
class Piece(object):
|
||||||
def __init__(self, p_index, p_hash, payload):
|
def __init__(self, p_hash, payload=b''):
|
||||||
self.index = p_index
|
|
||||||
self.hash = p_hash
|
self.hash = p_hash
|
||||||
self.payload = payload
|
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):
|
class Pyrrent(object):
|
||||||
multifile = False
|
shuttingdown = False
|
||||||
|
downloaded = 0
|
||||||
|
uploaded = 0
|
||||||
|
tracker_responce = {}
|
||||||
|
tracker_responce_ver = 0
|
||||||
def __init__(self, filepath):
|
def __init__(self, filepath):
|
||||||
self.data = tp.parse_torrent_file(filepath)
|
data = tp.parse_torrent_file(filepath)
|
||||||
self.piece_length = self.data['info']['piece length']
|
self.info = Info(data['info'], [data['announce']] + data['announce-list'] if 'announce-list' in data else [])
|
||||||
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)]
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
Loading…
Reference in New Issue