def run(self): """ Spawn i3status using a self generated config file and poll its output. """ try: with NamedTemporaryFile(prefix='py3status_') as tmpfile: self.write_tmp_i3status_config(tmpfile) syslog( LOG_INFO, 'i3status spawned using config file {}'.format( tmpfile.name)) i3status_pipe = Popen( ['i3status', '-c', tmpfile.name], stdout=PIPE, stderr=PIPE, ) self.poller_inp = IOPoller(i3status_pipe.stdout) self.poller_err = IOPoller(i3status_pipe.stderr) self.tmpfile_path = tmpfile.name try: # loop on i3status output while self.lock.is_set(): line = self.poller_inp.readline() if line: if line.startswith('[{'): print_line(line) with jsonify(line) as (prefix, json_list): self.last_output = json_list self.last_prefix = ',' self.set_responses(json_list) self.ready = True elif not line.startswith(','): if 'version' in line: header = loads(line) header.update({'click_events': True}) line = dumps(header) print_line(line) else: with jsonify(line) as (prefix, json_list): self.last_output = json_list self.last_prefix = prefix self.set_responses(json_list) else: err = self.poller_err.readline() code = i3status_pipe.poll() if code is not None: msg = 'i3status died' if err: msg += ' and said: {}'.format(err) else: msg += ' with code {}'.format(code) raise IOError(msg) except IOError: err = sys.exc_info()[1] self.error = err except OSError: # we cleanup the tmpfile ourselves so when the delete will occur # it will usually raise an OSError: No such file or directory pass
def run(self): """ Spawn i3status using a self generated config file and poll its output. """ try: with NamedTemporaryFile(prefix='py3status_') as tmpfile: self.write_tmp_i3status_config(tmpfile) syslog(LOG_INFO, 'i3status spawned using config file {}'.format( tmpfile.name)) i3status_pipe = Popen( ['i3status', '-c', tmpfile.name], stdout=PIPE, stderr=PIPE, ) self.poller_inp = IOPoller(i3status_pipe.stdout) self.poller_err = IOPoller(i3status_pipe.stderr) self.tmpfile_path = tmpfile.name try: # loop on i3status output while self.lock.is_set(): line = self.poller_inp.readline() if line: if line.startswith('[{'): print_line(line) with jsonify(line) as (prefix, json_list): self.last_output = json_list self.last_prefix = ',' self.set_responses(json_list) self.ready = True elif not line.startswith(','): if 'version' in line: header = loads(line) header.update({'click_events': True}) line = dumps(header) print_line(line) else: with jsonify(line) as (prefix, json_list): self.last_output = json_list self.last_prefix = prefix self.set_responses(json_list) else: err = self.poller_err.readline() code = i3status_pipe.poll() if code is not None: msg = 'i3status died' if err: msg += ' and said: {}'.format(err) else: msg += ' with code {}'.format(code) raise IOError(msg) except IOError: err = sys.exc_info()[1] self.error = err except OSError: # we cleanup the tmpfile ourselves so when the delete will occur # it will usually raise an OSError: No such file or directory pass
def run(self): """ Wait for an i3bar JSON event, then find the right module to dispatch the message to based on the 'name' and 'instance' of the event. In case the module does NOT support click_events, the default implementation is to clear the module's cache when the MIDDLE button (2) is pressed on it. Example event: {'y': 13, 'x': 1737, 'button': 1, 'name': 'empty', 'instance': 'first'} """ while self.lock.is_set(): event = self.poller_inp.readline() if not event: continue try: with jsonify(event) as (prefix, event): if self.config['debug']: syslog(LOG_INFO, 'received event {}'.format(event)) # usage variables instance = event.get('instance', '') name = event.get('name', '') # i3status module name guess instance, name = self.i3status_mod_guess(instance, name) if self.config['debug']: syslog( LOG_INFO, 'trying to dispatch event to module "{}"'.format( '{} {}'.format(name, instance).strip())) # guess the module config name module_name = '{} {}'.format(name, instance).strip() # do the work self.process_event(module_name, event) except Exception: err = sys.exc_info()[1] syslog(LOG_WARNING, 'event failed ({})'.format(err))
def run(self): """ Wait for an i3bar JSON event, then find the right module to dispatch the message to based on the 'name' and 'instance' of the event. In case the module does NOT support click_events, the default implementation is to clear the module's cache when the MIDDLE button (2) is pressed on it. Example event: {'y': 13, 'x': 1737, 'button': 1, 'name': 'empty', 'instance': 'first'} """ while self.lock.is_set(): event = self.poller_inp.readline() if not event: continue try: with jsonify(event) as (prefix, event): if self.config['debug']: syslog(LOG_INFO, 'received event {}'.format(event)) # usage variables button = event.get('button', 0) default_event = False dispatched = False instance = event.get('instance', '') name = event.get('name', '') # i3status module name guess instance, name = self.i3status_mod_guess(instance, name) if self.config['debug']: syslog( LOG_INFO, 'trying to dispatch event to module "{}"'.format( '{} {}'.format(name, instance).strip())) # guess the module config name module_name = '{} {}'.format(name, instance).strip() # execute any configured i3-msg command if self.on_click.get(module_name, {}).get(button): self.on_click_dispatcher( module_name, self.on_click[module_name].get(button)) dispatched = True # otherwise setup default action on button 2 press elif button == 2: default_event = True for module in self.modules.values(): # skip modules not supporting click_events # unless we have a default_event set if not module.click_events and not default_event: continue # check for the method name/instance for obj in module.methods.values(): if name == obj['name']: if instance: if instance == obj['instance']: self.dispatch(module, obj, event) dispatched = True break else: self.dispatch(module, obj, event) dispatched = True break # fall back to i3bar_click_events.py module if present if not dispatched: module = self.i3bar_click_events_module() if module: if self.config['debug']: syslog( LOG_INFO, 'dispatching event to i3bar_click_events') self.dispatch(module, obj, event) except Exception: err = sys.exc_info()[1] syslog(LOG_WARNING, 'event failed ({})'.format(err))