separate core and gui in different modules
[electrum-nvc.git] / gui / qrscanner.py
1 from electrum.util import print_error
2
3 try:
4     import zbar
5 except ImportError:    
6     print_error("Install zbar package to enable QR scans")
7     zbar = None
8
9 from urlparse import urlparse, parse_qs
10
11 def is_available():
12     if not zbar:
13         return False
14
15     try:
16         proc = zbar.Processor()
17         proc.init()
18     except zbar.SystemError:
19         # Cannot open video device
20         return False
21
22     return True
23
24 def scan_qr():
25     proc = zbar.Processor()
26     proc.init()
27     proc.visible = True
28
29     while True:
30         try:
31             proc.process_one()
32         except:
33             # User closed the preview window
34             return {}
35
36         for r in proc.results:
37             if str(r.type) != 'QRCODE':
38                 continue
39
40             return parse_uri(r.data)
41         
42 def parse_uri(uri):
43     if ':' not in uri:
44         # It's just an address (not BIP21)
45         return {'address': uri}
46
47     if '//' not in uri:
48         # Workaround for urlparse, it don't handle bitcoin: URI properly
49         uri = uri.replace(':', '://')
50         
51     uri = urlparse(uri)
52     result = {'address': uri.netloc} 
53     
54     if uri.path.startswith('?'):
55         params = parse_qs(uri.path[1:])
56     else:
57         params = parse_qs(uri.path)    
58
59     for k,v in params.items():
60         if k in ('amount', 'label', 'message'):
61             result[k] = v[0]
62         
63     return result    
64
65 if __name__ == '__main__':
66     # Run some tests
67     
68     assert(parse_uri('1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
69            {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
70
71     assert(parse_uri('bitcoin://1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
72            {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
73     
74     assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN') ==
75            {'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
76     
77     assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN?amount=10') ==
78            {'amount': '10', 'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
79     
80     assert(parse_uri('bitcoin:1Marek48fwU7mugmSe186do2QpUkBnpzSN?amount=10&label=slush&message=Small%20tip%20to%20slush') ==
81            {'amount': '10', 'label': 'slush', 'message': 'Small tip to slush', 'address': '1Marek48fwU7mugmSe186do2QpUkBnpzSN'})
82     
83