From 09c99c792440c3a6023f00320d38af7cdba1371a Mon Sep 17 00:00:00 2001 From: jackjack Date: Mon, 8 Aug 2011 18:35:55 +0200 Subject: [PATCH] Add export/import jsonfile of tx's and WI restructuring --- pywallet.py | 410 ++++++++++++++++++++++++---------------------------- 1 file changed, 187 insertions(+), 223 deletions(-) diff --git a/pywallet.py b/pywallet.py index 812acb3..b5584d2 100755 --- a/pywallet.py +++ b/pywallet.py @@ -863,7 +863,6 @@ def read_wallet(json_db, db_env, walletfile, print_wallet, print_wallet_transact else: json_db[type] = 'unsupported' - parse_wallet(db, item_callback) db.close() @@ -921,7 +920,16 @@ def balance(site, address): else: return json_acc['balance'] -from optparse import OptionParser +def read_jsonfile(filename): + filin = open(filename, 'r') + txdump = filin.read() + filin.close() + return json.loads(txdump) + +def write_jsonfile(filename, array): + filout = open(filename, 'w') + filout.write(json.dumps(array, sort_keys=True, indent=0)) + filout.close() def keyinfo(sec, keyishex): if keyishex is None: @@ -946,72 +954,138 @@ def keyinfo(sec, keyishex): return True +def WI_FormInit(title, action): + return '

%s

'%(title, action) + +def WI_InputText(label, name, id, value, size=30): + return '%s
'%(label, name, id, value, size) + +def WI_Submit(value, local_block, local_button, function): + return ''%(value, local_block, local_button, function) + +def WI_CloseButton(local_block, local_button): + return ''%(local_block, local_button, local_button) + +def WI_ReturnDiv(local_block): + return ''%(local_block) + +def WI_FormEnd(): + return '

' + +def WI_RadioButton(name, value, id, checked, label): + return '%s
'%(name, value, id, checked, label) + +def WI_Checkbox(name, value, id, other, label): + return '%s
'%(name, value, id, other, label) + +def WI_AjaxFunction(name, command_when_ready, query_string, command_until_ready): + return '\n\ +function ajax%s(){\n\ + var ajaxRequest;\n\ + try{\n\ + ajaxRequest = new XMLHttpRequest();\n\ + } catch (e){\n\ + try{\n\ + ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");\n\ + } catch (e) {\n\ + try{\n\ + ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");\n\ + } catch (e){\n\ + alert("Your browser broke!");\n\ + return false;\n\ + }\n\ + }\n\ + }\n\ + ajaxRequest.onreadystatechange = function(){\n\ + if(ajaxRequest.readyState == 4){\n\ + %s\n\ + }\n\ + };\n\ + var queryString = %s;\n\ + ajaxRequest.open("GET", queryString, true);\n\ + %s\n\ + ajaxRequest.send(null);\n\ +}\n\ +\n\ +'%(name, command_when_ready, query_string, command_until_ready) + + class WIRoot(resource.Resource): def render_GET(self, request): header = '

Pywallet Web Interface

CLOSE BITCOIN BEFORE USE!



' - DWForm = '

Dump your wallet:

\ - Wallet Directory:
\ - Wallet Filename:
\ - \ - \ - \ -

' + DWForm = WI_FormInit('Dump your wallet:', 'DumpWallet') + \ + WI_InputText('Wallet Directory: ', 'dir', 'dwf-dir', determine_db_dir()) + \ + WI_InputText('Wallet Filename: ', 'name', 'dwf-name', 'wallet.dat', 20) + \ + WI_Submit('Dump wallet', 'DWDiv', 'dwf-close', 'ajaxDW') + \ + WI_CloseButton('DWDiv', 'dwf-close') + \ + WI_ReturnDiv('DWDiv') + \ + WI_FormEnd() - InfoForm = '

Get some info about one key:

\ - Key:
\ - Version:
\ - Format:
\ - Regular, base 58
\ - Hexadecimal, 64 characters long
\ - \ - \ - \ -

