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