Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

146 lines
4.5KB

  1. import os
  2. import re
  3. import time
  4. import datetime
  5. from flask import json, request, send_from_directory
  6. from flask_classy import route, FlaskView
  7. from modules.core.db import DBModel
  8. from modules.core.baseview import RestApi
  9. from modules import cbpi
  10. from modules.database.dbmodel import Step
  11. from yaml import Loader, Dumper
  12. from yaml import load, dump
  13. from modules.step import StepView
  14. class RecipeBook(FlaskView):
  15. @route('/load', methods=["POST"])
  16. def load(self):
  17. data = request.json
  18. recipe_name = data.get("name")
  19. if re.match("^[A-Za-z0-9_-]*$", recipe_name) is None:
  20. return ('Recipie Name contains not allowed characters', 500)
  21. with open("./recipes/%s.json" % recipe_name) as json_data:
  22. d = json.load(json_data)
  23. Step.delete_all()
  24. StepView().reset()
  25. for s in d["steps"]:
  26. Step.insert(**{"name": s.get("name"), "type": s.get("type"), "config": s.get("config")})
  27. self.api.ws_emit("UPDATE_ALL_STEPS", Step.get_all())
  28. self.api.notify(headline="Recipe %s loaded successfully" % recipe_name, message="")
  29. return ('', 204)
  30. @route('/download/<name>', methods=["GET"])
  31. def download(self, name):
  32. """
  33. Download a log file by name
  34. ---
  35. tags:
  36. - logs
  37. parameters:
  38. - in: path
  39. name: file
  40. schema:
  41. type: string
  42. required: true
  43. description: filename
  44. responses:
  45. 200:
  46. description: Log file downloaded
  47. """
  48. file = "%s.json" % name
  49. if not self.check_filename(file):
  50. return ('File Not Found111', 404)
  51. return send_from_directory('../../recipes', file, as_attachment=True, attachment_filename=file)
  52. def check_filename(self, name):
  53. import re
  54. print "CHECK"
  55. pattern = re.compile('^([A-Za-z0-9-_])+.json$')
  56. return True if pattern.match(name) else False
  57. @route('/<name>', methods=["DELETE"])
  58. def remove(self, name):
  59. recipe_name = name
  60. if re.match("^[A-Za-z0-9_-]*$", recipe_name) is None:
  61. return ('Recipie Name contains not allowed characters', 500)
  62. filename = "./recipes/%s.json" % recipe_name
  63. if os.path.isfile(filename) == True:
  64. os.remove(filename)
  65. self.api.notify(headline="Recipe %s deleted successfully" % recipe_name, message="")
  66. return ('', 204)
  67. else:
  68. self.api.notify(headline="Faild to delete Recipe %s deleted" % recipe_name, message="")
  69. return ('', 404)
  70. return ('', 204)
  71. @route('/', methods=["GET"])
  72. def get_all(self):
  73. result = []
  74. for filename in os.listdir("./recipes"):
  75. if filename.endswith(".json"):
  76. result.append({"id":filename.split(".")[0], "name": filename.split(".")[0], "change_date": self._modification_date('./recipes/%s' % filename)})
  77. return json.dumps(result)
  78. def _modification_date(self, filename):
  79. t = os.path.getmtime(filename)
  80. return datetime.datetime.fromtimestamp(t).strftime('%Y-%m-%d %H:%M:%S')
  81. @route('/save', methods=["POST"])
  82. def save(self):
  83. """
  84. Save Recepie
  85. ---
  86. tags:
  87. - steps
  88. responses:
  89. 204:
  90. description: Recipe saved
  91. """
  92. recipe_name = self.api.get_config_parameter("brew_name")
  93. if recipe_name is None or len(recipe_name) <= 0:
  94. self.api.notify(headline="Please set brew name", message="Recipe not saved!", type="danger")
  95. return ('Recipie Name contains not allowed characters', 500)
  96. if re.match("^[\sA-Za-z0-9_-]*$", recipe_name) is None:
  97. self.api.notify(headline="Only alphanummeric charaters are allowd for recipe name", message="", type="danger")
  98. return ('Recipie Name contains not allowed characters', 500)
  99. recipe_data = {"name": recipe_name, "steps": Step.get_all()}
  100. file_name = recipe_name.replace(" ", "_")
  101. with open('./recipes/%s.json' % file_name, 'w') as outfile:
  102. json.dump(recipe_data, outfile, indent=4)
  103. self.api.notify(headline="Recipe %s saved successfully" % recipe_name, message="")
  104. return ('', 204)
  105. @cbpi.addon.core.initializer(order=2000)
  106. def init(cbpi):
  107. RecipeBook.api = cbpi
  108. RecipeBook.register(cbpi.web, route_base='/api/recipebook')