Ejemplo n.º 1
0
 def testFilterAll__get_registered(self):
     """ registration.get_registered: returns all registered plugins.
         """
     registration._registered.register(MockPlugin.name, MockPlugin,
                                       {'command': True})
     self.assertIn(MockPlugin.name,
                   [x.name for x in registration.get_registered()])
Ejemplo n.º 2
0
    def testFilterActiveTask__get_registered(self):
        """ registration.get_registered: returns all registered
            plugins that are available when a task is active.
            """
        class MockPlugin2(MockPlugin):
            name = 'hai 2'
            options = None

        class MockPlugin3(MockPlugin):
            name = 'hai 3'
            options = None
            task_only = True

        # register a couple test plugins
        registration._registered.register(MockPlugin.name, MockPlugin,
                                          {'event': True})
        registration._registered.register(MockPlugin2.name, MockPlugin2,
                                          {'command': True})
        registration._registered.register(MockPlugin3.name, MockPlugin3,
                                          {'command': True})

        # get list of registered names for active task plugins
        plugin_names = [
            x.name for x in registration.get_registered(task_active=True)
        ]

        self.assertIn(MockPlugin.name, plugin_names)
        self.assertIn(MockPlugin2.name, plugin_names)
        self.assertIn(MockPlugin3.name, plugin_names)
Ejemplo n.º 3
0
    def testFilterNoActiveTask__get_registered(self):
        """ registration.get_registered: returns all registered
            plugins that can be seen when a task is not active.
            """
        class MockPlugin2(MockPlugin):
            name = 'hai 2'
            options = None

        class MockPlugin3(MockPlugin):
            name = 'hai 3'
            options = None
            task_only = True

        # register a couple test plugins
        registration._registered.register(MockPlugin.name, MockPlugin,
                                          {'event': True})
        registration._registered.register(MockPlugin2.name, MockPlugin2,
                                          {'command': True})
        registration._registered.register(MockPlugin3.name, MockPlugin3,
                                          {'command': True})

        # get list of registered names for active task plugins
        plugin_names = [
            x.name for x in registration.get_registered(task_active=False)
        ]

        # check that only the non-option, task_only=False plugin is returned
        self.assertIn(MockPlugin2.name, plugin_names)
        self.assertNotIn(MockPlugin.name, plugin_names)
        self.assertNotIn(MockPlugin3.name, plugin_names)
Ejemplo n.º 4
0
 def testFilterAll__get_registered(self):
     """ registration.get_registered: returns all registered plugins.
         """
     registration._registered.register(MockPlugin.name, MockPlugin,
                                       {'command': True})
     self.assertIn(MockPlugin.name,
                   [x.name for x in registration.get_registered()])
Ejemplo n.º 5
0
    def testFilterActiveTask__get_registered(self):
        """ registration.get_registered: returns all registered
            plugins that are available when a task is active.
            """
        class MockPlugin2(MockPlugin):
            name = 'hai 2'
            options = None

        class MockPlugin3(MockPlugin):
            name = 'hai 3'
            options = None
            task_only = True

        # register a couple test plugins
        registration._registered.register(MockPlugin.name, MockPlugin,
                                          {'event': True})
        registration._registered.register(MockPlugin2.name, MockPlugin2,
                                          {'command': True})
        registration._registered.register(MockPlugin3.name, MockPlugin3,
                                          {'command': True})

        # get list of registered names for active task plugins
        plugin_names = [x.name for x in
                            registration.get_registered(task_active=True)]

        self.assertIn(MockPlugin.name, plugin_names)
        self.assertIn(MockPlugin2.name, plugin_names)
        self.assertIn(MockPlugin3.name, plugin_names)
