mirror of
https://github.com/jwinterm/cryptonoteRPCwalletGUI.git
synced 2026-10-17 05:51:33 +02:00
302 lines
11 KiB
Python
302 lines
11 KiB
Python
# !/usr/bin/python
|
|
from kivy.app import App
|
|
from kivy.uix.accordion import Accordion
|
|
from kivy.properties import ObjectProperty
|
|
from kivy.core.clipboard import Clipboard
|
|
from kivy.clock import Clock
|
|
from kivy.uix.boxlayout import BoxLayout
|
|
from kivy.uix.button import Button
|
|
from kivy.uix.popup import Popup
|
|
from kivy.storage.jsonstore import JsonStore
|
|
|
|
from lib.isrunning import isrunning
|
|
from lib.checklastblock import checklastblock
|
|
from lib.bitmonerodloader import bitmonerodloader
|
|
from lib.balancecheck import balancecheck
|
|
from lib.namecheck import namecheck
|
|
from lib.transferfunds import transferfundsrpccall
|
|
from lib.simplewalletloader import simplewalletloader
|
|
from lib.save_bc import save_bc
|
|
from lib.savewallet import storewallet
|
|
from lib.cpuminerloader import cpuminerloader
|
|
|
|
from sys import argv, platform
|
|
from os.path import isfile
|
|
import argparse
|
|
from multiprocessing import Process, Queue
|
|
|
|
|
|
# Signal that will switch to False on shutdown to kill children
|
|
kivysignal = True
|
|
|
|
|
|
class SaveBCPopup(Popup):
|
|
def really_save_bc(self):
|
|
self.storebcthread = Process(target=save_bc)
|
|
self.storebcthread.start()
|
|
self.storebcthread.join()
|
|
self.storebcthread.terminate()
|
|
self.storebcthread.join(timeout=3)
|
|
|
|
|
|
class TransferPopup(Popup):
|
|
popup_label = ObjectProperty()
|
|
|
|
def __init__(self, amount, address, mixin, paymentid):
|
|
super(TransferPopup, self).__init__()
|
|
self.amount = amount
|
|
self.address = address
|
|
self.mixin = mixin
|
|
self.paymentid = paymentid
|
|
self.popuptext = "Are you sure you want to send {0:0.9f} XMR\n to [size=8]{1}[/size]\n with mixin count {2} and payment id [size=8]{3}[/size]".format(
|
|
float(amount), address, mixin, paymentid)
|
|
self.popup_label.text = self.popuptext
|
|
|
|
def transfer(self):
|
|
txid = transferfundsrpccall(self.amount, self.address, self.mixin, self.paymentid)
|
|
p = TxIDPopup(txid)
|
|
p.open()
|
|
|
|
|
|
class TxIDPopup(Popup):
|
|
txid_label = ObjectProperty()
|
|
def __init__(self, txid):
|
|
super(TxIDPopup, self).__init__()
|
|
self.txid = txid
|
|
self.txid_label.text = "TxID: [ref=txid]{0}[/ref]\n(Click TxID to copy to clipboard)".format(txid)
|
|
def selecttxid(self):
|
|
Clipboard.put(self.txid)
|
|
|
|
|
|
class RootWidget(Accordion):
|
|
"""Root Kivy widget class"""
|
|
# Check to see if wallet name and password passed as arguments
|
|
if len(argv) == 1:
|
|
walletname, walletpw = "", ""
|
|
elif len(argv) == 3:
|
|
walletname, walletpw = argv[1], argv[2]
|
|
# Initialize other variables
|
|
address, rawaddress = "uninitialized", "uninitialized"
|
|
balance, unlockedbalance = "uninitialized", "uninitialized"
|
|
blockinfotext = "Last block info stats go here..."
|
|
namecheckmessage = "uninitialized"
|
|
isname = None
|
|
# Setup object properties to be modified/used by Kivy
|
|
# bitmonerod daemon tab
|
|
daemonchecker_label = ObjectProperty()
|
|
daemoninfo_label = ObjectProperty()
|
|
# init simplewallet tab
|
|
namechecker_label = ObjectProperty()
|
|
walletchecker_label = ObjectProperty()
|
|
input_name = ObjectProperty()
|
|
input_pw = ObjectProperty()
|
|
label_myaddress = ObjectProperty()
|
|
label_balance = ObjectProperty()
|
|
label_unlockedbalance = ObjectProperty()
|
|
# transfer tab
|
|
input_address = ObjectProperty()
|
|
input_amount = ObjectProperty()
|
|
input_mixin = ObjectProperty()
|
|
input_paymentid = ObjectProperty()
|
|
# mining tab
|
|
minerurl_input = ObjectProperty()
|
|
mineruser_input = ObjectProperty()
|
|
minerpw_input = ObjectProperty()
|
|
minerthreads_input = ObjectProperty()
|
|
|
|
# Setup queues, signals, and workers
|
|
isrunningjobqueue, isrunningresultsqueue = Queue(), Queue()
|
|
checklastblockjobqueue, checklastblockresultsqueue = Queue(), Queue()
|
|
loadwalletresultsqueue = Queue()
|
|
checkbalancejobqueue, checkbalanceresultsqueue = Queue(), Queue()
|
|
checknamejobqueue, checknameresultsqueue = Queue(), Queue()
|
|
daemonrunning = None
|
|
walletrunning = None
|
|
minerrunning = None
|
|
workers = [
|
|
Process(target=isrunning,
|
|
args=(isrunningjobqueue, isrunningresultsqueue)),
|
|
Process(target=checklastblock,
|
|
args=(checklastblockjobqueue, checklastblockresultsqueue)),
|
|
Process(target=balancecheck,
|
|
args=(checkbalancejobqueue, checkbalanceresultsqueue)),
|
|
Process(target=namecheck,
|
|
args=(checknamejobqueue, checknameresultsqueue))
|
|
]
|
|
|
|
def __init__(self, **kwargs):
|
|
super(RootWidget, self).__init__(**kwargs)
|
|
self.workers[0].start()
|
|
self.workers[1].start()
|
|
self.workers[2].start()
|
|
self.workers[3].start()
|
|
Clock.schedule_interval(self.checkisrunning, 0.1)
|
|
Clock.schedule_interval(self.getblockinfo, 1)
|
|
Clock.schedule_interval(self.checkbalance, 1)
|
|
Clock.schedule_interval(self.checkname, 0.1)
|
|
# load data if it exists
|
|
if isfile('forms.json'):
|
|
try:
|
|
store = JsonStore('forms.json')
|
|
self.input_name.text = store.get('forms')['walletname']
|
|
self.input_address.text = store.get('forms')['sendtoaddress']
|
|
self.input_amount.text = store.get('forms')['amount']
|
|
self.input_mixin.text = store.get('forms')['mixin']
|
|
self.input_paymentid.text = store.get('forms')['paymentid']
|
|
self.minerurl_input.text = store.get('forms')['mineraddress']
|
|
self.mineruser_input.text = store.get('forms')['mineruser']
|
|
self.minerpw_input.text = store.get('forms')['minerpw']
|
|
self.minerthreads_input.text = store.get('forms')[
|
|
'minerthreads']
|
|
except:
|
|
pass
|
|
|
|
def checkisrunning(self, dt):
|
|
"""Check if daemon is running"""
|
|
try:
|
|
self.daemonrunning, daemoncheckerlabeltext, self.walletrunning, walletcheckerlabeltext, self.minerrunning = self.isrunningresultsqueue.get_nowait()
|
|
self.daemonchecker_label.text = daemoncheckerlabeltext
|
|
self.walletchecker_label.text = walletcheckerlabeltext
|
|
except:
|
|
pass
|
|
self.isrunningjobqueue.put(kivysignal)
|
|
|
|
def getblockinfo(self, dt):
|
|
"""Try to update daemon stats"""
|
|
try:
|
|
self.blockinfotext = self.checklastblockresultsqueue.get_nowait()
|
|
except:
|
|
pass
|
|
# blockinfotext = "Last block info:\n No RPC info available."
|
|
self.daemoninfo_label.text = self.blockinfotext
|
|
self.checklastblockjobqueue.put((self.daemonrunning, kivysignal))
|
|
|
|
def launchdaemon(self):
|
|
"""launch the bitmonerod daemon in rpc mode"""
|
|
if not self.daemonrunning:
|
|
self.launchdaemonthread = Process(target=bitmonerodloader)
|
|
self.launchdaemonthread.start()
|
|
self.daemonrunning = True
|
|
|
|
def save_bc(self):
|
|
p = SaveBCPopup()
|
|
p.open()
|
|
|
|
def checkbalance(self, dt):
|
|
"""Try to update balance stats"""
|
|
try:
|
|
self.balance, self.unlockedbalance, self.rawaddress = self.checkbalanceresultsqueue.get_nowait()
|
|
self.label_balance.text = self.balance
|
|
self.label_unlockedbalance.text = self.unlockedbalance
|
|
self.address = '[color=00ffff][ref=addressselection]' + self.rawaddress + '[/ref][/color]'
|
|
self.label_myaddress.text = self.address
|
|
except:
|
|
pass
|
|
try:
|
|
wallet, self.address, self.rawaddress = self.loadwalletresultsqueue.get_nowait()
|
|
self.label_myaddress.text = self.address
|
|
except:
|
|
pass
|
|
self.checkbalancejobqueue.put((self.walletrunning, kivysignal))
|
|
|
|
def launchwallet(self):
|
|
"""create wallet if necessary and then launch in rpc mode"""
|
|
if not self.walletrunning:
|
|
self.walletname = self.input_name.text
|
|
self.walletpw = self.input_pw.text
|
|
self.launchwalletthread = Process(target=simplewalletloader,
|
|
args=(self.walletname,
|
|
self.walletpw,
|
|
self.isname))
|
|
self.launchwalletthread.start()
|
|
self.walletrunning = True
|
|
self.storeformdata()
|
|
|
|
def checkname(self, dt):
|
|
"""Check if wallet name exists in local directory"""
|
|
self.walletname = str(self.input_name.text)
|
|
self.checknamejobqueue.put((self.walletname, kivysignal))
|
|
if not self.walletname:
|
|
self.walletname = "No filename"
|
|
# print "no file!"
|
|
try:
|
|
self.isname, self.namecheckmessage = self.checknameresultsqueue.get_nowait()
|
|
# print self.isname
|
|
except:
|
|
pass
|
|
if self.walletrunning:
|
|
self.namecheckmessage = ""
|
|
self.namechecker_label.text = self.namecheckmessage
|
|
|
|
def selectaddress(self):
|
|
"""copy address to clipboard when user clicks"""
|
|
print('User clicked on ', self.rawaddress)
|
|
# Clipboard.put(self.rawaddress)
|
|
self.input_address.copy(self.rawaddress)
|
|
|
|
def savewallet(self):
|
|
self.storewalletthread = Process(target=storewallet)
|
|
self.storewalletthread.start()
|
|
self.storewalletthread.join(timeout=3)
|
|
self.storewalletthread.terminate()
|
|
self.storewalletthread.join()
|
|
|
|
def transferfunds(self):
|
|
"""initiate transfer of funds to new address"""
|
|
|
|
p = TransferPopup(self.input_amount.text, self.input_address.text,
|
|
self.input_mixin.text, self.input_paymentid.text)
|
|
p.open()
|
|
|
|
def transfer(self):
|
|
self.transferthread = Process(target=transferfundsrpccall,
|
|
args=(self.amount.text, self.address.text,
|
|
self.mixin.text,
|
|
self.paymentid.text))
|
|
self.transferthread.start()
|
|
self.transferthread.join()
|
|
self.transferthread.terminate()
|
|
self.transferthread.join(timeout=3)
|
|
|
|
def launchminer(self):
|
|
try:
|
|
if not self.minerrunning:
|
|
self.launchminerthread = Process(target=cpuminerloader,
|
|
args=(self.minerurl_input.text,
|
|
self.mineruser_input.text,
|
|
self.minerpw_input.text,
|
|
self.minerthreads_input.text))
|
|
self.launchminerthread.start()
|
|
self.minerrunning = True
|
|
self.storeformdata()
|
|
except:
|
|
pass
|
|
|
|
def storeformdata(self):
|
|
store = JsonStore('forms.json')
|
|
store.put('forms',
|
|
walletname=self.input_name.text,
|
|
sendtoaddress=self.input_address.text,
|
|
amount=self.input_amount.text,
|
|
mixin=self.input_mixin.text,
|
|
paymentid=self.input_paymentid.text,
|
|
mineraddress=self.minerurl_input.text,
|
|
mineruser=self.mineruser_input.text,
|
|
minerpw=self.minerpw_input.text,
|
|
minerthreads=self.minerthreads_input.text)
|
|
|
|
|
|
class KivyWalletApp(App):
|
|
def build(self):
|
|
return RootWidget()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
KivyWalletApp().run()
|
|
kivysignal = False
|
|
for i in RootWidget.workers:
|
|
print i.name
|
|
i.terminate()
|
|
i.join()
|
|
|