コード例 #1
0
    def _play_sound(self, filename):
        """ Shells player with the provided filename.

            `filename`
                Filename for sound file.
            """

        command = self._get_external_player()
        if not command:
            return  # no player found

        if common.IS_MACOSX:
            command += ' "{0}"'.format(filename)
        else:
            # append quiet flag and filename
            is_play = (command == 'play')
            command += ' -q "{0}"'.format(filename)

            # HACK: play can default to using pulseaudio. here, we
            # check if pulse command exists and delegate to alsa if
            # not
            if is_play and not common.which('pulseaudio'):
                command += ' -t alsa'

        # play sound file, ignore if it fails
        common.shell_process(command, background=True)
コード例 #2
0
ファイル: apps.py プロジェクト: nyimbi/focus
    def _run_apps(self, paths):
        """ Runs apps for the provided paths.
            """

        for path in paths:
            common.shell_process(path, background=True)
            time.sleep(0.2)  # delay some between starts
コード例 #3
0
    def _run_apps(self, paths):
        """ Runs apps for the provided paths.
            """

        for path in paths:
            common.shell_process(path, background=True)
            time.sleep(0.2)  # delay some between starts
コード例 #4
0
ファイル: sounds.py プロジェクト: nyimbi/focus
    def _play_sound(self, filename):
        """ Shells player with the provided filename.

            `filename`
                Filename for sound file.
            """

        command = self._get_external_player()
        if not command:
            return  # no player found

        if common.IS_MACOSX:
            command += ' "{0}"'.format(filename)
        else:
            # append quiet flag and filename
            is_play = (command == 'play')
            command += ' -q "{0}"'.format(filename)

            # HACK: play can default to using pulseaudio. here, we
            # check if pulse command exists and delegate to alsa if
            # not
            if is_play and not common.which('pulseaudio'):
                command += ' -t alsa'

        # play sound file, ignore if it fails
        common.shell_process(command, background=True)
コード例 #5
0
ファイル: test_common.py プロジェクト: nyimbi/focus
    def testExistCommand__shell_process(self):
        """ common.shell_process: works if command doesn't exist.
            """
        # test foregrounded
        self.assertIsNotNone(common.shell_process('ls'))
        res = common.shell_process('ls', exitcode=True)
        self.assertIsNotNone(res[0])
        self.assertEqual(res[1], 0)

        # test backgrounded, returns immediately with None
        self.assertIsNone(common.shell_process('ls', background=True))
        res = common.shell_process('ls', exitcode=True, background=True)
        self.assertIsNone(res[0])
        self.assertIsNone(res[1])
コード例 #6
0
    def testExistCommand__shell_process(self):
        """ common.shell_process: works if command doesn't exist.
            """
        # test foregrounded
        self.assertIsNotNone(common.shell_process('ls'))
        res = common.shell_process('ls', exitcode=True)
        self.assertIsNotNone(res[0])
        self.assertEqual(res[1], 0)

        # test backgrounded, returns immediately with None
        self.assertIsNone(common.shell_process('ls', background=True))
        res = common.shell_process('ls', exitcode=True, background=True)
        self.assertIsNone(res[0])
        self.assertIsNone(res[1])
コード例 #7
0
ファイル: test_common.py プロジェクト: nyimbi/focus
    def testNotExistCommand__shell_process(self):
        """ common.shell_process: fails if command doesn't exist.
            """
        # test foregrounded
        self.assertIsNone(common.shell_process('llama-llama'))
        res = common.shell_process('llama-llama', exitcode=True)
        self.assertIsNone(res[0])
        self.assertEqual(res[1], 127)  # shell exit code, command not found

        # test backgrounded, returns immediately with None
        self.assertIsNone(common.shell_process('llama-llama', background=True))
        res = common.shell_process('llama-llama', exitcode=True,
                                   background=True)
        self.assertIsNone(res[0])
        self.assertIsNone(res[1])
コード例 #8
0
ファイル: notify.py プロジェクト: xtrementl/focus
def _growlnotify(title, message):
    """ Shows growl notification message via `growlnotify` command.

        `title`
            Notification title.
        `message`
            Notification message.
        """

    try:
        paths = common.extract_app_paths(["growlnotify"])
    except ValueError:
        return

    common.shell_process([paths[0], "-t", title, "-m", message])
コード例 #9
0
ファイル: notify.py プロジェクト: xtrementl/focus
def _growlnotify(title, message):
    """ Shows growl notification message via `growlnotify` command.

        `title`
            Notification title.
        `message`
            Notification message.
        """

    try:
        paths = common.extract_app_paths(['growlnotify'])
    except ValueError:
        return

    common.shell_process([paths[0], '-t', title, '-m', message])
コード例 #10
0
ファイル: notify.py プロジェクト: xtrementl/focus
def _terminal_notifier(title, message):
    """ Shows user notification message via `terminal-notifier` command.

        `title`
            Notification title.
        `message`
            Notification message.
        """

    try:
        paths = common.extract_app_paths(["terminal-notifier"])
    except ValueError:
        pass

    common.shell_process([paths[0], "-title", title, "-message", message])
