Repository: Bitmessage/PyBitmessage

Issue:
Inbox messages are not being displayed
(on v.0.4.1 Ubuntu 12.10)
I get the following error msg in the console when a new message gets into my Inbox:

Traceback (most recent call last):
  File "/home/default2/PyBitmessage/src/bitmessageqt/**init**.py", line 1797, in displayNewInboxMessage
    self.notifierShow(unicode(_translate("MainWindow",'New Message').toUtf8(),'utf-8'), unicode(_translate("MainWindow",'From ').toUtf8(),'utf-8') + unicode(fromAddress, 'utf-8'), self.SOUND_UNKNOWN, None)
  File "/home/default2/PyBitmessage/src/bitmessageqt/__init__.py", line 1083, in notifierShow
    n.show()
  File "/usr/lib/python2.7/dist-packages/gi/types.py", line 47, in function
    return info.invoke(_args, *_kwargs)
gi._glib.GError: GDBus.Error:org.freedesktop.Notifications.MaxNotificationsExceeded: Exceeded maximum number of notifications

When I click the new message in the Inbox tab, I get:

Traceback (most recent call last):
  File "/home/default2/PyBitmessage/src/bitmessageqt/**init**.py", line 2707, in tableWidgetInboxItemClicked
    currentRow, 1).data(Qt.UserRole).toPyObject())
AttributeError: 'NoneType' object has no attribute 'data'

The message itself will not be displayed when I click it.
Only the "To" field contains info, "From","Subject","Received" are blank



Discussion:
Screenshot attached.
The first three messages are the "broken" ones. When I click on them, the text below does not change. The text below is from message 4.
I have to restart Bitmessage in order to make the first 3 messages appear normal.

![screen](https://f.cloud.github.com/assets/555272/1464096/0a76ad0e-453f-11e3-8c92-5ba1b6bfdf1c.png)

The first traceback caused the second one because the code the displayNewInboxMessage function didn't finish running and filling in the table.  The first traceback, as far as it appears, was triggered when too many operating system pop-up notifications were being displayed at the same time. I can add exception handling within notifierShow to handle this case easily. Thank you for reporting the problem!


Resolving patch:
diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py
--- a/src/bitmessageqt/__init__.py
+++ b/src/bitmessageqt/__init__.py
@@ -1218,7 +1218,14 @@ def notifierShow(self, title, subtitle, fromCategory, label):
         if withMessagingMenu:
             n = Notify.Notification.new(
                 title, subtitle, 'notification-message-email')
-            n.show()
+            try:
+                n.show()
+            except:
+                # n.show() has been known to throw this exception:
+                # gi._glib.GError: GDBus.Error:org.freedesktop.Notifications.
+                # MaxNotificationsExceeded: Exceeded maximum number of
+                # notifications
+                pass
             return
         else:
             self.tray.showMessage(title, subtitle, 1, 2000)
diff --git a/src/bitmessageqt/about.py b/src/bitmessageqt/about.py
--- a/src/bitmessageqt/about.py
+++ b/src/bitmessageqt/about.py
@@ -2,8 +2,8 @@
 
 # Form implementation generated from reading ui file 'about.ui'
 #
-# Created: Mon Mar 11 11:19:35 2013
-#      by: PyQt4 UI code generator 4.9.4
+# Created: Wed Nov 06 23:01:43 2013
+#      by: PyQt4 UI code generator 4.10.2
 #
 # WARNING! All changes made in this file will be lost!
 
@@ -12,7 +12,16 @@
 try:
     _fromUtf8 = QtCore.QString.fromUtf8
 except AttributeError:
-    _fromUtf8 = lambda s: s
+    def _fromUtf8(s):
+        return s
+
+try:
+    _encoding = QtGui.QApplication.UnicodeUTF8
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig, _encoding)
+except AttributeError:
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig)
 
 class Ui_aboutDialog(object):
     def setupUi(self, aboutDialog):
@@ -35,7 +44,7 @@ def setupUi(self, aboutDialog):
         self.labelVersion.setGeometry(QtCore.QRect(190, 126, 161, 20))
         self.labelVersion.setObjectName(_fromUtf8("labelVersion"))
         self.label_2 = QtGui.QLabel(aboutDialog)
-        self.label_2.setGeometry(QtCore.QRect(10, 150, 341, 20))
+        self.label_2.setGeometry(QtCore.QRect(10, 150, 341, 41))
         self.label_2.setAlignment(QtCore.Qt.AlignCenter)
         self.label_2.setObjectName(_fromUtf8("label_2"))
         self.label_3 = QtGui.QLabel(aboutDialog)
@@ -44,7 +53,7 @@ def setupUi(self, aboutDialog):
         self.label_3.setOpenExternalLinks(True)
         self.label_3.setObjectName(_fromUtf8("label_3"))
         self.label_5 = QtGui.QLabel(aboutDialog)
-        self.label_5.setGeometry(QtCore.QRect(10, 180, 341, 20))
+        self.label_5.setGeometry(QtCore.QRect(10, 190, 341, 20))
         self.label_5.setAlignment(QtCore.Qt.AlignCenter)
         self.label_5.setObjectName(_fromUtf8("label_5"))
 
