From ce4fe3a66b17fceddcf3b49e7832e38e8741c97c Mon Sep 17 00:00:00 2001 From: Biryuzovye Kleshni Date: Mon, 23 Jul 2018 06:23:15 +0000 Subject: [PATCH] Added sending cancellation --- src/bitmessageqt/__init__.py | 244 +++++++++++++++++++++++++-------- src/bitmessageqt/uisignaler.py | 13 +- src/class_objectProcessor.py | 2 + src/class_singleCleaner.py | 1 + src/class_smtpDeliver.py | 4 +- src/singleworker.py | 127 ++++++++++++++++- 6 files changed, 326 insertions(+), 65 deletions(-) diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py index dab209e6..a0562146 100644 --- a/src/bitmessageqt/__init__.py +++ b/src/bitmessageqt/__init__.py @@ -369,13 +369,16 @@ class MyForm(settingsmixin.SMainWindow): # Popup menu for the Sent page self.ui.sentContextMenuToolbar = QtGui.QToolBar() # Actions - self.actionTrashSentMessage = self.ui.sentContextMenuToolbar.addAction( - _translate( - "MainWindow", "Move to Trash"), self.on_action_SentTrash) self.actionSentClipboard = self.ui.sentContextMenuToolbar.addAction( _translate( "MainWindow", "Copy destination address to clipboard"), self.on_action_SentClipboard) + self.actionTrashSentMessage = self.ui.sentContextMenuToolbar.addAction( + _translate( + "MainWindow", "Move to Trash"), self.on_action_SentTrash) + self.actionCancelSending = self.ui.sentContextMenuToolbar.addAction( + _translate( + "MainWindow", "Cancel sending"), self.on_action_CancelSending) self.actionForceSend = self.ui.sentContextMenuToolbar.addAction( _translate( "MainWindow", "Force send"), self.on_action_ForceSend) @@ -778,13 +781,15 @@ class MyForm(settingsmixin.SMainWindow): QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "updateStatusBar(PyQt_PyObject)"), self.updateStatusBar) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateSentItemStatusByToAddress(PyQt_PyObject,PyQt_PyObject)"), self.updateSentItemStatusByToAddress) + "updateSentItemStatusByToAddress(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.updateSentItemStatusByToAddress) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( - "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"), self.updateSentItemStatusByAckdata) + "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.updateSentItemStatusByAckdata) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "displayNewInboxMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.displayNewInboxMessage) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.displayNewSentMessage) + QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( + "deleteSentItemByAckData(PyQt_PyObject)"), self.deleteSentItemByAckData) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( "setStatusIcon(PyQt_PyObject)"), self.setStatusIcon) QtCore.QObject.connect(self.UISignalThread, QtCore.SIGNAL( @@ -1102,6 +1107,8 @@ class MyForm(settingsmixin.SMainWindow): elif status == 'ackreceived': statusText = _translate("MainWindow", "Acknowledgement of the message received %1").arg( l10n.formatTimestamp(lastactiontime)) + elif status == "msgcanceled": + statusText = _translate("MainWindow", "Message canceled.") elif status == 'broadcastqueued': statusText = _translate( "MainWindow", "Broadcast queued.") @@ -1111,6 +1118,8 @@ class MyForm(settingsmixin.SMainWindow): elif status == 'broadcastsent': statusText = _translate("MainWindow", "Broadcast on %1").arg( l10n.formatTimestamp(lastactiontime)) + elif status == "broadcastcanceled": + statusText = _translate("MainWindow", "Broadcast canceled.") elif status == 'toodifficult': statusText = _translate("MainWindow", "Problem: The work demanded by the recipient is more difficult than you are willing to do. %1").arg( l10n.formatTimestamp(lastactiontime)) @@ -1764,7 +1773,7 @@ class MyForm(settingsmixin.SMainWindow): self.unreadCount = count return self.unreadCount - def updateSentItemStatusByToAddress(self, toAddress, textToDisplay): + def updateSentItemStatusByToAddress(self, status, toAddress, textToDisplay): for sent in [self.ui.tableWidgetInbox, self.ui.tableWidgetInboxSubscriptions, self.ui.tableWidgetInboxChans]: treeWidget = self.widgetConvert(sent) if self.getCurrentFolder(treeWidget) != "sent": @@ -1775,6 +1784,16 @@ class MyForm(settingsmixin.SMainWindow): for i in range(sent.rowCount()): rowAddress = sent.item(i, 0).data(QtCore.Qt.UserRole) if toAddress == rowAddress: + tableAckData = str(sent.item(i, 3).data(QtCore.Qt.UserRole).toPyObject()) + + count = sqlQuery(""" + SELECT COUNT(*) FROM "sent" + WHERE "ackdata" == ? AND "status" == ?; + """, tableAckData, status)[0][0] + + if count == 0: + continue + sent.item(i, 3).setToolTip(textToDisplay) try: newlinePosition = textToDisplay.indexOf('\n') @@ -1786,7 +1805,15 @@ class MyForm(settingsmixin.SMainWindow): else: sent.item(i, 3).setText(textToDisplay) - def updateSentItemStatusByAckdata(self, ackdata, textToDisplay): + def updateSentItemStatusByAckdata(self, status, ackdata, textToDisplay): + count = sqlQuery(""" + SELECT COUNT(*) FROM "sent" + WHERE "ackdata" == ? AND "status" == ?; + """, ackdata, status)[0][0] + + if count == 0: + return + if type(ackdata) is str: ackdata = QtCore.QByteArray(ackdata) for sent in [self.ui.tableWidgetInbox, self.ui.tableWidgetInboxSubscriptions, self.ui.tableWidgetInboxChans]: @@ -2356,6 +2383,37 @@ class MyForm(settingsmixin.SMainWindow): dialogs.EmailGatewayDialog( self, BMConfigParser(), acct).exec_() + def deleteSentItemByAckData(self, ackData): + ackData = QtCore.QByteArray(ackData) + + for tableWidget in [ + self.ui.tableWidgetInbox, + self.ui.tableWidgetInboxSubscriptions, + self.ui.tableWidgetInboxChans + ]: + treeWidget = self.widgetConvert(tableWidget) + + if self.getCurrentFolder(treeWidget) != "sent": + continue + + i = 0 + + while i < tableWidget.rowCount(): + tableAckData = tableWidget.item(i, 3).data(QtCore.Qt.UserRole).toPyObject() + + if ackData == tableAckData: + textEdit = self.getCurrentMessageTextedit() + + if textEdit is not False: + textEdit.setPlainText("") + + tableWidget.removeRow(i) + tableWidget.selectRow(max(0, i - 1)) + + self.updateStatusBar(_translate("MainWindow", "Moved items to trash.")) + else: + i += 1 + def click_pushButtonAddAddressBook(self, dialog=None): if not dialog: dialog = dialogs.AddAddressDialog(self) @@ -3286,47 +3344,95 @@ class MyForm(settingsmixin.SMainWindow): logger.exception('Message not saved', exc_info=True) self.updateStatusBar(_translate("MainWindow", "Write error.")) - # Send item on the Sent tab to trash def on_action_SentTrash(self): - currentRow = 0 - unread = False tableWidget = self.getCurrentMessagelist() + if not tableWidget: return - folder = self.getCurrentFolder() - shifted = (QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier) > 0 - while tableWidget.selectedIndexes() != []: - currentRow = tableWidget.selectedIndexes()[0].row() - ackdataToTrash = str(tableWidget.item( - currentRow, 3).data(QtCore.Qt.UserRole).toPyObject()) - if folder == "trash" or shifted: - sqlExecute('''DELETE FROM sent WHERE ackdata=?''', ackdataToTrash) - else: - sqlExecute('''UPDATE sent SET folder='trash' WHERE ackdata=?''', ackdataToTrash) - if tableWidget.item(currentRow, 0).unread: - self.propagateUnreadCount(tableWidget.item(currentRow, 1 if tableWidget.item(currentRow, 1).type == AccountMixin.SUBSCRIPTION else 0).data(QtCore.Qt.UserRole), folder, self.getCurrentTreeWidget(), -1) - self.getCurrentMessageTextedit().setPlainText("") - tableWidget.removeRow(currentRow) - self.updateStatusBar(_translate( - "MainWindow", "Moved items to trash.")) - self.ui.tableWidgetInbox.selectRow( - currentRow if currentRow == 0 else currentRow - 1) + shiftPressed = QtGui.QApplication.queryKeyboardModifiers() & QtCore.Qt.ShiftModifier != 0 + folder = self.getCurrentFolder() + trash = not (folder == "trash" or shiftPressed) + + for i in tableWidget.selectedIndexes(): + if i.column() != 3: + continue + + currentRow = i.row() + ackData = str(i.data(QtCore.Qt.UserRole).toPyObject()) + + queryReturn = sqlQuery("""SELECT "status" FROM "sent" WHERE "ackdata" == ?;""", ackData) + + if len(queryReturn) == 0: + continue + + status = queryReturn[0][0] + + if status in ["broadcastqueued", "doingbroadcastpow", "broadcastsent", "broadcastcanceled"]: + queues.workerQueue.put(("cancelBroadcast", ackData, True, trash)) + else: + queues.workerQueue.put(("cancelMessage", ackData, True, trash)) + + def on_action_CancelSending(self): + tableWidget = self.getCurrentMessagelist() + + if not tableWidget: + return + + for i in tableWidget.selectedIndexes(): + if i.column() != 3: + continue + + currentRow = i.row() + ackData = str(i.data(QtCore.Qt.UserRole).toPyObject()) + + queryReturn = sqlQuery("""SELECT "status" FROM "sent" WHERE "ackdata" == ?;""", ackData) + + if len(queryReturn) == 0: + continue + + status = queryReturn[0][0] + + if status in ["broadcastqueued", "doingbroadcastpow"]: + queues.workerQueue.put(("cancelBroadcast", ackData, False, None)) + elif status not in ["ackreceived", "msgsentnoackexpected", "badkey", "msgcanceled"]: + queues.workerQueue.put(("cancelMessage", ackData, False, None)) def on_action_ForceSend(self): - currentRow = self.ui.tableWidgetInbox.currentRow() - addressAtCurrentRow = self.ui.tableWidgetInbox.item( - currentRow, 0).data(QtCore.Qt.UserRole) - toRipe = decodeAddress(addressAtCurrentRow)[3] - sqlExecute( - '''UPDATE sent SET status='forcepow' WHERE toripe=? AND status='toodifficult' and folder='sent' ''', - toRipe) - queryreturn = sqlQuery('''select ackdata FROM sent WHERE status='forcepow' ''') - for row in queryreturn: - ackdata, = row - queues.UISignalQueue.put(('updateSentItemStatusByAckdata', ( - ackdata, 'Overriding maximum-difficulty setting. Work queued.'))) - queues.workerQueue.put(('sendmessage', '')) + tableWidget = self.getCurrentMessagelist() + + if not tableWidget: + return + + resendMessages = False + + for i in tableWidget.selectedIndexes(): + if i.column() != 3: + continue + + ackData = str(i.data(QtCore.Qt.UserRole).toPyObject()) + + queryReturn = sqlQuery("""SELECT "status" FROM "sent" WHERE "ackdata" == ?;""", ackData) + + if len(queryReturn) == 0: + continue + + if queryReturn[0][0] == "toodifficult": + sqlExecute(""" + UPDATE "sent" SET "status" = 'forcepow' + WHERE "ackdata" == ? AND "status" == 'toodifficult' AND "folder" = 'sent'; + """, ackData) + + queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "forcepow", + ackData, + "Overriding maximum-difficulty setting. Work queued." # TODO: add translation? + ))) + + resendMessages = True + + if resendMessages: + queues.workerQueue.put(("sendmessage", )) def on_action_SentClipboard(self): currentRow = self.ui.tableWidgetInbox.currentRow() @@ -3988,23 +4094,51 @@ class MyForm(settingsmixin.SMainWindow): self.popMenuInbox.exec_(tableWidget.mapToGlobal(point)) def on_context_menuSent(self, point): - self.popMenuSent = QtGui.QMenu(self) - self.popMenuSent.addAction(self.actionSentClipboard) - self.popMenuSent.addAction(self.actionTrashSentMessage) + tableWidget = self.getCurrentMessagelist() - # Check to see if this item is toodifficult and display an additional - # menu option (Force Send) if it is. - currentRow = self.ui.tableWidgetInbox.currentRow() - if currentRow >= 0: - ackData = str(self.ui.tableWidgetInbox.item( - currentRow, 3).data(QtCore.Qt.UserRole).toPyObject()) - queryreturn = sqlQuery('''SELECT status FROM sent where ackdata=?''', ackData) - for row in queryreturn: - status, = row - if status == 'toodifficult': + if not tableWidget: + return + + showMenu = False + cancelSending = False + forceSend = False + + for i in tableWidget.selectedIndexes(): + if i.column() != 3: + continue + + ackData = str(i.data(QtCore.Qt.UserRole).toPyObject()) + + queryReturn = sqlQuery("""SELECT "status" FROM "sent" WHERE "ackdata" == ?;""", ackData) + + if len(queryReturn) == 0: + continue + + status = queryReturn[0][0] + + if status not in [ + "ackreceived", "msgsentnoackexpected", "badkey", "msgcanceled", + "broadcastsent", "broadcastcanceled" + ]: + cancelSending = True + + if status == "toodifficult": + forceSend = True + + showMenu = True + + if showMenu: + self.popMenuSent = QtGui.QMenu(self) + self.popMenuSent.addAction(self.actionSentClipboard) + self.popMenuSent.addAction(self.actionTrashSentMessage) + + if cancelSending: + self.popMenuSent.addAction(self.actionCancelSending) + + if forceSend: self.popMenuSent.addAction(self.actionForceSend) - self.popMenuSent.exec_(self.ui.tableWidgetInbox.mapToGlobal(point)) + self.popMenuSent.exec_(tableWidget.mapToGlobal(point)) def inboxSearchLineEditUpdated(self, text): # dynamic search for too short text is slow diff --git a/src/bitmessageqt/uisignaler.py b/src/bitmessageqt/uisignaler.py index fbb24328..a3f590e9 100644 --- a/src/bitmessageqt/uisignaler.py +++ b/src/bitmessageqt/uisignaler.py @@ -26,14 +26,13 @@ class UISignaler(QThread): "writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), label, address, str(streamNumber)) elif command == 'updateStatusBar': self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"), data) - elif command == 'updateSentItemStatusByToAddress': - toAddress, message = data + elif command == "updateSentItemStatusByToAddress": self.emit(SIGNAL( - "updateSentItemStatusByToAddress(PyQt_PyObject,PyQt_PyObject)"), toAddress, message) - elif command == 'updateSentItemStatusByAckdata': - ackData, message = data + "updateSentItemStatusByToAddress(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), *data) + elif command == "updateSentItemStatusByAckdata": + status, address, message = data self.emit(SIGNAL( - "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject)"), ackData, message) + "updateSentItemStatusByAckdata(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), *data) elif command == 'displayNewInboxMessage': inventoryHash, toAddress, fromAddress, subject, body = data self.emit(SIGNAL( @@ -44,6 +43,8 @@ class UISignaler(QThread): self.emit(SIGNAL( "displayNewSentMessage(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), toAddress, fromLabel, fromAddress, subject, message, ackdata) + elif command == "deleteSentItemByAckData": + self.emit(SIGNAL("deleteSentItemByAckData(PyQt_PyObject)"), data) elif command == 'updateNetworkStatusTab': outbound, add, destination = data self.emit(SIGNAL("updateNetworkStatusTab(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), outbound, add, destination) diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py index 4a4224e7..8702ce0b 100644 --- a/src/class_objectProcessor.py +++ b/src/class_objectProcessor.py @@ -131,6 +131,7 @@ class objectProcessor(threading.Thread): """, int(time.time()), ackData) queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "ackreceived", ackData, tr._translate( "MainWindow", @@ -1041,6 +1042,7 @@ class objectProcessor(threading.Thread): for i, in queued: queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "msgqueued", i, tr._translate( "MainWindow", diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py index ee7dfed4..91a641af 100644 --- a/src/class_singleCleaner.py +++ b/src/class_singleCleaner.py @@ -60,6 +60,7 @@ def resendStaleMessages(): """, ackData) queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "msgqueued", ackData, tr._translate( "MainWindow", diff --git a/src/class_smtpDeliver.py b/src/class_smtpDeliver.py index f46a61b3..ff7e2a07 100644 --- a/src/class_smtpDeliver.py +++ b/src/class_smtpDeliver.py @@ -42,10 +42,10 @@ class smtpDeliver(threading.Thread, StoppableThread): elif command == 'updateStatusBar': pass elif command == 'updateSentItemStatusByToAddress': - toAddress, message = data + status, toAddress, message = data pass elif command == 'updateSentItemStatusByAckdata': - ackData, message = data + status, ackData, message = data pass elif command == 'displayNewInboxMessage': inventoryHash, toAddress, fromAddress, subject, body = data diff --git a/src/singleworker.py b/src/singleworker.py index 43e57183..c2315fb8 100644 --- a/src/singleworker.py +++ b/src/singleworker.py @@ -38,10 +38,14 @@ import workprover # | +-> toodifficult --> forcepow -+ # | | # +--------------------------------+ +# +# Can also be "msgcanceled" # Broadcast status flow: # # broadcastqueued --> doingbroadcastpow --> broadcastsent +# +# Can also be "broadcastcanceled" # TODO: queued pubkey messages are not saved to the database, they disappear when the client is closed @@ -191,6 +195,7 @@ def getDestinationAddressProperties(address): for i, in queued: queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "msgqueued", i, tr._translate( "MainWindow", @@ -282,8 +287,12 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): if command == "sendmessage": self.sendMessages() + elif command == "cancelMessage": + self.cancelMessage(*arguments) elif command == "sendbroadcast": self.sendBroadcasts() + elif command == "cancelBroadcast": + self.cancelBroadcast(*arguments) elif command == "sendMyPubkey": self.sendMyPubkey(*arguments) elif command == "requestPubkey": @@ -316,9 +325,10 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): def workDone(self, ID, nonce, expiryTime): debug.logger.info("Found proof of work %s", ID) - self.startedWorks[ID](nonce, expiryTime) + if ID in self.startedWorks: + self.startedWorks[ID](nonce, expiryTime) - del self.startedWorks[ID] + del self.startedWorks[ID] def sendMyPubkey(self, address): ID = "pubkey", address @@ -426,6 +436,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): addressProperties = getMyAddressProperties(address) except: queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "broadcastqueued", ackData, tr._translate( "MainWindow", @@ -527,6 +538,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): """, inventoryHash, int(time.time()), ackData) queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "broadcastsent", ackData, tr._translate("MainWindow", "Broadcast sent on %1").arg(l10n.formatTimestamp()) ))) @@ -543,6 +555,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): helper_sql.sqlExecute("""UPDATE "sent" SET "status" = 'doingbroadcastpow' WHERE "ackdata" == ?;""", ackData) queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "doingbroadcastpow", ackData, tr._translate( "MainWindow", @@ -569,6 +582,36 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): self.processBroadcast(*i) + def cancelBroadcast(self, ackData, delete, trash): + ID = "broadcast", ackData + + if ID in self.startedWorks: + del self.startedWorks[ID] + + self.workProver.commandsQueue.put(("cancelTask", ID)) + + helper_sql.sqlExecute(""" + UPDATE "sent" SET "status" = 'broadcastcanceled' + WHERE "ackdata" == ? AND "status" != 'broadcastsent'; + """, ackData) + + if delete: + if trash: + helper_sql.sqlExecute("""UPDATE "sent" SET "folder" = 'trash' WHERE "ackdata" == ?;""", ackData) + else: + helper_sql.sqlExecute("""DELETE FROM "sent" WHERE "ackdata" == ?""", ackData) + + queues.UISignalQueue.put(("deleteSentItemByAckData", ackData)) + else: + queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "broadcastcanceled", + ackData, + tr._translate( + "MainWindow", + "Broadcast canceled." + ) + ))) + def generateAckMessage(self, ackData, stream, TTL, callback): ID = "ack", ackData @@ -616,6 +659,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): queues.workerQueue.put(("requestPubkey", destination)) queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "awaitingpubkey", ackData, tr._translate( "MainWindow", @@ -634,6 +678,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): sourceProperties = getMyAddressProperties(source, defaultDifficulty) except: queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "msgqueued", ackData, tr._translate( "MainWindow", @@ -669,6 +714,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): helper_sql.sqlExecute("""UPDATE "sent" SET "status" = 'toodifficult' WHERE "ackdata" == ?;""", ackData) queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "toodifficult", ackData, tr._translate( "MainWindow", @@ -733,6 +779,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): helper_sql.sqlExecute("""UPDATE "sent" SET "status" = 'badkey' WHERE "ackdata" == ?;""", ackData) queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "badkey", ackData, tr._translate( "MainWindow", @@ -784,6 +831,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): if ackMessage is None: queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "msgsentnoackexpected", ackData, tr._translate( "MainWindow", @@ -792,6 +840,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): ))) else: queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "msgsent", ackData, tr._translate( "MainWindow", @@ -811,6 +860,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): if relativeByteDifficulty != 1 or relativeLengthExtension != 1: queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "doingmsgpow", ackData, tr._translate( "MainWindow", @@ -819,6 +869,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): ))) else: queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "doingmsgpow", ackData, tr._translate( "MainWindow", @@ -849,6 +900,75 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): self.processMessage(*i) + def cancelMessage(self, ackData, delete, trash): + #multpubky + #neededkeys + + ID = "ack", ackData + + if ID in self.startedWorks: + del self.startedWorks[ID] + + self.workProver.commandsQueue.put(("cancelTask", ID)) + + ID = "message", ackData + + if ID in self.startedWorks: + del self.startedWorks[ID] + + self.workProver.commandsQueue.put(("cancelTask", ID)) + + state.watchedAckData -= {ackData} + + queryReturn = helper_sql.sqlQuery("""SELECT "toaddress" FROM "sent" WHERE "ackdata" == ?;""", ackData) + + if len(queryReturn) != 0: + destination = queryReturn[0][0] + + count = helper_sql.sqlQuery(""" + SELECT COUNT(*) FROM "sent" + WHERE "status" IN ('doingpubkeypow', 'awaitingpubkey') AND "toaddress" == ? AND "ackdata" != ?; + """, destination, ackData)[0][0] + + if count == 0: + ID = "getpubkey", destination + + if ID in self.startedWorks: + del self.startedWorks[ID] + + self.workProver.commandsQueue.put(("cancelTask", ID)) + + status, version, stream, ripe = addresses.decodeAddress(destination) + + if version == 4: + secretEncryptionKey, tag = protocol.calculateAddressTag(version, stream, ripe) + + state.neededPubkeys.pop(tag, None) + else: + state.neededPubkeys.pop(destination, None) + + helper_sql.sqlExecute(""" + UPDATE "sent" SET "status" = 'msgcanceled' + WHERE "ackdata" == ? AND "status" NOT IN ('ackreceived', 'msgsentnoackexpected', 'badkey'); + """, ackData) + + if delete: + if trash: + helper_sql.sqlExecute("""UPDATE "sent" SET "folder" = 'trash' WHERE "ackdata" == ?;""", ackData) + else: + helper_sql.sqlExecute("""DELETE FROM "sent" WHERE "ackdata" == ?""", ackData) + + queues.UISignalQueue.put(("deleteSentItemByAckData", ackData)) + else: + queues.UISignalQueue.put(("updateSentItemStatusByAckdata", ( + "msgcanceled", + ackData, + tr._translate( + "MainWindow", + "Message canceled." + ) + ))) + def requestPubkey(self, address): ID = "getpubkey", address @@ -879,6 +999,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): """, currentExpiryTime, address) queues.UISignalQueue.put(("updateSentItemStatusByToAddress", ( + "awaitingpubkey", address, tr._translate( "MainWindow", @@ -912,6 +1033,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): """, sleepTill, int(time.time()), address) queues.UISignalQueue.put(("updateSentItemStatusByToAddress", ( + "awaitingpubkey", address, tr._translate( "MainWindow", @@ -925,6 +1047,7 @@ class singleWorker(threading.Thread, helper_threading.StoppableThread): """, address) queues.UISignalQueue.put(("updateSentItemStatusByToAddress", ( + "doingpubkeypow", address, tr._translate( "MainWindow",