Fix merge conflict with master

This commit is contained in:
Maran 2012-08-29 22:54:44 +02:00
commit 23d314462f
11 changed files with 229 additions and 112 deletions

1
TODO
View File

@ -3,6 +3,7 @@ Client:
- Wizard
- Multiple wallets
- Themes
- Extend GUI with history view (View -> Show History)
- Settings window
Server:

View File

@ -52,7 +52,7 @@
inkscape:groupmode="layer"
id="layer1">
<path
style="opacity:1;fill:#d7d7d7;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none"
style="opacity:0.83716047999999998;fill:#d7d7d7;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none"
d="m 472.75139,908.92052 c 46.46702,-26.26397 56.56855,-68.69038 66.67007,-98.99495 10.10153,-30.30458 52.52793,-228.29448 42.42641,-347.49248 -10.10153,-119.198 -58.58885,-135.36044 -107.07617,-159.6041 -48.48732,-24.24366 -133.34014,-18.18275 -175.76654,8.08122 -42.42642,26.26397 -92.93405,60.60915 -101.01527,143.44166 -8.08122,82.83251 9.13377,276.70605 46.46702,371.73614 22.22336,56.56854 47.29278,70.95769 78.79191,84.85281 31.49913,13.89512 116.60088,16.01267 149.50257,-2.0203 z"
id="path3050"
inkscape:connector-curvature="0"

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -16,7 +16,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re, sys
import re
import sys
# import argparse
import optparse
try:
from lib.util import print_error
except ImportError:
@ -24,22 +28,19 @@ except ImportError:
try:
import ecdsa
except:
print_error("Error: python-ecdsa does not seem to be installed. Try 'sudo pip install ecdsa'")
sys.exit(1)
except ImportError:
sys.exit("Error: python-ecdsa does not seem to be installed. Try 'sudo pip install ecdsa'")
try:
import aes
except:
print_error("Error: AES does not seem to be installed. Try 'sudo pip install slowaes'")
sys.exit(1)
except ImportError:
sys.exit("Error: AES does not seem to be installed. Try 'sudo pip install slowaes'")
try:
from lib import Wallet, WalletSynchronizer, format_satoshis, mnemonic, prompt_password
except ImportError:
from electrum import Wallet, WalletSynchronizer, format_satoshis, mnemonic, prompt_password
from optparse import OptionParser
from decimal import Decimal
known_commands = {
@ -77,9 +78,9 @@ options:\n --fee, -f: set transaction fee\n --fromaddr, -s: send from address
'import':
'Imports a key pair\nSyntax: import <address>:<privatekey>',
'signmessage':
'Signs a message with a key\nSyntax: signmessage <address> <message>',
'Signs a message with a key\nSyntax: signmessage <address> <message>\nIf you want to lead or end a message with spaces, or want double spaces inside the message make sure you quote the string. I.e. " Hello This is a weird String "',
'verifymessage':
'Verifies a signature\nSyntax: verifymessage <address> <signature> <message>',
'Verifies a signature\nSyntax: verifymessage <address> <signature> <message>\nIf you want to lead or end a message with spaces, or want double spaces inside the message make sure you quote the string. I.e. " Hello This is a weird String "',
'eval':
"Run python eval() on an object\nSyntax: eval <expression>\nExample: eval \"wallet.aliases\"",
'deseed':
@ -101,7 +102,7 @@ protected_commands = ['payto', 'password', 'mktx', 'seed', 'import','signmessage
if __name__ == '__main__':
usage = "usage: %prog [options] command\nCommands: "+ (', '.join(known_commands))
parser = OptionParser(usage=usage)
parser = optparse.OptionParser(prog=usage)
parser.add_option("-g", "--gui", dest="gui", default="lite", help="gui")
parser.add_option("-w", "--wallet", dest="wallet_path", help="wallet path (default: electrum.dat)")
parser.add_option("-o", "--offline", action="store_true", dest="offline", default=False, help="remain offline")
@ -128,7 +129,9 @@ if __name__ == '__main__':
else:
cmd = args[0]
firstarg = args[1] if len(args) > 1 else ''
#this entire if/else block is just concerned with importing the
#right GUI toolkit based the GUI command line option given
if cmd == 'gui':
if options.gui=='gtk':
@ -165,16 +168,17 @@ if __name__ == '__main__':
except ImportError:
import electrum.gui_qt as gui
else:
#use the lite version if no toolkit specified
try:
import lib.gui_lite as gui
except ImportError:
import electrum.gui_lite as gui
else:
print_error("Error: Unknown GUI: " + options.gui)
exit(1)
sys.exit("Error: Unknown GUI: " + options.gui)
gui = gui.ElectrumGui(wallet)
WalletSynchronizer(wallet,True).start()
interface = WalletSynchronizer(wallet, True, gui.server_list_changed)
interface.start()
try:
found = wallet.file_exists
@ -198,15 +202,13 @@ if __name__ == '__main__':
cmd = 'help'
if not wallet.file_exists and cmd not in ['help','create','restore']:
print_error("Error: Wallet file not found.")
print_error("Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option")
print "Error: Wallet file not found."
print "Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option"
sys.exit(0)
if cmd in ['create', 'restore']:
if wallet.file_exists:
print_error("Error: Remove the existing wallet first!")
sys.stderr.flush()
sys.exit(0)
sys.exit("Error: Remove the existing wallet first!")
password = prompt_password("Password (hit return if you do not wish to encrypt your wallet):")
w_host, w_port, w_protocol = wallet.server.split(':')
@ -230,8 +232,7 @@ if __name__ == '__main__':
print_error("Warning: Not hex, trying decode.")
seed = mnemonic.mn_decode( seed.split(' ') )
if not seed:
print_error("Error: No seed")
sys.exit(1)
sys.exit("Error: No seed")
wallet.seed = str(seed)
wallet.init_mpk( wallet.seed )
@ -316,7 +317,6 @@ if __name__ == '__main__':
cmd2 = firstarg
if cmd2 not in known_commands:
parser.print_help()
print
print "Type 'electrum help <command>' to see the help for a specific command"
print "Type 'electrum --help' to see the list of options"
print "List of commands:", ', '.join(known_commands)
@ -355,17 +355,15 @@ if __name__ == '__main__':
f = open(ns,'r')
data = f.read()
f.close()
except:
print_error("Error: Seed file not found")
sys.exit()
except IOError:
sys.exit("Error: Seed file not found")
try:
import ast
d = ast.literal_eval( data )
seed = d['seed']
imported_keys = d.get('imported_keys',{})
except:
print_error("Error: Error with seed file")
sys.exit(1)
sys.exit("Error: Error with seed file")
mpk = wallet.master_public_key
wallet.seed = seed
@ -511,9 +509,8 @@ if __name__ == '__main__':
elif cmd == 'password':
try:
seed = wallet.pw_decode( wallet.seed, password)
except:
print_error("Error: Password does not decrypt this wallet.")
sys.exit(1)
except ValueError:
sys.exit("Error: Password does not decrypt this wallet.")
new_password = prompt_password('New password:')
wallet.update_password(seed, password, new_password)
@ -543,7 +540,8 @@ if __name__ == '__main__':
try:
wallet.verify_message(address, signature, message)
print True
except:
except BaseException as e:
print "Verification error: {0}".format(e)
print False
elif cmd == 'freeze':

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -31,7 +31,7 @@ class Exchanger(threading.Thread):
connection = httplib.HTTPSConnection('intersango.com')
connection.request("GET", "/api/ticker.php")
response = connection.getresponse()
if response.status == 404:
if response.reason == httplib.responses[httplib.NOT_FOUND]:
return
response = json.loads(response.read())
# 1 = BTC:GBP
@ -40,16 +40,16 @@ class Exchanger(threading.Thread):
# 4 = BTC:PLN
quote_currencies = {}
try:
quote_currencies["GBP"] = self.lookup_rate(response, 1)
quote_currencies["EUR"] = self.lookup_rate(response, 2)
quote_currencies["USD"] = self.lookup_rate(response, 3)
quote_currencies["GBP"] = self._lookup_rate(response, 1)
quote_currencies["EUR"] = self._lookup_rate(response, 2)
quote_currencies["USD"] = self._lookup_rate(response, 3)
with self.lock:
self.quote_currencies = quote_currencies
self.parent.emit(SIGNAL("refresh_balance()"))
except KeyError:
pass
def lookup_rate(self, response, quote_id):
def _lookup_rate(self, response, quote_id):
return decimal.Decimal(response[str(quote_id)]["last"])
if __name__ == "__main__":

View File

@ -4,6 +4,7 @@ from PyQt4.QtCore import *
from PyQt4.QtGui import *
from decimal import Decimal as D
from interface import DEFAULT_SERVERS
from util import get_resource_path as rsrc
from i18n import _
import decimal
@ -41,14 +42,18 @@ def resize_line_edit_width(line_edit, text_input):
text_input += "A"
line_edit.setMinimumWidth(metrics.width(text_input))
class ElectrumGui:
class ElectrumGui(QObject):
def __init__(self, wallet):
super(QObject, self).__init__()
self.wallet = wallet
self.app = QApplication(sys.argv)
def main(self, url):
actuator = MiniActuator(self.wallet)
self.connect(self, SIGNAL("updateservers()"),
actuator.update_servers_list)
# Should probably not modify the current path but instead
# change the behaviour of rsrc(...)
old_path = QDir.currentPath()
@ -73,7 +78,11 @@ class ElectrumGui:
self.app.exec_()
def server_list_changed(self):
self.emit(SIGNAL("updateservers()"))
def expand(self):
"""Hide the lite mode window and show pro-mode."""
self.mini.hide()
self.expert.show()
@ -174,13 +183,15 @@ class MiniWindow(QDialog):
menubar = QMenuBar()
electrum_menu = menubar.addMenu(_("&Bitcoin"))
self.servers_menu = electrum_menu.addMenu(_("&Servers"))
self.servers_menu.addAction(_("Foo"))
servers_menu = electrum_menu.addMenu(_("&Servers"))
servers_group = QActionGroup(self)
self.actuator.set_servers_gui_stuff(servers_menu, servers_group)
self.actuator.populate_servers_menu()
electrum_menu.addSeparator()
brain_seed = electrum_menu.addAction(_("&BrainWallet Info"))
brain_seed.triggered.connect(self.actuator.show_seed_dialog)
electrum_menu.addAction(_("&Quit"))
quit_option = electrum_menu.addAction(_("&Quit"))
quit_option.triggered.connect(self.close)
view_menu = menubar.addMenu(_("&View"))
expert_gui = view_menu.addAction(_("&Pro Mode"))
@ -254,9 +265,10 @@ class MiniWindow(QDialog):
pass
def set_quote_currency(self, currency):
"""Set and display the fiat currency country."""
assert currency in self.quote_currencies
self.quote_currencies.remove(currency)
self.quote_currencies = [currency] + self.quote_currencies
self.quote_currencies.insert(0, currency)
self.refresh_balance()
def change_quote_currency(self):
@ -274,6 +286,7 @@ class MiniWindow(QDialog):
self.amount_input_changed(self.amount_input.text())
def set_balances(self, btc_balance):
"""Set the bitcoin balance and update the amount label accordingly."""
self.btc_balance = btc_balance
quote_text = self.create_quote_text(btc_balance)
if quote_text:
@ -283,6 +296,7 @@ class MiniWindow(QDialog):
self.setWindowTitle("Electrum - %s BTC" % btc_balance)
def amount_input_changed(self, amount_text):
"""Update the number of bitcoins displayed."""
self.check_button_status()
try:
@ -298,6 +312,8 @@ class MiniWindow(QDialog):
self.balance_label.show_balance()
def create_quote_text(self, btc_balance):
"""Return a string copy of the amount fiat currency the
user has in bitcoins."""
quote_currency = self.quote_currencies[0]
quote_balance = self.exchanger.exchange(btc_balance, quote_currency)
if quote_balance is None:
@ -314,8 +330,16 @@ class MiniWindow(QDialog):
self.amount_input.setText("")
def check_button_status(self):
"""Check that the bitcoin address is valid and that something
is entered in the amount before making the send button clickable."""
try:
value = D(str(self.amount_input.text())) * 10**8
except decimal.InvalidOperation:
value = None
# self.address_input.property(...) returns a qVariant, not a bool.
# The == is needed to properly invoke a comparison.
if (self.address_input.property("isValid") == True and
len(self.amount_input.text()) > 0):
value is not None and 0 < value <= self.btc_balance):
self.send_button.setDisabled(False)
else:
self.send_button.setDisabled(True)
@ -385,10 +409,12 @@ class BalanceLabel(QLabel):
self.amount_text = ""
def mousePressEvent(self, event):
"""Change the fiat currency selection if window background is clicked."""
if self.state != self.SHOW_CONNECTING:
self.change_quote_currency()
def set_balance_text(self, btc_balance, quote_text):
"""Set the amount of bitcoins in the gui."""
if self.state == self.SHOW_CONNECTING:
self.state = self.SHOW_BALANCE
self.balance_text = "<span style='font-size: 18pt'>%s</span> <span style='font-size: 10pt'>BTC</span> <span style='font-size: 10pt'>%s</span>" % (btc_balance, quote_text)
@ -466,7 +492,8 @@ class ReceivePopup(QDialog):
self.setMouseTracking(True)
self.setWindowTitle("Electrum - " + _("Receive Bitcoin payment"))
self.setWindowFlags(Qt.Window|Qt.FramelessWindowHint|Qt.MSWindowsFixedSizeDialogHint)
self.setWindowFlags(Qt.Window|Qt.FramelessWindowHint|
Qt.MSWindowsFixedSizeDialogHint)
self.layout().setSizeConstraint(QLayout.SetFixedSize)
#self.setFrameStyle(QFrame.WinPanel|QFrame.Raised)
#self.setAlignment(Qt.AlignCenter)
@ -480,33 +507,43 @@ class ReceivePopup(QDialog):
self.show()
class MiniActuator:
"""Initialize the definitions relating to themes and
sending/recieving bitcoins."""
def __init__(self, wallet):
"""Retrieve the gui theme used in previous session."""
self.wallet = wallet
self.theme_name = self.wallet.theme
self.themes = util.load_theme_paths()
def load_theme(self):
"""Load theme retrieved from wallet file."""
try:
theme_prefix, theme_path = self.themes[self.theme_name]
except KeyError:
util.print_error("Theme not found! ", self.theme_name)
util.print_error("Theme not found!", self.theme_name)
return
QDir.setCurrent(os.path.join(theme_prefix, theme_path))
with open(rsrc("style.css")) as style_file:
qApp.setStyleSheet(style_file.read())
def theme_names(self):
return self.themes.keys()
"""Sort themes."""
return sorted(self.themes.keys())
def selected_theme(self):
"""Select theme."""
return self.theme_name
def change_theme(self, theme_name):
"""Change theme."""
self.wallet.theme = self.theme_name = theme_name
self.load_theme()
def set_configured_currency(self, set_quote_currency):
"""Set the inital fiat currency conversion country (USD/EUR/GBP) in
the GUI to what it was set to in the wallet."""
currency = self.wallet.conversion_currency
# currency can be none when Electrum is used for the first
# time and no setting has been created yet.
@ -514,9 +551,70 @@ class MiniActuator:
set_quote_currency(currency)
def set_config_currency(self, conversion_currency):
"""Change the wallet fiat currency country."""
self.wallet.conversion_currency = conversion_currency
def set_servers_gui_stuff(self, servers_menu, servers_group):
self.servers_menu = servers_menu
self.servers_group = servers_group
def populate_servers_menu(self):
interface = self.wallet.interface
if not interface.servers:
print "No servers loaded yet."
self.servers_list = []
for server_string in DEFAULT_SERVERS:
host, port, protocol = server_string.split(':')
transports = [(protocol,port)]
self.servers_list.append((host, transports))
else:
print "Servers loaded."
self.servers_list = interface.servers
server_names = [details[0] for details in self.servers_list]
current_server = self.wallet.server.split(":")[0]
for server_name in server_names:
server_action = self.servers_menu.addAction(server_name)
server_action.setCheckable(True)
if server_name == current_server:
server_action.setChecked(True)
class SelectServerFunctor:
def __init__(self, server_name, server_selected):
self.server_name = server_name
self.server_selected = server_selected
def __call__(self, checked):
if checked:
# call server_selected
self.server_selected(self.server_name)
delegate = SelectServerFunctor(server_name, self.server_selected)
server_action.toggled.connect(delegate)
self.servers_group.addAction(server_action)
def update_servers_list(self):
# Clear servers_group
for action in self.servers_group.actions():
self.servers_group.removeAction(action)
self.populate_servers_menu()
def server_selected(self, server_name):
match = [transports for (host, transports) in self.servers_list
if host == server_name]
assert len(match) == 1
match = match[0]
# Default to TCP if available else use anything
# TODO: protocol should be selectable.
tcp_port = [port for (protocol, port) in match if protocol == "t"]
if len(tcp_port) == 0:
protocol = match[0][0]
port = match[0][1]
else:
protocol = "t"
port = tcp_port[0]
server_line = "%s:%s:%s" % (server_name, port, protocol)
# Should this have exception handling?
self.wallet.set_server(server_line)
def copy_address(self, receive_popup):
"""Copy the wallet addresses into the client."""
addrs = [addr for addr in self.wallet.all_addresses()
if not self.wallet.is_change(addr)]
# Select most recent addresses from gap limit
@ -527,6 +625,7 @@ class MiniActuator:
receive_popup.popup()
def send(self, address, amount, parent_window):
"""Send bitcoins to the target address."""
dest_address = self.fetch_destination(address)
if dest_address is None or not self.wallet.is_valid(dest_address):
@ -589,6 +688,7 @@ class MiniActuator:
return recipient
def is_valid(self, address):
"""Check if bitcoin address is valid."""
return self.wallet.is_valid(address)
def acceptbit(self, currency):

View File

@ -23,9 +23,7 @@ from util import print_error
try:
import PyQt4
except:
print_error("Error: Could not import PyQt4")
print_error("on Linux systems, you may try 'sudo apt-get install python-qt4'")
sys.exit(1)
sys.exit("Error: Could not import PyQt4 on Linux systems, you may try 'sudo apt-get install python-qt4'")
from PyQt4.QtGui import *
from PyQt4.QtCore import *
@ -36,9 +34,7 @@ from interface import DEFAULT_SERVERS
try:
import icons_rc
except:
print_error("Error: Could not import icons_rc.py")
print_error("Please generate it with: 'pyrcc4 icons.qrc -o lib/icons_rc.py'")
sys.exit(1)
sys.exit("Error: Could not import icons_rc.py, please generate it with: 'pyrcc4 icons.qrc -o lib/icons_rc.py'")
from wallet import format_satoshis
import bmp, mnemonic, pyqrnative, qrscanner
@ -1434,6 +1430,9 @@ class ElectrumGui:
if app is None:
self.app = QApplication(sys.argv)
def server_list_changed(self):
pass
def waiting_dialog(self):
s = Timer()

View File

@ -27,7 +27,7 @@ DEFAULT_TIMEOUT = 5
DEFAULT_SERVERS = [ 'ecdsa.org:50001:t',
'electrum.novit.ro:50001:t',
'uncle-enzo.info:50001:t',
'electrum.bytesized-hosting.com:50000:t'] # list of default servers
'electrum.bytesized-hosting.com:50001:t'] # list of default servers
def replace_keys(obj, old_key, new_key):
@ -306,12 +306,13 @@ class TcpStratumInterface(Interface):
class WalletSynchronizer(threading.Thread):
def __init__(self, wallet, loop=False):
def __init__(self, wallet, loop=False, servers_loaded_callback=None):
threading.Thread.__init__(self)
self.daemon = True
self.wallet = wallet
self.loop = loop
self.init_interface()
self.servers_loaded_callback = servers_loaded_callback
def init_interface(self):
try:
@ -334,7 +335,6 @@ class WalletSynchronizer(threading.Thread):
self.interface = InterfaceClass(host, port, self.wallet.debug_server)
self.wallet.interface = self.interface
def handle_response(self, r):
if r is None:
return
@ -354,15 +354,19 @@ class WalletSynchronizer(threading.Thread):
host = item[1]
ports = []
version = None
if len(item)>2:
if len(item) > 2:
for v in item[2]:
if re.match("[th]\d+",v):
ports.append((v[0],v[1:]))
if re.match("v(.?)+",v):
if re.match("[th]\d+", v):
ports.append((v[0], v[1:]))
if re.match("v(.?)+", v):
version = v[1:]
if ports and version:
servers.append( (host, ports) )
servers.append((host, ports))
self.interface.servers = servers
# servers_loaded_callback is None for commands, but should
# NEVER be None when using the GUI.
if self.servers_loaded_callback is not None:
self.servers_loaded_callback()
elif method == 'blockchain.address.subscribe':
addr = params[0]
@ -425,6 +429,7 @@ class WalletSynchronizer(threading.Thread):
self.wallet.trigger_callbacks()
if self.loop:
time.sleep(5)
# Server has been changed. Copy callback for new interface.
self.init_interface()
self.start_interface()
continue

