app.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import atexit
  2. import time
  3. from logging.config import dictConfig
  4. from threading import Thread
  5. from flask import Flask, request, render_template
  6. from config import BOTS_LOOKUP, SLEEP_TIME
  7. from command_system import RollbotMessage, RollbotResponse, RollbotFailure
  8. from rollbot import Rollbot
  9. from util import post_message
  10. dictConfig({
  11. "version": 1,
  12. "formatters": {"default": {
  13. "format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
  14. }},
  15. "handlers": {"wsgi": {
  16. "class": "logging.StreamHandler",
  17. "stream": "ext://flask.logging.wsgi_errors_stream",
  18. "formatter": "default"
  19. }},
  20. "root": {
  21. "level": "INFO",
  22. "handlers": ["wsgi"]
  23. }
  24. })
  25. app = Flask(__name__)
  26. rollbot = Rollbot(app.logger)
  27. rollbot.start_plugins()
  28. atexit.register(rollbot.shutdown_plugins)
  29. @app.route("/teamspeak", methods=["GET"])
  30. def teamspeak():
  31. response = rollbot.run_command(RollbotMessage.from_web("!teamspeak"))
  32. if response.is_success:
  33. response = response.txt
  34. else:
  35. response = response.failure_msg
  36. return render_template("teamspeak.html", r=response)
  37. @app.route("/services", methods=["GET", "POST"])
  38. def services():
  39. if request.method == "POST":
  40. msg = RollbotMessage.from_web(request.form["cmd"])
  41. if msg.is_command:
  42. response = rollbot.run_command(msg)
  43. if response.is_success:
  44. txt = response.txt
  45. img = response.img
  46. else:
  47. txt = response.failure_msg
  48. img = None
  49. return render_template("services.html", r=response.respond, txt=txt, img=img)
  50. return render_template("services.html", r=None)
  51. @app.route("/rollbot", methods=["POST"])
  52. def execute():
  53. json = request.get_json()
  54. msg = RollbotMessage.from_groupme(json)
  55. if not msg.is_command:
  56. app.logger.debug("Received non-command message")
  57. return "", 204
  58. if msg.group_id not in BOTS_LOOKUP:
  59. app.logger.warning(f"Received message from unknown group ID {msg.group_id}")
  60. return "Invalid group ID", 403
  61. def run_command_and_respond():
  62. app.logger.info(f"Entering command thread for {msg.message_id}")
  63. t = time.time()
  64. try:
  65. response = rollbot.run_command(msg)
  66. except Exception as e:
  67. app.logger.error(f"Exception during command execution {e}, for message {msg.message_id}")
  68. response = RollbotResponse(msg, failure=RollbotFailure.INTERNAL_ERROR)
  69. if not response.respond:
  70. app.logger.info(f"Skipping response to message {msg.message_id}")
  71. return
  72. app.logger.info(f"Responding to message {msg.message_id}")
  73. sleep = SLEEP_TIME - time.time() + t
  74. if sleep > 0:
  75. app.logger.info(f"Sleeping for {sleep:.3f}s before responding")
  76. time.sleep(sleep)
  77. bot_id = BOTS_LOOKUP[msg.group_id]
  78. if response.is_success:
  79. if response.txt is not None:
  80. post_message(response.txt, bot_id=bot_id)
  81. if response.img is not None:
  82. post_message(response.img, bot_id=bot_id)
  83. else:
  84. post_message(response.failure_msg, bot_id=bot_id)
  85. app.logger.warning(f"Failed command response: {response}")
  86. t = time.time() - t
  87. app.logger.info(f"Exiting command thread for {msg.message_id} after {t:.3f}s")
  88. t = Thread(target=run_command_and_respond)
  89. t.start()
  90. return "OK", 200
  91. if __name__ == "__main__":
  92. # default deployment in debug mode
  93. app.run(host="0.0.0.0", port=6070)