From ea38e9183945f9dc1c3a38ded4186fdea2065054 Mon Sep 17 00:00:00 2001
From: Dmitri Bogomolov <4glitch@gmail.com>
Date: Wed, 7 Nov 2018 13:56:06 +0200
Subject: [PATCH] Fixing namecoin button again (broken in c7d3784):   *
 separate method MyForm.resetNamecoinConnection() - sets MyForm.namecoin    
 to fresh instance of namecoin.namecoinConnection, tests it and shows or    
 hides "Fetch Namecoin ID" button;   * that method is called when MyForm
 initializes and when settingsDialog     instance is accepted;   *
 namecoin.namecoinConnection.query() checks found address and always    
 prepends it with display name, if query result doesn't contain "name"    
 field it will be the query string.

---
 src/bitmessageqt/__init__.py | 56 +++++++++++++++++++-----------------
 src/namecoin.py              | 46 ++++++++++++++++++-----------
 2 files changed, 59 insertions(+), 43 deletions(-)

diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py
index 1dd4bff7..be26a0d0 100644
--- a/src/bitmessageqt/__init__.py
+++ b/src/bitmessageqt/__init__.py
@@ -798,26 +798,14 @@ class MyForm(settingsmixin.SMainWindow):
             "valueChanged(int)"), self.updateTTL)
 
         self.initSettings()
-
-        namecoin.ensureNamecoinOptions()
-        self.namecoin = namecoin.namecoinConnection()
-
-        # Check to see whether we can connect to namecoin.
-        # Hide the 'Fetch Namecoin ID' button if we can't.
-        if BMConfigParser().safeGetBoolean(
-                'bitmessagesettings', 'dontconnect'
-                ) or self.namecoin.test()[0] == 'failed':
-            logger.warning(
-                'There was a problem testing for a Namecoin daemon. Hiding the'
-                ' Fetch Namecoin ID button')
-            self.ui.pushButtonFetchNamecoinID.hide()
+        self.resetNamecoinConnection()
 
     def updateTTL(self, sliderPosition):
         TTL = int(sliderPosition ** 3.199 + 3600)
         self.updateHumanFriendlyTTLDescription(TTL)
         BMConfigParser().set('bitmessagesettings', 'ttl', str(TTL))
         BMConfigParser().save()
-        
+
     def updateHumanFriendlyTTLDescription(self, TTL):
         numberOfHours = int(round(TTL / (60*60)))
         font = QtGui.QFont()
@@ -2160,9 +2148,8 @@ class MyForm(settingsmixin.SMainWindow):
             ))
 
     def click_pushButtonFetchNamecoinID(self):
-        nc = namecoinConnection()
         identities = str(self.ui.lineEditTo.text().toUtf8()).split(";")
-        err, addr = nc.query(identities[-1].strip())
+        err, addr = self.namecoin.query(identities[-1].strip())
         if err is not None:
             self.updateStatusBar(
                 _translate("MainWindow", "Error: %1").arg(err))
@@ -2481,7 +2468,8 @@ class MyForm(settingsmixin.SMainWindow):
                 self.settingsDialogInstance.ui.lineEditNamecoinUser.text()))
             BMConfigParser().set('bitmessagesettings', 'namecoinrpcpassword', str(
                 self.settingsDialogInstance.ui.lineEditNamecoinPassword.text()))
