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)
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
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])
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])
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])
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])
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])
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])
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
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])
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])
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])
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
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
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
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')
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])