Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

184 Zeilen
5.2KB

  1. # -*- coding: utf-8 -*-
  2. """
  3. enpoints for logging
  4. """
  5. import csv
  6. import datetime
  7. import os
  8. import re
  9. from flask import send_from_directory, json
  10. from flask_classy import FlaskView, route
  11. from modules import cbpi
  12. class LogView(FlaskView):
  13. """
  14. View for logging
  15. """
  16. @route('/', methods=['GET'])
  17. def get_all_logfiles(self): # pylint: disable=no-self-use
  18. """
  19. get all log files
  20. :return: json for all logs
  21. """
  22. result = []
  23. for filename in os.listdir("./logs"):
  24. if filename.endswith(".log"):
  25. result.append(filename)
  26. return json.dumps(result)
  27. @route('/actions')
  28. def actions(self): # pylint: disable=no-self-use
  29. """
  30. get actions log
  31. :return: json for actions log
  32. """
  33. filename = "./logs/action.log"
  34. if not os.path.isfile(filename):
  35. return ('File not found', 404)
  36. array = []
  37. with open(filename, 'r', encoding='utf-8') as csv_file:
  38. reader = csv.reader(csv_file)
  39. for row in reader:
  40. try:
  41. array.append([
  42. int((datetime.datetime.strptime(
  43. row[0], "%Y-%m-%d %H:%M:%S") -
  44. datetime.datetime(1970, 1, 1)).total_seconds()) *
  45. 1000, row[1]
  46. ])
  47. except IndexError:
  48. pass
  49. return json.dumps(array)
  50. @route('/<file>', methods=["DELETE"])
  51. def clearlog(self, file):
  52. """
  53. log delete
  54. :param file: log file name
  55. :return: HTTP 204
  56. """
  57. if not self.check_filename(file):
  58. return ('File Not Found', 404)
  59. filename = "./logs/%s" % file
  60. if os.path.isfile(filename):
  61. os.remove(filename)
  62. cbpi.notify("log deleted succesfully", "")
  63. else:
  64. cbpi.notify("Failed to delete log", "", type="danger")
  65. return ('', 204)
  66. def read_log_as_json(self, log_type, log_id): # pylint: disable=no-self-use
  67. """
  68. :param log_type: log type
  69. :param log_id: log id
  70. :return: log as array
  71. """
  72. filename = "./logs/%s_%s.log" % (log_type, log_id)
  73. if not os.path.isfile(filename):
  74. return ('File not found', 404)
  75. array = []
  76. with open(filename, 'r', encoding='utf-8') as csv_file:
  77. reader = csv.reader(csv_file)
  78. for row in reader:
  79. try:
  80. array.append([
  81. int((datetime.datetime.strptime(
  82. row[0], "%Y-%m-%d %H:%M:%S") -
  83. datetime.datetime(1970, 1, 1)).total_seconds()) *
  84. 1000,
  85. float(row[1])
  86. ])
  87. except IndexError:
  88. pass
  89. return array
  90. def convert_chart_data_to_json(self, chart_data):
  91. """
  92. :param chart_data: data for a chart
  93. :return: json for chart data
  94. """
  95. return {
  96. "name":
  97. chart_data["name"],
  98. "data":
  99. self.read_log_as_json(chart_data["data_type"],
  100. chart_data["data_id"])
  101. }
  102. @route('/<log_type>/<int:log_id>', methods=["POST"])
  103. def get_logs_as_json(self, log_type, log_id):
  104. """
  105. :param log_type: log type
  106. :param log_id: log id
  107. :return: log as array
  108. """
  109. result = []
  110. if log_type == "s":
  111. name = cbpi.cache.get("sensors").get(log_id).name
  112. result.append({
  113. "name": name,
  114. "data": self.read_log_as_json("sensor", log_id)
  115. })
  116. if log_type == "k":
  117. kettle = cbpi.cache.get("kettle").get(log_id)
  118. result = list(
  119. map(
  120. self.convert_chart_data_to_json,
  121. cbpi.get_controller(
  122. kettle.logic).get("class").chart(kettle)))
  123. if log_type == "f":
  124. fermenter = cbpi.cache.get("fermenter").get(log_id)
  125. result = list(
  126. map(
  127. self.convert_chart_data_to_json,
  128. cbpi.get_fermentation_controller(
  129. fermenter.logic).get("class").chart(fermenter)))
  130. return json.dumps(result)
  131. @route('/download/<file>')
  132. @cbpi.nocache
  133. def download(self, file):
  134. """
  135. :param file: log file name
  136. :return: log data
  137. """
  138. if not self.check_filename(file):
  139. return ('File Not Found', 404)
  140. return send_from_directory('../logs',
  141. file,
  142. as_attachment=True,
  143. attachment_filename=file)
  144. def check_filename(self, name): # pylint: disable=no-self-use
  145. """
  146. :param name: log file name
  147. :return: bool
  148. """
  149. pattern = re.compile('^([A-Za-z0-9-_])+.log$')
  150. return bool(pattern.match(name))
  151. @cbpi.initalizer()
  152. def init(app): # pylint: disable=unused-argument
  153. """
  154. Initializer for the message module
  155. :param app: the flask app
  156. :return: None
  157. """
  158. LogView.register(cbpi.app, route_base='/api/logs')