summaryrefslogtreecommitdiffstats
path: root/py3status
diff options
context:
space:
mode:
authorUltrabug <ultrabug@gentoo.org>2014-11-23 18:53:04 +0100
committerUltrabug <ultrabug@gentoo.org>2014-11-23 18:53:04 +0100
commit62b2bd2251997bf8608e9620d91f688585221040 (patch)
tree197129ae4b542a8a7768b0f1dd1292912e5832ab /py3status
parent8b79ab6d38c81864f71adeec86958010358d4340 (diff)
generate and use a temporary i3status config on the fly so that we can now extend it with our own modules without breaking i3status
Diffstat (limited to 'py3status')
-rwxr-xr-xpy3status/__init__.py129
1 files changed, 77 insertions, 52 deletions
diff --git a/py3status/__init__.py b/py3status/__init__.py
index 1b88374..31b623e 100755
--- a/py3status/__init__.py
+++ b/py3status/__init__.py
@@ -14,6 +14,7 @@ from signal import SIGUSR1
from subprocess import Popen
from subprocess import PIPE
from subprocess import call
+from tempfile import NamedTemporaryFile
from threading import Event, Thread
from time import sleep, time
from syslog import syslog, LOG_ERR, LOG_INFO, LOG_WARNING
@@ -82,7 +83,6 @@ class I3status(Thread):
"""
Thread.__init__(self)
self.error = None
- self.i3status_config_path = i3status_config_path
self.i3status_module_names = [
'battery',
'cpu_temperature',
@@ -108,9 +108,9 @@ class I3status(Thread):
self.standalone = standalone
self.time_format = '%Y-%m-%d %H:%M:%S'
#
- self.config = self.i3status_config_reader()
+ self.config = self.i3status_config_reader(i3status_config_path)
- def i3status_config_reader(self):
+ def i3status_config_reader(self, i3status_config_path):
"""
Parse i3status.conf so we can adapt our code to the i3status config.
"""
@@ -131,7 +131,7 @@ class I3status(Thread):
in_section = False
section_name = ''
- for line in open(self.i3status_config_path, 'r'):
+ for line in open(i3status_config_path, 'r'):
line = line.strip(' \t\n\r')
if not line or line.startswith('#'):
@@ -177,7 +177,7 @@ class I3status(Thread):
if config['general']['output_format'] != 'i3bar':
raise RuntimeError(
'i3status output_format should '
- 'be set to "i3bar" on {}'.format(self.i3status_config_path)
+ 'be set to "i3bar" on {}'.format(i3status_config_path)
)
return config
@@ -223,60 +223,85 @@ class I3status(Thread):
self.json_list = deepcopy(self.last_output)
self.json_list_ts = deepcopy(self.last_output_ts)
+ def write_tmp_i3status_config(self, tmpfile):
+ """
+ Given a temporary file descriptor, write a valid i3status config file
+ based on the parsed one from 'i3status_config_path'.
+ """
+ valid_section_names = self.i3status_module_names + ['general', 'order']
+ for section_name, conf in self.config.items():
+ if section_name == 'order':
+ for module_name in conf:
+ tmpfile.write('order += "%s"\n' % module_name)
+ tmpfile.write('\n')
+ elif section_name.split(' ')[0] in valid_section_names:
+ tmpfile.write('%s {\n' % section_name)
+ for key, value in conf.items():
+ tmpfile.write(' %s = "%s"\n' % (key, value))
+ tmpfile.write('}\n\n')
+ tmpfile.flush()
+
def run(self):
"""
- Spawn i3status and poll its output.
+ Spawn i3status using a self generated config file and poll its output.
"""
- i3status_pipe = Popen(
- ['i3status', '-c', self.i3status_config_path],
- stdout=PIPE,
- stderr=PIPE,
- )
- self.poller_inp = IOPoller(i3status_pipe.stdout)
- self.poller_err = IOPoller(i3status_pipe.stderr)
+ with NamedTemporaryFile(prefix='py3status_') as tmpfile:
+ self.write_tmp_i3status_config(tmpfile)
+ syslog(
+ LOG_INFO,
+ 'i3status spawned using config file {}'.format(tmpfile.name)
+ )
- try:
- # at first, poll very quickly to avoid delay in first i3bar display
- timeout = 0.001
+ 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)
- # loop on i3status output
- while self.lock.is_set():
- line = self.poller_inp.readline(timeout)
- if line:
- if line.startswith('[{'):
- with jsonify(line) as (prefix, json_list):
- self.last_output = json_list
- self.last_output_ts = datetime.utcnow()
- self.last_prefix = ','
- self.update_json_list()
- print_line(line)
- elif not line.startswith(','):
- if 'version' in line:
- header = loads(line)
- header.update({'click_events': True})
- line = dumps(header)
- print_line(line)
- else:
- timeout = 0.5
- with jsonify(line) as (prefix, json_list):
- self.last_output = json_list
- self.last_output_ts = datetime.utcnow()
- self.last_prefix = prefix
- else:
- err = self.poller_err.readline(timeout)
- code = i3status_pipe.poll()
- if code is not None:
- if err:
- msg = 'i3status died and said: {}'.format(err)
+ try:
+ # at first, poll very quickly to avoid delay in first i3bar display
+ timeout = 0.001
+
+ # loop on i3status output
+ while self.lock.is_set():
+ line = self.poller_inp.readline(timeout)
+ if line:
+ if line.startswith('[{'):
+ with jsonify(line) as (prefix, json_list):
+ self.last_output = json_list
+ self.last_output_ts = datetime.utcnow()
+ self.last_prefix = ','
+ self.update_json_list()
+ print_line(line)
+ elif not line.startswith(','):
+ if 'version' in line:
+ header = loads(line)
+ header.update({'click_events': True})
+ line = dumps(header)
+ print_line(line)
else:
- msg = 'i3status died with code {}'.format(code)
- raise IOError(msg)
+ timeout = 0.5
+ with jsonify(line) as (prefix, json_list):
+ self.last_output = json_list
+ self.last_output_ts = datetime.utcnow()
+ self.last_prefix = prefix
else:
- # poll is CPU intensive, breath a bit
- sleep(timeout)
- except IOError:
- err = sys.exc_info()[1]
- self.error = err
+ err = self.poller_err.readline(timeout)
+ code = i3status_pipe.poll()
+ if code is not None:
+ if err:
+ msg = 'i3status died and said: {}'.format(err)
+ else:
+ msg = 'i3status died with code {}'.format(code)
+ raise IOError(msg)
+ else:
+ # poll is CPU intensive, breath a bit
+ sleep(timeout)
+ except IOError:
+ err = sys.exc_info()[1]
+ self.error = err
def mock(self):
"""