' + DTxForm = WI_FormInit('Dump your transactions to a file:', 'DumpTx') + \ + WI_InputText('Wallet Directory: ', 'dir', 'dt-dir', determine_db_dir()) + \ + WI_InputText('Wallet Filename: ', 'name', 'dt-name', 'wallet.dat', 20) + \ + WI_InputText('Output file: ', 'file', 'dt-file', '') + \ + WI_Submit('Dump tx\'s', 'DTxDiv', 'dt-close', 'ajaxDTx') + \ + WI_CloseButton('DTxDiv', 'dt-close') + \ + WI_ReturnDiv('DTxDiv') + \ + WI_FormEnd() - ImportForm = '

Import a key into your wallet:

\ - Wallet Directory:
\ - Wallet Filename:
\ - Key:
\ - Label:
\ - Reserve
\ - Version:
\ - Format:
\ - Regular, base 58
\ - Hexadecimal, 64 characters long
\ - \ - \ - \ -

' + InfoForm = WI_FormInit('Get some info about one key:', 'Info') + \ + WI_InputText('Key: ', 'key', 'if-key', '', 60) + \ + WI_InputText('Version:', 'vers', 'if-vers', '0', 1) + \ + "Format:
" + \ + WI_RadioButton('format', 'reg', 'if-reg', 'CHECKED', ' Regular, base 58') + \ + WI_RadioButton('format', 'hex', 'if-hex', '', ' Hexadecimal, 64 characters long') + \ + WI_Submit('Get info', 'InfoDiv', 'if-close', 'ajaxInfo') + \ + WI_CloseButton('InfoDiv', 'if-close') + \ + WI_ReturnDiv('InfoDiv') + \ + WI_FormEnd() - DeleteForm = '

Delete a key from your wallet:

\ - Wallet Directory:
\ - Wallet Filename:
\ - Key:
\ - Type:
\ - Transaction (type "all" in "Key" to delete them all)
\ - Bitcoin address
\ - \ - \ - \ -

' - ImportTxForm = '

Import a transaction into your wallet:

\ - Wallet Directory:
\ - Wallet Filename:
\ - Txk:
\ - Txv:
\ - \ - \ - \ -

' + ImportForm = WI_FormInit('Import a key into your wallet:', 'Import') + \ + WI_InputText('Wallet Directory: ', 'dir', 'impf-dir', determine_db_dir(), 30) + \ + WI_InputText('Wallet Filename:', 'name', 'impf-name', 'wallet.dat', 20) + \ + WI_InputText('Key:', 'key', 'impf-key', '', 65) + \ + WI_InputText('Label:', 'label', 'impf-label', '') + \ + WI_Checkbox('reserve', 'true', 'impf-reserve', 'onClick="document.getElementById(\'impf-label\').disabled=document.getElementById(\'impf-reserve\').checked"', ' Reserve') + \ + WI_InputText('Version:', 'vers', 'impf-vers', '0', 1) + \ + "Format:
" + \ + WI_RadioButton('format', 'reg', 'impf-reg', 'CHECKED', ' Regular, base 58') + \ + WI_RadioButton('format', 'hex', 'impf-hex', '', ' Hexadecimal, 64 characters long') + \ + WI_Submit('Import key', 'ImportDiv', 'impf-close', 'ajaxImport') + \ + WI_CloseButton('ImportDiv', 'impf-close') + \ + WI_ReturnDiv('ImportDiv') + \ + WI_FormEnd() - BalanceForm = '

Print the balance of a Bitcoin address:

\ - Key:
\ -

\ -
\ -




