cli.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import os
  2. import os.path
  3. import sys
  4. from argparse import ArgumentParser, Action
  5. from datetime import datetime
  6. import logging
  7. logging.basicConfig(stream=sys.stdout)
  8. logger = logging.getLogger("cli")
  9. CWD = os.getcwd()
  10. from . import forge
  11. from . import maint
  12. from .config_manager import get_config
  13. from . import server
  14. def pre_check_permissions():
  15. def is_writable(d):
  16. return os.access(d, os.W_OK)
  17. if is_writable(get_config()["AUDIO_INPUT"]):
  18. yield "Audio input '%s' writable" % get_config()["AUDIO_INPUT"]
  19. if not os.access(get_config()["AUDIO_INPUT"], os.R_OK):
  20. yield "Audio input '%s' unreadable" % get_config()["AUDIO_INPUT"]
  21. sys.exit(10)
  22. if is_writable(os.getcwd()):
  23. yield "Code writable"
  24. if not is_writable(get_config()["AUDIO_OUTPUT"]):
  25. yield "Audio output '%s' not writable" % get_config()["AUDIO_OUTPUT"]
  26. logger.critical("Aborting")
  27. sys.exit(10)
  28. def pre_check_user():
  29. if os.geteuid() == 0:
  30. yield "You're running as root; this is dangerous"
  31. def pre_check_ffmpeg():
  32. path = get_config()["FFMPEG_PATH"]
  33. if not path.startswith("/"):
  34. yield "FFMPEG_PATH is not absolute: %s" % path
  35. from subprocess import check_output
  36. try:
  37. check_output([path, "-version"])
  38. except OSError:
  39. yield "FFMPEG not found as " + path
  40. else:
  41. if not os.path.exists(path):
  42. yield "FFMPEG not found in " + path
  43. class DateTimeAction(Action):
  44. def __call__(self, parser, namespace, values, option_string=None):
  45. if len(values) == 15 or len(values) == 13:
  46. parsed_val = datetime.strptime(values, "%Y%m%d-%H%M%S")
  47. else:
  48. raise ValueError("'%s' is not a valid datetime" % values)
  49. setattr(namespace, self.dest, parsed_val)
  50. def common_pre():
  51. prechecks = [pre_check_user, pre_check_permissions, pre_check_ffmpeg]
  52. configs = ["default_config.py"]
  53. if "TECHREC_CONFIG" in os.environ:
  54. for conf in os.environ["TECHREC_CONFIG"].split(":"):
  55. if not conf:
  56. continue
  57. path = os.path.realpath(conf)
  58. if not os.path.exists(path):
  59. logger.warn("Configuration file '%s' does not exist; skipping" % path)
  60. continue
  61. configs.append(path)
  62. if getattr(sys, 'frozen', False):
  63. os.chdir(sys._MEIPASS)
  64. else:
  65. os.chdir(os.path.dirname(os.path.realpath(__file__)))
  66. for conf in configs:
  67. get_config().from_pyfile(conf)
  68. for check in prechecks:
  69. for warn in check():
  70. logger.warn(warn)
  71. def main():
  72. parser = ArgumentParser(description="creates mp3 from live recordings")
  73. parser.add_argument(
  74. "--verbose",
  75. "-v",
  76. action="count",
  77. default=0,
  78. help="Increase verbosity; can be used multiple times",
  79. )
  80. parser.add_argument(
  81. "--pretend",
  82. "-p",
  83. action="store_true",
  84. default=False,
  85. help="Only pretend; no real action will be done",
  86. )
  87. sub = parser.add_subparsers(
  88. title="main subcommands", description="valid subcommands"
  89. )
  90. serve_p = sub.add_parser("serve", help="Start an HTTP server")
  91. serve_p.set_defaults(func=server.main_cmd)
  92. forge_p = sub.add_parser("forge", help="Create an audio file")
  93. forge_p.add_argument(
  94. "starttime",
  95. metavar="START",
  96. help="Start time, espressed as 19450425_1200 (%%Y%%m%%d-%%H%%M%%S)",
  97. action=DateTimeAction,
  98. )
  99. forge_p.add_argument(
  100. "endtime",
  101. metavar="END",
  102. help="End time, espressed as 19450425_1200 (%%Y%%m%%d-%%H%%M%%S)",
  103. action=DateTimeAction,
  104. )
  105. forge_p.add_argument(
  106. "-o",
  107. metavar="OUTFILE",
  108. dest="outfile",
  109. default="out.mp3",
  110. help="Path of the output mp3",
  111. )
  112. forge_p.set_defaults(func=forge.main_cmd)
  113. cleanold_p = sub.add_parser(
  114. "cleanold",
  115. help="Remove old files from DB",
  116. description="Will remove oldfiles with no filename from DB",
  117. )
  118. cleanold_p.add_argument(
  119. "-t",
  120. metavar="MINAGE",
  121. dest="minage",
  122. default="14",
  123. type=int,
  124. help="Minimum age (in days) for removal",
  125. )
  126. cleanold_p.set_defaults(func=maint.cleanold_cmd)
  127. options = parser.parse_args()
  128. options.cwd = CWD
  129. if options.verbose < 1:
  130. logging.basicConfig(level=logging.WARNING)
  131. elif options.verbose == 1:
  132. logging.basicConfig(level=logging.INFO)
  133. elif options.verbose >= 2:
  134. logging.basicConfig(level=logging.DEBUG)
  135. if options.verbose > 2:
  136. logging.info("giving verbose flag >2 times is useless")
  137. common_pre()
  138. options.func(options)
  139. if __name__ == "__main__":
  140. main()