def start(self): path = self.generate() web.path = path if web.payloads is not None: if self.dbms: if self.dbms == 'Mongo': cmd = "run -id -p {0}:80 -v {1}:{2}:rw -v {3}:/etc/php5/fpm/php.ini:ro -v {4}:/usr/lib/php5/modules/mongodb.so:ro --link {5}:{6} --name VW --workdir {2} {7} ".format( self.expose, web.path, self.mount_point, os.path.join(web.path, 'php.ini'), os.path.join(web.path, 'mongodb.so'), web.container_name, self.dbms.lower(), self.image) else: cmd = "run -id -p {0}:80 -v {1}:{2} -v {3}:/etc/php5/fpm/php.ini --link {4}:{5} --name VW --workdir {2} {6} ".format( self.expose, web.path, self.mount_point, os.path.join(web.path, 'php.ini'), web.container_name, self.dbms.lower(), self.image) if self.command: cmd = cmd + self.command web.dAgent.send(cmd) else: cmd = "run -id -p {0}:80 -v {1}:{2}:rw -v {3}:/etc/php5/fpm/php.ini:ro --name VW --workdir {2} {4} ".format( self.expose, web.path, self.mount_point, os.path.join(web.path, 'php.ini'), self.image) if self.command: cmd = cmd + self.command web.dAgent.send(cmd) web.ctr = web.dAgent.recv() if "cmd" in web.payloads: Logger.logInfo("[INFO] " + "CMD: {0}".format(web.payloads['cmd'])) web.dAgent.send("exec {0} -- {1}".format( web.ctr, web.payloads['cmd'])) if "warning" in web.payloads: for warning in web.payloads['warning']: Logger.logWarning("[WARNING] " + warning) if "error" in web.payloads: for error in web.payloads['error']: Logger.logError("[ERROR] " + error) url = [ 'http', '127.0.0.1:{0}'.format(self.expose), '/', '', '', '' ] params = {} if web.payloads['key'] is not None: for index, _ in enumerate(web.payloads['key']): if re.search("page", web.payloads['key'][index], flags=re.IGNORECASE): web.payloads['value'][index] = "index" params.update({ '{0}'.format(web.payloads['key'][index]): '{0}'.format(web.payloads['value'][index]) }) query = params url[4] = urlencode(query) t = Terminal() with t.location(0, t.height - 1): Logger.logSuccess( t.center( t.blink("Browse: {0}".format( urlparse.urlunparse(url))))) web.dAgent.send("logs {0} -f".format(web.ctr))
def monitor(run_once=False, broker=None): if not broker: broker = get_broker() term = Terminal() broker.ping() with term.fullscreen(), term.hidden_cursor(), term.cbreak(): val = None start_width = int(term.width / 8) while val not in (u'q', u'Q',): col_width = int(term.width / 8) # In case of resize if col_width != start_width: print(term.clear()) start_width = col_width print(term.move(0, 0) + term.black_on_green(term.center(_('Host'), width=col_width - 1))) print(term.move(0, 1 * col_width) + term.black_on_green(term.center(_('Id'), width=col_width - 1))) print(term.move(0, 2 * col_width) + term.black_on_green(term.center(_('State'), width=col_width - 1))) print(term.move(0, 3 * col_width) + term.black_on_green(term.center(_('Pool'), width=col_width - 1))) print(term.move(0, 4 * col_width) + term.black_on_green(term.center(_('TQ'), width=col_width - 1))) print(term.move(0, 5 * col_width) + term.black_on_green(term.center(_('RQ'), width=col_width - 1))) print(term.move(0, 6 * col_width) + term.black_on_green(term.center(_('RC'), width=col_width - 1))) print(term.move(0, 7 * col_width) + term.black_on_green(term.center(_('Up'), width=col_width - 1))) i = 2 stats = Stat.get_all(broker=broker) print(term.clear_eos()) for stat in stats: status = stat.status # color status if stat.status == Conf.WORKING: status = term.green(str(Conf.WORKING)) elif stat.status == Conf.STOPPING: status = term.yellow(str(Conf.STOPPING)) elif stat.status == Conf.STOPPED: status = term.red(str(Conf.STOPPED)) elif stat.status == Conf.IDLE: status = str(Conf.IDLE) # color q's tasks = str(stat.task_q_size) if stat.task_q_size > 0: tasks = term.cyan(str(stat.task_q_size)) if Conf.QUEUE_LIMIT and stat.task_q_size == Conf.QUEUE_LIMIT: tasks = term.green(str(stat.task_q_size)) results = stat.done_q_size if results > 0: results = term.cyan(str(results)) # color workers workers = len(stat.workers) if workers < Conf.WORKERS: workers = term.yellow(str(workers)) # format uptime uptime = (timezone.now() - stat.tob).total_seconds() hours, remainder = divmod(uptime, 3600) minutes, seconds = divmod(remainder, 60) uptime = '%d:%02d:%02d' % (hours, minutes, seconds) # print to the terminal print(term.move(i, 0) + term.center(stat.host[:col_width - 1], width=col_width - 1)) print(term.move(i, 1 * col_width) + term.center(stat.cluster_id, width=col_width - 1)) print(term.move(i, 2 * col_width) + term.center(status, width=col_width - 1)) print(term.move(i, 3 * col_width) + term.center(workers, width=col_width - 1)) print(term.move(i, 4 * col_width) + term.center(tasks, width=col_width - 1)) print(term.move(i, 5 * col_width) + term.center(results, width=col_width - 1)) print(term.move(i, 6 * col_width) + term.center(stat.reincarnations, width=col_width - 1)) print(term.move(i, 7 * col_width) + term.center(uptime, width=col_width - 1)) i += 1 # bottom bar i += 1 queue_size = broker.queue_size() lock_size = broker.lock_size() if lock_size: queue_size = '{}({})'.format(queue_size, lock_size) print(term.move(i, 0) + term.white_on_cyan(term.center(broker.info(), width=col_width * 2))) print(term.move(i, 2 * col_width) + term.black_on_cyan(term.center(_('Queued'), width=col_width))) print(term.move(i, 3 * col_width) + term.white_on_cyan(term.center(queue_size, width=col_width))) print(term.move(i, 4 * col_width) + term.black_on_cyan(term.center(_('Success'), width=col_width))) print(term.move(i, 5 * col_width) + term.white_on_cyan( term.center(models.Success.objects.count(), width=col_width))) print(term.move(i, 6 * col_width) + term.black_on_cyan(term.center(_('Failures'), width=col_width))) print(term.move(i, 7 * col_width) + term.white_on_cyan( term.center(models.Failure.objects.count(), width=col_width))) # for testing if run_once: return Stat.get_all(broker=broker) print(term.move(i + 2, 0) + term.center(_('[Press q to quit]'))) val = term.inkey(timeout=1)
def do_l(self, arg): 'Lists current portfolio' t = Terminal() portfolio = self.trader.portfolios() if portfolio['extended_hours_equity']: equity = float(portfolio['extended_hours_equity']) else: equity = float(portfolio['equity']) eq = '%.2f' % equity previous_close = float(portfolio['adjusted_equity_previous_close']) change = equity - previous_close change_pct = '%.2f' % (change / previous_close * 100.0) change_pct = color_data(change_pct) change = color_data(change) account_details = self.trader.get_account() if 'margin_balances' in account_details: buying_power = account_details['margin_balances'][ 'unallocated_margin_cash'] account_table = SingleTable( [['Portfolio Value', 'Change', 'Buying Power'], [eq, change + ' (' + change_pct + '%)', buying_power]], 'Account') print((account_table.table)) # Load Stocks positions = self.trader.securities_owned() instruments = [ position['instrument'] for position in positions['results'] ] symbols = [ self.get_symbol(position['instrument']) for position in positions['results'] ] market_data = self.trader.get_stock_marketdata(instruments) table_data = [] table_data.append([ "Symbol", "Last", "Shares", "Equity", "Avg Cost", "Return", "Day", "EquityChange", "Day %" ]) i = 0 for position in positions['results']: quantity = int(float(position['quantity'])) symbol = self.get_symbol(position['instrument']) price = market_data[i]['last_trade_price'] total_equity = float(price) * quantity buy_price = float(position['average_buy_price']) p_l = total_equity - buy_price * quantity day_change = float(market_data[i]['last_trade_price']) - float( market_data[i]['previous_close']) day_change_q_val = '{:04.2f}'.format(quantity * day_change) day_change_pct = '{:04.2f}'.format( float((day_change / float(market_data[i]['previous_close'])) * 100)) table_data.append([ symbol, price, quantity, total_equity, buy_price, color_data(p_l), color_data(day_change), color_data(day_change_q_val), color_data(day_change_pct) ]) i += 1 table = SingleTable(table_data, 'Portfolio') table.inner_row_border = True table.justify_columns = {0: 'center'} print((table.table))
def main(): from blessed import Terminal from deps.chars import specialChars, commonTopBorder, commonBottomBorder, commonEmptyLine global renderMode import time import subprocess global signal global dockerCommandsSelectionInProgress global mainMenuList global currentMenuItemIndex global screenActive global hideHelpText global needsRender try: # If not already set, then set it. hideHelpText = hideHelpText except: hideHelpText = False term = Terminal() hotzoneLocation = [7, 0] # Top text def onResize(sig, action): global mainMenuList global currentMenuItemIndex if (screenActive): mainRender(1, mainMenuList, currentMenuItemIndex) def installHassIo(): print(term.clear()) print("Install Home Assistant Supervisor") print("./.native/hassio_supervisor.sh") res = subprocess.call("./.native/hassio_supervisor.sh", shell=True) print("") if res == 0: print( "Preinstallation complete. Your system may run slow for a few hours as Hass.io installs its services." ) print( "Press [Up] or [Down] arrow key to show the menu if it has scrolled too far." ) else: print("Preinstallation not completed.") input("Process terminated. Press [Enter] to show menu and continue.") time.sleep(0.5) return True def installRtl433(): print(term.clear()) print("Install RTL_433") print("bash ./.native/rtl_433.sh") subprocess.call("bash ./.native/rtl_433.sh", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") return True def installRpiEasy(): print(term.clear()) print("Install RPIEasy") print("bash ./.native/rpieasy.sh") subprocess.call("bash ./.native/rpieasy.sh", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") return True def installDockerAndCompose(): print(term.clear()) print("Install docker") print("Install docker-compose") print("sudo bash ./scripts/install_docker.sh install") subprocess.call("sudo bash ./scripts/install_docker.sh install", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") return True def upgradeDockerAndCompose(): print(term.clear()) print("Install docker") print("Install docker-compose") print("sudo bash ./scripts/install_docker.sh upgrade") subprocess.call("sudo bash ./scripts/install_docker.sh upgrade", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") return True def goBack(): global dockerCommandsSelectionInProgress global needsRender global screenActive screenActive = False dockerCommandsSelectionInProgress = False needsRender = 1 return True mainMenuList = [ ["Hass.io (Supervisor)", installHassIo], ["RTL_433", installRtl433], ["RPIEasy", installRpiEasy], ["Upgrade Docker and Docker-Compose", upgradeDockerAndCompose], ["Install Docker and Docker-Compose", installDockerAndCompose], ["Back", goBack] ] dockerCommandsSelectionInProgress = True currentMenuItemIndex = 0 menuNavigateDirection = 0 # Render Modes: # 0 = No render needed # 1 = Full render # 2 = Hotzone only needsRender = 1 def renderHotZone(term, menu, selection, hotzoneLocation): print(term.move(hotzoneLocation[0], hotzoneLocation[1])) lineLengthAtTextStart = 71 for (index, menuItem) in enumerate(menu): toPrint = "" if index == selection: toPrint += ( '{bv} -> {t.blue_on_green} {title} {t.normal} <-'.format( t=term, title=menuItem[0], bv=specialChars[renderMode]["borderVertical"])) else: toPrint += ('{bv} {t.normal} {title} '.format( t=term, title=menuItem[0], bv=specialChars[renderMode]["borderVertical"])) for i in range(lineLengthAtTextStart - len(menuItem[0])): toPrint += " " toPrint += "{bv}".format( bv=specialChars[renderMode]["borderVertical"]) toPrint = term.center(toPrint) print(toPrint) def mainRender(needsRender, menu, selection): term = Terminal() if needsRender == 1: print(term.clear()) print(term.move_y(6 - hotzoneLocation[0])) print(term.black_on_cornsilk4(term.center('Native Installs'))) print("") print(term.center(commonTopBorder(renderMode))) print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Select service to install {bv}" .format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) if needsRender >= 1: renderHotZone(term, menu, selection, hotzoneLocation) if needsRender == 1: print(term.center(commonEmptyLine(renderMode))) if not hideHelpText: if term.height < 30: print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Not enough vertical room to render controls help text {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) else: print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Controls: {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Up] and [Down] to move selection cursor {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [H] Show/hide this text {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Enter] to run command {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Escape] to go back to main menu {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonBottomBorder(renderMode))) def runSelection(selection): global needsRender import types if len(mainMenuList[selection]) > 1 and isinstance( mainMenuList[selection][1], types.FunctionType): mainMenuList[selection][1]() needsRender = 1 else: print( term.green_reverse( 'IOTstack Error: No function assigned to menu item: "{}"'. format(mainMenuList[selection][0]))) def isMenuItemSelectable(menu, index): if len(menu) > index: if len(menu[index]) > 2: if menu[index][2]["skip"] == True: return False return True if __name__ == 'builtins': term = Terminal() with term.fullscreen(): global screenActive screenActive = True signal.signal(signal.SIGWINCH, onResize) menuNavigateDirection = 0 mainRender(needsRender, mainMenuList, currentMenuItemIndex) dockerCommandsSelectionInProgress = True with term.cbreak(): while dockerCommandsSelectionInProgress: menuNavigateDirection = 0 if not needsRender == 0: # Only rerender when changed to prevent flickering mainRender(needsRender, mainMenuList, currentMenuItemIndex) needsRender = 0 key = term.inkey(esc_delay=0.05) if key.is_sequence: if key.name == 'KEY_TAB': menuNavigateDirection += 1 if key.name == 'KEY_DOWN': menuNavigateDirection += 1 if key.name == 'KEY_UP': menuNavigateDirection -= 1 if key.name == 'KEY_ENTER': runSelection(currentMenuItemIndex) if dockerCommandsSelectionInProgress == False: screenActive = False return True mainRender(1, mainMenuList, currentMenuItemIndex) if key.name == 'KEY_ESCAPE': screenActive = False dockerCommandsSelectionInProgress = False return True elif key: if key == 'h': # H pressed if hideHelpText: hideHelpText = False else: hideHelpText = True mainRender(1, mainMenuList, currentMenuItemIndex) if menuNavigateDirection != 0: # If a direction was pressed, find next selectable item currentMenuItemIndex += menuNavigateDirection currentMenuItemIndex = currentMenuItemIndex % len( mainMenuList) needsRender = 2 while not isMenuItemSelectable(mainMenuList, currentMenuItemIndex): currentMenuItemIndex += menuNavigateDirection currentMenuItemIndex = currentMenuItemIndex % len( mainMenuList) screenActive = False return True screenActive = False return True
def main(): """Program entry point.""" above = lambda csr, n: ( Cursor(y=max(0, csr.y - n), x=csr.x, term=csr.term)) below = lambda csr, n: ( Cursor(y=min(csr.term.height - 1, csr.y + n), x=csr.x, term=csr.term)) right_of = lambda csr, n: ( Cursor(y=csr.y, x=min(csr.term.width - 1, csr.x + n), term=csr.term)) left_of = lambda csr, n: ( Cursor(y=csr.y, x=max(0, csr.x - n), term=csr.term)) home = lambda csr: ( Cursor(y=csr.y, x=0, term=csr.term)) end = lambda csr: ( Cursor(y=csr.y, x=csr.term.width - 1, term=csr.term)) bottom = lambda csr: ( Cursor(y=csr.term.height - 1, x=csr.x, term=csr.term)) center = lambda csr: Cursor( csr.term.height // 2, csr.term.width // 2, csr.term) lookup_move = lambda inp_code, csr, term: { # arrows, including angled directionals csr.term.KEY_END: below(left_of(csr, 1), 1), csr.term.KEY_KP_1: below(left_of(csr, 1), 1), csr.term.KEY_DOWN: below(csr, 1), csr.term.KEY_KP_2: below(csr, 1), csr.term.KEY_PGDOWN: below(right_of(csr, 1), 1), csr.term.KEY_LR: below(right_of(csr, 1), 1), csr.term.KEY_KP_3: below(right_of(csr, 1), 1), csr.term.KEY_LEFT: left_of(csr, 1), csr.term.KEY_KP_4: left_of(csr, 1), csr.term.KEY_CENTER: center(csr), csr.term.KEY_KP_5: center(csr), csr.term.KEY_RIGHT: right_of(csr, 1), csr.term.KEY_KP_6: right_of(csr, 1), csr.term.KEY_HOME: above(left_of(csr, 1), 1), csr.term.KEY_KP_7: above(left_of(csr, 1), 1), csr.term.KEY_UP: above(csr, 1), csr.term.KEY_KP_8: above(csr, 1), csr.term.KEY_PGUP: above(right_of(csr, 1), 1), csr.term.KEY_KP_9: above(right_of(csr, 1), 1), # shift + arrows csr.term.KEY_SLEFT: left_of(csr, 10), csr.term.KEY_SRIGHT: right_of(csr, 10), csr.term.KEY_SDOWN: below(csr, 10), csr.term.KEY_SUP: above(csr, 10), # carriage return csr.term.KEY_ENTER: home(below(csr, 1)), }.get(inp_code, csr) term = Terminal() csr = Cursor(0, 0, term) screen = {} with term.hidden_cursor(), \ term.raw(), \ term.location(), \ term.fullscreen(), \ term.keypad(): inp = None while True: echo_yx(csr, term.reverse(screen.get((csr.y, csr.x), u' '))) inp = term.inkey() if inp == chr(3): # ^c exits break elif inp == chr(19): # ^s saves echo_yx(home(bottom(csr)), term.ljust(term.bold_white(u'Filename: '))) echo_yx(right_of(home(bottom(csr)), len(u'Filename: ')), u'') save(screen, readline(term)) echo_yx(home(bottom(csr)), term.clear_eol) redraw(term=term, screen=screen, start=home(bottom(csr)), end=end(bottom(csr))) continue elif inp == chr(12): # ^l refreshes redraw(term=term, screen=screen) else: n_csr = lookup_move(inp.code, csr, term) if n_csr != csr: # erase old cursor, echo_yx(csr, screen.get((csr.y, csr.x), u' ')) csr = n_csr elif input_filter(inp): echo_yx(csr, inp) screen[(csr.y, csr.x)] = inp.__str__() n_csr = right_of(csr, 1) if n_csr == csr: # wrap around margin n_csr = home(below(csr, 1)) csr = n_csr
def print_formatted(self, fp=sys.stdout, force_color=False, no_color=False, show_cmd=False, show_full_cmd=False, show_user=False, show_pid=False, show_fan_speed=None, show_codec="", show_power=None, gpuname_width=16, show_header=True, eol_char=os.linesep, ): # ANSI color configuration if force_color and no_color: raise ValueError("--color and --no_color can't" " be used at the same time") if force_color: TERM = os.getenv('TERM') or 'xterm-256color' t_color = Terminal(kind=TERM, force_styling=True) # workaround of issue #32 (watch doesn't recognize sgr0 characters) t_color._normal = u'\x1b[0;10m' elif no_color: t_color = Terminal(force_styling=None) else: t_color = Terminal() # auto, depending on isatty # appearance settings entry_name_width = [len(g.entry['name']) for g in self] gpuname_width = max([gpuname_width or 0] + entry_name_width) # header if show_header: if IS_WINDOWS: # no localization is available; just use a reasonable default # same as str(timestr) but without ms timestr = self.query_time.strftime('%Y-%m-%d %H:%M:%S') else: time_format = locale.nl_langinfo(locale.D_T_FMT) timestr = self.query_time.strftime(time_format) header_template = '{t.bold_white}{hostname:{width}}{t.normal} ' header_template += '{timestr} ' header_template += '{t.bold_black}{driver_version}{t.normal}' header_msg = header_template.format( hostname=self.hostname, width=gpuname_width + 3, # len("[?]") timestr=timestr, driver_version=self.driver_version, t=t_color, ) fp.write(header_msg.strip()) fp.write(eol_char) # body for g in self: g.print_to(fp, show_cmd=show_cmd, show_full_cmd=show_full_cmd, show_user=show_user, show_pid=show_pid, show_fan_speed=show_fan_speed, show_codec=show_codec, show_power=show_power, gpuname_width=gpuname_width, term=t_color) fp.write(eol_char) fp.flush()
def main(): import os import time import ruamel.yaml import signal import sys import subprocess from blessed import Terminal from deps.chars import specialChars, commonTopBorder, commonBottomBorder, commonEmptyLine, padText from deps.consts import servicesDirectory, templatesDirectory, volumesDirectory, servicesFileName, buildSettingsFileName from deps.common_functions import getExternalPorts, getInternalPorts, checkPortConflicts, enterPortNumberWithWhiptail, generateRandomString global dockerComposeServicesYaml # The loaded memory YAML of all checked services global toRun # Switch for which function to run when executed global buildHooks # Where to place the options menu result global currentServiceName # Name of the current service global issues # Returned issues dict global haltOnErrors # Turn on to allow erroring # runtime vars portConflicts = [] serviceVolume = volumesDirectory + currentServiceName serviceService = servicesDirectory + currentServiceName serviceTemplate = templatesDirectory + currentServiceName buildSettings = serviceService + buildSettingsFileName yaml = ruamel.yaml.YAML() yaml.preserve_quotes = True try: # If not already set, then set it. hideHelpText = hideHelpText except: hideHelpText = False documentationHint = 'https://sensorsiot.github.io/IOTstack/Containers/Pi-hole' # This lets the menu know whether to put " >> Options " or not # This function is REQUIRED. def checkForOptionsHook(): try: buildHooks["options"] = callable(runOptionsMenu) except: buildHooks["options"] = False return buildHooks return buildHooks # This function is REQUIRED. def checkForPreBuildHook(): try: buildHooks["preBuildHook"] = callable(preBuild) except: buildHooks["preBuildHook"] = False return buildHooks return buildHooks # This function is REQUIRED. def checkForPostBuildHook(): try: buildHooks["postBuildHook"] = callable(postBuild) except: buildHooks["postBuildHook"] = False return buildHooks return buildHooks # This function is REQUIRED. def checkForRunChecksHook(): try: buildHooks["runChecksHook"] = callable(runChecks) except: buildHooks["runChecksHook"] = False return buildHooks return buildHooks # This service will not check anything unless this is set # This function is optional, and will run each time the menu is rendered def runChecks(): checkForIssues() return [] # This function is optional, and will run after the docker-compose.yml file is written to disk. def postBuild(): return True # This function is optional, and will run just before the build docker-compose.yml code. def preBuild(): # Multi-service: with open((r'%s/' % serviceTemplate) + servicesFileName) as objServiceFile: serviceYamlTemplate = yaml.load(objServiceFile) oldBuildCache = {} try: with open(r'%s' % buildCache) as objBuildCache: oldBuildCache = yaml.load(objBuildCache) except: pass buildCacheServices = {} if "services" in oldBuildCache: buildCacheServices = oldBuildCache["services"] if not os.path.exists(serviceService): os.makedirs(serviceService, exist_ok=True) if os.path.exists(buildSettings): # Password randomisation with open(r'%s' % buildSettings) as objBuildSettingsFile: piHoleYamlBuildOptions = yaml.load(objBuildSettingsFile) if (piHoleYamlBuildOptions["databasePasswordOption"] == "Randomise password for this build" or piHoleYamlBuildOptions["databasePasswordOption"] == "Randomise database password every build" or piHoleYamlBuildOptions["databasePasswordOption"] == "Use default password for this build"): if piHoleYamlBuildOptions[ "databasePasswordOption"] == "Use default password for this build": newAdminPassword = "******" else: newAdminPassword = generateRandomString() for (index, serviceName) in enumerate(serviceYamlTemplate): dockerComposeServicesYaml[ serviceName] = serviceYamlTemplate[serviceName] if "environment" in serviceYamlTemplate[serviceName]: for (envIndex, envName) in enumerate( serviceYamlTemplate[serviceName] ["environment"]): envName = envName.replace( "%randomAdminPassword%", newAdminPassword) dockerComposeServicesYaml[serviceName][ "environment"][envIndex] = envName # Ensure you update the "Do nothing" and other 2 strings used for password settings in 'passwords.py' if (piHoleYamlBuildOptions["databasePasswordOption"] == "Randomise password for this build"): piHoleYamlBuildOptions[ "databasePasswordOption"] = "Do nothing" with open(buildSettings, 'w') as outputFile: yaml.dump(piHoleYamlBuildOptions, outputFile) else: # Do nothing - don't change password for (index, serviceName) in enumerate(buildCacheServices): if serviceName in buildCacheServices: # Load service from cache if exists (to maintain password) dockerComposeServicesYaml[ serviceName] = buildCacheServices[serviceName] else: dockerComposeServicesYaml[ serviceName] = serviceYamlTemplate[serviceName] else: print( "PiHole Warning: Build settings file not found, using default password" ) time.sleep(1) newAdminPassword = "******" for (index, serviceName) in enumerate(serviceYamlTemplate): dockerComposeServicesYaml[serviceName] = serviceYamlTemplate[ serviceName] if "environment" in serviceYamlTemplate[serviceName]: for (envIndex, envName) in enumerate( serviceYamlTemplate[serviceName]["environment"]): envName = envName.replace("%randomAdminPassword%", newAdminPassword) dockerComposeServicesYaml[serviceName]["environment"][ envIndex] = envName piHoleYamlBuildOptions = { "version": "1", "application": "IOTstack", "service": "PiHole", "comment": "PiHole Build Options" } piHoleYamlBuildOptions["databasePasswordOption"] = "Do nothing" with open(buildSettings, 'w') as outputFile: yaml.dump(piHoleYamlBuildOptions, outputFile) return True # ##################################### # Supporting functions below # ##################################### def checkForIssues(): for (index, serviceName) in enumerate(dockerComposeServicesYaml): if not currentServiceName == serviceName: # Skip self currentServicePorts = getExternalPorts( currentServiceName, dockerComposeServicesYaml) portConflicts = checkPortConflicts(serviceName, currentServicePorts, dockerComposeServicesYaml) if (len(portConflicts) > 0): issues["portConflicts"] = portConflicts ############################ # Menu Logic ############################ global currentMenuItemIndex global selectionInProgress global menuNavigateDirection global needsRender selectionInProgress = True currentMenuItemIndex = 0 menuNavigateDirection = 0 needsRender = 1 term = Terminal() hotzoneLocation = [((term.height // 16) + 6), 0] def goBack(): global selectionInProgress global needsRender selectionInProgress = False needsRender = 1 return True def setPasswordOptions(): global needsRender global hasRebuiltAddons passwordOptionsMenuFilePath = "./.templates/{currentService}/passwords.py".format( currentService=currentServiceName) with open(passwordOptionsMenuFilePath, "rb") as pythonDynamicImportFile: code = compile(pythonDynamicImportFile.read(), passwordOptionsMenuFilePath, "exec") execGlobals = { "currentServiceName": currentServiceName, "renderMode": renderMode } execLocals = {} screenActive = False exec(code, execGlobals, execLocals) signal.signal(signal.SIGWINCH, onResize) screenActive = True needsRender = 1 def enterPortNumberExec(): # global term global needsRender global dockerComposeServicesYaml externalPort = getExternalPorts(currentServiceName, dockerComposeServicesYaml)[0] internalPort = getInternalPorts(currentServiceName, dockerComposeServicesYaml)[0] newPortNumber = enterPortNumberWithWhiptail(term, dockerComposeServicesYaml, currentServiceName, hotzoneLocation, externalPort) if newPortNumber > 0: dockerComposeServicesYaml[currentServiceName]["ports"][ 0] = "{newExtPort}:{oldIntPort}".format( newExtPort=newPortNumber, oldIntPort=internalPort) createMenu() needsRender = 1 def onResize(sig, action): global piHoleBuildOptions global currentMenuItemIndex mainRender(1, piHoleBuildOptions, currentMenuItemIndex) piHoleBuildOptions = [] def createMenu(): global piHoleBuildOptions try: piHoleBuildOptions = [] portNumber = getExternalPorts(currentServiceName, dockerComposeServicesYaml)[0] piHoleBuildOptions.append([ "Change external WUI Port Number from: {port}".format( port=portNumber), enterPortNumberExec ]) except: # Error getting port pass piHoleBuildOptions.append( ["PiHole Password Options", setPasswordOptions]) piHoleBuildOptions.append(["Go back", goBack]) def runOptionsMenu(): createMenu() menuEntryPoint() return True def renderHotZone(term, menu, selection, hotzoneLocation): lineLengthAtTextStart = 71 print(term.move(hotzoneLocation[0], hotzoneLocation[1])) for (index, menuItem) in enumerate(menu): toPrint = "" if index == selection: toPrint += ( '{bv} -> {t.blue_on_green} {title} {t.normal} <-'.format( t=term, title=menuItem[0], bv=specialChars[renderMode]["borderVertical"])) else: toPrint += ('{bv} {t.normal} {title} '.format( t=term, title=menuItem[0], bv=specialChars[renderMode]["borderVertical"])) for i in range(lineLengthAtTextStart - len(menuItem[0])): toPrint += " " toPrint += "{bv}".format( bv=specialChars[renderMode]["borderVertical"]) toPrint = term.center(toPrint) print(toPrint) def mainRender(needsRender, menu, selection): term = Terminal() if needsRender == 1: print(term.clear()) print(term.move_y(term.height // 16)) print( term.black_on_cornsilk4( term.center('IOTstack PiHole Options'))) print("") print(term.center(commonTopBorder(renderMode))) print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Select Option to configure {bv}" .format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) if needsRender >= 1: renderHotZone(term, menu, selection, hotzoneLocation) if needsRender == 1: print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) if not hideHelpText: print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Controls: {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print( term.center( "{bv} [Up] and [Down] to move selection cursor {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print( term.center( "{bv} [H] Show/hide this text {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print( term.center( "{bv} [Enter] to run command or save input {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print( term.center( "{bv} [Escape] to go back to build stack menu {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) if len(documentationHint) > 1: if len(documentationHint) > 56: documentationAndPadding = padText( documentationHint, 71) print( term.center( "{bv} Documentation: {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center("{bv} {dap} {bv}".format( bv=specialChars[renderMode]["borderVertical"], dap=documentationAndPadding))) else: documentationAndPadding = padText( documentationHint, 56) print( term.center( "{bv} Documentation: {dap} {bv}".format( bv=specialChars[renderMode] ["borderVertical"], dap=documentationAndPadding))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonBottomBorder(renderMode))) def runSelection(selection): import types global piHoleBuildOptions if len(piHoleBuildOptions[selection]) > 1 and isinstance( piHoleBuildOptions[selection][1], types.FunctionType): piHoleBuildOptions[selection][1]() else: print( term.green_reverse( 'IOTstack Error: No function assigned to menu item: "{}"'. format(nodeRedBuildOptions[selection][0]))) def isMenuItemSelectable(menu, index): if len(menu) > index: if len(menu[index]) > 2: if menu[index][2]["skip"] == True: return False return True def menuEntryPoint(): # These need to be reglobalised due to eval() global currentMenuItemIndex global selectionInProgress global menuNavigateDirection global needsRender global hideHelpText global piHoleBuildOptions term = Terminal() with term.fullscreen(): menuNavigateDirection = 0 mainRender(needsRender, piHoleBuildOptions, currentMenuItemIndex) selectionInProgress = True with term.cbreak(): while selectionInProgress: menuNavigateDirection = 0 if needsRender: # Only rerender when changed to prevent flickering mainRender(needsRender, piHoleBuildOptions, currentMenuItemIndex) needsRender = 0 key = term.inkey(esc_delay=0.05) if key.is_sequence: if key.name == 'KEY_TAB': menuNavigateDirection += 1 if key.name == 'KEY_DOWN': menuNavigateDirection += 1 if key.name == 'KEY_UP': menuNavigateDirection -= 1 if key.name == 'KEY_LEFT': goBack() if key.name == 'KEY_ENTER': runSelection(currentMenuItemIndex) if key.name == 'KEY_ESCAPE': return True elif key: if key == 'h': # H pressed if hideHelpText: hideHelpText = False else: hideHelpText = True mainRender(1, piHoleBuildOptions, currentMenuItemIndex) if menuNavigateDirection != 0: # If a direction was pressed, find next selectable item currentMenuItemIndex += menuNavigateDirection currentMenuItemIndex = currentMenuItemIndex % len( piHoleBuildOptions) needsRender = 2 while not isMenuItemSelectable(piHoleBuildOptions, currentMenuItemIndex): currentMenuItemIndex += menuNavigateDirection currentMenuItemIndex = currentMenuItemIndex % len( piHoleBuildOptions) return True #################### # End menu section #################### if haltOnErrors: eval(toRun)() else: try: eval(toRun)() except: pass
def center_multiline_string(multiline_string): # need to split into multiple lines first for string in multiline_string.splitlines(): print(Terminal().center(string))
def __init__(self, *a, **kw): self.term = Terminal() self.position = 0 self.routers = [] super(BrowseRouters, self).__init__(*a, **kw)
def __init__(self): from blessed import Terminal t = Terminal() self.cursor_color = t.color(196) self.cursor_str = s.rarrow self.cursorPosition = 1
def show_divider_line(): print(Terminal().center( "============================================================"))
from blessed import Terminal t = Terminal() class Symbol: def __init__(self): self.heart = u"\u2665" self.larrow = u"\u2190" self.rarrow = u"\u2B95" self.darrow = u"\u2193" self.uarrow = u"\u2191" s = Symbol() class Menu: def __init__(self): from blessed import Terminal t = Terminal() self.cursor_color = t.color(196) self.cursor_str = s.rarrow self.cursorPosition = 1 def refreshCursor(self): self.cursorPosition = 1 def cls(self): import os os.system("clear") def vert(self, title, *content): with t.hidden_cursor(): while True: self.cls() #clears the screen self.iteration = 0 #this attribute holds the choice # in the menu print(title) #prints out the menu title for msg in content: self.iteration += 1 #increments to the next iteration if self.iteration == self.cursorPosition: #check if the cursor position matches the choice #
def main(): from blessed import Terminal from deps.chars import specialChars, commonTopBorder, commonBottomBorder, commonEmptyLine import math import time import subprocess global dockerCommandsSelectionInProgress global renderMode global signal global mainMenuList global currentMenuItemIndex global hideHelpText try: # If not already set, then set it. hideHelpText = hideHelpText except: hideHelpText = False term = Terminal() hotzoneLocation = [7, 0] # Top text def onResize(sig, action): global mainMenuList global currentMenuItemIndex mainRender(1, mainMenuList, currentMenuItemIndex) def startStack(): print("Start Stack:") print("docker-compose up -d --remove-orphans") subprocess.call("docker-compose up -d", shell=True) print("") print("Stack Started") input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def restartStack(): print("Restarting Stack...") print("Stop Stack:") print("docker-compose down") subprocess.call("docker-compose down", shell=True) print("") print("Start Stack:") print("docker-compose up -d --remove-orphans") subprocess.call("docker-compose up -d", shell=True) # print("docker-compose restart") # subprocess.call("docker-compose restart", shell=True) print("") print("Stack Restarted") input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def stopStack(): print("Stop Stack:") print("docker-compose down") subprocess.call("docker-compose down", shell=True) print("") print("Stack Stopped") input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def stopAllStack(): print("Stop All Stack:") print("docker container stop $(docker container ls -aq)") subprocess.call("docker container stop $(docker container ls -aq)", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def pruneVolumes(): print("Stop All Stack:") print("docker container stop $(docker container ls -aq)") subprocess.call("docker container stop $(docker container ls -aq)", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def updateAllContainers(): print("Update All Containers:") print("docker-compose down") subprocess.call("docker-compose down", shell=True) print("") print("docker-compose pull") subprocess.call("docker-compose pull", shell=True) print("") print("docker-compose build") subprocess.call("docker-compose build", shell=True) print("") print("docker-compose up -d") subprocess.call("docker-compose up -d", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def deleteAndPruneVolumes(): print("Delete and prune volumes:") print("docker system prune --volumes") subprocess.call("docker system prune --volumes", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def deleteAndPruneImages(): print("Delete and prune volumes:") print("docker image prune -a") subprocess.call("docker image prune -a", shell=True) print("") input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def monitorLogs(): print("Monitor Logs:") print("Press CTRL+X or CTRL+C to exit.") time.sleep(2) print("") print("docker-compose logs -f") time.sleep(0.5) subprocess.call("docker-compose logs -f", shell=True) print("") time.sleep(0.5) input("Process terminated. Press [Enter] to show menu and continue.") needsRender = 1 return True def goBack(): global dockerCommandsSelectionInProgress global needsRender dockerCommandsSelectionInProgress = False needsRender = 1 return True mainMenuList = [ ["Start stack", startStack], ["Restart stack", restartStack], ["Stop stack", stopStack], ["Monitor Logs", monitorLogs], ["Stop ALL running docker containers", stopAllStack], ["Update all containers (may take a long time)", updateAllContainers], [ "Delete all stopped containers and docker volumes (prune volumes)", deleteAndPruneVolumes ], [ "Delete all images not associated with container", deleteAndPruneImages ], ["Back", goBack] ] dockerCommandsSelectionInProgress = True currentMenuItemIndex = 0 menuNavigateDirection = 0 # Render Modes: # 0 = No render needed # 1 = Full render # 2 = Hotzone only needsRender = 1 def renderHotZone(term, menu, selection, hotzoneLocation): print(term.move(hotzoneLocation[0], hotzoneLocation[1])) lineLengthAtTextStart = 71 for (index, menuItem) in enumerate(menu): toPrint = "" if index == selection: toPrint += ( '{bv} -> {t.blue_on_green} {title} {t.normal} <-'.format( t=term, title=menuItem[0], bv=specialChars[renderMode]["borderVertical"])) else: toPrint += ('{bv} {t.normal} {title} '.format( t=term, title=menuItem[0], bv=specialChars[renderMode]["borderVertical"])) for i in range(lineLengthAtTextStart - len(menuItem[0])): toPrint += " " toPrint += "{bv}".format( bv=specialChars[renderMode]["borderVertical"]) toPrint = term.center(toPrint) print(toPrint) def mainRender(needsRender, menu, selection): term = Terminal() if needsRender == 1: print(term.clear()) print(term.clear()) print(term.move_y(6 - hotzoneLocation[0])) print( term.black_on_cornsilk4( term.center('IOTstack Docker Commands'))) print("") print(term.center(commonTopBorder(renderMode))) print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Select Docker Command to run {bv}" .format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) if needsRender >= 1: renderHotZone(term, menu, selection, hotzoneLocation) if needsRender == 1: print(term.center(commonEmptyLine(renderMode))) if not hideHelpText: if term.height < 30: print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Not enough vertical room to render controls help text {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) else: print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Controls: {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Up] and [Down] to move selection cursor {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [H] Show/hide this text {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Enter] to run command {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Escape] to go back to main menu {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonBottomBorder(renderMode))) def runSelection(selection): import types if len(mainMenuList[selection]) > 1 and isinstance( mainMenuList[selection][1], types.FunctionType): mainMenuList[selection][1]() mainRender(1, mainMenuList, currentMenuItemIndex) else: print( term.green_reverse( 'IOTstack Error: No function assigned to menu item: "{}"'. format(mainMenuList[selection][0]))) def isMenuItemSelectable(menu, index): if len(menu) > index: if len(menu[index]) > 2: if menu[index][2]["skip"] == True: return False return True if __name__ == 'builtins': term = Terminal() signal.signal(signal.SIGWINCH, onResize) with term.fullscreen(): menuNavigateDirection = 0 mainRender(needsRender, mainMenuList, currentMenuItemIndex) dockerCommandsSelectionInProgress = True with term.cbreak(): while dockerCommandsSelectionInProgress: menuNavigateDirection = 0 if not needsRender == 0: # Only rerender when changed to prevent flickering mainRender(needsRender, mainMenuList, currentMenuItemIndex) needsRender = 0 key = term.inkey(esc_delay=0.05) if key.is_sequence: if key.name == 'KEY_TAB': menuNavigateDirection += 1 if key.name == 'KEY_DOWN': menuNavigateDirection += 1 if key.name == 'KEY_UP': menuNavigateDirection -= 1 if key.name == 'KEY_ENTER': mainRender(1, mainMenuList, currentMenuItemIndex) runSelection(currentMenuItemIndex) if dockerCommandsSelectionInProgress == False: return True if key.name == 'KEY_ESCAPE': dockerCommandsSelectionInProgress = False return True elif key: if key == 'h': # H pressed if hideHelpText: hideHelpText = False else: hideHelpText = True mainRender(1, mainMenuList, currentMenuItemIndex) if menuNavigateDirection != 0: # If a direction was pressed, find next selectable item currentMenuItemIndex += menuNavigateDirection currentMenuItemIndex = currentMenuItemIndex % len( mainMenuList) needsRender = 2 while not isMenuItemSelectable(mainMenuList, currentMenuItemIndex): currentMenuItemIndex += menuNavigateDirection currentMenuItemIndex = currentMenuItemIndex % len( mainMenuList) return True return True
import sys import dns.resolver import requests import logging from blessed import Terminal from tqdm import tqdm from modules import orca_helpers blessed_t = Terminal() def enumerate_bgp_domain(orca_dbconn, domain): url = "https://api.bgpview.io/search?query_term={}".format(domain.split('.')[0]) source = "bgpview" asset_type = "cidr" res = requests.get(url) if res.status_code == 200: json_results = res.json() for result in json_results['data']['ipv4_prefixes']: email_addrs = [] for email_addr in result['email_contacts']: if domain in email_addr: email_addrs.append(email_addr) asset = result['prefix'] print("Prefix: {}".format(asset)) print("Email addrs: {}".format(','.join(email_addrs))) if orca_helpers.is_cidr(asset):
def memory(run_once=False, workers=False, broker=None): if not broker: broker = get_broker() term = Terminal() broker.ping() if not psutil: print(term.clear_eos()) print( term.white_on_red( "Cannot start \"qmemory\" command. Missing \"psutil\" library." )) return with term.fullscreen(), term.hidden_cursor(), term.cbreak(): MEMORY_AVAILABLE_LOWEST_PERCENTAGE = 100.0 MEMORY_AVAILABLE_LOWEST_PERCENTAGE_AT = timezone.now() cols = 8 val = None start_width = int(term.width / cols) while val not in ["q", "Q"]: col_width = int(term.width / cols) # In case of resize if col_width != start_width: print(term.clear()) start_width = col_width # sentinel, monitor and workers memory usage print( term.move(0, 0 * col_width) + term.black_on_green(term.center(_("Host"), width=col_width - 1))) print( term.move(0, 1 * col_width) + term.black_on_green(term.center(_("Id"), width=col_width - 1))) print( term.move(0, 2 * col_width) + term.black_on_green( term.center(_("Available (%)"), width=col_width - 1))) print( term.move(0, 3 * col_width) + term.black_on_green( term.center(_("Available (MB)"), width=col_width - 1))) print( term.move(0, 4 * col_width) + term.black_on_green( term.center(_("Total (MB)"), width=col_width - 1))) print( term.move(0, 5 * col_width) + term.black_on_green( term.center(_("Sentinel (MB)"), width=col_width - 1))) print( term.move(0, 6 * col_width) + term.black_on_green( term.center(_("Monitor (MB)"), width=col_width - 1))) print( term.move(0, 7 * col_width) + term.black_on_green( term.center(_("Workers (MB)"), width=col_width - 1))) row = 2 stats = Stat.get_all(broker=broker) print(term.clear_eos()) for stat in stats: # memory available (%) memory_available_percentage = round( psutil.virtual_memory().available * 100 / psutil.virtual_memory().total, 2) # memory available (MB) memory_available = round( psutil.virtual_memory().available / 1024**2, 2) if memory_available_percentage < MEMORY_AVAILABLE_LOWEST_PERCENTAGE: MEMORY_AVAILABLE_LOWEST_PERCENTAGE = memory_available_percentage MEMORY_AVAILABLE_LOWEST_PERCENTAGE_AT = timezone.now() print( term.move(row, 0 * col_width) + term.center(stat.host[:col_width - 1], width=col_width - 1)) print( term.move(row, 1 * col_width) + term.center(str(stat.cluster_id)[-8:], width=col_width - 1)) print( term.move(row, 2 * col_width) + term.center( memory_available_percentage, width=col_width - 1)) print( term.move(row, 3 * col_width) + term.center(memory_available, width=col_width - 1)) print( term.move(row, 4 * col_width) + term.center(round(psutil.virtual_memory().total / 1024**2, 2), width=col_width - 1)) print( term.move(row, 5 * col_width) + term.center( get_process_mb(stat.sentinel), width=col_width - 1)) print( term.move(row, 6 * col_width) + term.center(get_process_mb(getattr(stat, 'monitor', None)), width=col_width - 1)) workers_mb = 0 for worker_pid in stat.workers: result = get_process_mb(worker_pid) if isinstance(result, str): result = 0 workers_mb += result print( term.move(row, 7 * col_width) + term.center(workers_mb or 'NO_PROCESSES_FOUND', width=col_width - 1)) row += 1 # each worker's memory usage if workers: row += 2 col_width = int(term.width / (1 + Conf.WORKERS)) print( term.move(row, 0 * col_width) + term.black_on_cyan( term.center(_("Id"), width=col_width - 1))) for worker_num in range(Conf.WORKERS): print( term.move(row, (worker_num + 1) * col_width) + term.black_on_cyan( term.center("Worker #{} (MB)".format(worker_num + 1), width=col_width - 1))) row += 2 for stat in stats: print( term.move(row, 0 * col_width) + term.center( str(stat.cluster_id)[-8:], width=col_width - 1)) for idx, worker_pid in enumerate(stat.workers): mb_used = get_process_mb(worker_pid) print( term.move(row, (idx + 1) * col_width) + term.center(mb_used, width=col_width - 1)) row += 1 row += 1 print( term.move(row, 0) + _("Available lowest (%): {} ({})").format( str(MEMORY_AVAILABLE_LOWEST_PERCENTAGE), MEMORY_AVAILABLE_LOWEST_PERCENTAGE_AT.strftime( '%Y-%m-%d %H:%M:%S+00:00'))) # for testing if run_once: return Stat.get_all(broker=broker) print(term.move(row + 2, 0) + term.center("[Press q to quit]")) val = term.inkey(timeout=1)
def test_turn_off_colors(self, mock_user_conf): mock_user_conf.return_value = {'COLOR': '0'} stream = StringIO() _out('Hello world', None, Terminal().red, stream) self.assertEquals('Hello world\n', stream.getvalue())
def print_to(self, fp, with_colors=True, # deprecated arg show_cmd=False, show_full_cmd=False, show_user=False, show_pid=False, show_fan_speed=None, show_codec="", show_power=None, gpuname_width=16, term=None, ): if term is None: term = Terminal(stream=sys.stdout) # color settings colors = {} def _conditional(cond_fn, true_value, false_value, error_value=term.bold_black): try: return cond_fn() and true_value or false_value except Exception: return error_value _ENC_THRESHOLD = 50 colors['C0'] = term.normal colors['C1'] = term.cyan colors['CBold'] = term.bold colors['CName'] = term.blue colors['CTemp'] = _conditional(lambda: self.temperature < 50, term.red, term.bold_red) colors['FSpeed'] = _conditional(lambda: self.fan_speed < 30, term.cyan, term.bold_cyan) colors['CMemU'] = term.bold_yellow colors['CMemT'] = term.yellow colors['CMemP'] = term.yellow colors['CCPUMemU'] = term.yellow colors['CUser'] = term.bold_black # gray colors['CUtil'] = _conditional(lambda: self.utilization < 30, term.green, term.bold_green) colors['CUtilEnc'] = _conditional( lambda: self.utilization_enc < _ENC_THRESHOLD, term.green, term.bold_green) colors['CUtilDec'] = _conditional( lambda: self.utilization_dec < _ENC_THRESHOLD, term.green, term.bold_green) colors['CCPUUtil'] = term.green colors['CPowU'] = _conditional( lambda: (self.power_limit is not None and float(self.power_draw) / self.power_limit < 0.4), term.magenta, term.bold_magenta ) colors['CPowL'] = term.magenta colors['CCmd'] = term.color(24) # a bit dark if not with_colors: for k in list(colors.keys()): colors[k] = '' def _repr(v, none_value='??'): return none_value if v is None else v # build one-line display information # we want power use optional, but if deserves being grouped with # temperature and utilization reps = u"%(C1)s[{entry[index]}]%(C0)s " \ "%(CName)s{entry[name]:{gpuname_width}}%(C0)s |" \ "%(CTemp)s{entry[temperature.gpu]:>3}°C%(C0)s, " if show_fan_speed: reps += "%(FSpeed)s{entry[fan.speed]:>3} %%%(C0)s, " reps += "%(CUtil)s{entry[utilization.gpu]:>3} %%%(C0)s" if show_codec: codec_info = [] if "enc" in show_codec: codec_info.append( "%(CBold)sE: %(C0)s" "%(CUtilEnc)s{entry[utilization.enc]:>3} %%%(C0)s") if "dec" in show_codec: codec_info.append( "%(CBold)sD: %(C0)s" "%(CUtilDec)s{entry[utilization.dec]:>3} %%%(C0)s") reps += " ({})".format(" ".join(codec_info)) if show_power: reps += ", %(CPowU)s{entry[power.draw]:>3}%(C0)s " if show_power is True or 'limit' in show_power: reps += "/ %(CPowL)s{entry[enforced.power.limit]:>3}%(C0)s " reps += "%(CPowL)sW%(C0)s" else: reps += "%(CPowU)sW%(C0)s" reps += " | %(C1)s%(CMemU)s{entry[memory.used]:>5}%(C0)s " \ "/ %(CMemT)s{entry[memory.total]:>5}%(C0)s MB" reps = (reps) % colors reps = reps.format(entry={k: _repr(v) for k, v in self.entry.items()}, gpuname_width=gpuname_width) reps += " |" def process_repr(p): r = '' if not show_cmd or show_user: r += "{CUser}{}{C0}".format( _repr(p['username'], '--'), **colors ) if show_cmd: if r: r += ':' r += "{C1}{}{C0}".format( _repr(p.get('command', p['pid']), '--'), **colors ) if show_pid: r += ("/%s" % _repr(p['pid'], '--')) r += '({CMemP}{}M{C0})'.format( _repr(p['gpu_memory_usage'], '?'), **colors ) return r def full_process_info(p): r = "{C0} ├─ {:>6} ".format( _repr(p['pid'], '--'), **colors ) r += "{C0}({CCPUUtil}{:4.0f}%{C0}, {CCPUMemU}{:>6}{C0})".format( _repr(p['cpu_percent'], '--'), util.bytes2human(_repr(p['cpu_memory_usage'], 0)), **colors ) full_command_pretty = util.prettify_commandline( p['full_command'], colors['C1'], colors['CCmd']) r += "{C0}: {CCmd}{}{C0}".format( _repr(full_command_pretty, '?'), **colors ) return r processes = self.entry['processes'] full_processes = [] if processes is None: # None (not available) reps += ' ({})'.format(NOT_SUPPORTED) else: for p in processes: reps += ' ' + process_repr(p) if show_full_cmd: full_processes.append(os.linesep + full_process_info(p)) if show_full_cmd and full_processes: full_processes[-1] = full_processes[-1].replace('├', '└', 1) reps += ''.join(full_processes) fp.write(reps) return fp
def test_colors(self, mock_user_conf): mock_user_conf.return_value = {} stream = StringIO() _out('Hello world', None, Terminal().red, stream) # RHEL 6 doesn't have self.assertRegexpMatches unfortunately self.assertTrue(re.match('.+Hello world.+\n', stream.getvalue()))
def mainRender(needsRender, menu, selection): term = Terminal() if needsRender == 1: print(term.clear()) print(term.move_y(term.height // 16)) print( term.black_on_cornsilk4( term.center('IOTstack PiHole Options'))) print("") print(term.center(commonTopBorder(renderMode))) print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Select Option to configure {bv}" .format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) if needsRender >= 1: renderHotZone(term, menu, selection, hotzoneLocation) if needsRender == 1: print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) if not hideHelpText: print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Controls: {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print( term.center( "{bv} [Up] and [Down] to move selection cursor {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print( term.center( "{bv} [H] Show/hide this text {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print( term.center( "{bv} [Enter] to run command or save input {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print( term.center( "{bv} [Escape] to go back to build stack menu {bv}" .format( bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) if len(documentationHint) > 1: if len(documentationHint) > 56: documentationAndPadding = padText( documentationHint, 71) print( term.center( "{bv} Documentation: {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center("{bv} {dap} {bv}".format( bv=specialChars[renderMode]["borderVertical"], dap=documentationAndPadding))) else: documentationAndPadding = padText( documentationHint, 56) print( term.center( "{bv} Documentation: {dap} {bv}".format( bv=specialChars[renderMode] ["borderVertical"], dap=documentationAndPadding))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonBottomBorder(renderMode)))
from blessed import Terminal from sys import stdout, exit from time import sleep import readchar import random import os terminal = Terminal() vanilla_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "texts", "vanilla") vanilla_file = open(vanilla_path, "r") vanilla_text = vanilla_file.read() vanilla_file.close() vanilla = vanilla_text.split("\n") board_items = [] board_size = (32, 32) board_colors = [ ] def vanilla_pick(): return random.choice(vanilla) def clear(): stdout.write(terminal.clear) def home():
def mainRender(needsRender, menu, selection): term = Terminal() if needsRender == 1: print(term.clear()) print(term.move_y(6 - hotzoneLocation[0])) print(term.black_on_cornsilk4(term.center('Native Installs'))) print("") print(term.center(commonTopBorder(renderMode))) print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Select service to install {bv}" .format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) if needsRender >= 1: renderHotZone(term, menu, selection, hotzoneLocation) if needsRender == 1: print(term.center(commonEmptyLine(renderMode))) if not hideHelpText: if term.height < 30: print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Not enough vertical room to render controls help text {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) else: print(term.center(commonEmptyLine(renderMode))) print( term.center( "{bv} Controls: {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Up] and [Down] to move selection cursor {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [H] Show/hide this text {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Enter] to run command {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print( term.center( "{bv} [Escape] to go back to main menu {bv}" .format(bv=specialChars[renderMode] ["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonBottomBorder(renderMode)))
def __init__(self, n_epochs, train_size, valid_size=0, train_bar_size=2, valid_bar_size=2): """ Parameters ---------- n_epochs: int number of epochs train_size: int number of training iterations valid_size:int number of validation iterations train_bar_size: int height of training bar valid_bar_size: int height of valid bar Examples -------------- Command Line: TermLogger(epochs=10,train_size=200,valid_size=100, train_bar_size=3, valid_bar_size=2) [Space] Epoch_bar Line [Space] Train_Writer Line Train_bar Line [Space] Valid_Writer Line Valid_bar Line [Space] """ if valid_size > 0: assert valid_bar_size >= 2 assert train_bar_size >= 2 self.n_epochs = n_epochs self.train_size = train_size self.valid_size = valid_size self.terminal = Terminal() self.t_height = self.terminal.height epoch_bar_size = 1 block_size = epoch_bar_size + train_bar_size + 3 if valid_size > 0: block_size += valid_bar_size + 1 block_begin = self.terminal.height - block_size - 1 epoch_bar_begin = block_begin + epoch_bar_size train_writer_begin = epoch_bar_begin + 2 train_bar_begin = train_writer_begin + train_bar_size - 1 valid_writer_begin = train_bar_begin + 2 valid_bar_begin = valid_writer_begin + valid_bar_size - 1 # create block for i in range(block_size): print('') widgets = [ 'Epochs:', SimpleProgress(), ' ', Bar('#'), ' ', Timer(), ' ', ETA(format='ETA: %(eta)8s') ] self.epoch_bar = ProgressBar(widgets=widgets, max_value=n_epochs, fd=Writer(self.terminal, (0, epoch_bar_begin))) # epoch self.train_writer = Writer(self.terminal, (0, train_writer_begin)) # loss self.train_bar_writer = Writer(self.terminal, (0, train_bar_begin)) # batch self.reset_train_bar() if self.valid_size > 0: self.valid_writer = Writer(self.terminal, (0, valid_writer_begin)) # error self.valid_bar_writer = Writer(self.terminal, (0, valid_bar_begin)) # batch self.reset_valid_bar() self.epoch_bar.start()
def main(): t = Terminal() # Prelude logger.info("----------------------------------") logger.info("Starting new run.") logger.info("Datetime: %s", datetime.datetime.now().isoformat()) logger.info("Revision: %s", os.getenv('REVISION')) logger.info("Terminal colors: %d", t.number_of_colors) logger.info("Terminal size: %dx%d", t.width, t.height) logger.info("----------------------------------") # # Create the world map_dimensions = (20, 12) if t.width < map_dimensions[0] or t.height < map_dimensions[1]: logger.fatal("Terminal too small: Must be at least %dx%d in size.", map_dimensions[0], map_dimensions[1]) sys.exit(1) game_map = GameMap(map_dimensions[0], map_dimensions[1]) game_map.make_map() fov_map = initialize_fov(game_map) entities = [ Entity(4, 4, '@', 'Player', FormattingString(t.red, t.normal), fighter=Fighter(hp=30, defense=2, power=5)), Entity(map_dimensions[0] // 2 + 5, map_dimensions[1] // 2 - 2, '$', 'Mysterious Object', FormattingString(t.yellow, t.normal)), Entity(3, 3, '%', 'Crate', FormattingString(t.blue, t.normal), pushable=True), Entity(10, 5, 'o', 'Goblin', FormattingString(t.green, t.normal), fighter=Fighter(hp=16, defense=1, power=3), ai=BasicMonster()) ] # Ready the screen for drawing print(t.enter_fullscreen()) with t.hidden_cursor(): # Handle input immediately with t.cbreak(): # Enter the main game loop game_loop(t, game_map, entities, fov_map) print(t.exit_fullscreen())
#Donsol game import random import math import time from blessed import Terminal TERM = Terminal() class Card: def __init__(self, suit, value, name=None): self.suit = suit self.name = name or suit self.value = value class Player: def __init__(self): self.max_health = 21 self.health = self.max_health self.shield = None self.can_drink_potion = True self.escaped_last_room = False self.last_monster_value = None #Build Deck # x2, clubs and spades heartCards = [ { 'value': 2,
def info(broker=None): if not broker: broker = get_broker() term = Terminal() broker.ping() stat = Stat.get_all(broker=broker) # general stats clusters = len(stat) workers = 0 reincarnations = 0 for cluster in stat: workers += len(cluster.workers) reincarnations += cluster.reincarnations # calculate tasks pm and avg exec time tasks_per = 0 per = _('day') exec_time = 0 last_tasks = models.Success.objects.filter(stopped__gte=timezone.now() - timedelta(hours=24)) tasks_per_day = last_tasks.count() if tasks_per_day > 0: # average execution time over the last 24 hours if not connection.vendor == 'sqlite': exec_time = last_tasks.aggregate(time_taken=Sum(F('stopped') - F('started'), output_field=FloatField())) exec_time = exec_time['time_taken'] / tasks_per_day else: # can't sum timedeltas on sqlite for t in last_tasks: exec_time += t.time_taken() exec_time = exec_time / tasks_per_day # tasks per second/minute/hour/day in the last 24 hours if tasks_per_day > 24 * 60 * 60: tasks_per = tasks_per_day / (24 * 60 * 60) per = _('second') elif tasks_per_day > 24 * 60: tasks_per = tasks_per_day / (24 * 60) per = _('minute') elif tasks_per_day > 24: tasks_per = tasks_per_day / 24 per = _('hour') else: tasks_per = tasks_per_day # print to terminal print(term.clear_eos()) col_width = int(term.width / 6) print(term.black_on_green( term.center( _('-- {} {} on {} --').format(Conf.PREFIX.capitalize(), '.'.join(str(v) for v in VERSION), broker.info())))) print(term.cyan(_('Clusters')) + term.move_x(1 * col_width) + term.white(str(clusters)) + term.move_x(2 * col_width) + term.cyan(_('Workers')) + term.move_x(3 * col_width) + term.white(str(workers)) + term.move_x(4 * col_width) + term.cyan(_('Restarts')) + term.move_x(5 * col_width) + term.white(str(reincarnations)) ) print(term.cyan(_('Queued')) + term.move_x(1 * col_width) + term.white(str(broker.queue_size())) + term.move_x(2 * col_width) + term.cyan(_('Successes')) + term.move_x(3 * col_width) + term.white(str(models.Success.objects.count())) + term.move_x(4 * col_width) + term.cyan(_('Failures')) + term.move_x(5 * col_width) + term.white(str(models.Failure.objects.count())) ) print(term.cyan(_('Schedules')) + term.move_x(1 * col_width) + term.white(str(models.Schedule.objects.count())) + term.move_x(2 * col_width) + term.cyan(_('Tasks/{}'.format(per))) + term.move_x(3 * col_width) + term.white('{0:.2f}'.format(tasks_per)) + term.move_x(4 * col_width) + term.cyan(_('Avg time')) + term.move_x(5 * col_width) + term.white('{0:.4f}'.format(exec_time)) ) return True
def child(): from blessed.sequences import Sequence from blessed import Terminal term = Terminal('xterm-256color') assert Sequence('xyz\b', term).padd() == u'xy' assert Sequence('xxxx\x1b[3Dzz', term).padd() == u'xzz'
import uuid import threading import websocket from blessed import Terminal from string import printable sysid = str(uuid.uuid1(uuid.getnode(), 0))[24:] term = Terminal() print(term.clear + 'ss2 client proto') class Client: def __init__(self): self.ws = websocket.WebSocketApp(f'ws://127.0.0.1:1337/test/{sysid}', on_message=self.on_message) self.ws.on_open = self.on_open @staticmethod def on_message(ws, message): with term.location(0, 5): print(f'RECV: {message}', end='') @staticmethod def on_open(ws): t = threading.Thread(target=doitup, args=(ws, )) t.daemon = True t.start() def doitup(ws):
def info(broker=None): if not broker: broker = get_broker() term = Terminal() broker.ping() stat = Stat.get_all(broker=broker) # general stats clusters = len(stat) workers = 0 reincarnations = 0 for cluster in stat: workers += len(cluster.workers) reincarnations += cluster.reincarnations # calculate tasks pm and avg exec time tasks_per = 0 per = _("day") exec_time = 0 last_tasks = models.Success.objects.filter(stopped__gte=timezone.now() - timedelta(hours=24)) tasks_per_day = last_tasks.count() if tasks_per_day > 0: # average execution time over the last 24 hours if connection.vendor != "sqlite": exec_time = last_tasks.aggregate( time_taken=Sum(F("stopped") - F("started"))) exec_time = exec_time["time_taken"].total_seconds() / tasks_per_day else: # can't sum timedeltas on sqlite for t in last_tasks: exec_time += t.time_taken() exec_time = exec_time / tasks_per_day # tasks per second/minute/hour/day in the last 24 hours if tasks_per_day > 24 * 60 * 60: tasks_per = tasks_per_day / (24 * 60 * 60) per = _("second") elif tasks_per_day > 24 * 60: tasks_per = tasks_per_day / (24 * 60) per = _("minute") elif tasks_per_day > 24: tasks_per = tasks_per_day / 24 per = _("hour") else: tasks_per = tasks_per_day # print to terminal print(term.clear_eos()) col_width = int(term.width / 6) print( term.black_on_green( term.center( _(f'-- {Conf.PREFIX.capitalize()} { ".".join(str(v) for v in VERSION)} on {broker.info()} --' )))) print( term.cyan(_("Clusters")) + term.move_x(1 * col_width) + term.white(str(clusters)) + term.move_x(2 * col_width) + term.cyan(_("Workers")) + term.move_x(3 * col_width) + term.white(str(workers)) + term.move_x(4 * col_width) + term.cyan(_("Restarts")) + term.move_x(5 * col_width) + term.white(str(reincarnations))) print( term.cyan(_("Queued")) + term.move_x(1 * col_width) + term.white(str(broker.queue_size())) + term.move_x(2 * col_width) + term.cyan(_("Successes")) + term.move_x(3 * col_width) + term.white(str(models.Success.objects.count())) + term.move_x(4 * col_width) + term.cyan(_("Failures")) + term.move_x(5 * col_width) + term.white(str(models.Failure.objects.count()))) print( term.cyan(_("Schedules")) + term.move_x(1 * col_width) + term.white(str(models.Schedule.objects.count())) + term.move_x(2 * col_width) + term.cyan(_(f"Tasks/{per}")) + term.move_x(3 * col_width) + term.white(f"{tasks_per:.2f}") + term.move_x(4 * col_width) + term.cyan(_("Avg time")) + term.move_x(5 * col_width) + term.white(f"{exec_time:.4f}")) return True
def main(): import os import time import ruamel.yaml import signal import sys from blessed import Terminal from deps.chars import specialChars, commonTopBorder, commonBottomBorder, commonEmptyLine, padText from deps.consts import servicesDirectory, templatesDirectory from deps.common_functions import getExternalPorts, getInternalPorts, checkPortConflicts, enterPortNumberWithWhiptail yaml = ruamel.yaml.YAML() yaml.preserve_quotes = True global dockerComposeServicesYaml # The loaded memory YAML of all checked services global toRun # Switch for which function to run when executed global buildHooks # Where to place the options menu result global currentServiceName # Name of the current service global issues # Returned issues dict global haltOnErrors # Turn on to allow erroring global hideHelpText # Showing and hiding the help controls text global serviceService serviceService = servicesDirectory + currentServiceName try: # If not already set, then set it. hideHelpText = hideHelpText except: hideHelpText = False documentationHint = 'https://sensorsiot.github.io/IOTstack/Containers/Home-Assistant' # runtime vars portConflicts = [] # This lets the menu know whether to put " >> Options " or not # This function is REQUIRED. def checkForOptionsHook(): try: buildHooks["options"] = callable(runOptionsMenu) except: buildHooks["options"] = False return buildHooks return buildHooks # This function is REQUIRED. def checkForPreBuildHook(): try: buildHooks["preBuildHook"] = callable(preBuild) except: buildHooks["preBuildHook"] = False return buildHooks return buildHooks # This function is REQUIRED. def checkForPostBuildHook(): try: buildHooks["postBuildHook"] = callable(postBuild) except: buildHooks["postBuildHook"] = False return buildHooks return buildHooks # This function is REQUIRED. def checkForRunChecksHook(): try: buildHooks["runChecksHook"] = callable(runChecks) except: buildHooks["runChecksHook"] = False return buildHooks return buildHooks # This service will not check anything unless this is set # This function is optional, and will run each time the menu is rendered def runChecks(): checkForIssues() return [] # This function is optional, and will run after the docker-compose.yml file is written to disk. def postBuild(): return True # This function is optional, and will run just before the build docker-compose.yml code. def preBuild(): return True # ##################################### # Supporting functions below # ##################################### def checkForIssues(): for (index, serviceName) in enumerate(dockerComposeServicesYaml): if not currentServiceName == serviceName: # Skip self currentServicePorts = getExternalPorts(currentServiceName, dockerComposeServicesYaml) portConflicts = checkPortConflicts(serviceName, currentServicePorts, dockerComposeServicesYaml) if (len(portConflicts) > 0): issues["portConflicts"] = portConflicts # ##################################### # End Supporting functions # ##################################### ############################ # Menu Logic ############################ global currentMenuItemIndex global selectionInProgress global menuNavigateDirection global needsRender selectionInProgress = True currentMenuItemIndex = 0 menuNavigateDirection = 0 needsRender = 1 term = Terminal() hotzoneLocation = [((term.height // 16) + 6), 0] def goBack(): global selectionInProgress global needsRender selectionInProgress = False needsRender = 1 return True def enterPortNumberExec(): # global term global needsRender global dockerComposeServicesYaml externalPort = getExternalPorts(currentServiceName, dockerComposeServicesYaml)[0] internalPort = getInternalPorts(currentServiceName, dockerComposeServicesYaml)[0] newPortNumber = enterPortNumberWithWhiptail(term, dockerComposeServicesYaml, currentServiceName, hotzoneLocation, externalPort) if newPortNumber > 0: dockerComposeServicesYaml[currentServiceName]["ports"][0] = "{newExtPort}:{oldIntPort}".format( newExtPort = newPortNumber, oldIntPort = internalPort ) createMenu() needsRender = 1 def onResize(sig, action): global homeAssistantBuildOptions global currentMenuItemIndex mainRender(1, homeAssistantBuildOptions, currentMenuItemIndex) homeAssistantBuildOptions = [] def createMenu(): global homeAssistantBuildOptions try: homeAssistantBuildOptions = [] portNumber = getExternalPorts(currentServiceName, dockerComposeServicesYaml)[0] # homeAssistantBuildOptions.append([ # "Change external WUI Port Number from: {port}".format(port=portNumber), # enterPortNumberExec # ]) except: # Error getting port pass homeAssistantBuildOptions.append(["Go back", goBack]) def runOptionsMenu(): createMenu() menuEntryPoint() return True def renderHotZone(term, menu, selection, hotzoneLocation): lineLengthAtTextStart = 71 print(term.move(hotzoneLocation[0], hotzoneLocation[1])) for (index, menuItem) in enumerate(menu): toPrint = "" if index == selection: toPrint += ('{bv} -> {t.blue_on_green} {title} {t.normal} <-'.format(t=term, title=menuItem[0], bv=specialChars[renderMode]["borderVertical"])) else: toPrint += ('{bv} {t.normal} {title} '.format(t=term, title=menuItem[0], bv=specialChars[renderMode]["borderVertical"])) for i in range(lineLengthAtTextStart - len(menuItem[0])): toPrint += " " toPrint += "{bv}".format(bv=specialChars[renderMode]["borderVertical"]) toPrint = term.center(toPrint) print(toPrint) def mainRender(needsRender, menu, selection): term = Terminal() if needsRender == 1: print(term.clear()) print(term.move_y(term.height // 16)) print(term.black_on_cornsilk4(term.center('IOTstack Home Assistant (Container) Options'))) print("") print(term.center(commonTopBorder(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center("{bv} Select Option to configure {bv}".format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) if needsRender >= 1: renderHotZone(term, menu, selection, hotzoneLocation) if needsRender == 1: print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) if not hideHelpText: print(term.center(commonEmptyLine(renderMode))) print(term.center("{bv} Controls: {bv}".format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center("{bv} [Up] and [Down] to move selection cursor {bv}".format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center("{bv} [H] Show/hide this text {bv}".format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center("{bv} [Enter] to run command or save input {bv}".format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center("{bv} [Escape] to go back to build stack menu {bv}".format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center(commonEmptyLine(renderMode))) if len(documentationHint) > 1: if len(documentationHint) > 56: documentationAndPadding = padText(documentationHint, 71) print(term.center("{bv} Documentation: {bv}".format(bv=specialChars[renderMode]["borderVertical"]))) print(term.center("{bv} {dap} {bv}".format(bv=specialChars[renderMode]["borderVertical"], dap=documentationAndPadding))) else: documentationAndPadding = padText(documentationHint, 56) print(term.center("{bv} Documentation: {dap} {bv}".format(bv=specialChars[renderMode]["borderVertical"], dap=documentationAndPadding))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonEmptyLine(renderMode))) print(term.center(commonBottomBorder(renderMode))) def runSelection(selection): import types global homeAssistantBuildOptions if len(homeAssistantBuildOptions[selection]) > 1 and isinstance(homeAssistantBuildOptions[selection][1], types.FunctionType): homeAssistantBuildOptions[selection][1]() else: print(term.green_reverse('IOTstack Error: No function assigned to menu item: "{}"'.format(nodeRedBuildOptions[selection][0]))) def isMenuItemSelectable(menu, index): if len(menu) > index: if len(menu[index]) > 2: if menu[index][2]["skip"] == True: return False return True def menuEntryPoint(): # These need to be reglobalised due to eval() global currentMenuItemIndex global selectionInProgress global menuNavigateDirection global needsRender global hideHelpText global homeAssistantBuildOptions term = Terminal() with term.fullscreen(): menuNavigateDirection = 0 mainRender(needsRender, homeAssistantBuildOptions, currentMenuItemIndex) selectionInProgress = True with term.cbreak(): while selectionInProgress: menuNavigateDirection = 0 if needsRender: # Only rerender when changed to prevent flickering mainRender(needsRender, homeAssistantBuildOptions, currentMenuItemIndex) needsRender = 0 key = term.inkey(esc_delay=0.05) if key.is_sequence: if key.name == 'KEY_TAB': menuNavigateDirection += 1 if key.name == 'KEY_DOWN': menuNavigateDirection += 1 if key.name == 'KEY_UP': menuNavigateDirection -= 1 if key.name == 'KEY_LEFT': goBack() if key.name == 'KEY_ENTER': runSelection(currentMenuItemIndex) if key.name == 'KEY_ESCAPE': return True elif key: if key == 'h': # H pressed if hideHelpText: hideHelpText = False else: hideHelpText = True mainRender(1, homeAssistantBuildOptions, currentMenuItemIndex) if menuNavigateDirection != 0: # If a direction was pressed, find next selectable item currentMenuItemIndex += menuNavigateDirection currentMenuItemIndex = currentMenuItemIndex % len(homeAssistantBuildOptions) needsRender = 2 while not isMenuItemSelectable(homeAssistantBuildOptions, currentMenuItemIndex): currentMenuItemIndex += menuNavigateDirection currentMenuItemIndex = currentMenuItemIndex % len(homeAssistantBuildOptions) return True #################### # End menu section #################### if haltOnErrors: eval(toRun)() else: try: eval(toRun)() except: pass
send_byte_buffer = ''.join([struct.pack('>H', h) for h in words]) # Debug a chunk; Compare to HexFiend to confirm serial read def debug_chunk(): firstchunk = bytearray(b'0' * 64) input_stream.readinto(firstchunk) print(' '.join('{:02X}'.format(c) for c in firstchunk)) print(' '.join([ '{:04X}'.format(((firstchunk[idx] & 0x00FF) << 8) | firstchunk[idx + 1]) for idx in range(0, 63, 2) ])) _t = Terminal(force_styling=True) _s = Settings(path='settings.json') _log = logging.getLogger('replay') def open_input(path=None): global input_stream # Open input stream input_file = path if path is not None else 'data/openlog-20160710-001.TXT' print(_t.bold('Reading from: {}'.format(input_file))) input_stream = io.open(input_file, mode='rb', buffering=io.DEFAULT_BUFFER_SIZE) return input_stream