threads fix and update
This commit is contained in:
parent
39fe859fe5
commit
742d853b11
4 changed files with 67 additions and 79 deletions
|
@ -243,30 +243,15 @@ def file_recv_chunk(tox, friend_number, file_number, position, chunk, length, us
|
||||||
"""
|
"""
|
||||||
Incoming chunk
|
Incoming chunk
|
||||||
"""
|
"""
|
||||||
if not length:
|
_thread.execute(Profile.get_instance().incoming_chunk, friend_number, file_number, position,
|
||||||
invoke_in_main_thread(Profile.get_instance().incoming_chunk,
|
chunk[:length] if length else None)
|
||||||
friend_number,
|
|
||||||
file_number,
|
|
||||||
position,
|
|
||||||
None)
|
|
||||||
else:
|
|
||||||
_thread.execute(Profile.get_instance().incoming_chunk, friend_number, file_number, position, chunk[:length])
|
|
||||||
#Profile.get_instance().incoming_chunk(friend_number, file_number, position, chunk[:length])
|
|
||||||
|
|
||||||
|
|
||||||
def file_chunk_request(tox, friend_number, file_number, position, size, user_data):
|
def file_chunk_request(tox, friend_number, file_number, position, size, user_data):
|
||||||
"""
|
"""
|
||||||
Outgoing chunk
|
Outgoing chunk
|
||||||
"""
|
"""
|
||||||
if size:
|
Profile.get_instance().outgoing_chunk(friend_number, file_number, position, size)
|
||||||
#_thread.execute(Profile.get_instance().outgoing_chunk, friend_number, file_number, position, size)
|
|
||||||
Profile.get_instance().outgoing_chunk(friend_number, file_number, position, size)
|
|
||||||
else:
|
|
||||||
invoke_in_main_thread(Profile.get_instance().outgoing_chunk,
|
|
||||||
friend_number,
|
|
||||||
file_number,
|
|
||||||
position,
|
|
||||||
size)
|
|
||||||
|
|
||||||
|
|
||||||
def file_recv_control(tox, friend_number, file_number, file_control, user_data):
|
def file_recv_control(tox, friend_number, file_number, file_control, user_data):
|
||||||
|
|
|
@ -10,8 +10,6 @@ except ImportError:
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
QtCore.Signal = QtCore.pyqtSignal
|
QtCore.Signal = QtCore.pyqtSignal
|
||||||
|
|
||||||
# TODO: threads!
|
|
||||||
|
|
||||||
|
|
||||||
TOX_FILE_TRANSFER_STATE = {
|
TOX_FILE_TRANSFER_STATE = {
|
||||||
'RUNNING': 0,
|
'RUNNING': 0,
|
||||||
|
@ -36,7 +34,12 @@ ALLOWED_FILES = ('toxygen_inline.png', 'utox-inline.png', 'sticker.png')
|
||||||
|
|
||||||
class StateSignal(QtCore.QObject):
|
class StateSignal(QtCore.QObject):
|
||||||
|
|
||||||
signal = QtCore.Signal(int, float, int) # state and progress
|
signal = QtCore.Signal(int, float, int) # state, progress, time in sec
|
||||||
|
|
||||||
|
|
||||||
|
class TransferFinishedSignal(QtCore.QObject):
|
||||||
|
|
||||||
|
signal = QtCore.Signal(int, int) # friend number, file number
|
||||||
|
|
||||||
|
|
||||||
class FileTransfer(QtCore.QObject):
|
class FileTransfer(QtCore.QObject):
|
||||||
|
@ -55,6 +58,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._finished = TransferFinishedSignal()
|
||||||
self._file_id = None
|
self._file_id = None
|
||||||
|
|
||||||
def set_tox(self, tox):
|
def set_tox(self, tox):
|
||||||
|
@ -63,6 +67,9 @@ class FileTransfer(QtCore.QObject):
|
||||||
def set_state_changed_handler(self, handler):
|
def set_state_changed_handler(self, handler):
|
||||||
self._state_changed.signal.connect(handler)
|
self._state_changed.signal.connect(handler)
|
||||||
|
|
||||||
|
def set_transfer_finished_handler(self, handler):
|
||||||
|
self._finished.signal.connect(handler)
|
||||||
|
|
||||||
def signal(self):
|
def signal(self):
|
||||||
percentage = self._done / self._size if self._size else 0
|
percentage = self._done / self._size if self._size else 0
|
||||||
if self._creation_time is None or not percentage:
|
if self._creation_time is None or not percentage:
|
||||||
|
@ -71,6 +78,9 @@ class FileTransfer(QtCore.QObject):
|
||||||
t = ((time() - self._creation_time) / percentage) * (1 - percentage)
|
t = ((time() - self._creation_time) / percentage) * (1 - percentage)
|
||||||
self._state_changed.signal.emit(self.state, percentage, int(t))
|
self._state_changed.signal.emit(self.state, percentage, int(t))
|
||||||
|
|
||||||
|
def finished(self):
|
||||||
|
self._finished.signal.emit(self._friend_number, self._file_number)
|
||||||
|
|
||||||
def get_file_number(self):
|
def get_file_number(self):
|
||||||
return self._file_number
|
return self._file_number
|
||||||
|
|
||||||
|
@ -143,12 +153,12 @@ class SendTransfer(FileTransfer):
|
||||||
data = self._file.read(size)
|
data = self._file.read(size)
|
||||||
self._tox.file_send_chunk(self._friend_number, self._file_number, position, data)
|
self._tox.file_send_chunk(self._friend_number, self._file_number, position, data)
|
||||||
self._done += size
|
self._done += size
|
||||||
self.signal()
|
|
||||||
else:
|
else:
|
||||||
if hasattr(self, '_file'):
|
if hasattr(self, '_file'):
|
||||||
self._file.close()
|
self._file.close()
|
||||||
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
|
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
|
||||||
self.signal()
|
self.finished()
|
||||||
|
self.signal()
|
||||||
|
|
||||||
|
|
||||||
class SendAvatar(SendTransfer):
|
class SendAvatar(SendTransfer):
|
||||||
|
@ -187,10 +197,10 @@ class SendFromBuffer(FileTransfer):
|
||||||
data = self._data[position:position + size]
|
data = self._data[position:position + size]
|
||||||
self._tox.file_send_chunk(self._friend_number, self._file_number, position, data)
|
self._tox.file_send_chunk(self._friend_number, self._file_number, position, data)
|
||||||
self._done += size
|
self._done += size
|
||||||
self.signal()
|
|
||||||
else:
|
else:
|
||||||
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
|
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
|
||||||
self.signal()
|
self.finished()
|
||||||
|
self.signal()
|
||||||
|
|
||||||
|
|
||||||
class SendFromFileBuffer(SendTransfer):
|
class SendFromFileBuffer(SendTransfer):
|
||||||
|
@ -213,7 +223,7 @@ class ReceiveTransfer(FileTransfer):
|
||||||
|
|
||||||
def __init__(self, path, tox, friend_number, size, file_number, position=0):
|
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', 1371 * 4)
|
||||||
self._file_size = position
|
self._file_size = position
|
||||||
self._file.truncate(position)
|
self._file.truncate(position)
|
||||||
self._missed = set()
|
self._missed = set()
|
||||||
|
@ -239,6 +249,7 @@ class ReceiveTransfer(FileTransfer):
|
||||||
if data is None:
|
if data is None:
|
||||||
self._file.close()
|
self._file.close()
|
||||||
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
|
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
|
||||||
|
self.finished()
|
||||||
else:
|
else:
|
||||||
data = bytearray(data)
|
data = bytearray(data)
|
||||||
if self._file_size < position:
|
if self._file_size < position:
|
||||||
|
@ -274,6 +285,7 @@ class ReceiveToBuffer(FileTransfer):
|
||||||
self._creation_time = time()
|
self._creation_time = time()
|
||||||
if data is None:
|
if data is None:
|
||||||
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
|
self.state = TOX_FILE_TRANSFER_STATE['FINISHED']
|
||||||
|
self.finished()
|
||||||
else:
|
else:
|
||||||
data = bytes(data)
|
data = bytes(data)
|
||||||
l = len(data)
|
l = len(data)
|
||||||
|
|
|
@ -410,7 +410,7 @@ class FileTransferItem(QtGui.QListWidget):
|
||||||
if time + 1:
|
if time + 1:
|
||||||
m, s = divmod(time, 60)
|
m, s = divmod(time, 60)
|
||||||
self.time_left.setText('{0:02d}:{1:02d}'.format(m, s))
|
self.time_left.setText('{0:02d}:{1:02d}'.format(m, s))
|
||||||
if self.state != state:
|
if self.state != state and self.state in ACTIVE_FILE_TRANSFERS:
|
||||||
if state == TOX_FILE_TRANSFER_STATE['CANCELLED']:
|
if state == TOX_FILE_TRANSFER_STATE['CANCELLED']:
|
||||||
self.setStyleSheet('QListWidget { border: 1px solid #B40404; }')
|
self.setStyleSheet('QListWidget { border: 1px solid #B40404; }')
|
||||||
self.cancel.setVisible(False)
|
self.cancel.setVisible(False)
|
||||||
|
|
|
@ -874,7 +874,9 @@ class Profile(contact.Contact, Singleton):
|
||||||
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]
|
||||||
pos = data[-1] if os.path.exists(data[0]) else 0
|
pos = data[-1] if os.path.exists(data[0]) else 0
|
||||||
print(pos, os.path.getsize(data[0]))
|
if pos >= os.path.getsize(data[0]):
|
||||||
|
self._tox.file_control(friend_number, file_number, TOX_FILE_CONTROL['CANCEL'])
|
||||||
|
return
|
||||||
self._tox.file_seek(friend_number, file_number, pos)
|
self._tox.file_seek(friend_number, file_number, pos)
|
||||||
self.accept_transfer(None, data[0], friend_number, file_number, size, False, pos)
|
self.accept_transfer(None, data[0], friend_number, file_number, size, False, pos)
|
||||||
tm = TransferMessage(MESSAGE_OWNER['FRIEND'],
|
tm = TransferMessage(MESSAGE_OWNER['FRIEND'],
|
||||||
|
@ -969,7 +971,12 @@ class Profile(contact.Contact, Singleton):
|
||||||
"""
|
"""
|
||||||
self.get_friend_by_number(friend_number).update_transfer_data(file_number,
|
self.get_friend_by_number(friend_number).update_transfer_data(file_number,
|
||||||
TOX_FILE_TRANSFER_STATE['RUNNING'])
|
TOX_FILE_TRANSFER_STATE['RUNNING'])
|
||||||
tr = self._file_transfers[(friend_number, file_number)]
|
try:
|
||||||
|
tr = self._file_transfers[(friend_number, file_number)]
|
||||||
|
except:
|
||||||
|
print('Exception in resume:', self._file_transfers)
|
||||||
|
print(friend_number, file_number, by_friend)
|
||||||
|
return
|
||||||
if by_friend:
|
if by_friend:
|
||||||
tr.state = TOX_FILE_TRANSFER_STATE['RUNNING']
|
tr.state = TOX_FILE_TRANSFER_STATE['RUNNING']
|
||||||
tr.signal()
|
tr.signal()
|
||||||
|
@ -1001,6 +1008,7 @@ class Profile(contact.Contact, Singleton):
|
||||||
rt = ReceiveTransfer(path, self._tox, friend_number, size, file_number, from_position)
|
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)
|
||||||
|
rt.set_transfer_finished_handler(self.transfer_finished)
|
||||||
self._file_transfers[(friend_number, file_number)] = rt
|
self._file_transfers[(friend_number, file_number)] = rt
|
||||||
self._tox.file_control(friend_number, file_number, TOX_FILE_CONTROL['RESUME'])
|
self._tox.file_control(friend_number, file_number, TOX_FILE_CONTROL['RESUME'])
|
||||||
if item is not None:
|
if item is not None:
|
||||||
|
@ -1032,6 +1040,7 @@ class Profile(contact.Contact, Singleton):
|
||||||
elif friend.status is None and is_resend:
|
elif friend.status is None and is_resend:
|
||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
st = SendFromBuffer(self._tox, friend.number, data, file_name)
|
st = SendFromBuffer(self._tox, friend.number, data, file_name)
|
||||||
|
st.set_transfer_finished_handler(self.transfer_finished)
|
||||||
self._file_transfers[(friend.number, st.get_file_number())] = st
|
self._file_transfers[(friend.number, st.get_file_number())] = st
|
||||||
tm = TransferMessage(MESSAGE_OWNER['ME'],
|
tm = TransferMessage(MESSAGE_OWNER['ME'],
|
||||||
time.time(),
|
time.time(),
|
||||||
|
@ -1064,7 +1073,9 @@ class Profile(contact.Contact, Singleton):
|
||||||
print('Error in sending')
|
print('Error in sending')
|
||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
st = SendTransfer(path, self._tox, friend_number, TOX_FILE_KIND['DATA'], file_id)
|
st = SendTransfer(path, self._tox, friend_number, TOX_FILE_KIND['DATA'], file_id)
|
||||||
|
st.set_transfer_finished_handler(self.transfer_finished)
|
||||||
self._file_transfers[(friend_number, st.get_file_number())] = st
|
self._file_transfers[(friend_number, st.get_file_number())] = st
|
||||||
|
print('In send file', self._file_transfers)
|
||||||
tm = TransferMessage(MESSAGE_OWNER['ME'],
|
tm = TransferMessage(MESSAGE_OWNER['ME'],
|
||||||
time.time(),
|
time.time(),
|
||||||
TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED'],
|
TOX_FILE_TRANSFER_STATE['OUTGOING_NOT_STARTED'],
|
||||||
|
@ -1075,67 +1086,47 @@ class Profile(contact.Contact, Singleton):
|
||||||
if friend_number == self.get_active_number():
|
if friend_number == self.get_active_number():
|
||||||
item = self.create_file_transfer_item(tm)
|
item = self.create_file_transfer_item(tm)
|
||||||
st.set_state_changed_handler(item.update)
|
st.set_state_changed_handler(item.update)
|
||||||
self._friends[self._active_friend].append_message(tm)
|
|
||||||
self._messages.scrollToBottom()
|
self._messages.scrollToBottom()
|
||||||
|
self._friends[friend_number].append_message(tm)
|
||||||
|
|
||||||
def incoming_chunk(self, friend_number, file_number, position, data):
|
def incoming_chunk(self, friend_number, file_number, position, data):
|
||||||
"""
|
"""
|
||||||
Incoming chunk
|
Incoming chunk
|
||||||
"""
|
"""
|
||||||
if (friend_number, file_number) in self._file_transfers:
|
self._file_transfers[(friend_number, file_number)].write_chunk(position, data)
|
||||||
transfer = self._file_transfers[(friend_number, file_number)]
|
|
||||||
transfer.write_chunk(position, data)
|
|
||||||
if transfer.state not in ACTIVE_FILE_TRANSFERS: # finished or cancelled
|
|
||||||
if type(transfer) is ReceiveAvatar:
|
|
||||||
self.get_friend_by_number(friend_number).load_avatar()
|
|
||||||
self.set_active(None)
|
|
||||||
elif type(transfer) is ReceiveToBuffer: # inline image
|
|
||||||
print('inline')
|
|
||||||
inline = InlineImage(transfer.get_data())
|
|
||||||
i = self.get_friend_by_number(friend_number).update_transfer_data(file_number,
|
|
||||||
TOX_FILE_TRANSFER_STATE['FINISHED'],
|
|
||||||
inline)
|
|
||||||
if friend_number == self.get_active_number():
|
|
||||||
count = self._messages.count()
|
|
||||||
if count + i + 1 >= 0:
|
|
||||||
elem = QtGui.QListWidgetItem()
|
|
||||||
item = InlineImageItem(transfer.get_data(), self._messages.width(), elem)
|
|
||||||
elem.setSizeHint(QtCore.QSize(self._messages.width(), item.height()))
|
|
||||||
self._messages.insertItem(count + i + 1, elem)
|
|
||||||
self._messages.setItemWidget(elem, item)
|
|
||||||
else:
|
|
||||||
self.get_friend_by_number(friend_number).update_transfer_data(file_number,
|
|
||||||
TOX_FILE_TRANSFER_STATE['FINISHED'])
|
|
||||||
del self._file_transfers[(friend_number, file_number)]
|
|
||||||
|
|
||||||
def outgoing_chunk(self, friend_number, file_number, position, size):
|
def outgoing_chunk(self, friend_number, file_number, position, size):
|
||||||
"""
|
"""
|
||||||
Outgoing chunk
|
Outgoing chunk
|
||||||
"""
|
"""
|
||||||
if (friend_number, file_number) in self._file_transfers:
|
self._file_transfers[(friend_number, file_number)].send_chunk(position, size)
|
||||||
transfer = self._file_transfers[(friend_number, file_number)]
|
|
||||||
transfer.send_chunk(position, size)
|
@QtCore.Slot(int, int)
|
||||||
if transfer.state not in ACTIVE_FILE_TRANSFERS: # finished or cancelled
|
def transfer_finished(self, friend_number, file_number):
|
||||||
del self._file_transfers[(friend_number, file_number)]
|
transfer = self._file_transfers[(friend_number, file_number)]
|
||||||
if type(transfer) is not SendAvatar:
|
t = type(transfer)
|
||||||
if type(transfer) is SendFromBuffer and Settings.get_instance()['allow_inline']: # inline
|
if t is ReceiveAvatar:
|
||||||
inline = InlineImage(transfer.get_data())
|
self.get_friend_by_number(friend_number).load_avatar()
|
||||||
print('inline')
|
self.set_active(None)
|
||||||
i = self.get_friend_by_number(friend_number).update_transfer_data(file_number,
|
elif t is ReceiveToBuffer or (t is SendFromBuffer and Settings.get_instance()['allow_inline']): # inline image
|
||||||
TOX_FILE_TRANSFER_STATE[
|
print('inline')
|
||||||
'FINISHED'],
|
inline = InlineImage(transfer.get_data())
|
||||||
inline)
|
i = self.get_friend_by_number(friend_number).update_transfer_data(file_number,
|
||||||
if friend_number == self.get_active_number():
|
TOX_FILE_TRANSFER_STATE['FINISHED'],
|
||||||
count = self._messages.count()
|
inline)
|
||||||
if count + i + 1 >= 0:
|
if friend_number == self.get_active_number():
|
||||||
elem = QtGui.QListWidgetItem()
|
count = self._messages.count()
|
||||||
item = InlineImageItem(transfer.get_data(), self._messages.width(), elem)
|
if count + i + 1 >= 0:
|
||||||
elem.setSizeHint(QtCore.QSize(self._messages.width(), item.height()))
|
elem = QtGui.QListWidgetItem()
|
||||||
self._messages.insertItem(count + i + 1, elem)
|
item = InlineImageItem(transfer.get_data(), self._messages.width(), elem)
|
||||||
self._messages.setItemWidget(elem, item)
|
elem.setSizeHint(QtCore.QSize(self._messages.width(), item.height()))
|
||||||
else:
|
self._messages.insertItem(count + i + 1, elem)
|
||||||
self.get_friend_by_number(friend_number).update_transfer_data(file_number,
|
self._messages.setItemWidget(elem, item)
|
||||||
TOX_FILE_TRANSFER_STATE['FINISHED'])
|
elif t is not SendAvatar:
|
||||||
|
self.get_friend_by_number(friend_number).update_transfer_data(file_number,
|
||||||
|
TOX_FILE_TRANSFER_STATE['FINISHED'])
|
||||||
|
del self._file_transfers[(friend_number, file_number)]
|
||||||
|
del transfer
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------------------------
|
||||||
# Avatars support
|
# Avatars support
|
||||||
|
|
Loading…
Reference in a new issue