commit
43b72066f4
@ -7,19 +7,14 @@ from threading import Thread
|
||||
import time
|
||||
from contextlib import contextmanager
|
||||
|
||||
class BaseModule:
|
||||
class Module:
|
||||
output = None
|
||||
position = 0
|
||||
|
||||
def registered(self, status_handler):
|
||||
"""Called when this module is registered with a status handler"""
|
||||
|
||||
def tick(self):
|
||||
"""Called once per tick"""
|
||||
|
||||
class Module(BaseModule):
|
||||
pass
|
||||
|
||||
class AsyncModule(BaseModule):
|
||||
class AsyncModule(Module):
|
||||
def registered(self, status_handler):
|
||||
self.thread = Thread(target=self.mainloop)
|
||||
self.thread.daemon = True
|
||||
@ -44,35 +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):
|
||||
"""Iterate over all JSON input (Generator)"""
|
||||
|
||||
for line in self.io.read():
|
||||
with self.parse_line(line) as j:
|
||||
yield j
|
||||
|
||||
@contextmanager
|
||||
def read(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,8 +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 = []
|
||||
@ -90,22 +105,16 @@ class I3statusHandler:
|
||||
if fd is None:
|
||||
fd = sys.stdin
|
||||
|
||||
self.io = IOHandler(fd)
|
||||
self.io = JSONIO(IOHandler(fd))
|
||||
|
||||
def register(self, module):
|
||||
def register(self, module, position=0):
|
||||
"""Register a new module."""
|
||||
|
||||
self.modules.append(module)
|
||||
module.position = position
|
||||
module.registered(self)
|
||||
|
||||
def run(self):
|
||||
jio = JSONIO(self.io)
|
||||
|
||||
while True:
|
||||
with jio.read() as j:
|
||||
for module in self.modules:
|
||||
module.tick()
|
||||
|
||||
output = module.output
|
||||
if output:
|
||||
j.insert(0, output)
|
||||
for j in self.io.read():
|
||||
for module in self.modules:
|
||||
j.insert(module.position, module.output)
|
||||
|
Loading…
Reference in New Issue
Block a user