142 lines
4.1 KiB
Python
Executable file
142 lines
4.1 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
import time
|
|
import socket
|
|
import select
|
|
import logging
|
|
import threading
|
|
|
|
import bumblebee_status.discover
|
|
|
|
bumblebee_status.discover.discover()
|
|
|
|
import core.config
|
|
import core.output
|
|
import core.module
|
|
import core.input
|
|
import core.event
|
|
|
|
|
|
class CommandSocket(object):
|
|
def __init__(self):
|
|
self.__name = "/tmp/.bumblebee-status.{}".format(os.getpid())
|
|
self.__socket = None
|
|
|
|
def __enter__(self):
|
|
self.__socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
self.__socket.bind(self.__name)
|
|
self.__socket.listen(5)
|
|
return self.__socket
|
|
|
|
def __exit__(self, type, value, traceback):
|
|
self.__socket.close()
|
|
os.unlink(self.__name)
|
|
|
|
|
|
def handle_input(output):
|
|
with CommandSocket() as cmdsocket:
|
|
poll = select.poll()
|
|
poll.register(sys.stdin.fileno(), select.POLLIN)
|
|
poll.register(cmdsocket, select.POLLIN)
|
|
|
|
while True:
|
|
events = poll.poll()
|
|
|
|
modules = {}
|
|
for fileno, event in events:
|
|
if fileno == cmdsocket.fileno():
|
|
tmp, _ = cmdsocket.accept()
|
|
line = tmp.recv(4096).decode()
|
|
tmp.close()
|
|
logging.debug("socket event {}".format(line))
|
|
else:
|
|
line = "["
|
|
while line.startswith("["):
|
|
line = sys.stdin.readline().strip(",").strip()
|
|
logging.info("input event: {}".format(line))
|
|
try:
|
|
event = json.loads(line)
|
|
core.input.trigger(event)
|
|
if "name" in event:
|
|
modules[event["name"]] = True
|
|
except ValueError:
|
|
pass
|
|
core.event.trigger("update", modules.keys())
|
|
core.event.trigger("draw")
|
|
|
|
poll.unregister(sys.stdin.fileno())
|
|
|
|
|
|
def main():
|
|
config = core.config.Config(sys.argv[1:])
|
|
level = logging.DEBUG if config.debug() else logging.ERROR
|
|
if config.logfile():
|
|
logging.basicConfig(
|
|
level=level,
|
|
format="[%(asctime)s] %(module)-16s %(levelname)-8s %(message)s",
|
|
filename=os.path.abspath(os.path.expanduser(config.logfile())),
|
|
)
|
|
else:
|
|
logging.basicConfig(
|
|
level=level,
|
|
format="[%(asctime)s] %(module)-16s %(levelname)-8s %(message)s",
|
|
stream=sys.stderr,
|
|
)
|
|
|
|
theme = core.theme.Theme(config.theme(), config.iconset())
|
|
output = core.output.i3(theme, config)
|
|
modules = []
|
|
|
|
core.input.register(None, core.input.WHEEL_UP, "i3-msg workspace prev_on_output")
|
|
core.input.register(None, core.input.WHEEL_DOWN, "i3-msg workspace next_on_output")
|
|
|
|
input_thread = threading.Thread(target=handle_input, args=(output,))
|
|
input_thread.daemon = True
|
|
input_thread.start()
|
|
|
|
if config.debug():
|
|
modules.append(core.module.load("debug", config, theme))
|
|
|
|
for module in config.modules():
|
|
modules.append(core.module.load(module, config, theme))
|
|
modules[-1].register_callbacks()
|
|
|
|
if config.reverse():
|
|
modules.reverse()
|
|
|
|
output.modules(modules)
|
|
core.event.trigger("start")
|
|
while True:
|
|
core.event.trigger("update")
|
|
core.event.trigger("draw")
|
|
output.wait(config.interval())
|
|
core.event.trigger("stop")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
main()
|
|
except Exception as e:
|
|
# really basic errors -> make sure these are shown in the status bar by minimal config
|
|
while True:
|
|
sys.stdout.write(
|
|
json.dumps(
|
|
[
|
|
{
|
|
"full_text": " {} ".format(e),
|
|
"background": "#ff0000",
|
|
"color": "#ffffff",
|
|
"name": "error",
|
|
"instance": "the-only-one",
|
|
}
|
|
]
|
|
)
|
|
)
|
|
sys.stdout.write(",\n")
|
|
sys.stdout.flush()
|
|
time.sleep(5)
|
|
|
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|