Exemple #1
0
 def testStr__from_utf8(self):
     """ common.from_utf8: properly encodes ``str`` string to ``unicode``
         type.
         """
     # strings of urdu chars
     u = (u'\u06be\u06d2\u062a\u06a9\u0644\u06cc\u0641\u0646'
          u'\u06c1\u06cc\u06ba\u06c1\u0648\u062a\u06cc')
     s = ('\xda\xbe\xdb\x92\xd8\xaa\xda\xa9\xd9\x84\xdb'
          '\x8c\xd9\x81\xd9\x86\xdb\x81\xdb\x8c\xda\xba'
          '\xdb\x81\xd9\x88\xd8\xaa\xdb\x8c')
     self.assertIsInstance(common.from_utf8(s), unicode)
     self.assertEqual(common.from_utf8(s), u)
Exemple #2
0
 def testStr__from_utf8(self):
     """ common.from_utf8: properly encodes ``str`` string to ``unicode``
         type.
         """
     # strings of urdu chars
     u = (u'\u06be\u06d2\u062a\u06a9\u0644\u06cc\u0641\u0646'
          u'\u06c1\u06cc\u06ba\u06c1\u0648\u062a\u06cc')
     s = ('\xda\xbe\xdb\x92\xd8\xaa\xda\xa9\xd9\x84\xdb'
          '\x8c\xd9\x81\xd9\x86\xdb\x81\xdb\x8c\xda\xba'
          '\xdb\x81\xd9\x88\xd8\xaa\xdb\x8c')
     self.assertIsInstance(common.from_utf8(s), unicode)
     self.assertEqual(common.from_utf8(s), u)
Exemple #3
0
    def remove_option(self, block, name):
        """ Removes first matching option that exists from the AST.

            `block`
                Block name. Set to ``None`` for non-block option.
            `name`
                Option name to remove.

            * Raises a ``ValueError`` exception if `name` and/or `block`
              haven't been added.
            """

        if block:
            # block doesn't exist
            if not self._ast or not block in self._block_map:
                raise ValueError(u"Block '{0}' does not exist"
                                 .format(common.from_utf8(block)))

            # lookup block index and remove
            block_idx = self._block_map[block]

            for i, opt in enumerate(self._ast[2][block_idx][1]):
                if opt[0] == name:
                    item_idx = i
                    break
            else:
                raise ValueError(u"Option '{0}' does not exist"
                                 .format(common.from_utf8(name)))

            # pop off the block option
            options = self._ast[2][block_idx][1]
            options.pop(item_idx)

        else:
            if not self._ast:
                raise ValueError(u"Option '{0}' does not exist"
                                 .format(common.from_utf8(name)))

            # non-block option
            for i, opt in enumerate(self._ast[1]):
                if opt[0] == name:
                    item_idx = i
                    break
            else:
                raise ValueError(u"Option '{0}' does not exist"
                                 .format(common.from_utf8(name)))

            # pop off non-block option
            self._ast[1].pop(item_idx)
Exemple #4
0
    def remove_option(self, block, name):
        """ Removes first matching option that exists from the AST.

            `block`
                Block name. Set to ``None`` for non-block option.
            `name`
                Option name to remove.

            * Raises a ``ValueError`` exception if `name` and/or `block`
              haven't been added.
            """

        if block:
            # block doesn't exist
            if not self._ast or not block in self._block_map:
                raise ValueError(u"Block '{0}' does not exist".format(
                    common.from_utf8(block)))

            # lookup block index and remove
            block_idx = self._block_map[block]

            for i, opt in enumerate(self._ast[2][block_idx][1]):
                if opt[0] == name:
                    item_idx = i
                    break
            else:
                raise ValueError(u"Option '{0}' does not exist".format(
                    common.from_utf8(name)))

            # pop off the block option
            options = self._ast[2][block_idx][1]
            options.pop(item_idx)

        else:
            if not self._ast:
                raise ValueError(u"Option '{0}' does not exist".format(
                    common.from_utf8(name)))

            # non-block option
            for i, opt in enumerate(self._ast[1]):
                if opt[0] == name:
                    item_idx = i
                    break
            else:
                raise ValueError(u"Option '{0}' does not exist".format(
                    common.from_utf8(name)))

            # pop off non-block option
            self._ast[1].pop(item_idx)
