From e3829b5700fd1dbee250811071a1878d323ffeeb Mon Sep 17 00:00:00 2001 From: enkore Date: Mon, 18 Feb 2013 19:15:27 +0100 Subject: [PATCH] We were finally successful in moving the input loop to the lower I/O layer. This means we unified the loop with it's implicit abort condition (end of stream or ^C). --- i3pystatus/__init__.py | 50 ++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/i3pystatus/__init__.py b/i3pystatus/__init__.py index dac594f..485de11 100644 --- a/i3pystatus/__init__.py +++ b/i3pystatus/__init__.py @@ -39,40 +39,56 @@ class IOHandler: self.inp = inp self.out = out - def write(self, message): + def write_line(self, message): """Unbuffered printing to stdout.""" self.out.write(message + "\n") self.out.flush() def read(self): - """Interrupted respecting reader for stdin.""" + """Iterate over all input lines (Generator)""" + + while True: + try: + yield self.read_line() + except EOFError: + return + + def read_line(self): + """Interrupted respecting reader for stdin. + + Raises EOFError if the end of stream has been reached""" - # try reading a line, removing any extra whitespace try: line = self.inp.readline().decode("utf-8").strip() - # i3status sends EOF, or an empty line - if not line: - sys.exit(3) - return line - # exit on ctrl-c except KeyboardInterrupt: - sys.exit() + raise EOFError() + + # i3status sends EOF, or an empty line + if not line: + raise EOFError() + return line class JSONIO: def __init__(self, io): self.io = io - self.io.write(self.io.read()) - self.io.write(self.io.read()) + self.io.write_line(self.io.read_line()) + self.io.write_line(self.io.read_line()) def read(self): - while True: - with self.read_line() as j: + """Iterate over all JSON input (Generator)""" + + for line in self.io.read(): + with self.parse_line(line) as j: yield j @contextmanager - def read_line(self): - line, prefix = self.io.read(), "" + def parse_line(self, line): + """Parse a single line of JSON and write modified JSON back. + + Usage is quite simple using the usual with-Syntax.""" + + prefix = "" # ignore comma at start of lines if line.startswith(","): @@ -80,7 +96,7 @@ class JSONIO: j = json.loads(line) yield j - self.io.write(prefix + json.dumps(j)) + self.io.write_line(prefix + json.dumps(j)) class I3statusHandler: modules = [] @@ -99,6 +115,6 @@ class I3statusHandler: module.registered(self) def run(self): - for j in self.io.read(): + for j in self.io.read(): for module in self.modules: j.insert(module.position, module.output)