def do_load_base64(self, line): """ load filename=(file) load base64=(base64 encoded) Send new code to shoebot. If it does not run successfully shoebot will attempt to role back. Editors can enable livecoding by sending new code as it is edited. """ cookie = self.cookie executor = self.bot._executor def source_good(): self.print_response(status=RESPONSE_CODE_OK, cookie=cookie) executor.clear_callbacks() def source_bad(tb): if called_good: # good and bad callbacks shouldn't both be called raise ValueError('Good AND Bad callbacks called !') self.print_response(status=RESPONSE_REVERTED, keep=True, cookie=cookie) self.print_response(tb.replace('\n', '\\n'), cookie=cookie) executor.clear_callbacks() called_good = False source = str(base64.b64decode(line)) # Test compile publish_event(SOURCE_CHANGED_EVENT, data=source, extra_channels="shoebot.source") self.bot._executor.load_edited_source(source, good_cb=source_good, bad_cb=source_bad)
def do_load_base64(self, line): """ load filename=(file) load base64=(base64 encoded) Send new code to shoebot. If it does not run successfully shoebot will attempt to role back. Editors can enable livecoding by sending new code as it is edited. """ cookie = self.cookie executor = self.bot._executor def source_good(): self.print_response(status=RESPONSE_CODE_OK, cookie=cookie) executor.clear_callbacks() def source_bad(tb): if called_good: # good and bad callbacks shouldn't both be called raise ValueError('Good AND Bad callbacks called !') self.print_response(status=RESPONSE_REVERTED, keep=True, cookie=cookie) self.print_response(tb.replace('\n', '\\n'), cookie=cookie) executor.clear_callbacks() called_good = False source = str(base64.b64decode(line)) # Test compile publish_event(SOURCE_CHANGED_EVENT, data=source, extra_channels="shoebot.source") self.bot._executor.load_edited_source(source, good_cb=source_good, bad_cb=source_bad)
def do_load_base64(self, line): """ load filename=(file) load base64=(base64 encoded) """ cookie = self.cookie executor = self.bot._executor def source_good(): self.print_response(status=RESPONSE_CODE_OK, cookie=cookie) executor.clear_callbacks() def source_bad(tb): if called_good: # good and bad callbacks shouldn't both be called raise ValueError('Good AND Bad callbacks called !') # TODO - get simple_trace_back of exception to send back self.print_response(status=RESPONSE_REVERTED, keep=True, cookie=cookie) self.print_response(tb.replace('\n', '\\n'), cookie=cookie) executor.clear_callbacks() called_good = False source = str(base64.b64decode(line)) # Test compile publish_event(SOURCE_CHANGED_EVENT, data=source, extra_channels="shoebot.source") self.bot._executor.load_edited_source(source, good_cb=source_good, bad_cb=source_bad)
def do_exit(self, line): """ Exit shell and shoebot """ if self.trusted: publish_event(QUIT_EVENT) self.print_response('Bye.\n') return True
def var_changed(self, name, value): self.bot._namespace[name] = value if self.var_window: return self.var_window.update_var(name, value) else: v = self.bot._vars[name] publish_event(EVENT_VARIABLE_UPDATED, v) return True, value
def snapshot_png(self, widget): """ Request to save a PNG file after drawing is complete. """ self.pending_snapshots.append(self.output_image_filename("png")) publish_event(REDRAW_EVENT, data=(None, None)) # TODO - this probably wants its own event
def do_exit(self, line): """ Exit shell and shoebot """ if self.trusted: publish_event(QUIT_EVENT) self.print_response('Bye.\n') return True
def var_changed(self, name, value): self.bot._namespace[name] = value if self.var_window: return self.var_window.update_var(name, value) else: v = self.bot._vars[name] publish_event(VARIABLE_UPDATED_EVENT, v) return True, value
def do_window_close(self, widget,data=None): publish_event(QUIT_EVENT) if self.has_server: self.sock.close() self.hide_variables_window() self.destroy() self.window_open = False
def widget_changed(self, widget, v): """ Called when a slider is adjusted. """ # set the appropriate bot var if v.type is NUMBER: self.bot._namespace[v.name] = widget.get_value() self.bot._vars[v.name].value = widget.get_value() elif v.type is BOOLEAN: self.bot._namespace[v.name] = widget.get_active() self.bot._vars[v.name].value = widget.get_active() elif v.type is TEXT: self.bot._namespace[v.name] = widget.get_text() self.bot._vars[v.name].value = widget.get_text() publish_event(VARIABLE_CHANGED_EVENT, v)
def do_window_close(self, widget, data=None): """ Widget Action to Close the window, triggering the quit event. """ publish_event(QUIT_EVENT) if self.has_server: self.sock.close() self.hide_variables_window() self.destroy() self.window_open = False
def do_load_base64(self, line): """ load filename=(file) load base64=(base64 encoded) Send new code to shoebot. If it does not run successfully shoebot will attempt to role back. Editors can enable live-coding by sending new code as it is edited. """ # TODO use publish_event to change source, and let the mainloop update the executor. cookie = self.cookie executor = self.bot._executor # noqa def source_good(): self.print_response(status=RESPONSE_CODE_OK, cookie=cookie) executor.clear_callbacks() def source_bad(tb): if called_good: # good and bad callbacks shouldn't both be called raise ValueError( "Unexpected condition, Good and bad callbacks were called !" ) self.print_response(status=RESPONSE_REVERTED, keep=True, cookie=cookie) self.print_response(tb.replace("\n", "\\n"), cookie=cookie) executor.clear_callbacks() called_good = False source = base64.b64decode(line).decode("utf-8") # Test compile publish_event(SOURCE_CHANGED_EVENT, data=source, extra_channels="shoebot.source") self.bot._executor.load_edited_source( # noqa source, good_cb=source_good, bad_cb=source_bad)
def widget_changed(self, widget, v): ''' Called when a slider is adjusted. ''' # set the appropriate bot var if v.type is NUMBER: self.bot._namespace[v.name] = widget.get_value() self.bot._vars[v.name].value = widget.get_value() ## Not sure if this is how to do this - stu publish_event(VARIABLE_UPDATED_EVENT, v) # pretty dumb for now elif v.type is BOOLEAN: self.bot._namespace[v.name] = widget.get_active() self.bot._vars[v.name].value = widget.get_active() ## Not sure if this is how to do this - stu publish_event(VARIABLE_UPDATED_EVENT, v) # pretty dumb for now elif v.type is TEXT: self.bot._namespace[v.name] = widget.get_text() self.bot._vars[v.name].value = widget.get_text() ## Not sure if this is how to do this - stu publish_event(VARIABLE_UPDATED_EVENT, v) # pretty dumb for now
def widget_changed(self, widget, v): ''' Called when a slider is adjusted. ''' # set the appropriate bot var if v.type is NUMBER: self.bot._namespace[v.name] = widget.get_value() self.bot._vars[v.name].value = widget.get_value() ## Not sure if this is how to do this - stu publish_event(EVENT_VARIABLE_UPDATED, v) # pretty dumb for now elif v.type is BOOLEAN: self.bot._namespace[v.name] = widget.get_active() self.bot._vars[v.name].value = widget.get_active() ## Not sure if this is how to do this - stu publish_event(EVENT_VARIABLE_UPDATED, v) # pretty dumb for now elif v.type is TEXT: self.bot._namespace[v.name] = widget.get_text() self.bot._vars[v.name].value = widget.get_text() ## Not sure if this is how to do this - stu publish_event(EVENT_VARIABLE_UPDATED, v) # pretty dumb for now
def on_resize(self, widget, dimensions): self.width = dimensions.width self.height = dimensions.height publish_event(REDRAW)
def on_resize(self, widget, dimensions): self.width = dimensions.width self.height = dimensions.height publish_event(REDRAW)
def run(src, grammar=NODEBOX, format=None, outputfile=None, iterations=1, buff=None, window=True, title=None, fullscreen=None, close_window=False, server=False, port=7777, show_vars=False, vars=None, namespace=None, run_shell=False, args=[], verbose=False, background_thread=True): """ Create and run a bot, the arguments all correspond to sanitized commandline options. :param background_thread: If True then use a background thread. Other args are split into create_args and run_args See create_bot for details on create_args run_args are passed to bot.run - see Nodebot.run or Drawbot.run Background thread: readline in python is blocking, running the app in a background thread opens up the main thread for IO on stdin/stdout, which can be used for communication with shoebot when livecoding is enabled. See shoebot.io for implementation of the shell, and the gedit plugin for an example of using livecoding. """ # Munge shoebogt sys.argv sys.argv = [sys.argv[ 0]] + args # Remove shoebot parameters so sbot can be used in place of the python interpreter (e.g. for sphinx). # arguments for create_bot create_args = [src, grammar, format, outputfile, iterations, buff, window, title, fullscreen, server, port, show_vars] create_kwargs = dict(vars=vars, namespace=namespace) run_args = [src] run_kwargs = dict( iterations=iterations, frame_limiter=window, verbose=verbose, # run forever except 1. windowed mode is off 2. if --close-window was specified and # 3. if an output file was indicated run_forever=window and not (close_window or bool(outputfile)), ) # Run shoebot in a background thread so we can run a cmdline shell in the current thread if background_thread: sbot_thread = ShoebotThread( create_args=create_args, create_kwargs=create_kwargs, run_args=run_args, run_kwargs=run_kwargs, send_sigint=run_shell ) sbot_thread.start() sbot = sbot_thread.sbot else: print('background thread disabled') # This is a debug option, things should always work using the # background thread (crosses fingers) if run_shell: # python readline is blocking, so ui must run in a seperate # thread raise ValueError('UI Must run in a separate thread to shell and shell needs main thread') sbot_thread = None sbot = create_bot(*create_args, **create_kwargs) sbot.run(*run_args, **run_kwargs) if run_shell: import shoebot.sbio.shell shell = shoebot.sbio.shell.ShoebotCmd(sbot, trusted=True) try: shell.cmdloop() except KeyboardInterrupt as e: publish_event(QUIT_EVENT) # Handle Ctrl-C # KeyboardInterrupt is generated by os.kill from the other thread if verbose: raise else: return elif background_thread: try: while sbot_thread.is_alive(): sleep(1) except KeyboardInterrupt: publish_event(QUIT_EVENT) if all((background_thread, sbot_thread)): sbot_thread.join() return sbot
def do_exit(self, line): print(self.trusted, file=self.stdout) if self.trusted: publish_event(QUIT_EVENT) self.print_response('Bye.\n') return True
def do_title(self, title): """ Change window title. """ publish_event(SET_WINDOW_TITLE, data=title)
def on_resize(self, widget, dimensions): self.width = dimensions.width self.height = dimensions.height if self.bot_size is not None: publish_event(REDRAW_EVENT, data=(self.width, self.height))
def run(src, grammar=NODEBOX, format=None, outputfile=None, iterations=1, buff=None, window=True, title=None, fullscreen=None, close_window=False, server=False, port=7777, show_vars=False, vars=None, namespace=None, run_shell=False, args=[], verbose=False, background_thread=True): """ Create and run a bot, the arguments all correspond to sanitized commandline options. :param background_thread: If True then use a background thread. Other args are split into create_args and run_args See create_bot for details on create_args run_args are passed to bot.run - see Nodebot.run or Drawbot.run Background thread: readline in python is blocking, running the app in a background thread opens up the main thread for IO on stdin/stdout, which can be used for communication with shoebot when livecoding is enabled. See shoebot.io for implementation of the shell, and the gedit plugin for an example of using livecoding. """ # Munge shoebogt sys.argv sys.argv = [ sys.argv[0] ] + args # Remove shoebot parameters so sbot can be used in place of the python interpreter (e.g. for sphinx). # arguments for create_bot create_args = [ src, grammar, format, outputfile, iterations, buff, window, title, fullscreen, server, port, show_vars ] create_kwargs = dict(vars=vars, namespace=namespace) run_args = [src] run_kwargs = dict( iterations=iterations, frame_limiter=window, verbose=verbose, # run forever except 1. windowed mode is off 2. if --close-window was specified and # 3. if an output file was indicated run_forever=window and not (close_window or bool(outputfile)), ) # Run shoebot in a background thread so we can run a cmdline shell in the current thread if background_thread: sbot_thread = ShoebotThread(create_args=create_args, create_kwargs=create_kwargs, run_args=run_args, run_kwargs=run_kwargs, send_sigint=run_shell) sbot_thread.start() sbot = sbot_thread.sbot else: print('background thread disabled') # This is a debug option, things should always work using the # background thread (crosses fingers) if run_shell: # python readline is blocking, so ui must run in a seperate # thread raise ValueError( 'UI Must run in a separate thread to shell and shell needs main thread' ) sbot_thread = None sbot = create_bot(*create_args, **create_kwargs) sbot.run(*run_args, **run_kwargs) if run_shell: import shoebot.sbio.shell shell = shoebot.sbio.shell.ShoebotCmd(sbot, trusted=True) try: shell.cmdloop() except KeyboardInterrupt as e: publish_event(QUIT_EVENT) # Handle Ctrl-C # KeyboardInterrupt is generated by os.kill from the other thread if verbose: raise else: return elif background_thread: try: while sbot_thread.is_alive(): sleep(1) except KeyboardInterrupt: publish_event(QUIT_EVENT) if all((background_thread, sbot_thread)): sbot_thread.join() return sbot
def do_title(self, title): """ Change window title. """ publish_event(SET_WINDOW_TITLE, data=title)