3 # btcspy - electrum client history outputter
4 # Copyright (C) 2011 thomasv@gitorious
5 # Copyright (C) 2014 David Llewellyn-Jones (david@flypig.co.uk)
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 from decimal
import Decimal
31 # use this if you want to include modules from a subforder
32 cmd_subfolder
= os
.path
.realpath(os
.path
.abspath(os
.path
.join(os
.path
.split(inspect
.getfile( inspect
.currentframe() ))[0],"lib")))
33 if cmd_subfolder
not in sys
.path
:
34 sys
.path
.insert(0, cmd_subfolder
)
37 import simple_config
, wallet
38 from simple_config
import *
39 from commands
import *
40 from util
import print_msg
, print_stderr
, print_json
, set_verbosity
43 is_local
= os
.path
.dirname(os
.path
.realpath(__file__
)) == os
.getcwd()
44 is_android
= 'ANDROID_DATA' in os
.environ
47 #__builtin__.use_local_modules = is_local or is_android
49 ## load local module as electrum
50 #if __builtin__.use_local_modules:
52 # #imp.load_module('electrum', *imp.find_module('lib'))
55 sys
.path
.append('lib')
58 #from electrum import SimpleConfig, Wallet, WalletStorage
59 #from electrum.util import print_msg, print_stderr, print_json, set_verbosity
61 # get password routine
62 def prompt_password(prompt
, confirm
=True):
64 if sys
.stdin
.isatty():
65 password
= getpass
.getpass(prompt
)
66 if password
and confirm
:
67 password2
= getpass
.getpass("Confirm: ")
68 if password
!= password2
:
69 sys
.exit("Error: Passwords do not match.")
71 password
= raw_input(prompt
)
78 usage
= "btcspy [options] command"
79 details
= "Outputs a list of Bitcoin transactions in JSON format taken from the Electrum wallet of the current user. It can also be imported into a Python program using 'import btcspy', after which 'btcspy.history()' will return the history as a structure,"
80 parser
= optparse
.OptionParser(prog
=usage
, add_help_option
=False, description
=details
)
82 parser
.add_option("-h", "--help", action
="callback", callback
=print_help_cb
, help="show this help text")
83 parser
.add_option("-v", "--verbose", action
="store_true", dest
="verbose", default
=False, help="show debugging information")
84 parser
.add_option("-W", "--password", dest
="password", default
=None, help="set password for usage with commands (currently only implemented for create command, do not use it for longrunning gui session since the password is visible in /proc)")
85 parser
.add_option("-w", "--wallet", dest
="wallet_path", help="wallet path (default: electrum.dat)")
89 def print_help(parser
):
91 print_msg("Type 'btcspy --help' to see the list of options")
92 run_command(known_commands
['help'], None)
96 def print_help_cb(self
, opt
, value
, parser
):
100 def run_command(cmd
, wallet
, password
=None, args
=[]):
103 cmd_runner
= Commands(wallet
)
104 func
= getattr(cmd_runner
, cmd
.name
)
105 cmd_runner
.password
= password
107 result
= func(*args
[1:])
109 traceback
.print_exc(file=sys
.stdout
)
112 if type(result
) == str:
114 elif result
is not None:
117 def get_command(cmd
, wallet
, password
=None, args
=[]):
120 cmd_runner
= Commands(wallet
)
121 func
= getattr(cmd_runner
, cmd
.name
)
122 cmd_runner
.password
= password
124 result
= func(*args
[1:])
126 traceback
.print_exc(file=sys
.stdout
)
132 if __name__
== '__main__':
134 parser
= arg_parser()
135 options
, args
= parser
.parse_args()
136 # if options.wallet_path is None:
137 # options.electrum_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'electrum_data')
139 config_options
= eval(str(options
))
140 for k
, v
in config_options
.items():
142 config_options
.pop(k
)
144 set_verbosity(config_options
.get('verbose'))
146 config
= SimpleConfig(config_options
)
154 if cmd
not in known_commands
:
157 cmd
= known_commands
[cmd
]
159 # instanciate wallet for command-line
160 storage
= WalletStorage(config
)
163 if cmd
.requires_wallet
and not storage
.file_exists
:
164 print_msg("Error: Wallet file not found.")
168 wallet
= Wallet(storage
)
171 # commands needing password
172 if cmd
.requires_password
:
173 if wallet
.seed
== '':
176 elif wallet
.use_encryption
:
177 password
= prompt_password('Password:', False)
179 print_msg("Error: Password required")
183 seed
= wallet
.get_seed(password
)
185 print_msg("Error: This password does not decode this wallet.")
189 seed
= wallet
.get_seed(None)
193 # add missing arguments, do type conversions
194 if cmd
.name
== 'help':
198 # check the number of arguments
199 argslength
= len(args
) - 1
203 if argslength
< cmd
.min_args
:
204 print_msg("Not enough arguments")
205 print_msg("Syntax:", cmd
.syntax
)
208 if cmd
.max_args
>= 0 and argslength
> cmd
.max_args
:
209 print_msg("too many arguments", args
)
210 print_msg("Syntax:", cmd
.syntax
)
214 if len(args
) > cmd
.min_args
+ 1:
215 message
= ' '.join(args
[cmd
.min_args
:])
216 print_msg("Warning: Final argument was reconstructed from several arguments:", repr(message
))
217 args
= args
[0:cmd
.min_args
] + [message
]
222 run_command(cmd
, wallet
, password
, args
)
229 config
= SimpleConfig()
234 cmd
= known_commands
[cmd
]
236 # instanciate wallet for command-line
237 storage
= WalletStorage(config
)
240 if cmd
.requires_wallet
and not storage
.file_exists
:
241 print_msg("Error: Wallet file not found.")
245 wallet
= Wallet(storage
)
247 # commands needing password
248 if cmd
.requires_password
:
249 if wallet
.seed
== '':
252 elif wallet
.use_encryption
:
253 password
= prompt_password('Password:', False)
255 print_msg("Error: Password required")
259 seed
= wallet
.get_seed(password
)
261 print_msg("Error: This password does not decode this wallet.")
265 seed
= wallet
.get_seed(None)
270 return get_command(cmd
, wallet
, password
)