Exemple #5
0
    def __init__(self, description=None):
        self.description = u"Error importing user plugins"

        if description:
            self.description += u": " + common.from_utf8(description)

        super(UserPluginImport, self).__init__(self.description)
Exemple #6
0
    def _expect_empty(self):
        """ Checks if the token stream is empty.

            * Raises a ``ParseError` exception if a token is found.
            """

        item = self._lexer.get_token()
        if item:
            line_no, token = item
            raise ParseError(u"Unexpected token '{0}' on line {1}".format(
                common.from_utf8(token.strip()), line_no))
Exemple #7
0
    def _expect_empty(self):
        """ Checks if the token stream is empty.

            * Raises a ``ParseError` exception if a token is found.
            """

        item = self._lexer.get_token()
        if item:
            line_no, token = item
            raise ParseError(u"Unexpected token '{0}' on line {1}"
                             .format(common.from_utf8(token.strip()), line_no))
Exemple #8
0
    def add_option(self, block, name, *values):
        """ Adds an option to the AST, either as a non-block option or for an
            existing block.

            `block`
                Block name. Set to ``None`` for non-block option.
            `name`
                Option name.
            `*values`
                String values for the option.

            * Raises a ``ValueError`` exception if `values` is empty, `name`
              is invalid, or `block` doesn't exist.
            """

        if not self.RE_NAME.match(name):
            raise ValueError(u"Invalid option name '{0}'".format(
                common.from_utf8(name)))

        if not values:
            raise ValueError(u"Must provide a value")
        else:
            values = list(values)

        if block:
            # block doesn't exist
            if not block in self._block_map:
                raise ValueError(u"Block '{0}' does not exist".format(
                    common.from_utf8(block)))

            # lookup block index and append
            block_idx = self._block_map[block]

            # 0: block name, 1: option_list
            self._ast[2][block_idx][1].append([name, values])

        else:
            # non-block option
            self._ast[1].append([name, values])
Exemple #9
0
    def add_option(self, block, name, *values):
        """ Adds an option to the AST, either as a non-block option or for an
            existing block.

            `block`
                Block name. Set to ``None`` for non-block option.
            `name`
                Option name.
            `*values`
                String values for the option.

            * Raises a ``ValueError`` exception if `values` is empty, `name`
              is invalid, or `block` doesn't exist.
            """

        if not self.RE_NAME.match(name):
            raise ValueError(u"Invalid option name '{0}'"
                             .format(common.from_utf8(name)))

        if not values:
            raise ValueError(u"Must provide a value")
        else:
            values = list(values)

        if block:
            # block doesn't exist
            if not block in self._block_map:
                raise ValueError(u"Block '{0}' does not exist"
                                 .format(common.from_utf8(block)))

            # lookup block index and append
            block_idx = self._block_map[block]

            # 0: block name, 1: option_list
            self._ast[2][block_idx][1].append([name, values])

        else:
            # non-block option
            self._ast[1].append([name, values])
Exemple #10
0
    def add_block(self, name):
        """ Adds a new block to the AST.

            `name`
                Block name.

            * Raises a ``ValueError`` exception if `name` is invalid or
              an existing block name matches value provided for `name`.
            """

        if not self.RE_NAME.match(name):
            raise ValueError(u"Invalid block name '{0}'"
                             .format(common.from_utf8(name)))

        if name in self._block_map:
            raise ValueError(u"Block '{0}' already exists"
                             .format(common.from_utf8(name)))

        # add new block and index mapping
        self._block_map[name] = len(self._ast[2])  # must come first
        option_list = []
        block = [name, option_list]
        self._ast[2].append(block)
Exemple #11
0
    def add_block(self, name):
        """ Adds a new block to the AST.

            `name`
                Block name.

            * Raises a ``ValueError`` exception if `name` is invalid or
              an existing block name matches value provided for `name`.
            """

        if not self.RE_NAME.match(name):
            raise ValueError(u"Invalid block name '{0}'".format(
                common.from_utf8(name)))

        if name in self._block_map:
            raise ValueError(u"Block '{0}' already exists".format(
                common.from_utf8(name)))

        # add new block and index mapping
        self._block_map[name] = len(self._ast[2])  # must come first
        option_list = []
        block = [name, option_list]
        self._ast[2].append(block)