コード例 #11
0
ファイル: notify.py プロジェクト: xtrementl/focus
def _terminal_notifier(title, message):
    """ Shows user notification message via `terminal-notifier` command.

        `title`
            Notification title.
        `message`
            Notification message.
        """

    try:
        paths = common.extract_app_paths(['terminal-notifier'])
    except ValueError:
        pass

    common.shell_process([paths[0], '-title', title, '-message', message])
コード例 #12
0
ファイル: daemon.py プロジェクト: nyimbi/focus
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
コード例 #13
0
    def testNotExistCommand__shell_process(self):
        """ common.shell_process: fails if command doesn't exist.
            """
        # test foregrounded
        self.assertIsNone(common.shell_process('llama-llama'))
        res = common.shell_process('llama-llama', exitcode=True)
        self.assertIsNone(res[0])
        self.assertEqual(res[1], 127)  # shell exit code, command not found

        # test backgrounded, returns immediately with None
        self.assertIsNone(common.shell_process('llama-llama', background=True))
        res = common.shell_process('llama-llama',
                                   exitcode=True,
                                   background=True)
        self.assertIsNone(res[0])
        self.assertIsNone(res[1])
コード例 #14
0
ファイル: notify.py プロジェクト: xtrementl/focus
def _osx_popup(title, message):
    """ Shows a popup dialog message via System Events daemon.

        `title`
            Notification title.
        `message`
            Notification message.
        """

    message = message.replace('"', '\\"')  # escape message

    # build applescript
    script = """
     tell application "System Events"
       display dialog "{0}"
     end tell""".format(message)

    # run it
    common.shell_process(['osascript', '-e', script])
コード例 #15
0
ファイル: im.py プロジェクト: xtrementl/focus
def _adium_status(status, message):
    """ Updates status and message for Adium IM application.

        `status`
            Status type.
        `message`
            Status message.
        """

    # map status code
    code = ADIUM_CODE_MAP[status]

    # get message
    if not message:
        default_messages = {
            'busy': 'Busy',
            'long_away': 'Extended away'
        }
        message = default_messages.get(status, '')
    else:
        message = message.replace('"', '\\"')  # escape message

    # build applescript
    #  if adium is running:
    #  * set status
    #  * also set status message, if provided
    script = """
     tell application "System Events"
      if exists process "Adium" then
       tell application "Adium" to go {0}""".format(code)

    if message:
        # set status message
        script += ' with message "{0}"'.format(message)

    script += """
      end if
     end tell"""

    # run it
    common.shell_process(['osascript', '-e', script])
コード例 #16
0
ファイル: notify.py プロジェクト: xtrementl/focus
def _osx_popup(title, message):
    """ Shows a popup dialog message via System Events daemon.

        `title`
            Notification title.
        `message`
            Notification message.
        """

    message = message.replace('"', '\\"')  # escape message

    # build applescript
    script = """
     tell application "System Events"
       display dialog "{0}"
     end tell""".format(
        message
    )

    # run it
    common.shell_process(["osascript", "-e", script])
コード例 #17
0
ファイル: registration.py プロジェクト: xtrementl/focus
    def run_root(self, command):
        """ Executes a shell command as root.

            `command`
                Shell command string.

            Returns boolean.
            """
        try:
            return not (common.shell_process('sudo ' + command) is None)

        except KeyboardInterrupt:  # user cancelled
            return False
コード例 #18
0
ファイル: registration.py プロジェクト: nyimbi/focus
    def run_root(self, command):
        """ Executes a shell command as root.

            `command`
                Shell command string.

            Returns boolean.
            """
        try:
            return not (common.shell_process('sudo ' + command) is None)

        except KeyboardInterrupt:  # user cancelled
            return False
コード例 #19
0
ファイル: daemon.py プロジェクト: nyimbi/focus
    def _process_commands(self):
        """ Processes commands received and executes them accordingly.
            Returns ``True`` if successful, ``False`` if connection closed or
            server terminated.
            """

        try:
            # poll for data, so we don't block forever
            if self._cmd_pipe.poll(1):  # 1 sec timeout
                payload = self._cmd_pipe.recv_bytes()

                if payload:
                    # segment payload
                    parts = payload.split('\x80', 2)
                    _op = parts[0]

                    # terminate operation
                    if _op == 'TRM':
                        raise EOFError

                    # shell command operation
                    elif _op == 'SHL' and len(parts) == 2:
                        command = parts[1]

                        if command:
                            # run command and return success or fail
                            res = common.shell_process(command)

                            if res is not None:
                                self._cmd_pipe.send_bytes('OK')
                                return True

                    # everything else, should reply with "FAIL"
                    self._cmd_pipe.send_bytes('FAIL')

        except (EOFError, IOError):
            return False

        else:
            return True