Ejemplo n.º 6
0
    def testFilterNoActiveTask__get_registered(self):
        """ registration.get_registered: returns all registered
            plugins that can be seen when a task is not active.
            """
        class MockPlugin2(MockPlugin):
            name = 'hai 2'
            options = None

        class MockPlugin3(MockPlugin):
            name = 'hai 3'
            options = None
            task_only = True

        # register a couple test plugins
        registration._registered.register(MockPlugin.name, MockPlugin,
                                          {'event': True})
        registration._registered.register(MockPlugin2.name, MockPlugin2,
                                          {'command': True})
        registration._registered.register(MockPlugin3.name, MockPlugin3,
                                          {'command': True})

        # get list of registered names for active task plugins
        plugin_names = [x.name for x in
                            registration.get_registered(task_active=False)]

        # check that only the non-option, task_only=False plugin is returned
        self.assertIn(MockPlugin2.name, plugin_names)
        self.assertNotIn(MockPlugin.name, plugin_names)
        self.assertNotIn(MockPlugin3.name, plugin_names)
Ejemplo n.º 7
0
def shell_focusd(data_dir):
    """ Shells a new instance of a focusd daemon process.

        `data_dir`
            Home directory for focusd data.

        Returns boolean.

        * Raises ``ValueError`` if sudo used and all passwords tries failed.
        """

    command = 'focusd {0}'.format(data_dir)

    # see what event hook plugins are registered
    plugins = registration.get_registered(event_hooks=True)

    if not plugins:  # none registered, bail
        raise errors.NoPluginsRegistered

    # do any of the plugins need root access?
    # if so, wrap command with sudo to escalate privs, if not already root
    needs_root = any(p for p in plugins if p.needs_root)

    if needs_root and os.getuid() != 0:  # only if not already root
        command = 'sudo ' + command
    else:
        needs_root = False

    # shell the daemon process
    _, code = common.shell_process(command, exitcode=True)

    if code == 1 and needs_root:  # passwords failed?
        raise ValueError

    return code == 0
Ejemplo n.º 8
0
    def _prepare(self):
        """ Setup initial requirements for daemon run.
            """

        super(CommandServer, self)._prepare()

        # unregister all active plugins
        for plugin in registration.get_registered():
            registration.disable_plugin_instance(plugin)
Ejemplo n.º 9
0
def focusd(task):
    """ Forks the current process as a daemon to run a task.

        `task`
            ``Task`` instance for the task to run.
        """

    # determine if command server should be started
    if registration.get_registered(event_hooks=True, root_access=True):
        # root event plugins available
        start_cmd_srv = (os.getuid() == 0)  # must be root
    else:
        start_cmd_srv = False

    # daemonize our current process
    _run = lambda: Focusd(task).run(start_cmd_srv)
    daemonize(get_daemon_pidfile(task), task.task_dir, _run)
Ejemplo n.º 10
0
    def testGoodPlugins__load(self):
        """ Environment.load: successfully loads valid plugins.
            """
        # build test command plugin and load
        plugin_dir = os.path.join(self.env._data_dir, 'plugins')
        os.makedirs(plugin_dir)
        filename = os.path.join(plugin_dir, 'testplugin.py')
        with open(filename, 'w', 0) as f:
            f.write('from focus.plugin import Plugin\n')
            f.write('class MyTestPlugin(Plugin):\n')
            f.write('  name = "MyTestPlugin"\n')
            f.write('  target_version = ">=0.1.0"\n')
            f.write('  version = "1.0"\n')
            f.write('  command = "oh_hai"\n')
            f.write('  def execute(self, env): env.io.write("You rang.")\n')
            f.write('  def help(self, env): return u"focus oh_hai"\n')
        self.env.load()

        # confirm plugin registration in a couple ways..
        # 1) scan registered list
        # 2) get command hook version
        # 3) execute methods and compare
        plugin = None
        for p in registration.get_registered(command_hooks=True):
            if p.name == 'MyTestPlugin':
                plugin = p
                break

        success = False
        if plugin:
            test_plugin = registration.get_command_hook('oh_hai')
            if test_plugin == plugin:
                # test execute()
                plugin.execute(self.env)
                self.assertEqual(self.env.io.test__write_data, 'You rang.\n')

                # test help()
                data = plugin.help(self.env)
                self.assertEqual(data, u'focus oh_hai')
                success = True

        self.assertTrue(success)

        # clean up
        self.clean_paths(filename, filename + 'c')