Exemple #12
0
    def load(self):
        """ Loads a task if the active file is available.
            """

        try:
            _parser = parser.parse_config(self._paths['active_file'],
                                          self.HEADER_ACTIVE_FILE)

            # parse expected options into a dict to de-dupe
            keys = ('name', 'start_time')
            opts = dict(o for o in _parser.options if o[0] in keys)

            # check for all keys
            for k in keys:
                if not opts.get(k):
                    return False
            task_name = opts.get('name')[0]

            # setup the paths
            task_dir = self._get_task_dir(task_name)
            task_config = os.path.join(task_dir, 'task.cfg')

            # validate start time
            value = opts.get('start_time')[0]
            start_time = datetime.datetime.strptime(value,
                                                    '%Y-%m-%d %H:%M:%S.%f')

            # get user id for process ownership when running task
            # here, we use the owner of the active file
            file_meta = os.stat(self._paths['active_file'])
            owner = file_meta.st_uid

            # parse task config and send its options to registered plugins
            _parser = parser.parse_config(task_config, self.HEADER_TASK_CONFIG)
            registration.run_option_hooks(_parser)

            self._name = common.from_utf8(task_name)
            self._start_time = start_time
            self._owner = owner
            self._paths['task_dir'] = task_dir
            self._paths['task_config'] = task_config
            self._loaded = True

        except (parser.ParseError, ValueError, TypeError, OSError):
            # something failed, cleanup
            self._clean()

        self._clean_prior()
        return self._loaded
Exemple #13
0
    def load(self):
        """ Loads a task if the active file is available.
            """

        try:
            _parser = parser.parse_config(self._paths['active_file'],
                                          self.HEADER_ACTIVE_FILE)

            # parse expected options into a dict to de-dupe
            keys = ('name', 'start_time')
            opts = dict(o for o in _parser.options if o[0] in keys)

            # check for all keys
            for k in keys:
                if not opts.get(k):
                    return False
            task_name = opts.get('name')[0]

            # setup the paths
            task_dir = self._get_task_dir(task_name)
            task_config = os.path.join(task_dir, 'task.cfg')

            # validate start time
            value = opts.get('start_time')[0]
            start_time = datetime.datetime.strptime(value,
                                                    '%Y-%m-%d %H:%M:%S.%f')

            # get user id for process ownership when running task
            # here, we use the owner of the active file
            file_meta = os.stat(self._paths['active_file'])
            owner = file_meta.st_uid

            # parse task config and send its options to registered plugins
            _parser = parser.parse_config(task_config, self.HEADER_TASK_CONFIG)
            registration.run_option_hooks(_parser)

            self._name = common.from_utf8(task_name)
            self._start_time = start_time
            self._owner = owner
            self._paths['task_dir'] = task_dir
            self._paths['task_config'] = task_config
            self._loaded = True

        except (parser.ParseError, ValueError, TypeError, OSError):
            # something failed, cleanup
            self._clean()

        self._clean_prior()
        return self._loaded
Exemple #14
0
    def remove_block(self, name):
        """ Removes an existing block from the AST.

            `name`
                Block name.

            * Raises a ``ValueError`` exception if `name` hasn't been added.
            """

        if not self._ast or not name in self._block_map:
            raise ValueError(u"Block '{0}' does not exist"
                             .format(common.from_utf8(name)))

        block_idx = self._block_map[name]

        # remove block
        self._ast[2].pop(block_idx)
        del self._block_map[name]
def parse_config(filename, header):
    """ Parses the provided filename and returns ``SettingParser`` if the
        parsing was successful and header matches the header defined in the
        file.

        Returns ``SettingParser`` instance.

        * Raises a ``ParseError`` exception if header doesn't match or parsing
          fails.
        """

    parser = SettingParser(filename)
    if parser.header != header:
        header_value = parser.header or ''
        raise ParseError(u"Unexpected header '{0}', expecting '{1}'".format(
            common.from_utf8(header_value), header))

    return parser
Exemple #16
0
def parse_config(filename, header):
    """ Parses the provided filename and returns ``SettingParser`` if the
        parsing was successful and header matches the header defined in the
        file.

        Returns ``SettingParser`` instance.

        * Raises a ``ParseError`` exception if header doesn't match or parsing
          fails.
        """

    parser = SettingParser(filename)
    if parser.header != header:
        header_value = parser.header or ''
        raise ParseError(u"Unexpected header '{0}', expecting '{1}'"
                         .format(common.from_utf8(header_value), header))

    return parser