@@ -54,10 +63,10 @@ def setupUi(self, aboutDialog):
         QtCore.QMetaObject.connectSlotsByName(aboutDialog)
 
     def retranslateUi(self, aboutDialog):
-        aboutDialog.setWindowTitle(QtGui.QApplication.translate("aboutDialog", "About", None, QtGui.QApplication.UnicodeUTF8))
-        self.label.setText(QtGui.QApplication.translate("aboutDialog", "PyBitmessage", None, QtGui.QApplication.UnicodeUTF8))
-        self.labelVersion.setText(QtGui.QApplication.translate("aboutDialog", "version ?", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_2.setText(QtGui.QApplication.translate("aboutDialog", "Copyright © 2013 Jonathan Warren", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_3.setText(QtGui.QApplication.translate("aboutDialog", "<html><head/><body><p>Distributed under the MIT/X11 software license; see <a href=\"http://www.opensource.org/licenses/mit-license.php\"><span style=\" text-decoration: underline; color:#0000ff;\">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
-        self.label_5.setText(QtGui.QApplication.translate("aboutDialog", "This is Beta software.", None, QtGui.QApplication.UnicodeUTF8))
+        aboutDialog.setWindowTitle(_translate("aboutDialog", "About", None))
+        self.label.setText(_translate("aboutDialog", "PyBitmessage", None))
+        self.labelVersion.setText(_translate("aboutDialog", "version ?", None))
+        self.label_2.setText(_translate("aboutDialog", "<html><head/><body><p>Copyright © 2012-2013 Jonathan Warren<br/>Copyright © 2013 The Bitmessage Developers</p></body></html>", None))
+        self.label_3.setText(_translate("aboutDialog", "<html><head/><body><p>Distributed under the MIT/X11 software license; see <a href=\"http://www.opensource.org/licenses/mit-license.php\"><span style=\" text-decoration: underline; color:#0000ff;\">http://www.opensource.org/licenses/mit-license.php</span></a></p></body></html>", None))
+        self.label_5.setText(_translate("aboutDialog", "This is Beta software.", None))
 
diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py
--- a/src/class_singleWorker.py
+++ b/src/class_singleWorker.py
@@ -147,17 +147,26 @@ def doPOWForMyV2Pubkey(self, hash):  # This function also broadcasts out the pub
         shared.broadcastToSendDataQueues((
             streamNumber, 'advertiseobject', inventoryHash))
         shared.UISignalQueue.put(('updateStatusBar', ''))
-        shared.config.set(
-            myAddress, 'lastpubkeysendtime', str(int(time.time())))
-        with open(shared.appdata + 'keys.dat', 'wb') as configfile:
-            shared.config.write(configfile)
+        try:
+            shared.config.set(
+                myAddress, 'lastpubkeysendtime', str(int(time.time())))
+            with open(shared.appdata + 'keys.dat', 'wb') as configfile:
+                shared.config.write(configfile)
+        except:
+            # The user deleted the address out of the keys.dat file before this
+            # finished.
+            pass
 
     # If this isn't a chan address, this function assembles the pubkey data,
     # does the necessary POW and sends it out. If it *is* a chan then it
     # assembles the pubkey and stores is in the pubkey table so that we can
     # send messages to "ourselves".
     def sendOutOrStoreMyV3Pubkey(self, hash): 
-        myAddress = shared.myAddressesByHash[hash]
+        try:
+            myAddress = shared.myAddressesByHash[hash]
+        except:
+            #The address has been deleted.
+            return
         if shared.safeConfigGetBoolean(myAddress, 'chan'):
             with shared.printLock:
                 print 'This is a chan address. Not sending pubkey.'
@@ -224,14 +233,22 @@ def sendOutOrStoreMyV3Pubkey(self, hash):
         shared.broadcastToSendDataQueues((
             streamNumber, 'advertiseobject', inventoryHash))
         shared.UISignalQueue.put(('updateStatusBar', ''))
-        shared.config.set(
-            myAddress, 'lastpubkeysendtime', str(int(time.time())))
-        with open(shared.appdata + 'keys.dat', 'wb') as configfile:
-            shared.config.write(configfile)
+        try:
+            shared.config.set(
+                myAddress, 'lastpubkeysendtime', str(int(time.time())))
+            with open(shared.appdata + 'keys.dat', 'wb') as configfile:
+                shared.config.write(configfile)
+        except:
+            # The user deleted the address out of the keys.dat file before this
+            # finished.
+            pass
 
     # If this isn't a chan address, this function assembles the pubkey data,
     # does the necessary POW and sends it out. 
     def sendOutOrStoreMyV4Pubkey(self, myAddress):
+        if not shared.config.has_section(myAddress):
+            #The address has been deleted.
+            return
         if shared.safeConfigGetBoolean(myAddress, 'chan'):
             with shared.printLock:
                 print 'This is a chan address. Not sending pubkey.'


Test patch: