Source code for i3pystatus.core.io
import time
import json
import sys
from contextlib import contextmanager
[docs]class IOHandler:
def __init__(self, inp=sys.stdin, out=sys.stdout):
self.inp = inp
self.out = out
[docs] def write_line(self, message):
"""Unbuffered printing to stdout."""
self.out.write(message + "\n")
self.out.flush()
[docs] def read(self):
"""Iterate over all input lines (Generator)"""
while True:
try:
yield self.read_line()
except EOFError:
return
[docs] def read_line(self):
"""
Interrupted respecting reader for stdin.
Raises EOFError if the end of stream has been reached
"""
try:
line = self.inp.readline().strip()
except KeyboardInterrupt:
raise EOFError()
# i3status sends EOF, or an empty line
if not line:
raise EOFError()
return line
[docs]class StandaloneIO(IOHandler):
"""
I/O handler for standalone usage of i3pystatus (w/o i3status)
Writing works as usual, but reading will always return a empty JSON array,
and the i3bar protocol header
"""
n = -1
proto = [
{"version": 1, "click_events": True}, "[", "[]", ",[]",
]
def __init__(self, click_events, interval=1):
super().__init__()
self.interval = interval
self.proto[0]['click_events'] = click_events
self.proto[0] = json.dumps(self.proto[0])
[docs] def read(self):
while True:
try:
time.sleep(self.interval)
except KeyboardInterrupt:
return
yield self.read_line()
[docs] def read_line(self):
self.n += 1
return self.proto[min(self.n, len(self.proto) - 1)]
[docs]class JSONIO:
def __init__(self, io, skiplines=2):
self.io = io
for i in range(skiplines):
self.io.write_line(self.io.read_line())
[docs] def read(self):
"""Iterate over all JSON input (Generator)"""
for line in self.io.read():
with self.parse_line(line) as j:
yield j
@contextmanager
[docs] def parse_line(self, line):
"""Parse a single line of JSON and write modified JSON back."""
prefix = ""
# ignore comma at start of lines
if line.startswith(","):
line, prefix = line[1:], ","
j = json.loads(line)
yield j
self.io.write_line(prefix + json.dumps(j))