Exemple #17
0
    def remove_block(self, name):
        """ Removes an existing block from the AST.

            `name`
                Block name.

            * Raises a ``ValueError`` exception if `name` hasn't been added.
            """

        if not self._ast or not name in self._block_map:
            raise ValueError(u"Block '{0}' does not exist".format(
                common.from_utf8(name)))

        block_idx = self._block_map[name]

        # remove block
        self._ast[2].pop(block_idx)
        del self._block_map[name]
Exemple #18
0
    def __init__(self, description=None, code=None):
        """ Class init.

            `description`
                Error description string.
            `code`
                Exit status code. ``Default: 2``
            """

        super(FocusError, self).__init__(description)

        if not description is None:
            self.description = description
        else:
            self.description = getattr(self, "description", None)
        if self.description:
            self.description = common.from_utf8(self.description)

        if not code is None:
            self.code = code
        else:
            self.code = getattr(self, "code", None) or 2
Exemple #19
0
    def _expect_token(self, expected):
        """ Compares the next token in the stream to the specified token.

            `expected`
                Expected token string to match.

            * Raises a ``ParseError`` exception if token doesn't match
              `expected`.
            """

        item = self._lexer.get_token()

        if not item:
            raise ParseError(u'Unexpected end of file')

        else:
            line_no, token = item

        if token != expected:
            raise ParseError(u"Unexpected token '{0}', "
                             u"expecting '{1}' on line {2}"
                             .format(common.from_utf8(token.strip()), expected,
                                     line_no))
Exemple #20
0
    def _expect_token(self, expected):
        """ Compares the next token in the stream to the specified token.

            `expected`
                Expected token string to match.

            * Raises a ``ParseError`` exception if token doesn't match
              `expected`.
            """

        item = self._lexer.get_token()

        if not item:
            raise ParseError(u'Unexpected end of file')

        else:
            line_no, token = item

        if token != expected:
            raise ParseError(u"Unexpected token '{0}', "
                             u"expecting '{1}' on line {2}".format(
                                 common.from_utf8(token.strip()), expected,
                                 line_no))
Exemple #21
0
    def _get_token(self, regex=None):
        """ Consumes the next token in the token stream.

            `regex`
                Validate against the specified `re.compile()` regex instance.

            Returns token string.

            * Raises a ``ParseError`` exception if stream is empty or regex
              match fails.
            """

        item = self._lexer.get_token()

        if not item:
            raise ParseError(u'Unexpected end of file')
        else:
            line_no, token = item
            if regex and not regex.match(token):
                pattern = u"Unexpected format in token '{0}' on line {1}"
                token_val = common.from_utf8(token.strip())
                raise ParseError(pattern.format(token_val, line_no))

            return token
Exemple #22
0
    def _get_token(self, regex=None):
        """ Consumes the next token in the token stream.

            `regex`
                Validate against the specified `re.compile()` regex instance.

            Returns token string.

            * Raises a ``ParseError`` exception if stream is empty or regex
              match fails.
            """

        item = self._lexer.get_token()

        if not item:
            raise ParseError(u'Unexpected end of file')
        else:
            line_no, token = item
            if regex and not regex.match(token):
                pattern = u"Unexpected format in token '{0}' on line {1}"
                token_val = common.from_utf8(token.strip())
                raise ParseError(pattern.format(token_val, line_no))

            return token
