file resuming (part 2)
This commit is contained in:
parent
99e8691f0b
commit
59154d081f
3 changed files with 46 additions and 25 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue