something something managing too many camera stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
6.2 KiB

  1. import datetime
  2. import hashlib
  3. import os
  4. import subprocess
  5. from os.path import splitext
  6. from flask import current_app
  7. from flask_security import current_user
  8. from models import db, Role, Logging, Config, UserLogging
  9. IMAGES = tuple("jpg jpe jpeg png gif".split())
  10. def gcfg():
  11. _config = Config.query.one()
  12. if not _config:
  13. return {"app_name": "ree2bits"}
  14. return {"app_name": _config.app_name}
  15. class InvalidUsage(Exception):
  16. status_code = 400
  17. def __init__(self, message, status_code=None, payload=None):
  18. Exception.__init__(self)
  19. self.message = message
  20. if status_code is not None:
  21. self.status_code = status_code
  22. self.payload = payload
  23. def to_dict(self):
  24. rv = dict(self.payload or ())
  25. rv["message"] = self.message
  26. rv["status"] = "error"
  27. rv["code"] = self.status_code
  28. return rv
  29. def is_admin():
  30. adm = Role.query.filter(Role.name == "admin").first()
  31. if not current_user or not current_user.is_authenticated or not adm:
  32. return False
  33. if adm in current_user.roles:
  34. return True
  35. return False
  36. def add_log(category, level, message):
  37. if not category or not level or not message:
  38. print("!! Fatal error in add_log() one of three variables not set")
  39. print("[LOG][{0}][{1}] {2}".format(level.upper(), category, message))
  40. a = Logging(category=category, level=level.upper(), message=message)
  41. db.session.add(a)
  42. db.session.commit()
  43. # categories used, they are used to map the item_id to the right model
  44. # - sounds
  45. # - albums
  46. # - user
  47. # - global
  48. def add_user_log(item, user, category, level, message):
  49. if not category or not level or not message or not item:
  50. print("!! Fatal error in add_user_log() one of three variables not set")
  51. print("[LOG][{0}][{1}][u:{2}i:{3}] {4}".format(level.upper(), category, user, item, message))
  52. a = UserLogging(category=category, level=level.upper(), message=message, item_id=item, user_id=user)
  53. db.session.add(a)
  54. db.session.commit()
  55. def duration_elapsed_human(seconds):
  56. print(seconds)
  57. seconds = round(seconds)
  58. minutes, seconds = divmod(seconds, 60)
  59. hours, minutes = divmod(minutes, 60)
  60. days, hours = divmod(hours, 24)
  61. years, days = divmod(days, 365.242199)
  62. minutes = int(minutes)
  63. hours = int(hours)
  64. days = int(days)
  65. years = int(years)
  66. if years > 0:
  67. return "%d y" % years
  68. elif days > 0:
  69. return "%d d" % days
  70. elif hours > 0:
  71. return "%d h" % hours + "s" * (hours != 1)
  72. elif minutes > 0:
  73. return "%d mn" % minutes + "s" * (minutes != 1)
  74. else:
  75. return "right now"
  76. def duration_song_human(seconds):
  77. if seconds is None:
  78. return "error"
  79. seconds = float(seconds)
  80. seconds = seconds
  81. minutes, seconds = divmod(seconds, 60)
  82. hours, minutes = divmod(minutes, 60)
  83. days, hours = divmod(hours, 24)
  84. years, days = divmod(days, 365.242199)
  85. minutes = int(minutes)
  86. hours = int(hours)
  87. days = int(days)
  88. years = int(years)
  89. if years > 0:
  90. return "%d year" % years + "s" * (years != 1)
  91. elif days > 0:
  92. return "%d day" % days + "s" * (days != 1)
  93. elif hours > 0:
  94. return "%d hour" % hours + "s" * (hours != 1)
  95. elif minutes > 0:
  96. return "%d mn" % minutes + "s" * (minutes != 1)
  97. else:
  98. return "%.2f sec" % seconds + "s" * (seconds != 1)
  99. def get_waveform(filename):
  100. binary = current_app.config["AUDIOWAVEFORM_BIN"]
  101. if not os.path.exists(binary) or not os.path.exists(filename):
  102. add_log("AUDIOWAVEFORM", "ERROR", "Filename {0} or binary {1} invalid".format(filename, binary))
  103. return None
  104. tmpjson = "{0}.json".format(filename)
  105. cmd = [binary, "-i", filename, "--pixels-per-second", "10", "-b", "8", "-o", tmpjson]
  106. """
  107. Failed: Can't generate "xxx" from "xxx"
  108. OK:
  109. Input file: piano2.wav
  110. Frames: 302712
  111. Sample rate: 48000 Hz
  112. Channels: 2
  113. Format: 0x10002
  114. Sections: 1
  115. Seekable: yes
  116. Generating waveform data...
  117. Samples per pixel: 4800
  118. Input channels: 2
  119. Done: 100%
  120. Read 302712 frames
  121. Generated 64 points
  122. Writing output file: some-file.json
  123. """
  124. try:
  125. process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  126. if not process:
  127. add_log("AUDIOWAVEFORM", "ERROR", "Subprocess returned None")
  128. return None
  129. except subprocess.CalledProcessError as e:
  130. add_log("AUDIOWAVEFORM", "ERROR", "Process error: {0}".format(e))
  131. return None
  132. print("- Command ran with: {0}".format(process.args))
  133. if process.stderr.startswith(b"Can't generate"):
  134. add_log("AUDIOWAVEFORM", "ERROR", "Process error: {0}".format(process.stderr))
  135. return None
  136. with open(tmpjson, "r") as f:
  137. json = f.readlines()
  138. os.unlink(tmpjson)
  139. if isinstance(json, list):
  140. json = json[0].rstrip()
  141. return json
  142. def create_png_waveform(fn_audio, fn_png):
  143. binary = current_app.config["AUDIOWAVEFORM_BIN"]
  144. if not os.path.exists(binary) or not os.path.exists(fn_audio):
  145. add_log("AUDIOWAVEFORM_PNG", "ERROR", "Filename {0} or binary {1} invalid".format(fn_audio, binary))
  146. return None
  147. pngwf = "{0}.png".format(fn_png)
  148. cmd = [binary, "-i", fn_audio, "--width", "384", "--height", "64", "--no-axis-labels", "-o", pngwf]
  149. try:
  150. process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  151. if not process:
  152. add_log("AUDIOWAVEFORM_PNG", "ERROR", "Subprocess returned None")
  153. return None
  154. except subprocess.CalledProcessError as e:
  155. add_log("AUDIOWAVEFORM_PNG", "ERROR", "Process error: {0}".format(e))
  156. return None
  157. print("- Command ran with: {0}".format(process.args))
  158. if process.stderr.startswith(b"Can't generate"):
  159. add_log("AUDIOWAVEFORM_PNG", "ERROR", "Process error: {0}".format(process.stderr))
  160. return None
  161. return True
  162. def get_hashed_filename(filename):
  163. f_n, f_e = splitext(filename)
  164. fs_fname = hashlib.sha256()
  165. hashed_format = "%s-%s" % (f_n, datetime.datetime.now())
  166. fs_fname.update(hashed_format.encode("utf-8"))
  167. fs_fname = fs_fname.hexdigest()
  168. return fs_fname + f_e