View File

@ -3,12 +3,13 @@ import platform
import sys
def print_error(*args):
for item in args:
sys.stderr.write(str(item))
sys.stderr.write("\n")
# Stringify args
args = [str(item) for item in args]
sys.stderr.write(" ".join(args) + "\n")
sys.stderr.flush()
def appdata_dir():
"""Find the path to the application data directory; add an electrum folder and return path."""
if platform.system() == "Windows":
return os.path.join(os.environ["APPDATA"], "Electrum")
elif platform.system() == "Linux":
@ -23,6 +24,7 @@ def get_resource_path(*args):
return os.path.join(".", *args)
def local_data_dir():
"""Return path to the data folder."""
assert sys.argv
prefix_path = os.path.dirname(sys.argv[0])
local_data = os.path.join(prefix_path, "data")

View File

@ -16,9 +16,20 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import base64
import os
import re
import hashlib
import copy
import operator
import ast
import threading
import random
import getpass
import aes
import ecdsa
import sys, base64, os, re, hashlib, copy, operator, ast, threading, random, getpass
import aes, ecdsa
from ecdsa.util import string_to_number, number_to_string
from util import print_error
@ -65,8 +76,7 @@ __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
__b58base = len(__b58chars)
def b58encode(v):
""" encode v, which is a string of bytes, to base58.
"""
""" encode v, which is a string of bytes, to base58."""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
@ -89,8 +99,7 @@ def b58encode(v):
return (__b58chars[0]*nPad) + result
def b58decode(v, length):
""" decode v into a string of len bytes
"""
""" decode v into a string of len bytes."""
long_value = 0L
for (i, c) in enumerate(v[::-1]):
long_value += __b58chars.find(c) * (__b58base**i)
@ -157,8 +166,7 @@ def prompt_password(prompt, confirm=True):
password2 = getpass.getpass("Confirm: ")
if password != password2:
print_error("Error: Passwords do not match.")
sys.exit(1)
sys.exit("Error: Passwords do not match.")
else:
password = raw_input(prompt)
@ -282,7 +290,7 @@ class Wallet:
self.num_zeros = 0
self.master_public_key = ''
self.conversion_currency = None
self.theme = None
self.theme = "Cleanlook"
# saved fields
self.use_encryption = False
@ -342,7 +350,7 @@ class Wallet:
# raise an error if the format isnt correct
a,b,c = server.split(':')
b = int(b)
assert c in ['t','h','n']
assert c in ['t', 'h', 'n']
# set the server
if server != self.server:
self.server = server
@ -351,22 +359,24 @@ class Wallet:
self.interface.poke()
def set_path(self, wallet_path):
"""Set the path of the wallet."""
if wallet_path is not None:
self.path = wallet_path
return
# Look for wallet file in the default data directory.
# Keeps backwards compatibility.
if "HOME" in os.environ:
wallet_dir = os.path.join(os.environ["HOME"], ".electrum")
elif "LOCALAPPDATA" in os.environ:
wallet_dir = os.path.join(os.environ["LOCALAPPDATA"], "Electrum")
elif "APPDATA" in os.environ:
wallet_dir = os.path.join(os.environ["APPDATA"], "Electrum")
else:
# backward compatibility: look for wallet file in the default data directory
if "HOME" in os.environ:
wallet_dir = os.path.join( os.environ["HOME"], '.electrum')
elif "LOCALAPPDATA" in os.environ:
wallet_dir = os.path.join( os.environ["LOCALAPPDATA"], 'Electrum' )
elif "APPDATA" in os.environ:
wallet_dir = os.path.join( os.environ["APPDATA"], 'Electrum' )
else:
raise BaseException("No home directory found in environment variables.")
if not os.path.exists( wallet_dir ): os.mkdir( wallet_dir )
self.path = os.path.join( wallet_dir, 'electrum.dat' )
raise BaseException("No home directory found in environment variables.")
# Make wallet directory if it does not yet exist.
if not os.path.exists(wallet_dir):
os.mkdir(wallet_dir)
self.path = os.path.join(wallet_dir, "electrum.dat")
def import_key(self, keypair, password):
address, key = keypair.split(':')
@ -676,19 +686,19 @@ class Wallet:
os.chmod(self.path,stat.S_IREAD | stat.S_IWRITE)
def read(self):
"""Read the contents of the wallet file."""
import interface
upgrade_msg = """This wallet seed is deprecated. Please run upgrade.py for a diagnostic."""
self.file_exists = False
try:
f = open(self.path,"r")
data = f.read()
f.close()
except:
with open(self.path, "r") as f:
data = f.read()
except IOError:
return
try:
d = ast.literal_eval( data )
d = ast.literal_eval( data ) #parse raw data from reading wallet file
interface.old_to_new(d)
self.seed_version = d.get('seed_version')
self.master_public_key = d.get('master_public_key').decode('hex')
self.use_encryption = d.get('use_encryption')
@ -714,12 +724,12 @@ class Wallet:
self.conversion_currency = d.get('conversion_currency', 'USD')
self.theme = d.get('theme', 'Cleanlook')
except:
raise BaseException("cannot read wallet file")
raise IOError("Cannot read wallet file.")
self.update_tx_history()
if self.seed_version != SEED_VERSION:
raise BaseException(upgrade_msg)
raise ValueError("This wallet seed is deprecated. Please run upgrade.py for a diagnostic.")
if self.remote_url: assert self.master_public_key.encode('hex') == self.get_remote_mpk()
@ -838,7 +848,7 @@ class Wallet:
try:
d.decode('hex')
except:
raise BaseException("Invalid password")
raise ValueError("Invalid password")
return d
else:
return s
@ -921,10 +931,10 @@ class Wallet:
def mktx(self, to_address, amount, label, password, fee=None, change_addr=None, from_addr= None):
if not self.is_valid(to_address):
raise BaseException("Invalid address")
raise ValueError("Invalid address")
inputs, total, fee = self.choose_tx_inputs( amount, fee, from_addr )
if not inputs:
raise BaseException("Not enough funds")
raise ValueError("Not enough funds")
if not self.use_change and not change_addr:
change_addr = inputs[0][0]
@ -995,7 +1005,7 @@ class Wallet:
self.verify_message(previous, signature, "alias:%s:%s"%(alias,target))
if not self.is_valid(target):
raise BaseException("Invalid bitcoin address")
raise ValueError("Invalid bitcoin address")
return target, signing_addr, auth_name