-            
+            self.resetNamecoinConnection()
+
             # Demanded difficulty tab
             if float(self.settingsDialogInstance.ui.lineEditTotalDifficulty.text()) >= 1:
                 BMConfigParser().set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(int(float(
@@ -4129,6 +4117,22 @@ class MyForm(settingsmixin.SMainWindow):
         else:
             self.statusbar.showMessage(message, 10000)
 
+    def resetNamecoinConnection(self):
+        namecoin.ensureNamecoinOptions()
+        self.namecoin = namecoin.namecoinConnection()
+
+        # Check to see whether we can connect to namecoin.
+        # Hide the 'Fetch Namecoin ID' button if we can't.
+        if BMConfigParser().safeGetBoolean(
+                'bitmessagesettings', 'dontconnect'
+        ) or self.namecoin.test()[0] == 'failed':
+            logger.warning(
+                'There was a problem testing for a Namecoin daemon. Hiding the'
+                ' Fetch Namecoin ID button')
+            self.ui.pushButtonFetchNamecoinID.hide()
+        else:
+            self.ui.pushButtonFetchNamecoinID.show()
+
     def initSettings(self):
         QtCore.QCoreApplication.setOrganizationName("PyBitmessage")
         QtCore.QCoreApplication.setOrganizationDomain("bitmessage.org")
@@ -4344,7 +4348,7 @@ class settingsDialog(QtGui.QDialog):
     def namecoinTypeChanged(self, checked):
         nmctype = self.getNamecoinType()
         assert nmctype == "namecoind" or nmctype == "nmcontrol"
-            
+
         isNamecoind = (nmctype == "namecoind")
         self.ui.lineEditNamecoinUser.setEnabled(isNamecoind)
         self.ui.labelNamecoinUser.setEnabled(isNamecoind)
@@ -4356,23 +4360,21 @@ class settingsDialog(QtGui.QDialog):
         else:
             self.ui.lineEditNamecoinPort.setText("9000")
 
-    # Test the namecoin settings specified in the settings dialog.
     def click_pushButtonNamecoinTest(self):
+        """Test the namecoin settings specified in the settings dialog."""
         self.ui.labelNamecoinTestResult.setText(_translate(
-                "MainWindow", "Testing..."))
+            "MainWindow", "Testing..."))
         options = {}
         options["type"] = self.getNamecoinType()
         options["host"] = str(self.ui.lineEditNamecoinHost.text().toUtf8())
         options["port"] = str(self.ui.lineEditNamecoinPort.text().toUtf8())
         options["user"] = str(self.ui.lineEditNamecoinUser.text().toUtf8())
         options["password"] = str(self.ui.lineEditNamecoinPassword.text().toUtf8())
-        nc = namecoinConnection(options)
-        response = nc.test()
-        responseStatus = response[0]
-        responseText = response[1]
-        self.ui.labelNamecoinTestResult.setText(responseText)
-        if responseStatus== 'success':
-            self.parent.ui.pushButtonFetchNamecoinID.show()
+        nc = namecoin.namecoinConnection(options)
+        status, text = nc.test()
+        self.ui.labelNamecoinTestResult.setText(text)
+        if status == 'success':
+            self.parent.namecoin = nc
 
 
 # In order for the time columns on the Inbox and Sent tabs to be sorted
diff --git a/src/namecoin.py b/src/namecoin.py
index e8af3349..6674bdcd 100644
--- a/src/namecoin.py
+++ b/src/namecoin.py
@@ -34,6 +34,7 @@ import os
 import socket
 import sys
 
+from addresses import decodeAddress
 from debug import logger
 import defaults
 import tr  # translate
@@ -102,7 +103,10 @@ class namecoinConnection(object):
         """
         slashPos = string.find("/")
         if slashPos < 0:
+            display_name = string
             string = "id/" + string
+        else:
+            display_name = string.split("/")[1]
 
         try:
             if self.nmctype == "namecoind":
@@ -112,7 +116,9 @@ class namecoinConnection(object):
                 res = self.callRPC("data", ["getValue", string])
                 res = res["reply"]
                 if not res:
-                    return (tr._translate("MainWindow", 'The name %1 was not found.').arg(unicode(string)), None)
+                    return (tr._translate(
+                        "MainWindow", 'The name %1 was not found.'
+                    ).arg(unicode(string)), None)
             else:
                 assert False
         except RPCError as exc:
@@ -121,29 +127,37 @@ class namecoinConnection(object):
                 errmsg = exc.error["message"]
             else:
                 errmsg = exc.error
-            return (tr._translate("MainWindow", 'The namecoin query failed (%1)').arg(unicode(errmsg)), None)
+            return (tr._translate(
+                "MainWindow", 'The namecoin query failed (%1)'
+            ).arg(unicode(errmsg)), None)
+        except AssertionError:
+            return (tr._translate(
+                "MainWindow", 'Unknown namecoin interface type: %1'
+            ).arg(unicode(self.nmctype)), None)
         except Exception:
             logger.exception("Namecoin query exception")
-            return (tr._translate("MainWindow", 'The namecoin query failed.'), None)
+            return (tr._translate(
+                "MainWindow", 'The namecoin query failed.'), None)
 
         try:
-            val = json.loads(res)
-        except:
-            logger.exception("Namecoin query json exception")
-            return (tr._translate("MainWindow", 'The name %1 has no valid JSON data.').arg(unicode(string)), None)
+            res = json.loads(res)
+        except ValueError:
+            pass
+        else:
+            try:
+                display_name = res["name"]
+            except KeyError:
+                pass
+            res = res.get("bitmessage")
 
-        if "bitmessage" in val:
-            if "name" in val:
-                ret = "%s <%s>" % (val["name"], val["bitmessage"])
-            else:
-                ret = val["bitmessage"]
-            return (None, ret)
+        valid = decodeAddress(res)[0] == 'success'
         return (
+            None, "%s <%s>" % (display_name, res)
+        ) if valid else (
             tr._translate(
                 "MainWindow",
-                'The name %1 has no associated Bitmessage address.').arg(
-                    unicode(string)),
-            None)
+                'The name %1 has no associated Bitmessage address.'
+            ).arg(unicode(string)), None)
 
     def test(self):
         """