New port numbers
[electrum-nvc.git] / gui / stdio.py
1 from decimal import Decimal
2 _ = lambda x:x
3 #from i18n import _
4 from electrum_nvc import mnemonic_encode, WalletStorage, Wallet
5 from electrum_nvc.util import format_satoshis, set_verbosity
6 from electrum_nvc.bitcoin import is_valid
7 from electrum_nvc.network import filter_protocol
8 import sys, getpass, datetime
9
10 # minimal fdisk like gui for console usage
11 # written by rofl0r, with some bits stolen from the text gui (ncurses)
12
13 class ElectrumGui:
14
15     def __init__(self, config, network):
16         self.network = network
17         self.config = config
18         storage = WalletStorage(config)
19         if not storage.file_exists:
20             print "Wallet not found. try 'electrum-nvc create'"
21             exit()
22
23         self.done = 0
24         self.last_balance = ""
25
26         set_verbosity(False)
27
28         self.str_recipient = ""
29         self.str_description = ""
30         self.str_amount = ""
31         self.str_fee = ""
32
33         self.wallet = Wallet(storage)
34         self.wallet.start_threads(network)
35         
36         self.wallet.network.register_callback('updated', self.updated)
37         self.wallet.network.register_callback('connected', self.connected)
38         self.wallet.network.register_callback('disconnected', self.disconnected)
39         self.wallet.network.register_callback('disconnecting', self.disconnecting)
40         self.wallet.network.register_callback('peers', self.peers)
41         self.wallet.network.register_callback('banner', self.print_banner)
42         self.commands = [_("[h] - displays this help text"), \
43                          _("[i] - display transaction history"), \
44                          _("[o] - enter payment order"), \
45                          _("[p] - print stored payment order"), \
46                          _("[s] - send stored payment order"), \
47                          _("[r] - show own receipt addresses"), \
48                          _("[c] - display contacts"), \
49                          _("[b] - print server banner"), \
50                          _("[q] - quit") ]
51         self.num_commands = len(self.commands)
52
53     def main_command(self):
54         self.print_balance()
55         c = raw_input("enter command: ")
56         if   c == "h" : self.print_commands()
57         elif c == "i" : self.print_history()
58         elif c == "o" : self.enter_order()
59         elif c == "p" : self.print_order()
60         elif c == "s" : self.send_order()
61         elif c == "r" : self.print_addresses()
62         elif c == "c" : self.print_contacts()
63         elif c == "b" : self.print_banner()
64         elif c == "n" : self.network_dialog()
65         elif c == "e" : self.settings_dialog()
66         elif c == "q" : self.done = 1
67         else: self.print_commands()
68
69     def peers(self):
70         print("got peers list:")
71         l = filter_protocol(self.wallet.network.get_servers(), 's')
72         for s in l:
73             print (s)
74
75     def connected(self):
76         print ("connected")
77
78     def disconnected(self):
79         print ("disconnected")
80
81     def disconnecting(self):
82         print ("disconnecting")
83
84     def updated(self):
85         s = self.get_balance()
86         if s != self.last_balance:
87             print(s)
88         self.last_balance = s
89         return True
90
91     def print_commands(self):
92         self.print_list(self.commands, "Available commands")
93
94     def print_history(self):
95         width = [20, 40, 14, 14]
96         delta = (80 - sum(width) - 4)/3
97         format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%" \
98         + "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s"
99         b = 0 
100         messages = []
101
102         for item in self.wallet.get_tx_history():
103             tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item
104             if confirmations:
105                 try:
106                     time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3]
107                 except Exception:
108                     time_str = "unknown"
109             else:
110                 time_str = 'pending'
111
112             label, is_default_label = self.wallet.get_label(tx_hash)
113             messages.append( format_str%( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True) ) )
114
115         self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance")))
116
117
118     def print_balance(self):
119         print(self.get_balance())
120
121     def get_balance(self):
122         if self.wallet.network.interface and self.wallet.network.interface.is_connected:
123             if not self.wallet.up_to_date:
124                 msg = _( "Synchronizing..." )
125             else: 
126                 c, u =  self.wallet.get_balance()
127                 msg = _("Balance")+": %f  "%(Decimal( c ) / 1000000)
128                 if u: msg += "  [%f unconfirmed]"%(Decimal( u ) / 1000000)
129         else:
130                 msg = _( "Not connected" )
131             
132         return(msg)
133
134
135     def print_contacts(self):
136         messages = map(lambda addr: "%30s    %30s       "%(addr, self.wallet.labels.get(addr,"")), self.wallet.addressbook)
137         self.print_list(messages, "%19s  %25s "%("Address", "Label"))
138
139     def print_addresses(self):
140         messages = map(lambda addr: "%30s    %30s       "%(addr, self.wallet.labels.get(addr,"")), self.wallet.addresses())
141         self.print_list(messages, "%19s  %25s "%("Address", "Label"))
142
143     def print_order(self):
144         print("send order to " + self.str_recipient + ", amount: " + self.str_amount \
145               + "\nfee: " + self.str_fee + ", desc: " + self.str_description)
146
147     def enter_order(self):
148         self.str_recipient = raw_input("Pay to: ")
149         self.str_description = raw_input("Description : ")
150         self.str_amount = raw_input("Amount: ")
151         self.str_fee = raw_input("Fee: ")
152
153     def send_order(self):
154         self.do_send()
155
156     def print_banner(self):
157         for i, x in enumerate( self.wallet.network.banner.split('\n') ):
158             print( x )
159
160     def print_list(self, list, firstline):
161         self.maxpos = len(list)
162         if not self.maxpos: return
163         print(firstline)
164         for i in range(self.maxpos):
165             msg = list[i] if i < len(list) else ""
166             print(msg)
167
168            
169     def main(self,url):
170         while self.done == 0: self.main_command()
171
172     def do_send(self):
173         if not is_valid(self.str_recipient):
174             print(_('Invalid Novacoin address'))
175             return
176         try:
177             amount = int( Decimal( self.str_amount) * 1000000 )
178         except Exception:
179             print(_('Invalid Amount'))
180             return
181         try:
182             fee = int( Decimal( self.str_fee) * 1000000 )
183         except Exception:
184             print(_('Invalid Fee'))
185             return
186
187         if self.wallet.use_encryption:
188             password = self.password_dialog()
189             if not password:
190                 return
191         else:
192             password = None
193
194         c = ""
195         while c != "y":
196             c = raw_input("ok to send (y/n)?")
197             if c == "n": return
198
199         try:
200             tx = self.wallet.mktx( [(self.str_recipient, amount)], password, fee)
201         except Exception as e:
202             print(str(e))
203             return
204             
205         if self.str_description: 
206             self.wallet.labels[tx.hash()] = self.str_description
207
208         h = self.wallet.send_tx(tx)
209         print(_("Please wait..."))
210         self.wallet.tx_event.wait()
211         status, msg = self.wallet.receive_tx( h, tx )
212
213         if status:
214             print(_('Payment sent.'))
215             #self.do_clear()
216             #self.update_contacts_tab()
217         else:
218             print(_('Error'))
219
220     def network_dialog(self):
221         print("use 'electrum-nvc setconfig server/proxy' to change your network settings")
222         return True
223
224
225     def settings_dialog(self):
226         print("use 'electrum-nvc setconfig' to change your settings")
227         return True
228
229     def password_dialog(self):
230         return getpass.getpass()
231         
232
233 #   XXX unused
234
235     def run_receive_tab(self, c):
236         #if c == 10:
237         #    out = self.run_popup('Address', ["Edit label", "Freeze", "Prioritize"])
238         return
239             
240     def run_contacts_tab(self, c):
241         pass
242 #        if c == 10 and self.wallet.addressbook:
243 #            out = self.run_popup('Adress', ["Copy", "Pay to", "Edit label", "Delete"]).get('button')
244 #            address = self.wallet.addressbook[self.pos%len(self.wallet.addressbook)]
245 #            if out == "Pay to":
246 #                self.tab = 1
247 #                self.str_recipient = address 
248 #                self.pos = 2
249 #            elif out == "Edit label":
250 #                s = self.get_string(6 + self.pos, 18)
251 #                if s:
252 #                    self.wallet.labels[address] = s