View File

@ -7,15 +7,12 @@ from lib.version import ELECTRUM_VERSION as version
import lib.util as util
import os, sys, platform
from lib.util import print_error
if sys.version_info[:3] < (2,6,0):
print_error("Error: Electrum requires Python version >= 2.6.0...")
sys.exit(1)
sys.exit("Error: Electrum requires Python version >= 2.6.0...")
data_files = []
if platform.system() != 'Windows' and platform.system() != 'Darwin':
if (len(sys.argv) > 1 and (sys.argv[1] == "sdist")) or (platform.system() != 'Windows' and platform.system() != 'Darwin'):
print "Including all files"
data_files += [
('/usr/share/applications/',['electrum.desktop']),
('/usr/share/app-install/icons/',['electrum.png'])
@ -27,10 +24,15 @@ if platform.system() != 'Windows' and platform.system() != 'Darwin':
data_files.append( ('/usr/share/locale/%s/LC_MESSAGES'%lang, ['locale/%s/LC_MESSAGES/electrum.mo'%lang]) )
data_files += [
(util.appdata_dir(), ["data/background.png", "data/style.css"]),
(os.path.join(util.appdata_dir(), "icons"), [
"data/icons/confirmed.png",
"data/icons/unconfirmed.png"
(util.appdata_dir(), ["data/noface.svg", "data/README"]),
(os.path.join(util.appdata_dir(), "cleanlook"), [
"data/cleanlook/name.cfg",
"data/cleanlook/style.css"
]),
(os.path.join(util.appdata_dir(), "dark"), [
"data/dark/background.png",
"data/dark/name.cfg",
"data/dark/style.css"
])
]