Ejemplo n.º 11
0
    def testGoodPlugins__load(self):
        """ Environment.load: successfully loads valid plugins.
            """
        # build test command plugin and load
        plugin_dir = os.path.join(self.env._data_dir, 'plugins')
        os.makedirs(plugin_dir)
        filename = os.path.join(plugin_dir, 'testplugin.py')
        with open(filename, 'w', 0) as f:
            f.write('from focus.plugin import Plugin\n')
            f.write('class MyTestPlugin(Plugin):\n')
            f.write('  name = "MyTestPlugin"\n')
            f.write('  target_version = ">=0.1.0"\n')
            f.write('  version = "1.0"\n')
            f.write('  command = "oh_hai"\n')
            f.write('  def execute(self, env): env.io.write("You rang.")\n')
            f.write('  def help(self, env): return u"focus oh_hai"\n')
        self.env.load()

        # confirm plugin registration in a couple ways..
        # 1) scan registered list
        # 2) get command hook version
        # 3) execute methods and compare
        plugin = None
        for p in registration.get_registered(command_hooks=True):
            if p.name == 'MyTestPlugin':
                plugin = p
                break

        success = False
        if plugin:
            test_plugin = registration.get_command_hook('oh_hai')
            if test_plugin == plugin:
                # test execute()
                plugin.execute(self.env)
                self.assertEqual(self.env.io.test__write_data, 'You rang.\n')

                # test help()
                data = plugin.help(self.env)
                self.assertEqual(data, u'focus oh_hai')
                success = True

        self.assertTrue(success)

        # clean up
        self.clean_paths(filename, filename + 'c')
Ejemplo n.º 12
0
    def testFilterEventHook__get_registered(self):
        """ registration.get_registered: returns all registered task event
            plugins.
            """
        class MockPlugin2(MockPlugin):
            name = 'hai 2'

        # register a command and event plugin
        registration._registered.register(MockPlugin.name, MockPlugin,
                                          {'event': True})
        registration._registered.register(MockPlugin2.name, MockPlugin2,
                                          {'command': True})

        # get list of registered names for event plugins
        plugin_names = [x.name for x in
                            registration.get_registered(event_hooks=True)]

        # make sure MockPlugin is the only event plugin
        self.assertIn(MockPlugin.name, plugin_names)
        self.assertNotIn(MockPlugin2.name, plugin_names)
Ejemplo n.º 13
0
    def testFilterEventHook__get_registered(self):
        """ registration.get_registered: returns all registered task event
            plugins.
            """
        class MockPlugin2(MockPlugin):
            name = 'hai 2'

        # register a command and event plugin
        registration._registered.register(MockPlugin.name, MockPlugin,
                                          {'event': True})
        registration._registered.register(MockPlugin2.name, MockPlugin2,
                                          {'command': True})

        # get list of registered names for event plugins
        plugin_names = [
            x.name for x in registration.get_registered(event_hooks=True)
        ]

        # make sure MockPlugin is the only event plugin
        self.assertIn(MockPlugin.name, plugin_names)
        self.assertNotIn(MockPlugin2.name, plugin_names)
Ejemplo n.º 14
0
    def _setup_root_plugins(self):
        """ Injects a `run_root` method into the registered root event plugins.
            """

        def run_root(_self, command):
            """ Executes a shell command as root.

                `command`
                    Shell command string.

                Returns boolean.
                """

            try:
                # get lock, so this plugin has exclusive access to command pipe
                self._rlock.acquire()

                # TODO: log root command for this plugin
                self._cmd_pipe.send_bytes('\x80'.join(['SHL', command]))
                res = self._cmd_pipe.recv_bytes()

                if res != 'TRM':  # sentinel value, shutdown
                    return res == 'OK'

            except (EOFError, IOError):
                pass

            finally:
                self._rlock.release()

            self.shutdown(skip_hooks=True)
            return False

        # inject method into each event plugin
        for plugin in registration.get_registered(event_hooks=True,
                                                  root_access=True):
            plugin.run_root = types.MethodType(run_root, plugin)
