Merge branch 'master' of git://github.com/spesmilo/electrum
This commit is contained in:
commit
4f27d8ce0f
8
electrum
8
electrum
|
@ -34,8 +34,10 @@ except ImportError:
|
|||
sys.exit("Error: AES does not seem to be installed. Try 'sudo pip install slowaes'")
|
||||
|
||||
|
||||
is_android = 'ANDROID_DATA' in os.environ
|
||||
|
||||
# load local module as electrum
|
||||
if os.path.exists("lib"):
|
||||
if os.path.exists("lib") or is_android:
|
||||
import imp
|
||||
fp, pathname, description = imp.find_module('lib')
|
||||
imp.load_module('electrum', fp, pathname, description)
|
||||
|
@ -89,8 +91,8 @@ if __name__ == '__main__':
|
|||
set_verbosity(options.verbose)
|
||||
|
||||
# config is an object passed to the various constructors (wallet, interface, gui)
|
||||
if 'ANDROID_DATA' in os.environ:
|
||||
config_options = {'wallet_path':"/sdcard/electrum.dat", 'portable':True, 'verbose':True, 'gui':'android'}
|
||||
if is_android:
|
||||
config_options = {'wallet_path':"/sdcard/electrum.dat", 'portable':True, 'verbose':True, 'gui':'android', 'auto_cycle':True}
|
||||
else:
|
||||
config_options = eval(str(options))
|
||||
for k, v in config_options.items():
|
||||
|
|
|
@ -325,6 +325,9 @@ class ElectrumWindow(QMainWindow):
|
|||
# set initial message
|
||||
self.console.showMessage(self.wallet.banner)
|
||||
|
||||
# plugins that need to change the GUI do it here
|
||||
self.run_hook('init')
|
||||
|
||||
|
||||
# plugins
|
||||
def init_plugins(self):
|
||||
|
@ -357,11 +360,27 @@ class ElectrumWindow(QMainWindow):
|
|||
if callback in h: h.remove(callback)
|
||||
self.plugin_hooks[name] = h
|
||||
|
||||
def run_hook(self, name, args):
|
||||
def run_hook(self, name, args = ()):
|
||||
args = (self,) + args
|
||||
for cb in self.plugin_hooks.get(name,[]):
|
||||
apply(cb, args)
|
||||
|
||||
|
||||
def set_label(self, name, text = None):
|
||||
changed = False
|
||||
old_text = self.wallet.labels.get(name)
|
||||
if text:
|
||||
if old_text != text:
|
||||
self.wallet.labels[name] = text
|
||||
changed = True
|
||||
else:
|
||||
if old_text:
|
||||
self.wallet.labels.pop(name)
|
||||
changed = True
|
||||
self.run_hook('set_label', (name, text, changed))
|
||||
return changed
|
||||
|
||||
|
||||
# custom wrappers for getOpenFileName and getSaveFileName, that remember the path selected by the user
|
||||
def getOpenFileName(self, title, filter = None):
|
||||
directory = self.config.get('io_dir', os.path.expanduser('~'))
|
||||
|
@ -382,14 +401,14 @@ class ElectrumWindow(QMainWindow):
|
|||
|
||||
def close(self):
|
||||
QMainWindow.close(self)
|
||||
self.run_hook('close_main_window', (self,))
|
||||
self.run_hook('close_main_window')
|
||||
|
||||
def connect_slots(self, sender):
|
||||
self.connect(sender, QtCore.SIGNAL('timersignal'), self.timer_actions)
|
||||
self.previous_payto_e=''
|
||||
|
||||
def timer_actions(self):
|
||||
self.run_hook('timer_actions', (self,))
|
||||
self.run_hook('timer_actions')
|
||||
|
||||
if self.payto_e.hasFocus():
|
||||
return
|
||||
|
@ -534,13 +553,11 @@ class ElectrumWindow(QMainWindow):
|
|||
self.is_edit=True
|
||||
tx_hash = str(item.data(0, Qt.UserRole).toString())
|
||||
tx = self.wallet.transactions.get(tx_hash)
|
||||
s = self.wallet.labels.get(tx_hash)
|
||||
text = unicode( item.text(2) )
|
||||
self.set_label(tx_hash, text)
|
||||
if text:
|
||||
self.wallet.labels[tx_hash] = text
|
||||
item.setForeground(2, QBrush(QColor('black')))
|
||||
else:
|
||||
if s: self.wallet.labels.pop(tx_hash)
|
||||
text = self.wallet.get_default_label(tx_hash)
|
||||
item.setText(2, text)
|
||||
item.setForeground(2, QBrush(QColor('gray')))
|
||||
|
@ -574,33 +591,23 @@ class ElectrumWindow(QMainWindow):
|
|||
text = unicode( item.text(column_label) )
|
||||
changed = False
|
||||
|
||||
if text:
|
||||
if text not in self.wallet.aliases.keys():
|
||||
old_addr = self.wallet.labels.get(text)
|
||||
if old_addr != addr:
|
||||
self.wallet.labels[addr] = text
|
||||
changed = True
|
||||
else:
|
||||
print_error("Error: This is one of your aliases")
|
||||
label = self.wallet.labels.get(addr,'')
|
||||
item.setText(column_label, QString(label))
|
||||
if text in self.wallet.aliases.keys():
|
||||
print_error("Error: This is one of your aliases")
|
||||
label = self.wallet.labels.get(addr,'')
|
||||
item.setText(column_label, QString(label))
|
||||
else:
|
||||
s = self.wallet.labels.get(addr)
|
||||
if s:
|
||||
self.wallet.labels.pop(addr)
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
self.update_history_tab()
|
||||
self.update_completions()
|
||||
changed = self.set_label(addr, text)
|
||||
if changed:
|
||||
self.update_history_tab()
|
||||
self.update_completions()
|
||||
|
||||
self.current_item_changed(item)
|
||||
|
||||
self.run_hook('item_changed',(self, item, column))
|
||||
self.run_hook('item_changed', (item, column))
|
||||
|
||||
|
||||
def current_item_changed(self, a):
|
||||
self.run_hook('current_item_changed',(self, a))
|
||||
self.run_hook('current_item_changed', (a,))
|
||||
|
||||
|
||||
|
||||
|
@ -746,7 +753,7 @@ class ElectrumWindow(QMainWindow):
|
|||
self.amount_e.textChanged.connect(lambda: entry_changed(False) )
|
||||
self.fee_e.textChanged.connect(lambda: entry_changed(True) )
|
||||
|
||||
self.run_hook('create_send_tab',(self,grid))
|
||||
self.run_hook('create_send_tab', (grid,))
|
||||
return w2
|
||||
|
||||
|
||||
|
@ -806,10 +813,10 @@ class ElectrumWindow(QMainWindow):
|
|||
self.show_message(str(e))
|
||||
return
|
||||
|
||||
self.run_hook('send_tx', (self.wallet, self, tx))
|
||||
self.run_hook('send_tx', (tx,))
|
||||
|
||||
if label:
|
||||
self.wallet.labels[tx.hash()] = label
|
||||
self.set_label(tx.hash(), label)
|
||||
|
||||
if tx.is_complete:
|
||||
h = self.wallet.send_tx(tx)
|
||||
|
@ -1002,7 +1009,7 @@ class ElectrumWindow(QMainWindow):
|
|||
t = _("Unprioritize") if addr in self.wallet.prioritized_addresses else _("Prioritize")
|
||||
menu.addAction(t, lambda: self.toggle_priority(addr))
|
||||
|
||||
self.run_hook('receive_menu', (self, menu,))
|
||||
self.run_hook('receive_menu', (menu,))
|
||||
menu.exec_(self.receive_list.viewport().mapToGlobal(position))
|
||||
|
||||
|
||||
|
@ -1023,8 +1030,7 @@ class ElectrumWindow(QMainWindow):
|
|||
if self.question(_("Do you want to remove")+" %s "%x +_("from your list of contacts?")):
|
||||
if not is_alias and x in self.wallet.addressbook:
|
||||
self.wallet.addressbook.remove(x)
|
||||
if x in self.wallet.labels.keys():
|
||||
self.wallet.labels.pop(x)
|
||||
self.set_label(x, None)
|
||||
elif is_alias and x in self.wallet.aliases:
|
||||
self.wallet.aliases.pop(x)
|
||||
self.update_history_tab()
|
||||
|
@ -1060,7 +1066,7 @@ class ElectrumWindow(QMainWindow):
|
|||
label = self.wallet.labels.get(address,'')
|
||||
item.setData(1,0,label)
|
||||
|
||||
self.run_hook('update_receive_item', (self, address, item))
|
||||
self.run_hook('update_receive_item', (address, item))
|
||||
|
||||
c, u = self.wallet.get_addr_balance(address)
|
||||
balance = format_satoshis( c + u, False, self.wallet.num_zeros )
|
||||
|
@ -1679,7 +1685,7 @@ class ElectrumWindow(QMainWindow):
|
|||
if not tx_dict["complete"]:
|
||||
assert "input_info" in tx_dict.keys()
|
||||
except:
|
||||
QMessageBox.critical(None, "Unable to parse transaction", _("Electrum was unable to parse your transaction:"))
|
||||
QMessageBox.critical(None, "Unable to parse transaction", _("Electrum was unable to parse your transaction"))
|
||||
return None
|
||||
return tx_dict
|
||||
|
||||
|
@ -1706,7 +1712,7 @@ class ElectrumWindow(QMainWindow):
|
|||
if fileName:
|
||||
with open(fileName, "w+") as f:
|
||||
f.write(json.dumps(tx.as_dict(),indent=4) + '\n')
|
||||
self.show_message(_("Transaction saved succesfully"))
|
||||
self.show_message(_("Transaction saved successfully"))
|
||||
if dialog:
|
||||
dialog.done(0)
|
||||
except BaseException, e:
|
||||
|
@ -1716,7 +1722,7 @@ class ElectrumWindow(QMainWindow):
|
|||
def send_raw_transaction(self, raw_tx, dialog = ""):
|
||||
result, result_message = self.wallet.sendtx( raw_tx )
|
||||
if result:
|
||||
self.show_message("Transaction succesfully sent: %s" % (result_message))
|
||||
self.show_message("Transaction successfully sent: %s" % (result_message))
|
||||
if dialog:
|
||||
dialog.done(0)
|
||||
else:
|
||||
|
@ -1759,7 +1765,7 @@ class ElectrumWindow(QMainWindow):
|
|||
l = QGridLayout()
|
||||
dialog.setLayout(l)
|
||||
|
||||
l.addWidget(QLabel(_("Transaction status: ")), 3,0)
|
||||
l.addWidget(QLabel(_("Transaction status:")), 3,0)
|
||||
l.addWidget(QLabel(_("Actions")), 4,0)
|
||||
|
||||
if tx_dict["complete"] == False:
|
||||
|
|
|
@ -44,10 +44,12 @@ languages = {
|
|||
'es':_('Spanish'),
|
||||
'fr':_('French'),
|
||||
'it':_('Italian'),
|
||||
'ja':_('Japanese'),
|
||||
'lv':_('Latvian'),
|
||||
'nl':_('Dutch'),
|
||||
'ru':_('Russian'),
|
||||
'sl':_('Slovenian'),
|
||||
'ta':_('Tamil'),
|
||||
'vi':_('Vietnamese'),
|
||||
'zh':_('Chinese')
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
# source: http://stackoverflow.com/questions/2758159/how-to-embed-a-python-interpreter-in-a-pyqt-widget
|
||||
|
||||
import sys, os, re
|
||||
import traceback
|
||||
import traceback, platform
|
||||
from PyQt4 import QtCore
|
||||
from PyQt4 import QtGui
|
||||
from electrum import util
|
||||
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
MONOSPACE_FONT = 'Lucida Console'
|
||||
elif platform.system() == 'Darwin':
|
||||
MONOSPACE_FONT = 'Monaco'
|
||||
else:
|
||||
MONOSPACE_FONT = 'monospace'
|
||||
|
||||
|
||||
class Console(QtGui.QPlainTextEdit):
|
||||
def __init__(self, prompt='>> ', startup_message='', parent=None):
|
||||
|
@ -20,7 +27,7 @@ class Console(QtGui.QPlainTextEdit):
|
|||
self.setGeometry(50, 75, 600, 400)
|
||||
self.setWordWrapMode(QtGui.QTextOption.WrapAnywhere)
|
||||
self.setUndoRedoEnabled(False)
|
||||
self.document().setDefaultFont(QtGui.QFont("monospace", 10, QtGui.QFont.Normal))
|
||||
self.document().setDefaultFont(QtGui.QFont(MONOSPACE_FONT, 10, QtGui.QFont.Normal))
|
||||
self.showMessage(startup_message)
|
||||
|
||||
self.updateNamespace({'run':self.run_script})
|
||||
|
|
|
@ -825,7 +825,7 @@ class Transaction:
|
|||
for i in self.inputs:
|
||||
e = { 'txid':i['tx_hash'], 'vout':i['index'],
|
||||
'scriptPubKey':i.get('raw_output_script'),
|
||||
'electrumKeyID':i.get('electrumKeyID'),
|
||||
'KeyID':i.get('KeyID'),
|
||||
'redeemScript':i.get('redeemScript'),
|
||||
'signatures':i.get('signatures'),
|
||||
'pubkeys':i.get('pubkeys'),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
ELECTRUM_VERSION = "1.7" # version of the client package
|
||||
PROTOCOL_VERSION = '0.6' # protocol version requested
|
||||
SEED_VERSION = 4 # bump this every time the seed generation is modified
|
||||
TRANSLATION_ID = 3958 # version of the wiki page
|
||||
TRANSLATION_ID = 3992 # version of the wiki page
|
||||
|
|
|
@ -256,7 +256,7 @@ class Wallet:
|
|||
if item.get('txid') == txin['tx_hash'] and item.get('vout') == txin['index']:
|
||||
txin['raw_output_script'] = item['scriptPubKey']
|
||||
txin['redeemScript'] = item.get('redeemScript')
|
||||
txin['electrumKeyID'] = item.get('electrumKeyID')
|
||||
txin['KeyID'] = item.get('KeyID')
|
||||
break
|
||||
else:
|
||||
for item in unspent_coins:
|
||||
|
@ -268,8 +268,9 @@ class Wallet:
|
|||
raise
|
||||
|
||||
# find the address:
|
||||
if txin.get('electrumKeyID'):
|
||||
account, sequence = txin.get('electrumKeyID')
|
||||
if txin.get('KeyID'):
|
||||
account, name, sequence = txin.get('KeyID')
|
||||
if name != 'Electrum': continue
|
||||
sec = self.sequences[account].get_private_key(sequence, seed)
|
||||
addr = self.sequences[account].get_address(sequence)
|
||||
txin['address'] = addr
|
||||
|
@ -771,7 +772,7 @@ class Wallet:
|
|||
pk_addresses.append(address)
|
||||
continue
|
||||
account, sequence = self.get_address_index(address)
|
||||
txin['electrumKeyID'] = (account, sequence) # used by the server to find the key
|
||||
txin['KeyID'] = (account, 'Electrum', sequence) # used by the server to find the key
|
||||
pk_addr, redeemScript = self.sequences[account].get_input_info(sequence)
|
||||
if redeemScript: txin['redeemScript'] = redeemScript
|
||||
pk_addresses.append(pk_addr)
|
||||
|
@ -1197,9 +1198,6 @@ class WalletSynchronizer(threading.Thread):
|
|||
while not self.interface.is_connected:
|
||||
time.sleep(1)
|
||||
|
||||
# request banner, because 'connected' event happens before this thread is started
|
||||
self.interface.send([('server.banner',[])],'synchronizer')
|
||||
|
||||
# subscriptions
|
||||
self.subscribe_to_addresses(self.wallet.addresses(True))
|
||||
|
||||
|
|
|
@ -20,10 +20,13 @@ if __name__ == '__main__':
|
|||
# android
|
||||
os.system('rm -rf dist/e4a-%s'%version)
|
||||
os.mkdir('dist/e4a-%s'%version)
|
||||
shutil.copyfile("electrum",'dist/e4a-%s/electrum.py'%version)
|
||||
shutil.copyfile("electrum",'dist/e4a-%s/e4a.py'%version)
|
||||
shutil.copytree("ecdsa",'dist/e4a-%s/ecdsa'%version)
|
||||
shutil.copytree("aes",'dist/e4a-%s/aes'%version)
|
||||
shutil.copytree("lib",'dist/e4a-%s/electrum'%version)
|
||||
shutil.copytree("lib",'dist/e4a-%s/lib'%version)
|
||||
os.mkdir('dist/e4a-%s/gui'%version)
|
||||
shutil.copy("gui/gui_android.py",'dist/e4a-%s/gui'%version)
|
||||
shutil.copy("gui/__init__.py",'dist/e4a-%s/gui'%version)
|
||||
|
||||
os.chdir("dist")
|
||||
# create the zip file
|
||||
|
|
|
@ -103,6 +103,7 @@ def init(gui):
|
|||
gui.requested_amounts = config.get('requested_amounts',{})
|
||||
gui.merchant_name = config.get('merchant_name', 'Invoice')
|
||||
gui.qr_window = None
|
||||
do_enable(gui, is_enabled())
|
||||
|
||||
def is_enabled():
|
||||
return config.get('pointofsale') is True
|
||||
|
@ -110,32 +111,44 @@ def is_enabled():
|
|||
def is_available():
|
||||
return True
|
||||
|
||||
def toggle(gui):
|
||||
|
||||
if not is_enabled():
|
||||
def toggle(gui):
|
||||
enabled = not is_enabled()
|
||||
config.set_key('pointofsale', enabled, True)
|
||||
do_enable(gui, enabled)
|
||||
update_gui(gui)
|
||||
return enabled
|
||||
|
||||
|
||||
def do_enable(gui, enabled):
|
||||
if enabled:
|
||||
gui.expert_mode = True
|
||||
gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')])
|
||||
gui.set_hook('item_changed', item_changed)
|
||||
gui.set_hook('current_item_changed', recv_changed)
|
||||
gui.set_hook('receive_menu', receive_menu)
|
||||
gui.set_hook('update_receive_item', update_receive_item)
|
||||
gui.set_hook('timer_actions', timer_actions)
|
||||
gui.set_hook('close_main_window', close_main_window)
|
||||
enabled = True
|
||||
gui.set_hook('init', update_gui)
|
||||
else:
|
||||
gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')])
|
||||
gui.unset_hook('item_changed', item_changed)
|
||||
gui.unset_hook('current_item_changed', recv_changed)
|
||||
gui.unset_hook('receive_menu', receive_menu)
|
||||
gui.unset_hook('update_receive_item', update_receive_item)
|
||||
gui.unset_hook('timer_actions', timer_actions)
|
||||
gui.unset_hook('close_main_window', close_main_window)
|
||||
enabled = False
|
||||
gui.unset_hook('init', update_gui)
|
||||
|
||||
|
||||
|
||||
def update_gui(gui):
|
||||
enabled = is_enabled()
|
||||
if enabled:
|
||||
gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')])
|
||||
else:
|
||||
gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')])
|
||||
|
||||
config.set_key('pointofsale', enabled, True)
|
||||
toggle_QR_window(gui, enabled)
|
||||
return enabled
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue