file resuming (part 2)

This commit is contained in:
ingvar1995 2016-07-30 21:43:28 +03:00
parent 99e8691f0b
commit 59154d081f
3 changed files with 46 additions and 25 deletions

View file

@ -55,6 +55,7 @@ class FileTransfer(QtCore.QObject):
self._size = float(size) self._size = float(size)
self._done = 0 self._done = 0
self._state_changed = StateSignal() self._state_changed = StateSignal()
self._file_id = None
def set_tox(self, tox): def set_tox(self, tox):
self._tox = tox self._tox = tox
@ -76,6 +77,9 @@ class FileTransfer(QtCore.QObject):
def get_friend_number(self): def get_friend_number(self):
return self._friend_number return self._friend_number
def get_id(self):
return self._file_id
def get_path(self): def get_path(self):
return self._path return self._path
@ -124,6 +128,7 @@ class SendTransfer(FileTransfer):
self.state = TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED'] self.state = TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED']
self._file_number = tox.file_send(friend_number, kind, size, file_id, self._file_number = tox.file_send(friend_number, kind, size, file_id,
bytes(basename(path), 'utf-8') if path else b'') bytes(basename(path), 'utf-8') if path else b'')
self._file_id = self.get_file_id()
def send_chunk(self, position, size): def send_chunk(self, position, size):
""" """
@ -206,16 +211,22 @@ class SendFromFileBuffer(SendTransfer):
class ReceiveTransfer(FileTransfer): class ReceiveTransfer(FileTransfer):
def __init__(self, path, tox, friend_number, size, file_number): def __init__(self, path, tox, friend_number, size, file_number, position=0):
super(ReceiveTransfer, self).__init__(path, tox, friend_number, size, file_number) super(ReceiveTransfer, self).__init__(path, tox, friend_number, size, file_number)
self._file = open(self._path, 'wb') self._file = open(self._path, 'wb')
self._file.truncate(0) self._file_size = position
self._file_size = 0 self._file.truncate(position)
self._missed = set()
self._file_id = self.get_file_id()
def cancel(self): def cancel(self):
super(ReceiveTransfer, self).cancel() super(ReceiveTransfer, self).cancel()
remove(self._path) remove(self._path)
def total_size(self):
self._missed.add(self._file_size)
return min(self._missed)
def write_chunk(self, position, data): def write_chunk(self, position, data):
""" """
Incoming chunk Incoming chunk
@ -232,6 +243,9 @@ class ReceiveTransfer(FileTransfer):
if self._file_size < position: if self._file_size < position:
self._file.seek(0, 2) self._file.seek(0, 2)
self._file.write(b'\0' * (position - self._file_size)) self._file.write(b'\0' * (position - self._file_size))
self._missed.add(self._file_size)
else:
self._missed.discard(position)
self._file.seek(position) self._file.seek(position)
self._file.write(data) self._file.write(data)
l = len(data) l = len(data)

View file

