main.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. from flask import Flask, request, send_file, jsonify, make_response
  2. from flask_cors import CORS
  3. import jwt
  4. from images_manipulator import PngFile, SvgFile, JpgFile
  5. from dotenv import load_dotenv
  6. from functools import wraps
  7. import os
  8. load_dotenv()
  9. import tempfile
  10. def create_app():
  11. app = Flask(__name__)
  12. app.config.update(SECRET_KEY=os.environ.get('SECRET_KEY'))
  13. USERS = os.environ.get('USERS').split(',')
  14. CORS(app)
  15. # Authentication decorator
  16. def token_required(f):
  17. @wraps(f)
  18. def decorator(*args, **kwargs):
  19. token = None
  20. # ensure the jwt-token is passed with the headers
  21. if 'x-access-token' in request.headers:
  22. token = request.headers['x-access-token']
  23. if not token: # throw error if no token provided
  24. return make_response(jsonify({"message": "A valid token is missing!"}), 401)
  25. try:
  26. # decode the token to obtain user public_id
  27. data = jwt.decode(
  28. token, app.config['SECRET_KEY'], algorithms=['HS256'])
  29. if not data['aktivisda_user'] in USERS:
  30. return make_response(jsonify({"message": "Invalid token!"}), 401)
  31. app.logger.info(f'Request { f.__name__} for user { data["aktivisda_user"]}')
  32. except Exception as e:
  33. return make_response(jsonify({"message": "Invalid token!"}), 401)
  34. # Return the user information attached to the token
  35. return f(*args, **kwargs)
  36. return decorator
  37. @app.route('/', methods=['GET'])
  38. def hello_world():
  39. return "hello world"
  40. @app.route("/vectorize", methods=['POST'])
  41. @token_required
  42. def vectorize():
  43. if request.method == 'POST':
  44. print('53')
  45. f = request.files['image']
  46. assert f.filename.endswith('.png')
  47. tempfilename = tempfile.NamedTemporaryFile(delete=True, suffix='.png').name
  48. f.save(tempfilename)
  49. png_file = PngFile(tempfilename)
  50. png_file._is_temporary_file = True
  51. nb_colors = int(request.args.get('nb_colors', 1))
  52. white_is_alpha = request.args.get('white_is_alpha', 'false') == 'true'
  53. svg_file = png_file.to_svg(nb_colors=nb_colors, white_is_alpha=white_is_alpha)
  54. svg_file._is_temporary_file = False
  55. svg_file.format_colors()
  56. return send_file(svg_file.filepath, mimetype='image/svg+xml')
  57. @app.route("/canonize", methods=['POST'])
  58. @token_required
  59. def canonize():
  60. if request.method == 'POST':
  61. f = request.files['image']
  62. assert f.filename.endswith('.svg')
  63. tempfilename = tempfile.NamedTemporaryFile(delete=True, suffix='.svg').name
  64. f.save(tempfilename)
  65. svg_file = SvgFile(tempfilename)
  66. svg_file._is_temporary_file = True
  67. svg_file.canonize()
  68. return send_file(svg_file.filepath, mimetype='image/svg+xml')
  69. @app.route("/posterize", methods=['POST'])
  70. @token_required
  71. def posterize():
  72. if request.method == 'POST':
  73. f = request.files['image']
  74. assert f.filename.endswith('.png')
  75. tempfilename = tempfile.NamedTemporaryFile(delete=True, suffix='.png').name
  76. f.save(tempfilename)
  77. png_file = PngFile(tempfilename)
  78. png_file._is_temporary_file = True
  79. nb_colors = int(request.args.get('nb_colors', 1))
  80. white_is_alpha = request.args.get('white_is_alpha', 'false') == 'true'
  81. posterized_file = png_file.posterize(nb_colors=nb_colors, white_is_alpha=white_is_alpha)[0]
  82. return send_file(posterized_file.filepath, mimetype='image/png')
  83. @app.route("/hitform", methods=['POST'])
  84. @token_required
  85. def hitpath():
  86. if request.method == 'POST':
  87. f = request.files['image']
  88. assert f.filename.endswith('.svg')
  89. tempfilename = tempfile.NamedTemporaryFile(delete=True, suffix='.svg').name
  90. f.save(tempfilename)
  91. svg_file = SvgFile(tempfilename)
  92. svg_file._is_temporary_file = True
  93. hitpath = svg_file.compute_hitpath()
  94. return jsonify(hitpath=hitpath)
  95. @app.route("/hull", methods=['POST'])
  96. @token_required
  97. def hull():
  98. if request.method == 'POST':
  99. hull = request.files['image']
  100. assert hull.filename.endswith('.svg')
  101. tempfilename = tempfile.NamedTemporaryFile(delete=True, suffix='.svg').name
  102. hull.save(tempfilename)
  103. svg_file = SvgFile(tempfilename)
  104. svg_file.canonize()
  105. hull = svg_file.compute_hull()
  106. return jsonify(hull=hull)
  107. @app.route("/preview", methods=['POST'])
  108. @token_required
  109. def preview():
  110. if request.method == 'POST':
  111. image = request.files['image']
  112. extension = os.path.splitext(image.filename)[1]
  113. tempfilename = tempfile.NamedTemporaryFile(delete=True, suffix=extension).name
  114. image.save(tempfilename)
  115. if extension == '.svg':
  116. svg_file = SvgFile(tempfilename)
  117. png_file = svg_file.to_png(minimum_size=120)
  118. png_file.compress()
  119. return send_file(png_file.filepath, mimetype='image/png')
  120. elif extension == '.jpg':
  121. jpg_file = JpgFile(tempfilename)
  122. jpg_file.resize(120, 120)
  123. jpg_file.compress()
  124. return send_file(jpg_file.filepath, mimetype='image/jpg')
  125. elif extension == '.png':
  126. png_file = PngFile(tempfilename)
  127. png_file.resize(120, 120)
  128. png_file.compress()
  129. return send_file(png_file.filepath, mimetype='image/png')
  130. return make_response(jsonify({"message": f"Unknown file extension { extension }"}), 400)
  131. @app.route("/thumbnail", methods=['POST'])
  132. @token_required
  133. def thumbnail():
  134. if request.method == 'POST':
  135. image = request.files['image']
  136. extension = os.path.splitext(image.filename)[1]
  137. assert extension in ('.png', '.jpg', '.jpeg')
  138. tempfilename = tempfile.NamedTemporaryFile(delete=True, suffix=extension).name
  139. image.save(tempfilename)
  140. if extension == '.png':
  141. image_file = PngFile(tempfilename)
  142. elif extension == '.jpg' or extension == '.jpeg':
  143. image_file = JpgFile(tempfilename)
  144. webp_file = image_file.to_webp(width=100, height=110)
  145. # webp_file.compress()
  146. return send_file(webp_file.filepath, mimetype='image/webp')
  147. return app
  148. if __name__ == '__main__':
  149. app = create_app()