def start_processes(self): """Start helper and daemon via pkexec to run in the background.""" # this function is overwritten in tests self.dbus = Daemon.connect() debug = ' -d' if is_debug() else '' cmd = f'pkexec key-mapper-control --command helper {debug}' logger.debug('Running `%s`', cmd) exit_code = os.system(cmd) if exit_code != 0: logger.error('Failed to pkexec the helper, code %d', exit_code) sys.exit()
def connect(cls, fallback=True): """Get an interface to start and stop injecting keystrokes. Parameters ---------- fallback : bool If true, returns an instance of the daemon instead if it cannot connect """ try: bus = SystemBus() interface = bus.get(BUS_NAME) logger.info('Connected to the service') except GLib.GError as error: if not fallback: logger.error('Service not running? %s', error) return None logger.info('Starting the service') # Blocks until pkexec is done asking for the password. # Runs via key-mapper-control so that auth_admin_keep works # for all pkexec calls of the gui debug = ' -d' if is_debug() else '' cmd = f'pkexec key-mapper-control --command start-daemon {debug}' # using pkexec will also cause the service to continue running in # the background after the gui has been closed, which will keep # the injections ongoing logger.debug('Running `%s`', cmd) os.system(cmd) time.sleep(0.2) # try a few times if the service was just started for attempt in range(3): try: interface = bus.get(BUS_NAME) break except GLib.GError as error: logger.debug( 'Attempt %d to connect to the service failed: "%s"', attempt + 1, error) time.sleep(0.2) else: logger.error('Failed to connect to the service') sys.exit(1) return interface
def log(key, msg, *args): """Function that logs nicely formatted spams.""" if not is_debug(): return msg = msg % args str_key = str(key) str_key = str_key.replace(',)', ')') spacing = ' ' + '-' * max(0, 30 - len(str_key)) if len(spacing) == 1: spacing = '' msg = f'{str_key}{spacing} {msg}' logger.spam(msg) return msg