diff --git a/twister-control.py b/twister-control.py new file mode 100755 index 00000000..527d0670 --- /dev/null +++ b/twister-control.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python +# +# very simple wrapper for starting twisterd and launching the web browser +# +# generates a default rpcpassword, twister.conf file etc. +# may also setup automatic twisterd script on desktop login. + +from Tkinter import * +from tkMessageBox import * +from subprocess import call, check_output +import csv +import operator +import string +import random +import os +import sys +import stat +import socket +import time +import webbrowser +import argparse + +configFilename = os.path.expanduser('~/.twister/twister.conf') +startupScript = os.path.expanduser('~/.config/autostart/twisterd-startup.desktop') + +def passwordGenerator(size=10, chars=string.ascii_lowercase + string.digits): + return ''.join(random.choice(chars) for _ in range(size)) + +configOptions = { + 'rpcuser' : 'user', + 'rpcpassword' : passwordGenerator(), + 'rpcallowip' : '127.0.0.1', + 'rpcport' : '28332', +} + +def loadConfig(): + try: + with open(configFilename, "rb") as csvfile: + reader = csv.reader(csvfile, delimiter='=', escapechar='\\', quoting=csv.QUOTE_NONE) + for row in reader: + if len(row) != 2: + raise csv.Error("Too many fields on row with contents: "+str(row)) + configOptions[row[0]] = row[1] + except: + pass + +def saveConfig(): + with open(configFilename, "wb") as csvfile: + writer = csv.writer(csvfile, delimiter='=', escapechar='\\', quoting=csv.QUOTE_NONE) + for key, value in sorted(configOptions.items(), key=operator.itemgetter(0)): + writer.writerow([ key, value]) + +def get_pid(name): + try: + return check_output(["pidof",name]) + except: + return [] + +def getBrowser(): + prefList = ['google-chrome', 'chrome', 'chromium'] + for browserName in prefList: + try: + return webbrowser.get(browserName) + except: + pass + customPathList = ['/usr/bin/google-chrome'] + for browserExe in customPathList: + if os.path.exists(browserExe): + return webbrowser.get(browserExe + ' %s &') + return webbrowser + +def daemon(): + try: + call(["twisterd", "-daemon"]) + except: + try: + twisterd = os.path.dirname(os.path.realpath(sys.argv[0])) + "/twisterd" + call([twisterd, "-daemon"]) + except: + print "running 'twisterd' failed. check if installed and PATH is correctly configured" + +def launch(): + justLaunched = False + if not get_pid('twisterd'): + print "launching twisterd..." + daemon() + justLaunched = True + + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + daemonUp = False + while not daemonUp: + try: + s.connect(('127.0.0.1', int(configOptions['rpcport']))) + daemonUp = True + except: + print "waiting for twisterd initialization..." + time.sleep(1) + + if justLaunched: + time.sleep(1) # may prevent useless warning about not connected etc + + print "launching webbrowser..." + url = "http://" + configOptions['rpcuser'] + ":" + configOptions['rpcpassword'] + url += "@127.0.0.1:" + configOptions['rpcport'] + getBrowser().open_new(url) + +def addStartup(): + desktopFile = \ + "[Desktop Entry]\n" \ + "Type=Application\n" \ + "Version=1.0\n" \ + "Name=twisterd-startup\n" \ + "Comment=start twisterd on login\n" \ + "Terminal=false\n" + desktopFile += "Exec=" + os.path.realpath(sys.argv[0]) + " --daemon\n" + autostartDir = os.path.dirname(startupScript) + if not os.path.exists(autostartDir): + os.makedirs(os.path.dirname(startupScript)) + open(startupScript,"wb").write(desktopFile) + st = os.stat(startupScript) + os.chmod(startupScript, st.st_mode | stat.S_IEXEC) + +def removeStartup(): + try: + os.remove(startupScript) + except: + pass + +def guiLaunch(): + loadConfig() + saveConfig() + launch() + exit() + +def guiAddStartup(): + addStartup() + showinfo('Ok', 'Startup script added!\ntwisterd will start automatically\non next login.') + +def guiRemoveStartup(): + removeStartup() + showinfo('Ok', 'Startup script removed') + +def createGui(): + root = Tk() + root.title('twister control') + root.minsize(width=200,height=100) + Button(text='Launch twister', command=guiLaunch).pack(fill=X) + Button(text='Add startup script', command=guiAddStartup).pack(fill=X) + Button(text='Remove startup script', command=guiRemoveStartup).pack(fill=X) + Button(text='Quit', command=exit).pack(fill=X) + + mainloop() + +parser = argparse.ArgumentParser() +parser.add_argument("--launch", help="launch twister daemon and browser", action="store_true") +parser.add_argument("--daemon", help="launch twister daemon only", action="store_true") +parser.add_argument("--addstartup", help="add startup script", action="store_true") +parser.add_argument("--removestartup", help="add startup script", action="store_true") +parser.add_argument("--gui", help="open twister control gui", action="store_true") +args = parser.parse_args() + +if args.launch or args.daemon: + loadConfig() + saveConfig() + +if args.launch: + launch() +elif args.daemon: + daemon() +elif args.addstartup: + addStartup() +elif args.removestartup: + removeStartup() +else: + createGui() + diff --git a/twister-test.py b/twister-test.py deleted file mode 100755 index 377fc834..00000000 --- a/twister-test.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python - -import os,sys,time - -ext_ip = os.environ['EXTIP'] -twister = "./twisterd" - -cmd = sys.argv[1] -n = int(sys.argv[2]) - -datadir = "/tmp/twister%d" % n -port = "%d" % (30000+n) -rpcport = "%d" % (40000+n) -rpcline = " -genproclimit=1 -rpcuser=user -rpcpassword=pwd -rpcallowip=127.0.0.1 -rpcport=" -rpccfg = rpcline + rpcport -rpccfg1 = rpcline + "40001" - - -if cmd == "start": - try: - os.mkdir(datadir) - except: - pass - os.system( twister + " -datadir=" + datadir + - " -port=" + port + " -daemon" + - rpccfg ) - if( n != 1): - time.sleep(1) - os.system( twister + rpccfg1 + " addnode " + ext_ip + ":" + port + " onetry" ) - os.system( twister + rpccfg + " addnode " + ext_ip + ":30001 onetry" ) - -if cmd == "cmd": - if( len(sys.argv) < 4 ): - print "missing command (try help)" - sys.exit(-1) - parms = "" - for i in xrange(3,len(sys.argv)): - parms += " '" + sys.argv[i] + "'" - os.system( twister + rpccfg + parms ) -