Ejemplo n.º 15
0
Archivo: cli.py Proyecto: nyimbi/focus
    def _get_parser(self, env):
        """ Creates base argument parser.

            `env`
                Runtime ``Environment`` instance.

            * Raises ``HelpBanner`` exception when certain conditions apply.

            Returns ``FocusArgumentParser`` object.
            """

        version_str = 'focus version ' + __version__
        usage_str = 'focus [-h] [-v] [--no-color] <command> [<args>]'

        # setup parser
        parser = FocusArgParser(description=("Command-line productivity tool "
                                             "for improved task workflows."),
                                epilog=("See 'focus help <command>' for more "
                                        "information on a specific command."),
                                usage=usage_str)

        parser.add_argument('-v', '--version', action='version',
                            version=version_str)
        parser.add_argument('--no-color', action='store_true',
                            help='disables colors')

        # fetch command plugins
        commands = []
        active = env.task.active
        command_hooks = registration.get_registered(command_hooks=True,
                                                    task_active=active)

        # extract command name and docstrings as help text
        for plugin in command_hooks:
            help_text = (plugin.__doc__ or '').strip().rstrip('.').lower()
            commands.append((plugin.command, help_text))
        commands.sort(key=lambda x: x[0])  # command ordered

        # install subparsers
        subparsers = parser.add_subparsers(title='available commands')

        # install 'help' subparser
        help_parser = subparsers.add_parser('help', add_help=False)
        help_parser.set_defaults(func=self._handle_help)

        # install 'version' subparser
        version_parser = subparsers.add_parser('version', add_help=False)

        def _print_version(env, args):
            env.io.write(version_str)
            return True
        version_parser.set_defaults(func=_print_version)

        # install command subparsers based on registered command plugins.
        # this allows for focus commands (e.g. focus on [...])

        for command, help_ in commands:
            cmd_parser = subparsers.add_parser(command, help=help_,
                                               add_help=False)

            # use wrapper to bind command value and passthru to _handle_command
            # when executed later
            def _run(command):
                def _wrapper(env, args):
                    return self._handle_command(command, env, args)
                return _wrapper
            cmd_parser.set_defaults(func=_run(command))

        return parser
Ejemplo n.º 16
0
    def _get_parser(self, env):
        """ Creates base argument parser.

            `env`
                Runtime ``Environment`` instance.

            * Raises ``HelpBanner`` exception when certain conditions apply.

            Returns ``FocusArgumentParser`` object.
            """

        version_str = 'focus version ' + __version__
        usage_str = 'focus [-h] [-v] [--no-color] <command> [<args>]'

        # setup parser
        parser = FocusArgParser(description=("Command-line productivity tool "
                                             "for improved task workflows."),
                                epilog=("See 'focus help <command>' for more "
                                        "information on a specific command."),
                                usage=usage_str)

        parser.add_argument('-v',
                            '--version',
                            action='version',
                            version=version_str)
        parser.add_argument('--no-color',
                            action='store_true',
                            help='disables colors')

        # fetch command plugins
        commands = []
        active = env.task.active
        command_hooks = registration.get_registered(command_hooks=True,
                                                    task_active=active)

        # extract command name and docstrings as help text
        for plugin in command_hooks:
            help_text = (plugin.__doc__ or '').strip().rstrip('.').lower()
            commands.append((plugin.command, help_text))
        commands.sort(key=lambda x: x[0])  # command ordered

        # install subparsers
        subparsers = parser.add_subparsers(title='available commands')

        # install 'help' subparser
        help_parser = subparsers.add_parser('help', add_help=False)
        help_parser.set_defaults(func=self._handle_help)

        # install 'version' subparser
        version_parser = subparsers.add_parser('version', add_help=False)

        def _print_version(env, args):
            env.io.write(version_str)
            return True

        version_parser.set_defaults(func=_print_version)

        # install command subparsers based on registered command plugins.
        # this allows for focus commands (e.g. focus on [...])

        for command, help_ in commands:
            cmd_parser = subparsers.add_parser(command,
                                               help=help_,
                                               add_help=False)

            # use wrapper to bind command value and passthru to _handle_command
            # when executed later
            def _run(command):
                def _wrapper(env, args):
                    return self._handle_command(command, env, args)

                return _wrapper

            cmd_parser.set_defaults(func=_run(command))

        return parser