예제 #1
0
    def execute(self, name, current, and_exit, loader):
        cwd = os.path.split(api.log.data_source)[0]
        if name is None and not current:
            file = 'output.txt'
            if file in os.listdir(cwd):
                i = 1
                file = 'output_{}.txt'.format(i)
                while file in os.listdir(cwd):
                    i += 1
                    file = 'output_{}.txt'.format(i)
            file = os.path.join(cwd, file)
        else:
            if current:
                name = os.path.basename(api.log.data_source)
            if name in os.listdir(cwd):
                print('File already exists - do you want to overwrite?')
                r = input('Type \'yes\' to overwrite\n').strip().lower()
                if r != 'yes':
                    return
            file = os.path.join(cwd, name)

        try:
            loader = api.loaders[loader]()
        except KeyError:
            raise api.CommandError(f'no loader \'{loader}\'')
        if not hasattr(loader, 'save'):
            raise api.CommandError('loader has no save method')
        loader.save(file)
        print('Saved to {}'.format(file))
        api.log.unsaved_changes = False

        if and_exit:
            api.manual_execute(ExitCommand(), {})
예제 #2
0
    def parse_using_signature(self, command):
        """Parse a command's arguments using its signature.

        command: command instance [Command]

        return: command with inputs assigned to it [Command]
        """
        if hasattr(command, 'sig_cache'):
            self.signature_parts = command.sig_cache
        else:
            signature = api.resolve_signature(command)
            if api.is_disabled(command):
                raise api.CommandError(f'command \'{command.ID}\' is disabled')
            self.sig = SignatureParser(lexers.SignatureLexer(signature),
                                       command.ID)
            self.signature_parts = self.sig.make_signature()
            type(command).sig_cache = self.signature_parts  # set on class

        self.parts = Buffer(iter(self.signature_parts))
        found_inputs = self.scan_for_inputs_or_flags(self.signature_parts)
        self.inputs = found_inputs
        self.next_part()  # to initialise self.current_part

        while not isinstance(self.current_part, structure.End):
            try:
                if self.current_token.type == STAR:
                    self.eat(STAR)
                self.parse_signature_token()
            except api.CommandError as e:
                self.raise_error(
                    f'{str(e)} for command \'{command.ID}\'\n'
                    f'(signature: {api.resolve_signature(command)})',
                    error=api.CommandError)
        command.inputs = self.inputs
        return command
예제 #3
0
 def parse(self, parser):
     for part in self.parts:
         current = parser.current_token
         if current.type == KEYWORD and current.value == part.value:
             parser.eat(KEYWORD)
         else:
             raise api.CommandError(
                 f'expected token KEYWORD ({part.value})')
예제 #4
0
 def execute(self, file, loader):
     try:
         loader = api.loaders[loader]()
     except KeyError:
         raise api.CommandError(f'no loader \'{loader}\'')
     if not hasattr(loader, 'load'):
         raise api.CommandError('loader has no load method')
     prev = api.log.disable_all, api.log.is_startup
     api.log.disable_all = False
     api.log.is_startup = True
     api.log.data_source = os.path.abspath(file)
     api.log.new_commands = 0
     api._import_base_plugin(reload=True)
     api.log.new_hooks = 0
     api.log.new_loaders = 0
     r = loader.load(file)
     api.log.disable_all, api.log.is_startup = prev
     # run the loading command
     api.tree = api.Tree(r)
예제 #5
0
 def set_input(self, parser, key, value):
     try:
         current = parser.inputs[key]
     except KeyError:
         raise api.CommandError('signature object tried to assign to '
                                f'unscanned input \'{key}\'')
     if isinstance(current, list):
         current.append(value)
     else:
         parser.inputs[key] = value
예제 #6
0
 def parse_child(self, parser):
     ref = []
     if parser.current_token.type == DOT:
         ref.append(parser.eat(parser.current_token.type))
         parser.eat(SLASH)
     else:
         ref.append('.')
     if parser.current_token.type in (NUMBER, KEYWORD):
         ref.append(parser.eat(parser.current_token.type))
     else:
         raise api.CommandError(
             'expected token NUMBER or KEYWORD (child reference)')
     self.set_input(parser, self.value, ref)
