"""
This module is for the main application logic
"""
from __future__ import print_function
import json
import logging
import logging.config
import os
import signal
import subprocess
import sys
import tempfile
from time import sleep
import gevent
from gevent import monkey
from gevent.pywsgi import WSGIServer
from larigira.config import get_conf
from larigira.mpc import Controller, get_mpd_client
from larigira.rpc import create_app
monkey.patch_all(subprocess=True)
[docs]def on_main_crash(*args, **kwargs):
print('A crash occurred in "main" greenlet. Aborting...')
sys.exit(1)
[docs]class Larigira(object):
def __init__(self):
self.log = logging.getLogger("larigira")
self.conf = get_conf()
self.controller = Controller(self.conf)
self.controller.link_exception(on_main_crash)
self.http_server = WSGIServer(
(self.conf["HTTP_ADDRESS"], int(self.conf["HTTP_PORT"])),
create_app(self.controller.q, self),
)
[docs] def start(self):
self.controller.start()
self.http_server.start()
[docs]def sd_notify(ready=False, status=None):
args = ["systemd-notify"]
if ready:
args.append("--ready")
if status is not None:
args.append("--status")
args.append(status)
try:
subprocess.check_call(args)
except:
pass
[docs]def main():
logging.addLevelName(9, "DEBUGV")
if get_conf()["LOG_CONFIG"]:
logging.config.fileConfig(
get_conf()["LOG_CONFIG"], disable_existing_loggers=True
)
else:
log_format = (
"%(asctime)s|%(levelname)s[%(name)s:%(lineno)d] %(message)s"
)
logging.basicConfig(
level="DEBUGV" if get_conf()["DEBUG"] else logging.INFO,
format=log_format,
datefmt="%H:%M:%S",
)
def debugv(self, message, *args, **kws):
if self.isEnabledFor(9):
self._log(9, message, args, **kws)
logging.Logger.debugv = debugv
logging.debug(
"Starting larigira with this conf:\n%s",
json.dumps(get_conf(), indent=2),
)
if get_conf()["UMASK"]:
umask = int(get_conf()["UMASK"], base=8)
logging.debug(
"Setting umask %s (decimal: %d)", get_conf()["UMASK"], umask
)
os.umask(umask)
tempfile.tempdir = os.environ["TMPDIR"] = os.path.join(
os.getenv("TMPDIR", "/tmp"), "larigira.%d" % os.getuid()
)
if not os.path.isdir(os.environ["TMPDIR"]):
os.makedirs(os.environ["TMPDIR"])
if get_conf()["MPD_WAIT_START"]:
while True:
try:
get_mpd_client(get_conf())
except Exception as exc:
print("exc", exc, file=sys.stderr)
logging.debug(
"Could not connect to MPD at (%s,%s), waiting",
get_conf()["MPD_HOST"],
get_conf()["MPD_PORT"],
)
sd_notify(status="Waiting MPD connection")
sleep(int(get_conf()["MPD_WAIT_START_RETRYSECS"]))
else:
logging.info("MPD ready!")
sd_notify(ready=True, status="Ready")
break
larigira = Larigira()
larigira.start()
def sig(*args):
print("invoked sig", args)
larigira.controller.q.put(dict(kind="signal", args=args))
for signum in (signal.SIGHUP, signal.SIGALRM):
gevent.signal(signum, sig, signum)
gevent.wait()
if __name__ == "__main__":
main()