コード例 #20
0
def _get_process_cwd(pid):
    """ Returns the working directory for the provided process identifier.

        `pid`
            System process identifier.

        Returns string or ``None``.

        Note this is used as a workaround, since `psutil` isn't consistent on
        being able to provide this path in all cases, especially MacOS X.
        """

    cmd = 'lsof -a -p {0} -d cwd -Fn'.format(pid)

    data = common.shell_process(cmd)

    if not data is None:
        lines = str(data).split('\n')

        # the cwd is the second line with 'n' prefix removed from value
        if len(lines) > 1:
            return lines[1][1:] or None

    return None
コード例 #21
0
ファイル: apps.py プロジェクト: nyimbi/focus
def _get_process_cwd(pid):
    """ Returns the working directory for the provided process identifier.

        `pid`
            System process identifier.

        Returns string or ``None``.

        Note this is used as a workaround, since `psutil` isn't consistent on
        being able to provide this path in all cases, especially MacOS X.
        """

    cmd = 'lsof -a -p {0} -d cwd -Fn'.format(pid)

    data = common.shell_process(cmd)

    if not data is None:
        lines = str(data).split('\n')

        # the cwd is the second line with 'n' prefix removed from value
        if len(lines) > 1:
            return lines[1][1:] or None

    return None
コード例 #22
0
ファイル: test_common.py プロジェクト: nyimbi/focus
    def testExistCommandInputData__shell_process(self):
        """ common.shell_process: passes input data to process and supports
            shell redirection.
            """
        # test foregrounded
        self.assertEqual(common.shell_process('cat -', input_data='monkeys'),
                         'monkeys')

        res = common.shell_process('cat -', exitcode=True,
                                   input_data='monkeys')
        self.assertEqual(res[0], 'monkeys')
        self.assertEqual(res[1], 0)

        # backgrounded doesn't support passing `input`
        with self.assertRaises(TypeError):
            common.shell_process('ls', background=True, input_data='monkeys')
        with self.assertRaises(TypeError):
            common.shell_process('ls', exitcode=True, background=True,
                input_data='monkeys')
コード例 #23
0
    def testExistCommandInputData__shell_process(self):
        """ common.shell_process: passes input data to process and supports
            shell redirection.
            """
        # test foregrounded
        self.assertEqual(common.shell_process('cat -', input_data='monkeys'),
                         'monkeys')

        res = common.shell_process('cat -',
                                   exitcode=True,
                                   input_data='monkeys')
        self.assertEqual(res[0], 'monkeys')
        self.assertEqual(res[1], 0)

        # backgrounded doesn't support passing `input`
        with self.assertRaises(TypeError):
            common.shell_process('ls', background=True, input_data='monkeys')
        with self.assertRaises(TypeError):
            common.shell_process('ls',
                                 exitcode=True,
                                 background=True,
                                 input_data='monkeys')
コード例 #24
0
ファイル: im.py プロジェクト: xtrementl/focus
def _osx_skype_status(status, message):
    """ Updates status and message for Skype IM application on Mac OSX.

        `status`
            Status type.
        `message`
            Status message.
        """

    # XXX: Skype has a bug with it's applescript support on Snow Leopard
    # where it will ignore the "not exists process" expression when
    # combined with "tell application Skype" and thus launches Skype if
    # it's not running. Obviously, this is what we're trying to avoid.
    #
    # The workaround here is to scan the user process list for Skype and
    # bail if we don't find it.

    uid = os.getuid()

    for proc in psutil.process_iter():
        try:
            if proc.uids.real == uid and proc.name == 'Skype':
                skype_running = True
                break
        except (psutil.AccessDenied, psutil.NoSuchProcess):
            pass
    else:
        skype_running = False

    if skype_running:
        code = SKYPE_CODE_MAP[status]  # map status code
        message = message.replace('"', '\\"')  # escape message

        # build applescript
        #   auto-approve skype security dialog
        #   * hide dialog by setting app hidden
        #   * select allow radio button and click OK on dialog
        #   * restore original app visibility

        #   main loop
        #   * while security dialog is shown or app is loading
        #   ** fetch user status to determine if in pending state
        #   ** run auto-approve if still in pending state

        #   set status command
        #   set status message (mood)

        script = """
         on approve()
          tell application "System Events"
            set vis to the visible of process "Skype"
            set visible of process "Skype" to false
            tell process "Skype"
              set winName to "Skype API Security"
              set rdoBtn to "Allow this application to use Skype"
              if exists (radio button rdoBtn of radio group 1 of window {LC}
              winName) then
                click radio button rdoBtn of radio group 1 of window winName
                delay 0.5
                click button "OK" of window winName
              end if
            end tell
            set visible of process "Skype" to vis
          end tell
         end approve

         tell application "Skype"
          set stat to "COMMAND_PENDING"
          repeat until stat is not equal to "COMMAND_PENDING"
           set stat to send command "GET USERSTATUS" script name "focus"
           if stat is equal to "COMMAND_PENDING" then my approve()
           delay 0.5
          end repeat

          send command "SET USERSTATUS {code}" script name "focus"
          send command "SET PROFILE MOOD_TEXT {mood}" script name "focus"
         end tell""".format(**{
            'code': code,
            'mood': message,
            'LC': "\xc2\xac"
        })

        # run it
        common.shell_process(['osascript', '-e', script])