' + + DeleteForm = WI_FormInit('Delete a key from your wallet:', 'Delete') + \ + WI_InputText('Wallet Directory: ', 'dir', 'd-dir', determine_db_dir(), 40) + \ + WI_InputText('Wallet Filename:', 'name', 'd-name', 'wallet.dat') + \ + WI_InputText('Key:', 'key', 'd-key', '', 65) + \ + "Type:
" + \ + WI_RadioButton('d-type', 'tx', 'd-r-tx', 'CHECKED', ' Transaction (type "all" in "Key" to delete them all)') + \ + WI_RadioButton('d-type', 'key', 'd-r-key', '', ' Bitcoin address') + \ + WI_Submit('Delete', 'DeleteDiv', 'd-close', 'ajaxDelete') + \ + WI_CloseButton('DeleteDiv', 'd-close') + \ + WI_ReturnDiv('DeleteDiv') + \ + WI_FormEnd() + + ImportTxForm = WI_FormInit('Import a transaction into your wallet:', 'ImportTx') + \ + WI_InputText('Wallet Directory: ', 'dir', 'it-dir', determine_db_dir(), 40) + \ + WI_InputText('Wallet Filename:', 'name', 'it-name', 'wallet.dat') + \ + WI_InputText('Txk:', 'key', 'it-txk', '', 65) + \ + WI_InputText('Txv:', 'label', 'it-txv', '', 65) + \ + WI_Submit('Import', 'ImportTxDiv', 'it-close', 'ajaxImportTx') + \ + WI_CloseButton('ImportTxDiv', 'it-close') + \ + WI_ReturnDiv('ImportTxDiv') + \ + WI_FormEnd() + + BalanceForm = WI_FormInit('Print the balance of a Bitcoin address:', 'Balance') + \ + WI_InputText('Key:', 'key', 'bf-key', '', 35) + \ + '
' + \ + WI_FormEnd() Misc = '' @@ -1024,166 +1098,17 @@ class WIRoot(resource.Resource): }\ }\ return rad_val;\ - }\ - function ajaxDW(){\ - var ajaxRequest;\ - try{\ - ajaxRequest = new XMLHttpRequest();\ - } catch (e){\ - try{\ - ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");\ - } catch (e) {\ - try{\ - ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");\ - } catch (e){\ - alert("Your browser broke!");\ - return false;\ - }\ - }\ - }\ - ajaxRequest.onreadystatechange = function(){\ - if(ajaxRequest.readyState == 4){\ - document.getElementById("DWDiv").innerHTML = ajaxRequest.responseText;\ - }\ - };\ - var queryString = "/DumpWallet?dir="+document.getElementById("dwf-dir").value+"&name="+document.getElementById("dwf-name").value;\ - ajaxRequest.open("GET", queryString, true);\ - document.getElementById("DWDiv").innerHTML = "Loading...";\ - ajaxRequest.send(null);\ - }\ - function ajaxInfo(){\ - var ajaxRequest;\ - try{\ - ajaxRequest = new XMLHttpRequest();\ - } catch (e){\ - try{\ - ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");\ - } catch (e) {\ - try{\ - ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");\ - } catch (e){\ - alert("Your browser broke!");\ - return false;\ - }\ - }\ - }\ - ajaxRequest.onreadystatechange = function(){\ - if(ajaxRequest.readyState == 4){\ - document.getElementById("InfoDiv").innerHTML = ajaxRequest.responseText;\ - }\ - };\ - var queryString = "/Info?key="+document.getElementById("if-key").value+"&vers="+document.getElementById("if-vers").value+"&format="+(document.getElementById("if-hex").checked?"hex":"reg");\ - ajaxRequest.open("GET", queryString, true);\ - document.getElementById("InfoDiv").innerHTML = "Loading...";\ - ajaxRequest.send(null);\ - }\ - function ajaxImport(){\ - var ajaxRequest;\ - try{\ - ajaxRequest = new XMLHttpRequest();\ - } catch (e){\ - try{\ - ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");\ - } catch (e) {\ - try{\ - ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");\ - } catch (e){\ - alert("Your browser broke!");\ - return false;\ - }\ - }\ - }\ - ajaxRequest.onreadystatechange = function(){\ - if(ajaxRequest.readyState == 4){\ - document.getElementById("ImportDiv").innerHTML = ajaxRequest.responseText;\ - }\ - };\ - var queryString = "/Import?dir="+document.getElementById("impf-dir").value+"&name="+document.getElementById("impf-name").value+"&key="+document.getElementById("impf-key").value+"&label="+document.getElementById("impf-label").value+"&vers="+document.getElementById("impf-vers").value+"&format="+(document.getElementById("impf-hex").checked?"hex":"reg")+(document.getElementById("impf-reserve").checked?"&reserve=1":"");\ - ajaxRequest.open("GET", queryString, true);\ - document.getElementById("ImportDiv").innerHTML = "Loading...";\ - ajaxRequest.send(null);\ - }\ - function ajaxBalance(){\ - var ajaxRequest;\ - try{\ - ajaxRequest = new XMLHttpRequest();\ - } catch (e){\ - try{\ - ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");\ - } catch (e) {\ - try{\ - ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");\ - } catch (e){\ - alert("Your browser broke!");\ - return false;\ - }\ - }\ - }\ - ajaxRequest.onreadystatechange = function(){\ - if(ajaxRequest.readyState == 4){\ - document.getElementById("BalanceDiv").innerHTML = "Balance of " + document.getElementById("bf-key").value + ": " + ajaxRequest.responseText;\ - }\ - };\ - var queryString = "/Balance?key="+document.getElementById("bf-key").value;\ - ajaxRequest.open("GET", queryString, true);\ - document.getElementById("BalanceDiv").innerHTML = "Loading...";\ - ajaxRequest.send(null);\ - }\ - function ajaxDelete(){\ - var ajaxRequest;\ - try{\ - ajaxRequest = new XMLHttpRequest();\ - } catch (e){\ - try{\ - ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");\ - } catch (e) {\ - try{\ - ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");\ - } catch (e){\ - alert("Your browser broke!");\ - return false;\ - }\ - }\ - }\ - ajaxRequest.onreadystatechange = function(){\ - if(ajaxRequest.readyState == 4){\ - document.getElementById("DeleteDiv").innerHTML = ajaxRequest.responseText;\ - }\ - };\ - var queryString = "/Delete?dir="+document.getElementById("d-dir").value+"&name="+document.getElementById("d-name").value+"&keydel="+document.getElementById("d-key").value+"&typedel="+get_radio_value(document.getElementsByName("d-type"));\n\ - ajaxRequest.open("GET", queryString, true);\n\ - document.getElementById("DeleteDiv").innerHTML = "Loading...";\ - ajaxRequest.send(null);\ - }\ - function ajaxImportTx(){\ - var ajaxRequest;\ - try{\ - ajaxRequest = new XMLHttpRequest();\ - } catch (e){\ - try{\ - ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");\ - } catch (e) {\ - try{\ - ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");\ - } catch (e){\ - alert("Your browser broke!");\ - return false;\ - }\ - }\ - }\ - ajaxRequest.onreadystatechange = function(){\ - if(ajaxRequest.readyState == 4){\ - document.getElementById("ImportTxDiv").innerHTML = ajaxRequest.responseText;\ - }\ - };\ - var queryString = "/ImportTx?dir="+document.getElementById("it-dir").value+"&name="+document.getElementById("it-name").value+"&txk="+document.getElementById("it-txk").value+"&txv="+document.getElementById("it-txv").value;\n\ - ajaxRequest.open("GET", queryString, true);\n\ - document.getElementById("ImportTxDiv").innerHTML = "Loading...";\ - ajaxRequest.send(null);\ - }\ - ' + }' + \ + WI_AjaxFunction('DW', 'document.getElementById("DWDiv").innerHTML = ajaxRequest.responseText;', '"/DumpWallet?dir="+document.getElementById("dwf-dir").value+"&name="+document.getElementById("dwf-name").value', 'document.getElementById("DWDiv").innerHTML = "Loading...";') + \ + WI_AjaxFunction('DTx', 'document.getElementById("DTxDiv").innerHTML = ajaxRequest.responseText;', '"/DumpTx?dir="+document.getElementById("dt-dir").value+"&name="+document.getElementById("dt-name").value+"&file="+document.getElementById("dt-file").value', 'document.getElementById("DTxDiv").innerHTML = "Loading...";') + \ + WI_AjaxFunction('Info', 'document.getElementById("InfoDiv").innerHTML = ajaxRequest.responseText;', '"/Info?key="+document.getElementById("if-key").value+"&vers="+document.getElementById("if-vers").value+"&format="+(document.getElementById("if-hex").checked?"hex":"reg")', 'document.getElementById("ImportDiv").innerHTML = "Loading...";') + \ + WI_AjaxFunction('Import', 'document.getElementById("ImportDiv").innerHTML = ajaxRequest.responseText;', '"/Import?dir="+document.getElementById("impf-dir").value+"&name="+document.getElementById("impf-name").value+"&key="+document.getElementById("impf-key").value+"&label="+document.getElementById("impf-label").value+"&vers="+document.getElementById("impf-vers").value+"&format="+(document.getElementById("impf-hex").checked?"hex":"reg")+(document.getElementById("impf-reserve").checked?"&reserve=1":"")', 'document.getElementById("ImportDiv").innerHTML = "Loading...";') + \ + WI_AjaxFunction('Balance', 'document.getElementById("BalanceDiv").innerHTML = "Balance of " + document.getElementById("bf-key").value + ": " + ajaxRequest.responseText;', '"/Balance?key="+document.getElementById("bf-key").value', 'document.getElementById("BalanceDiv").innerHTML = "Loading...";') + \ + WI_AjaxFunction('Delete', 'document.getElementById("DeleteDiv").innerHTML = ajaxRequest.responseText;', '"/Delete?dir="+document.getElementById("d-dir").value+"&name="+document.getElementById("d-name").value+"&keydel="+document.getElementById("d-key").value+"&typedel="+get_radio_value(document.getElementsByName("d-type"))', 'document.getElementById("DeleteDiv").innerHTML = "Loading...";') + \ + WI_AjaxFunction('ImportTx', 'document.getElementById("ImportTxDiv").innerHTML = ajaxRequest.responseText;', '"/ImportTx?dir="+document.getElementById("it-dir").value+"&name="+document.getElementById("it-name").value+"&txk="+document.getElementById("it-txk").value+"&txv="+document.getElementById("it-txv").value', 'document.getElementById("ImportTxDiv").innerHTML = "Loading...";') + \ + '' - page = 'Pywallet Web Interface' + header + Javascript + DWForm + InfoForm + ImportForm + ImportTxForm + DeleteForm + BalanceForm + Misc + '' + page = 'Pywallet Web Interface' + header + Javascript + DWForm + DTxForm + InfoForm + ImportForm + ImportTxForm + DeleteForm + BalanceForm + Misc + '' return page def getChild(self, name, request): @@ -1216,6 +1141,31 @@ class WIDumpWallet(resource.Resource): def render_POST(self, request): return self.render_GET(request) +class WIDumpTx(resource.Resource): + + def render_GET(self, request): + try: + wdir=request.args['dir'][0] + wname=request.args['name'][0] + jsonfile=request.args['file'][0] + log.msg('Wallet Dir: %s' %(wdir)) + log.msg('Wallet Name: %s' %(wname)) + + if not os.path.isfile(wdir+"/"+wname): + return '%s/%s doesn\'t exist'%(wdir, wname) + if os.path.isfile(jsonfile): + return '%s exists'%(jsonfile) + + read_wallet(json_db, create_env(wdir), wname, True, True, "", None) + write_jsonfile(jsonfile, json_db['tx']) + return 'Wallet: %s/%s
Transations dumped in %s'%(wdir, wname, jsonfile) + except: + log.err() + return 'Error in dumptx page' + + def render_POST(self, request): + return self.render_GET(request) + class WIBalance(resource.Resource): def render_GET(self, request): @@ -1295,22 +1245,33 @@ class WIImportTx(resource.Resource): wname=request.args['name'][0] txk=request.args['txk'][0] txv=request.args['txv'][0] - + d = {} + if not os.path.isfile(wdir+"/"+wname): return '%s/%s doesn\'t exist'%(wdir, wname) + if txk not in "file": + dd = [{'tx_k':txk, 'tx_v':txv}] + else: + if not os.path.isfile(txv): + return '%s doesn\'t exist'%(txv) + dd = read_jsonfile(txv) + + db_env = create_env(wdir) read_wallet(json_db, db_env, wname, True, True, "", None) db = open_wallet(db_env, wname, writable=True) - d = {} - d['txi'] = txk - d['txv'] = txv - update_wallet(db, "tx", d) + i=0 + for tx in dd: + d = {'txi':tx['tx_k'], 'txv':tx['tx_v']} + print(d) + update_wallet(db, "tx", d) + i+=1 db.close() - return "
txk: %s\nTransaction imported in %s/%s
" % (txk, wdir, wname)
+				return "
txk: %s\n%d transaction%s imported in %s/%s
" % (txk, i, iais(i), wdir, wname)
 
         except:
             log.err()
@@ -1379,6 +1340,8 @@ class WI404(resource.Resource):
         return 'Page Not Found'
 
 
+from optparse import OptionParser
+
 if __name__ == '__main__':
 
 	parser = OptionParser(usage="%prog [options]", version="%prog 1.1")
@@ -1440,6 +1403,7 @@ if __name__ == '__main__':
 		 'DumpWallet': WIDumpWallet(),
 		 'Import': WIImport(),
 		 'ImportTx': WIImportTx(),
+		 'DumpTx': WIDumpTx(),
 		 'Info': WIInfo(),
 		 'Delete': WIDelete(),
 		 'Balance': WIBalance()