Fixes Qt imports
[electrum-nvc.git] / plugins / qrscanner.py
1 from electrum.util import print_error
2 from urlparse import urlparse, parse_qs
3 from PyQt4.QtGui import QPushButton
4 from electrum_gui.i18n import _
5
6 try:
7     import zbar
8 except ImportError:
9     zbar = None
10
11
12
13 def init(gui):
14     if is_enabled():
15         gui.set_hook('create_send_tab', create_send_tab)
16     else:
17         gui.unset_hook('create_send_tab', create_send_tab)
18
19 def get_info():
20     return 'QR scans', "QR Scans.\nInstall the zbar package to enable this plugin"
21
22 def is_enabled():
23     return is_available()
24
25 def toggle(gui):
26     return is_enabled()
27
28
29 def is_available():
30     if not zbar:
31         return False
32
33     try:
34         proc = zbar.Processor()
35         proc.init()
36     except zbar.SystemError:
37         # Cannot open video device
38         return False
39
40     return True
41
42 def scan_qr():
43     proc = zbar.Processor()
44     proc.init()
45     proc.visible = True
46
47     while True:
48         try:
49             proc.process_one()
50         except:
51             # User closed the preview window
52             return {}
53
54         for r in proc.results:
55             if str(r.type) != 'QRCODE':
56                 continue
57
58             return parse_uri(r.data)
59         
60 def parse_uri(uri):
61     if ':' not in uri:
62         # It's just an address (not BIP21)
63         return {'address': uri}
64
65     if '//' not in uri:
66         # Workaround for urlparse, it don't handle bitcoin: URI properly
67         uri = uri.replace(':', '://')
68         
69     uri = urlparse(uri)
70     result = {'address': uri.netloc} 
71     
72     if uri.path.startswith('?'):
73         params = parse_qs(uri.path[1:])
74     else:
75         params = parse_qs(uri.path)    
76
77     for k,v in params.items():
78         if k in ('amount', 'label', 'message'):
79             result[k] = v[0]
80         
81     return result    
82
83
84
85 def fill_from_qr(self):
86     qrcode = scan_qr()
87     if 'address' in qrcode:
88         self.payto_e.setText(qrcode['address'])
89     if 'amount' in qrcode:
90         self.amount_e.setText(str(qrcode['amount']))
91     if 'label' in qrcode:
92         self.message_e.setText(qrcode['label'])
93     if 'message' in qrcode:
94         self.message_e.setText("%s (%s)" % (self.message_e.text(), qrcode['message']))
95                 
96
97 def create_send_tab(gui, grid):
98     if is_available():
99         b = QPushButton(_("Scan QR code"))
100         b.clicked.connect(lambda: fill_from_qr(gui))
101         grid.addWidget(b, 1, 5)
102
103
104
105 if __name__ == '__main__':
106     # Run some tests
107     
108     assert(parse_uri('1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
109            {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
110
111     assert(parse_uri('bitcoin://1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
112            {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
113     
114     assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
115            {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
116     
117     assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN?amount=10') ==
118            {'amount': '10', 'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
119     
120     assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN?amount=10&label=slush&message=Small%20tip%20to%20slush') ==
121            {'amount': '10', 'label': 'slush', 'message': 'Small tip to slush', 'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
122     
123