def fetch_synchronize_status(): """ Returns the synchronization status information for the currently opened project """ r = Response() project = cd.project.get_internal_project() if not project: r.fail( code='NO_PROJECT', message='No open project on which to retrieve status' ) else: with open(project.source_path, 'r') as f: definition = json.load(f) result = status.of_project(project) r.update( sync_time=sync_status.get('time', 0), source_directory=project.source_directory, remote_source_directory=project.remote_source_directory, status=result, definition=definition ) return r.flask_serialize()
def clean_step(step_name: str): """ """ r = Response() project = cauldron.project.internal_project if not project: return flask.jsonify(r.fail( code='PROJECT_FETCH_ERROR', message='No project is currently open' ).response.serialize()) step = project.get_step(step_name) if not step: return flask.jsonify(r.fail( code='STEP_FETCH_ERROR', message='No such step "{}" found'.format(step_name) ).response.serialize()) step.mark_dirty(False, force=True) return flask.jsonify(r.update( project=project.kernel_serialize() ).response.serialize())
def test_echo(self): """Should echo information""" r = Response() r.warn('WARNING', something=[1, 2, 3], value=False) r.fail('ERROR') result = r.echo() self.assertGreater(result.find('WARNING'), 0) self.assertGreater(result.find('ERROR'), 0)
def execute(exec_async: bool = False): """ :param exec_async: Whether or not to allow asynchronous command execution that returns before the command is complete with a run_uid that can be used to track the continued execution of the command until completion. """ r = Response() r.update(server=server_runner.get_server_data()) cmd, args = parse_command_args(r) if r.failed: return flask.jsonify(r.serialize()) try: commander.execute(cmd, args, r) if not r.thread: return flask.jsonify(r.serialize()) if not exec_async: r.thread.join() server_runner.active_execution_responses[r.thread.uid] = r # Watch the thread for a bit to see if the command finishes in # that time. If it does the command result will be returned directly # to the caller. Otherwise, a waiting command will be issued count = 0 while count < 5: count += 1 r.thread.join(0.25) if not r.thread.is_alive(): break if r.thread.is_alive(): return flask.jsonify(Response().update( run_log=r.get_thread_log(), run_status='running', run_uid=r.thread.uid, step_changes=server_runner.get_running_step_changes(True), server=server_runner.get_server_data()).serialize()) del server_runner.active_execution_responses[r.thread.uid] r.update(run_log=r.get_thread_log(), run_status='complete', run_multiple_updates=False, run_uid=r.thread.uid) except Exception as err: r.fail(code='KERNEL_EXECUTION_FAILURE', message='Unable to execute command', cmd=cmd, args=args, error=err) return flask.jsonify(r.serialize())
def sync_source_file(): """ """ r = Response() args = arguments.from_request() relative_path = args.get('relative_path') chunk = args.get('chunk') index = args.get('index', 0) sync_time = args.get('sync_time', -1) location = args.get('location', 'project') offset = args.get('offset', 0) if None in [relative_path, chunk]: return r.fail( code='INVALID_ARGS', message='Missing or invalid arguments' ).response.flask_serialize() project = cd.project.get_internal_project() if not project: return r.fail( code='NO_OPEN_PROJECT', message='No project is open. Unable to sync' ).response.flask_serialize() parts = relative_path.replace('\\', '/').strip('/').split('/') root_directory = project.source_directory if location == 'shared': root_directory = os.path.realpath(os.path.join( root_directory, '..', '__cauldron_shared_libs' )) file_path = os.path.join(root_directory, *parts) parent_directory = os.path.dirname(file_path) if not os.path.exists(parent_directory): os.makedirs(parent_directory) sync.io.write_file_chunk( file_path=file_path, packed_chunk=chunk, append=index > 0, offset=offset ) sync_status.update({}, time=sync_time) return r.notify( kind='SYNCED', code='SAVED_CHUNK', message='File chunk {} {}'.format(offset, file_path) ).console().response.flask_serialize()
def touch_project(): """ Touches the project to trigger refreshing its cauldron.json state. """ r = Response() project = cd.project.get_internal_project() if project: project.refresh() else: r.fail(code='NO_PROJECT', message='No open project to refresh') return r.update(sync_time=sync_status.get('time', 0)).flask_serialize()
def sync_source_file(): """ """ r = Response() args = arguments.from_request() relative_path = args.get('relative_path') chunk = args.get('chunk') index = args.get('index', 0) sync_time = args.get('sync_time', -1) location = args.get('location', 'project') offset = args.get('offset', 0) if None in [relative_path, chunk]: return r.fail( code='INVALID_ARGS', message='Missing or invalid arguments').response.flask_serialize() project = cd.project.get_internal_project() if not project: return r.fail(code='NO_OPEN_PROJECT', message='No project is open. Unable to sync' ).response.flask_serialize() parts = relative_path.replace('\\', '/').strip('/').split('/') root_directory = project.source_directory if location == 'shared': root_directory = os.path.realpath( os.path.join(root_directory, '..', '__cauldron_shared_libs')) file_path = os.path.join(root_directory, *parts) parent_directory = os.path.dirname(file_path) if not os.path.exists(parent_directory): os.makedirs(parent_directory) sync.io.write_file_chunk(file_path=file_path, packed_chunk=chunk, append=index > 0, offset=offset) sync_status.update({}, time=sync_time) print('SAVED CHUNK:', offset, file_path) return r.notify(kind='SUCCESS', code='SAVED_CHUNK', message='Saved file chunk').response.flask_serialize()
def execute(name: str, raw_args: str, response: Response = None, remote_connection: 'environ.RemoteConnection' = None) -> Response: """ :return: """ if not response: response = Response(identifier=name) command_module = fetch().get(name) if command_module is None: return response.fail( code='NO_SUCH_COMMAND', message='There is no command "{}"'.format(name)).kernel( name=name).console(""" "{name}" is not a recognized command. For a list of available commands enter help or ?. """.format(name=name)).response args = parse.args(command_module, raw_args) response.consume(args.response) if args.parser is None: # The parse failed and the execution should be aborted return response if args.args is None or args.args['show_help']: # Overrides standard execution and instead displays the help for the # command args.parser.print_help() return response del args.args['show_help'] context = cli.make_command_context(name=name, args=args.args, raw_args=raw_args, parser=args.parser, response=response, remote_connection=remote_connection) response.update(remote_connection=remote_connection) if not context.remote_connection.active and name == 'run': preload() t = CauldronThread() t.command = get_command_from_module( command_module=command_module, remote_connection=context.remote_connection) t.context = context t.parser = args.parser t.kwargs = args.args t.response = response response.thread = t t.start() return response
def show_help(command_name: str = None, raw_args: str = '') -> Response: """ Prints the basic command help to the console """ response = Response() cmds = fetch() if command_name and command_name in cmds: parser, result = parse.get_parser(cmds[command_name], parse.explode_line(raw_args), dict()) if parser is not None: out = parser.format_help() return response.notify( kind='INFO', code='COMMAND_DESCRIPTION').kernel(commands=out).console( out, whitespace=1).response environ.log_header('Available Commands') response.consume(print_module_help()) return response.fail(code='NO_SUCH_COMMAND', message='Failed to show command help for "{}"'.format( command_name)).console( """ For more information on the various commands, enter help on the specific command: help [COMMAND] """, whitespace_bottom=1).response
def touch_project(): """ Touches the project to trigger refreshing its cauldron.json state. """ r = Response() project = cd.project.get_internal_project() if project: project.refresh() else: r.fail( code='NO_PROJECT', message='No open project to refresh' ) return r.update( sync_time=sync_status.get('time', 0) ).flask_serialize()
def project_status(): """...""" r = Response() try: project = cauldron.project.get_internal_project() if project: r.update(project=project.status()) else: r.update(project=None) except Exception as err: r.fail( code='PROJECT_STATUS_ERROR', message='Unable to check status of currently opened project', error=err ) r.update(server=server_runner.get_server_data()) return flask.jsonify(r.serialize())
def sync_create_project(): """ """ r = Response() args = arguments.from_request() name = args.get('name') remote_source_directory = args.get('source_directory') optional_args = args.get('args', {}) if None in [name, remote_source_directory]: return r.fail( code='INVALID_ARGS', message='Invalid arguments. Unable to create project' ).response.flask_serialize() container_folder = tempfile.mkdtemp(prefix='cd-remote-project-') os.makedirs(os.path.join(container_folder, '__cauldron_shared_libs')) os.makedirs(os.path.join(container_folder, '__cauldron_downloads')) r.consume(create_command.execute( cli.make_command_context('create'), project_name=name, directory=container_folder, forget=True, **optional_args )) if r.failed: return r.flask_serialize() sync_status.update({}, time=-1, project=None) project = cd.project.get_internal_project() project.remote_source_directory = remote_source_directory with open(project.source_path, 'r') as f: definition = json.load(f) sync_status.update({}, time=-1, project=project) return r.update( source_directory=project.source_directory, remote_source_directory=remote_source_directory, definition=definition, project=project.kernel_serialize() ).notify( kind='SUCCESS', code='PROJECT_CREATED', message='Project created' ).response.flask_serialize()
def sync_open_project(): """ """ r = Response() args = arguments.from_request() definition = args.get('definition') source_directory = args.get('source_directory') if None in [definition, source_directory]: return r.fail( code='INVALID_ARGS', message='Invalid arguments. Unable to open project' ).response.flask_serialize() # Remove any shared library folders from the library list. These will be # stored using the single shared library folder instead definition['library_folders'] = [ lf for lf in definition.get('library_folders', ['libs']) if lf and not lf.startswith('..') ] definition['library_folders'] += ['../__cauldron_shared_libs'] container_folder = tempfile.mkdtemp(prefix='cd-remote-project-') os.makedirs(os.path.join(container_folder, '__cauldron_shared_libs')) os.makedirs(os.path.join(container_folder, '__cauldron_downloads')) project_folder = os.path.join(container_folder, definition['name']) os.makedirs(project_folder) definition_path = os.path.join(project_folder, 'cauldron.json') writer.write_json_file(definition_path, definition) sync_status.update({}, time=-1, project=None) open_response = project_opener.open_project(project_folder, forget=True) open_response.join() project = cd.project.get_internal_project() project.remote_source_directory = source_directory sync_status.update({}, time=-1, project=project) return r.consume(open_response).update( source_directory=project.source_directory, project=project.kernel_serialize() ).notify( kind='OPENED', code='PROJECT_OPENED', message='Project opened' ).response.flask_serialize()
def fetch_synchronize_status(): """ Returns the synchronization status information for the currently opened project """ r = Response() project = cd.project.get_internal_project() if not project: r.fail(code='NO_PROJECT', message='No open project on which to retrieve status') else: with open(project.source_path, 'r') as f: definition = json.load(f) result = status.of_project(project) r.update(sync_time=sync_status.get('time', 0), source_directory=project.source_directory, remote_source_directory=project.remote_source_directory, status=result, definition=definition) return r.flask_serialize()
def clean_step(step_name: str): """...""" r = Response() project = cauldron.project.get_internal_project() if not project: return flask.jsonify(r.fail( code='PROJECT_FETCH_ERROR', message='No project is currently open' ).response.serialize()) step = project.get_step(step_name) if not step: return flask.jsonify(r.fail( code='STEP_FETCH_ERROR', message='No such step "{}" found'.format(step_name) ).response.serialize()) step.mark_dirty(False, force=True) return flask.jsonify(r.update( project=project.kernel_serialize() ).response.serialize())
def sync_create_project(): """ """ r = Response() args = arguments.from_request() name = args.get('name') remote_source_directory = args.get('source_directory') optional_args = args.get('args', {}) if None in [name, remote_source_directory]: return r.fail(code='INVALID_ARGS', message='Invalid arguments. Unable to create project' ).response.flask_serialize() container_folder = tempfile.mkdtemp(prefix='cd-remote-project-') os.makedirs(os.path.join(container_folder, '__cauldron_shared_libs')) os.makedirs(os.path.join(container_folder, '__cauldron_downloads')) r.consume( create_command.execute(cli.make_command_context('create'), project_name=name, directory=container_folder, forget=True, **optional_args)) if r.failed: return r.flask_serialize() sync_status.update({}, time=-1, project=None) project = cd.project.get_internal_project() project.remote_source_directory = remote_source_directory with open(project.source_path, 'r') as f: definition = json.load(f) sync_status.update({}, time=-1, project=project) return r.update(source_directory=project.source_directory, remote_source_directory=remote_source_directory, definition=definition, project=project.kernel_serialize()).notify( kind='SUCCESS', code='PROJECT_CREATED', message='Project created').response.flask_serialize()
def sync_open_project(): """ """ r = Response() args = arguments.from_request() definition = args.get('definition') source_directory = args.get('source_directory') if None in [definition, source_directory]: return r.fail(code='INVALID_ARGS', message='Invalid arguments. Unable to open project' ).response.flask_serialize() # Remove any shared library folders from the library list. These will be # stored using the single shared library folder instead definition['library_folders'] = [ lf for lf in definition.get('library_folders', ['libs']) if lf and not lf.startswith('..') ] definition['library_folders'] += ['../__cauldron_shared_libs'] container_folder = tempfile.mkdtemp(prefix='cd-remote-project-') os.makedirs(os.path.join(container_folder, '__cauldron_shared_libs')) os.makedirs(os.path.join(container_folder, '__cauldron_downloads')) project_folder = os.path.join(container_folder, definition['name']) os.makedirs(project_folder) definition_path = os.path.join(project_folder, 'cauldron.json') writer.write_json_file(definition_path, definition) sync_status.update({}, time=-1, project=None) open_response = project_opener.open_project(project_folder, forget=True) open_response.join() project = cd.project.get_internal_project() project.remote_source_directory = source_directory sync_status.update({}, time=-1, project=project) return r.consume(open_response).update( source_directory=project.source_directory, project=project.kernel_serialize()).notify( kind='SUCCESS', code='PROJECT_OPENED', message='Project opened').response.flask_serialize()
def test_get_response(self): """ should get the response back from the response message """ r = Response() self.assertEqual(r, r.fail().get_response())
def execute(asynchronous: bool = False): """ :param asynchronous: Whether or not to allow asynchronous command execution that returns before the command is complete with a run_uid that can be used to track the continued execution of the command until completion. """ r = Response() r.update(server=server_runner.get_server_data()) cmd, args = parse_command_args(r) if r.failed: return flask.jsonify(r.serialize()) try: commander.execute(cmd, args, r) if not r.thread: return flask.jsonify(r.serialize()) if not asynchronous: r.thread.join() server_runner.active_execution_responses[r.thread.uid] = r # Watch the thread for a bit to see if the command finishes in # that time. If it does the command result will be returned directly # to the caller. Otherwise, a waiting command will be issued count = 0 while count < 5: count += 1 r.thread.join(0.25) if not r.thread.is_alive(): break if r.thread.is_alive(): return flask.jsonify( Response() .update( run_log=r.get_thread_log(), run_status='running', run_uid=r.thread.uid, step_changes=server_runner.get_running_step_changes(True), server=server_runner.get_server_data() ) .serialize() ) del server_runner.active_execution_responses[r.thread.uid] r.update( run_log=r.get_thread_log(), run_status='complete', run_multiple_updates=False, run_uid=r.thread.uid ) except Exception as err: r.fail( code='KERNEL_EXECUTION_FAILURE', message='Unable to execute command', cmd=cmd, args=args, error=err ) return flask.jsonify(r.serialize())
def test_get_response(self): """Should get the response back from the response message""" r = Response() self.assertEqual(r, r.fail().get_response())
return flask.jsonify(Response().update( run_log=r.get_thread_log(), run_status='running', run_uid=r.thread.uid, step_changes=server_runner.get_running_step_changes(True), server=server_runner.get_server_data()).serialize()) del server_runner.active_execution_responses[r.thread.uid] r.update(run_log=r.get_thread_log(), run_status='complete', run_multiple_updates=False, run_uid=r.thread.uid) except Exception as err: r.fail(code='KERNEL_EXECUTION_FAILURE', message='Unable to execute command', cmd=cmd, args=args, error=err) return flask.jsonify(r.serialize()) @server_runner.APPLICATION.route('/abort', methods=['GET', 'POST']) @authorization.gatekeeper def abort(): """ :return: """ uid_list = list(server_runner.active_execution_responses.keys())