Merge branch 'cobleebuilder'
authorMaran <maran.hidskes@gmail.com>
Thu, 2 Aug 2012 16:07:25 +0000 (18:07 +0200)
committerMaran <maran.hidskes@gmail.com>
Thu, 2 Aug 2012 16:07:25 +0000 (18:07 +0200)
electrum
lib/gui_qt.py
lib/qrscanner.py [new file with mode: 0644]

index d927860..43c907c 100755 (executable)
--- a/electrum
+++ b/electrum
@@ -267,7 +267,7 @@ if __name__ == '__main__':
                 
     # commands needing password
     if cmd in protected_commands or ( cmd=='addresses' and options.show_keys):
-        password = prompt_password('Password:') if wallet.use_encryption and not is_temporary else None
+        password = prompt_password('Password:', False) if wallet.use_encryption and not is_temporary else None
         # check password
         try:
             wallet.pw_decode( wallet.seed, password)
@@ -276,7 +276,11 @@ if __name__ == '__main__':
             exit(1)
 
     if cmd == 'import':
-        keypair = args[1]
+        # See if they specificed a key on the cmd line, if not prompt
+        if len(args) > 1:
+            keypair = args[1]
+        else:
+            keypair = prompt_password('Enter Address:PrivateKey (will not echo):', False)
         try:
             wallet.import_key(keypair,password)
             wallet.save()
index d61e5a8..4b6214d 100644 (file)
@@ -41,7 +41,7 @@ except:
     sys.exit(1)
 
 from wallet import format_satoshis
-import bmp, mnemonic, pyqrnative
+import bmp, mnemonic, pyqrnative, qrscanner
 
 from decimal import Decimal
 
@@ -443,6 +443,24 @@ class ElectrumWindow(QMainWindow):
         self.payto_e = QLineEdit()
         grid.addWidget(QLabel(_('Pay to')), 1, 0)
         grid.addWidget(self.payto_e, 1, 1, 1, 3)
+        
+        def fill_from_qr():
+            qrcode = qrscanner.scan_qr()
+            if 'address' in qrcode:
+                self.payto_e.setText(qrcode['address'])
+            if 'amount' in qrcode:
+                self.amount_e.setText(str(qrcode['amount']))
+            if 'label' in qrcode:
+                self.message_e.setText(qrcode['label'])
+            if 'message' in qrcode:
+                self.message_e.setText("%s (%s)" % (self.message_e.text(), qrcode['message']))
+                
+
+        if qrscanner.is_available():
+            b = QPushButton(_("Scan QR code"))
+            b.clicked.connect(fill_from_qr)
+            grid.addWidget(b, 1, 5)
+    
         grid.addWidget(HelpButton(_('Recipient of the funds.') + '\n\n' + _('You may enter a Bitcoin address, a label from your list of contacts (a list of completions will be proposed), or an alias (email-like address that forwards to a Bitcoin address)')), 1, 4)
 
         completer = QCompleter()
diff --git a/lib/qrscanner.py b/lib/qrscanner.py
new file mode 100644 (file)
index 0000000..eb3571a
--- /dev/null
@@ -0,0 +1,75 @@
+from util import print_error
+
+try:
+    import zbar
+except ImportError:    
+    print_error("Install zbar package to enable QR scans")
+    zbar = None
+
+from urlparse import urlparse, parse_qs
+
+def is_available():
+    if not zbar:
+        return False
+    return True
+
+def scan_qr():
+    proc = zbar.Processor()
+    proc.init()
+    proc.visible = True
+
+    while True:
+        try:
+            proc.process_one()
+        except:
+            # User closed the preview window
+            return {}
+
+        for r in proc.results:
+            if str(r.type) != 'QRCODE':
+                continue
+
+            return parse_uri(r.data)
+        
+def parse_uri(uri):
+    if ':' not in uri:
+        # It's just an address (not BIP21)
+        return {'address': uri}
+
+    if '//' not in uri:
+        # Workaround for urlparse, it don't handle bitcoin: URI properly
+        uri = uri.replace(':', '://')
+        
+    uri = urlparse(uri)
+    result = {'address': uri.netloc} 
+    
+    if uri.path.startswith('?'):
+        params = parse_qs(uri.path[1:])
+    else:
+        params = parse_qs(uri.path)    
+
+    for k,v in params.items():
+        if k in ('amount', 'label', 'message'):
+            result[k] = v[0]
+        
+    return result    
+
+if __name__ == '__main__':
+    # Run some tests
+    
+    assert(parse_uri('1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
+           {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
+
+    assert(parse_uri('bitcoin://1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
+           {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
+    
+    assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
+           {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
+    
+    assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN?amount=10') ==
+           {'amount': '10', 'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
+    
+    assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN?amount=10&label=slush&message=Small%20tip%20to%20slush') ==
+           {'amount': '10', 'label': 'slush', 'message': 'Small tip to slush', 'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
+    
+