예제 #7
0
 def phrase(self, optional=False):
     self.eat(LBRACKET if optional else LPAREN)
     parts = [self.get_part()]
     end = RBRACKET if optional else RPAREN
     while self.current_token.type != end:
         if self.current_token.type == EOF:
             raise api.CommandError(
                 f'missing {end}, got {self.current_token.type}')
         parts.append(self.get_part())
     self.eat(RBRACKET if optional else RPAREN)
     if optional:
         r = structure.OptionalPhrase(parts)
     else:
         r = structure.Phrase(parts)
     return r
예제 #8
0
 def parse_signature_token(self):
     """Parse one element of a command's signature."""
     current_part = self.current_part
     if current_part.match(self):
         current_part.parse(self)
         self.next_part()
     elif current_part.is_optional:
         self.next_part()
     else:
         message = (f'expected token {current_part.type} '
                    f'(got {self.current_token.type})')
         if isinstance(current_part, structure.Keyword):
             message += f' ({current_part.value})'
         message += f' in {current_part.__class__.__name__}'
         raise api.CommandError(message)
예제 #9
0
 def load(self, file):
     with open(file, 'r') as f:
         try:
             object = json.load(f)
         except json.decoder.JSONDecodeError as e:
             raise api.CommandError(f'cannot load file:\n{str(e)}')
         if 'data' not in object:
             api.warning('no tree title given, defaulting to Tree')
             object['data'] = 'Tree'
         root = structure.Root(object['data'])
         tags = object.get('tags', {})
         if 'config' in tags:
             self.found_plugin_file(tags['config'])
         self.add_tags(root, tags)
         for child in object.get('children', []):
             root.children.append(
                 self.recursive_construct(child, depth=1, parent=root))
         return root
예제 #10
0
 def parse_forward(self, parser):
     ref = []
     if parser.current_token.type == DOT:
         ref.append(parser.eat(parser.current_token.type))
     elif parser.current_token.type == KEYWORD:
         ref.extend(['.', parser.eat(KEYWORD)])
     elif parser.current_token.type == NUMBER:
         ref.extend(['.', parser.eat(NUMBER)])
     else:
         ref.append('.')  # assume starting slash means from current (dot)
     while parser.current_token.type == SLASH:
         parser.eat(SLASH)
         if parser.current_token.type in (NUMBER, KEYWORD):
             ref.append(parser.eat(parser.current_token.type))
         else:
             raise api.CommandError(
                 'expected token NUMBER or KEYWORD (forward reference)')
     self.set_input(parser, self.value, ref)
예제 #11
0
 def parse(self, parser):
     if self.option == 'forward':
         self.parse_forward(parser)
         return
     elif self.option == 'child':
         self.parse_child(parser)
         return
     ref = []
     if parser.current_token.type in (DOT, DOTDOT, TILDE):
         ref.append(parser.eat(parser.current_token.type))
     elif parser.current_token.type == KEYWORD:
         ref.extend(['.', parser.eat(KEYWORD)])
     elif parser.current_token.type == NUMBER:
         ref.extend(['.', parser.eat(NUMBER)])
     else:
         ref.append('.')  # assume starting slash means from current (dot)
     while parser.current_token.type == SLASH:
         parser.eat(SLASH)
         if parser.current_token.type in (DOTDOT, NUMBER, KEYWORD):
             ref.append(parser.eat(parser.current_token.type))
         else:
             raise api.CommandError(
                 'expected token NUMBER, KEYWORD or DOTDOT')
     self.set_input(parser, self.value, ref)
예제 #12
0
 def parse(self, parser):
     if self.part_found is None:
         raise api.CommandError('cannot parse OR expression')
     self.parts[self.part_found].parse(parser)
예제 #13
0
 def parse(self, parser):
     raise api.CommandError(f'parsing for {self.__class__.__name__} not yet'
                            'implemented')