@ -287,9 +287,11 @@ class Profile(contact.Contact, Singleton):
else: else:
self.send_file(data[0], friend_number, True) self.send_file(data[0], friend_number, True)
friend.clear_unsent_files() friend.clear_unsent_files()
for key in self._paused_file_transfers: for key in list(self._paused_file_transfers.keys()):
data = self._paused_file_transfers[key] data = self._paused_file_transfers[key]
if data[1] == friend_number and not data[2]: if not os.path.exists(data[0]):
del self._paused_file_transfers[key]
elif data[1] == friend_number and not data[2]:
self.send_file(data[0], friend_number, True, key) self.send_file(data[0], friend_number, True, key)
del self._paused_file_transfers[key] del self._paused_file_transfers[key]
if friend_number == self.get_active_number(): if friend_number == self.get_active_number():
@ -309,9 +311,9 @@ class Profile(contact.Contact, Singleton):
if friend_num == friend_number: if friend_num == friend_number:
ft = self._file_transfers[(friend_num, file_num)] ft = self._file_transfers[(friend_num, file_num)]
if type(ft) is SendTransfer: if type(ft) is SendTransfer:
self._paused_file_transfers[ft.get_file_id()] = [ft.get_path(), friend_num, False] self._paused_file_transfers[ft.get_id()] = [ft.get_path(), friend_num, False, -1]
elif type(ft) is ReceiveTransfer: elif type(ft) is ReceiveTransfer:
self._paused_file_transfers[ft.get_file_id()] = [ft.get_path(), friend_num, True] self._paused_file_transfers[ft.get_id()] = [ft.get_path(), friend_num, True, ft.total_size()]
ft.cancelled() ft.cancelled()
del self._file_transfers[(friend_num, file_num)] del self._file_transfers[(friend_num, file_num)]
@ -821,18 +823,16 @@ class Profile(contact.Contact, Singleton):
Recreate tox instance Recreate tox instance
:param restart: method which calls restart and returns new tox instance :param restart: method which calls restart and returns new tox instance
""" """
# TODO: file transfers!! for friend in self._friends:
for key in list(self._file_transfers.keys()): self.friend_exit(friend.number)
self._file_transfers[key].cancelled()
del self._file_transfers[key]
self._call.stop() self._call.stop()
del self._call
del self._tox del self._tox
self._tox = restart() self._tox = restart()
self._call = calls.AV(self._tox.AV) self._call = calls.AV(self._tox.AV)
self.status = None self.status = None
for friend in self._friends: for friend in self._friends:
friend.status = None friend.number = self._tox.friend_by_public_key(friend.tox_id) # numbers update
friend.number = self._tox.friend_by_public_key(friend.tox_id)
self.update_filtration() self.update_filtration()
def reconnect(self): def reconnect(self):
@ -847,7 +847,7 @@ class Profile(contact.Contact, Singleton):
for i in range(len(self._friends)): for i in range(len(self._friends)):
del self._friends[0] del self._friends[0]
settings = Settings.get_instance() settings = Settings.get_instance()
settings['paused_file_transfers'] = self._paused_file_transfers settings['paused_file_transfers'] = self._paused_file_transfers if settings['resend_files'] else {}
settings.save() settings.save()
# ----------------------------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------------------------
@ -870,8 +870,12 @@ class Profile(contact.Contact, Singleton):
accepted = True accepted = True
if file_id in self._paused_file_transfers: if file_id in self._paused_file_transfers:
data = self._paused_file_transfers[file_id] data = self._paused_file_transfers[file_id]
# TODO: check size of file and send seek control if not os.path.exists(data[0]):
self.accept_transfer(None, data[0], friend_number, file_number, size) pos = 0
else:
pos = data[-1]
self._tox.file_seek(friend_number, file_number, pos)
self.accept_transfer(None, data[0], friend_number, file_number, size, False, pos)
tm = TransferMessage(MESSAGE_OWNER['FRIEND'], tm = TransferMessage(MESSAGE_OWNER['FRIEND'],
time.time(), time.time(),
TOX_FILE_TRANSFER_STATE['RUNNING'], TOX_FILE_TRANSFER_STATE['RUNNING'],
@ -971,7 +975,7 @@ class Profile(contact.Contact, Singleton):
else: else:
tr.send_control(TOX_FILE_CONTROL['RESUME']) tr.send_control(TOX_FILE_CONTROL['RESUME'])
def accept_transfer(self, item, path, friend_number, file_number, size, inline=False): def accept_transfer(self, item, path, friend_number, file_number, size, inline=False, from_position=0):
""" """
:param item: transfer item. :param item: transfer item.
:param path: path for saving :param path: path for saving
@ -979,9 +983,11 @@ class Profile(contact.Contact, Singleton):
:param file_number: file number :param file_number: file number
:param size: file size :param size: file size
:param inline: is inline image :param inline: is inline image
:param from_position: position for start
""" """
path, file_name = os.path.split(path) path, file_name = os.path.split(path)
new_file_name, i = file_name, 1 new_file_name, i = file_name, 1
if not from_position:
while os.path.isfile(path + '/' + new_file_name): # file with same name already exists while os.path.isfile(path + '/' + new_file_name): # file with same name already exists
if '.' in file_name: # has extension if '.' in file_name: # has extension
d = file_name.rindex('.') d = file_name.rindex('.')
@ -991,7 +997,7 @@ class Profile(contact.Contact, Singleton):
i += 1 i += 1
path = os.path.join(path, new_file_name) path = os.path.join(path, new_file_name)
if not inline: if not inline:
rt = ReceiveTransfer(path, self._tox, friend_number, size, file_number) rt = ReceiveTransfer(path, self._tox, friend_number, size, file_number, from_position)
else: else:
rt = ReceiveToBuffer(self._tox, friend_number, size, file_number) rt = ReceiveToBuffer(self._tox, friend_number, size, file_number)
self._file_transfers[(friend_number, file_number)] = rt self._file_transfers[(friend_number, file_number)] = rt

View file

@ -118,6 +118,7 @@ class Settings(dict, Singleton):
'show_online_friends': False, 'show_online_friends': False,
'auto_accept_from_friends': [], 'auto_accept_from_friends': [],
'paused_file_transfers': {}, 'paused_file_transfers': {},
'resend_files': True,
'friends_aliases': [], 'friends_aliases': [],
'show_avatars': False, 'show_avatars': False,
'typing_notifications': False, 'typing_notifications': False,