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