larigira.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. """
  2. This module is for the main application logic
  3. """
  4. from __future__ import print_function
  5. import logging
  6. import logging.config
  7. import os
  8. import signal
  9. import subprocess
  10. import sys
  11. import tempfile
  12. from time import sleep
  13. import gevent
  14. from gevent import monkey
  15. from gevent.pywsgi import WSGIServer
  16. from .config import get_conf
  17. from .mpc import Controller, get_mpd_client
  18. from .rpc import create_app
  19. monkey.patch_all(subprocess=True)
  20. def on_main_crash(*args, **kwargs):
  21. print('A crash occurred in "main" greenlet. Aborting...')
  22. sys.exit(1)
  23. class Larigira(object):
  24. def __init__(self):
  25. self.log = logging.getLogger("larigira")
  26. self.conf = get_conf()
  27. self.controller = Controller(self.conf)
  28. self.controller.link_exception(on_main_crash)
  29. self.http_server = WSGIServer(
  30. ("", int(self.conf["HTTP_PORT"])), create_app(self.controller.q, self)
  31. )
  32. def start(self):
  33. self.controller.start()
  34. self.http_server.start()
  35. def sd_notify(ready=False, status=None):
  36. args = ["systemd-notify"]
  37. if ready:
  38. args.append("--ready")
  39. if status is not None:
  40. args.append("--status")
  41. args.append(status)
  42. try:
  43. subprocess.check_call(args)
  44. except:
  45. pass
  46. def main():
  47. tempfile.tempdir = os.environ["TMPDIR"] = os.path.join(
  48. os.getenv("TMPDIR", "/tmp"), "larigira.%d" % os.getuid()
  49. )
  50. if not os.path.isdir(os.environ["TMPDIR"]):
  51. os.makedirs(os.environ["TMPDIR"])
  52. if get_conf()["LOG_CONFIG"]:
  53. logging.config.fileConfig(
  54. get_conf()["LOG_CONFIG"], disable_existing_loggers=True
  55. )
  56. else:
  57. log_format = "%(asctime)s|%(levelname)s[%(name)s:%(lineno)d] %(message)s"
  58. logging.basicConfig(
  59. level=logging.DEBUG if get_conf()["DEBUG"] else logging.INFO,
  60. format=log_format,
  61. datefmt="%H:%M:%S",
  62. )
  63. logging.addLevelName(9, "DEBUGV")
  64. def debugv(self, message, *args, **kws):
  65. if self.isEnabledFor(9):
  66. self._log(9, message, args, **kws)
  67. logging.Logger.debugv = debugv
  68. if get_conf()["MPD_WAIT_START"]:
  69. while True:
  70. try:
  71. get_mpd_client(get_conf())
  72. except Exception as exc:
  73. print("exc", exc, file=sys.stderr)
  74. logging.debug(
  75. "Could not connect to MPD at (%s,%s), waiting",
  76. get_conf()["MPD_HOST"],
  77. get_conf()["MPD_PORT"],
  78. )
  79. sd_notify(status="Waiting MPD connection")
  80. sleep(int(get_conf()["MPD_WAIT_START_RETRYSECS"]))
  81. else:
  82. logging.info("MPD ready!")
  83. sd_notify(ready=True, status="Ready")
  84. break
  85. larigira = Larigira()
  86. larigira.start()
  87. def sig(*args):
  88. print("invoked sig", args)
  89. larigira.controller.q.put(dict(kind="signal", args=args))
  90. for signum in (signal.SIGHUP, signal.SIGALRM):
  91. gevent.signal(signum, sig, signum)
  92. gevent.wait()
  93. if __name__ == "__main__":
  94. main()