Exemple #23
0
    def start(self, task_name):
        """ Starts a new task matching the provided name.

            `task_name`
                Name of existing task to start.

            Returns boolean.

            * Raises a ``TaskNotFound`` exception if task doesn't exist, an
              ``InvalidTaskConfig` exception if task config file is invalid, or
              ``DaemonFailStart`` exception if task daemons failed to fork.
            """

        self._clean_prior()

        if self._loaded:
            raise errors.ActiveTask

        # get paths
        task_dir = os.path.join(self._paths['base_dir'], 'tasks', task_name)
        task_config = os.path.join(task_dir, 'task.cfg')

        if not os.path.isdir(task_dir):
            raise errors.TaskNotFound(task_name)

        try:
            # raise if task config is missing
            if not os.path.isfile(task_config):
                reason = u"Config file could not be found."
                raise errors.InvalidTaskConfig(task_config, reason=reason)

            # parse task config and send its options to registered plugins
            _parser = parser.parse_config(task_config, self.HEADER_TASK_CONFIG)
            registration.run_option_hooks(_parser)

        except parser.ParseError as exc:
            raise errors.InvalidTaskConfig(task_config, reason=unicode(exc))

        # populate task info
        self._name = common.from_utf8(task_name)
        self._start_time = datetime.datetime.now()
        self._owner = os.getuid()
        self._paths['task_dir'] = task_dir
        self._paths['task_config'] = task_config
        self._loaded = True

        # task is setup, save active file
        # note, order is *important*; this is needed first
        # for the daemon to load
        self._save_active_file()

        # shell the focusd daemon
        try:
            started = daemon.shell_focusd(self._paths['base_dir'])

        # user cancelled or passwords failed?
        except (KeyboardInterrupt, ValueError):
            self._clean()
            return False

        # no event plugins registered, carry on
        except errors.NoPluginsRegistered:
            return True

        # failed, cleanup our mess
        if not started:
            self._clean()
            raise errors.DaemonFailStart

        return True
Exemple #24
0
 def testUnicode__from_utf8(self):
     """ common.from_utf8: returns same value if already unicode.
         """
     self.assertIsInstance(common.from_utf8(u'hey'), unicode)
     self.assertEqual(common.from_utf8(u'hey'), u'hey')
Exemple #25
0
 def testUnicode__from_utf8(self):
     """ common.from_utf8: returns same value if already unicode.
         """
     self.assertIsInstance(common.from_utf8(u'hey'), unicode)
     self.assertEqual(common.from_utf8(u'hey'), u'hey')
Exemple #26
0
    def __init__(self, filename, reason):
        self.filename = common.from_utf8(filename)
        self.reason = common.from_utf8(reason)
        self.description = u'Invalid task config "{0}",{1}   reason: {2}'.format(filename, os.linesep, reason)

        super(InvalidTaskConfig, self).__init__(self.description)
Exemple #27
0
    def __init__(self, task_name):
        self.description = u'Task "{0}" already exists'.format(common.from_utf8(task_name))

        super(TaskExists, self).__init__(self.description)
Exemple #28
0
    def start(self, task_name):
        """ Starts a new task matching the provided name.

            `task_name`
                Name of existing task to start.

            Returns boolean.

            * Raises a ``TaskNotFound`` exception if task doesn't exist, an
              ``InvalidTaskConfig` exception if task config file is invalid, or
              ``DaemonFailStart`` exception if task daemons failed to fork.
            """

        self._clean_prior()

        if self._loaded:
            raise errors.ActiveTask

        # get paths
        task_dir = os.path.join(self._paths['base_dir'], 'tasks', task_name)
        task_config = os.path.join(task_dir, 'task.cfg')

        if not os.path.isdir(task_dir):
            raise errors.TaskNotFound(task_name)

        try:
            # raise if task config is missing
            if not os.path.isfile(task_config):
                reason = u"Config file could not be found."
                raise errors.InvalidTaskConfig(task_config, reason=reason)

            # parse task config and send its options to registered plugins
            _parser = parser.parse_config(task_config, self.HEADER_TASK_CONFIG)
            registration.run_option_hooks(_parser)

        except parser.ParseError as exc:
            raise errors.InvalidTaskConfig(task_config,
                                           reason=unicode(exc))

        # populate task info
        self._name = common.from_utf8(task_name)
        self._start_time = datetime.datetime.now()
        self._owner = os.getuid()
        self._paths['task_dir'] = task_dir
        self._paths['task_config'] = task_config
        self._loaded = True

        # task is setup, save active file
        # note, order is *important*; this is needed first
        # for the daemon to load
        self._save_active_file()

        # shell the focusd daemon
        try:
            started = daemon.shell_focusd(self._paths['base_dir'])

        # user cancelled or passwords failed?
        except (KeyboardInterrupt, ValueError):
            self._clean()
            return False

        # no event plugins registered, carry on
        except errors.NoPluginsRegistered:
            return True

        # failed, cleanup our mess
        if not started:
            self._clean()
            raise errors.DaemonFailStart

        return True
Exemple #29
0
    def __init__(self, task_name):
        self.description = u'Task "{0}" does not exist'.format(common.from_utf8(task_name))

        super(TaskNotFound, self).__init__(self.description)