diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..dc9ea49
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..69b43c1
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/tcc.iml b/.idea/tcc.iml
new file mode 100644
index 0000000..d0876a7
--- /dev/null
+++ b/.idea/tcc.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FlaskAPI/.dockerignore b/FlaskAPI/.dockerignore
new file mode 100644
index 0000000..3edb0b5
--- /dev/null
+++ b/FlaskAPI/.dockerignore
@@ -0,0 +1,34 @@
+# Include any files or directories that you don't want to be copied to your
+# container here (e.g., local build artifacts, temporary files, etc.).
+#
+# For more help, visit the .dockerignore file reference guide at
+# https://docs.docker.com/engine/reference/builder/#dockerignore-file
+
+**/.DS_Store
+**/__pycache__
+**/.venv
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/bin
+**/charts
+**/docker-compose*
+**/compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
diff --git a/FlaskAPI/.idea/.gitignore b/FlaskAPI/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/FlaskAPI/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/FlaskAPI/.idea/FlaskAPI.iml b/FlaskAPI/.idea/FlaskAPI.iml
new file mode 100644
index 0000000..15b7777
--- /dev/null
+++ b/FlaskAPI/.idea/FlaskAPI.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FlaskAPI/.idea/inspectionProfiles/profiles_settings.xml b/FlaskAPI/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/FlaskAPI/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FlaskAPI/.idea/misc.xml b/FlaskAPI/.idea/misc.xml
new file mode 100644
index 0000000..4bdfec8
--- /dev/null
+++ b/FlaskAPI/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/FlaskAPI/.idea/modules.xml b/FlaskAPI/.idea/modules.xml
new file mode 100644
index 0000000..6fa8fc8
--- /dev/null
+++ b/FlaskAPI/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FlaskAPI/.vscode/launch.json b/FlaskAPI/.vscode/launch.json
new file mode 100644
index 0000000..6a28b4c
--- /dev/null
+++ b/FlaskAPI/.vscode/launch.json
@@ -0,0 +1,17 @@
+{
+ "version": "0.0.1",
+ "configurations": [
+
+ {
+ "name": "Python: Flask",
+ "type": "python",
+ "request": "launch",
+ "module": "flask",
+ "env": { "FLASK_APP": "app.py", "FLASK_DEBUG": "1" },
+ "args": ["run", "--no-debugger", "--no-reload"],
+ "jinja": true,
+ "justMyCode": true
+ }
+
+ ]
+}
diff --git a/FlaskAPI/.vscode/settings.json b/FlaskAPI/.vscode/settings.json
new file mode 100644
index 0000000..e69de29
diff --git a/FlaskAPI/Dockerfile b/FlaskAPI/Dockerfile
new file mode 100644
index 0000000..b6a5924
--- /dev/null
+++ b/FlaskAPI/Dockerfile
@@ -0,0 +1,45 @@
+# syntax=docker/dockerfile:1
+
+# Comments are provided throughout this file to help you get started.
+# If you need more help, visit the Dockerfile reference guide at
+# https://docs.docker.com/engine/reference/builder/
+
+ARG PYTHON_VERSION=3.10.12
+FROM python:${PYTHON_VERSION}-slim as base
+
+# Prevents Python from writing pyc files.
+ENV PYTHONDONTWRITEBYTECODE=1
+
+# Keeps Python from buffering stdout and stderr to avoid situations where
+# the application crashes without emitting any logs due to buffering.
+ENV PYTHONUNBUFFERED=1
+
+WORKDIR /app
+
+# Copy the source code into the container.
+COPY . .
+
+RUN apt-get update && apt-get install -y imagemagick && apt-get install -y wget && ls
+
+RUN wget https://files.ivanch.me/api/public/dl/iFuXSNhw/small-image.png && \
+ wget https://files.ivanch.me/api/public/dl/81Bkht5C/big-image.png && \
+ wget https://files.ivanch.me/api/public/dl/nAndfAjK/video.mp4 && \
+ rm -rf runtimes && \
+ mkdir -p ./static && \
+ mv small-image.png ./static && \
+ mv big-image.png ./static && \
+ mv video.mp4 ./static
+
+# Download dependencies as a separate step to take advantage of Docker's caching.
+# Leverage a cache mount to /root/.cache/pip to speed up subsequent builds.
+# Leverage a bind mount to requirements.txt to avoid having to copy them into
+# into this layer.
+RUN --mount=type=cache,target=/root/.cache/pip \
+ --mount=type=bind,source=requirements.txt,target=requirements.txt \
+ python -m pip install -r requirements.txt
+
+# Expose the port that the application listens on.
+EXPOSE 5000
+
+# Run the application.
+CMD gunicorn 'app:app' --bind=0.0.0.0:5000
diff --git a/FlaskAPI/__pycache__/app.cpython-310.pyc b/FlaskAPI/__pycache__/app.cpython-310.pyc
new file mode 100644
index 0000000..c38168b
Binary files /dev/null and b/FlaskAPI/__pycache__/app.cpython-310.pyc differ
diff --git a/FlaskAPI/app.py b/FlaskAPI/app.py
new file mode 100644
index 0000000..b048e75
--- /dev/null
+++ b/FlaskAPI/app.py
@@ -0,0 +1,12 @@
+from flask import Flask
+from controllers.status import status_blueprint
+from controllers.image import image_blueprint
+
+app = Flask(__name__)
+
+if __name__ == '__main__':
+ app.run()
+
+#
+app.register_blueprint(status_blueprint)
+app.register_blueprint(image_blueprint)
\ No newline at end of file
diff --git a/FlaskAPI/blurred_temp_image.jpeg b/FlaskAPI/blurred_temp_image.jpeg
new file mode 100644
index 0000000..77ff865
Binary files /dev/null and b/FlaskAPI/blurred_temp_image.jpeg differ
diff --git a/FlaskAPI/compose.yaml b/FlaskAPI/compose.yaml
new file mode 100644
index 0000000..94e7d9c
--- /dev/null
+++ b/FlaskAPI/compose.yaml
@@ -0,0 +1,49 @@
+# Comments are provided throughout this file to help you get started.
+# If you need more help, visit the Docker compose reference guide at
+# https://docs.docker.com/compose/compose-file/
+
+# Here the instructions define your application as a service called "server".
+# This service is built from the Dockerfile in the current directory.
+# You can add other services your application may depend on here, such as a
+# database or a cache. For examples, see the Awesome Compose repository:
+# https://github.com/docker/awesome-compose
+services:
+ server:
+ build:
+ context: .
+ ports:
+ - 5000:5000
+
+# The commented out section below is an example of how to define a PostgreSQL
+# database that your application can use. `depends_on` tells Docker Compose to
+# start the database before your application. The `db-data` volume persists the
+# database data between container restarts. The `db-password` secret is used
+# to set the database password. You must create `db/password.txt` and add
+# a password of your choosing to it before running `docker compose up`.
+# depends_on:
+# db:
+# condition: service_healthy
+# db:
+# image: postgres
+# restart: always
+# user: postgres
+# secrets:
+# - db-password
+# volumes:
+# - db-data:/var/lib/postgresql/data
+# environment:
+# - POSTGRES_DB=example
+# - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
+# expose:
+# - 5432
+# healthcheck:
+# test: [ "CMD", "pg_isready" ]
+# interval: 10s
+# timeout: 5s
+# retries: 5
+# volumes:
+# db-data:
+# secrets:
+# db-password:
+# file: db/password.txt
+
diff --git a/FlaskAPI/controllers/__pycache__/image.cpython-310.pyc b/FlaskAPI/controllers/__pycache__/image.cpython-310.pyc
new file mode 100644
index 0000000..7cc4314
Binary files /dev/null and b/FlaskAPI/controllers/__pycache__/image.cpython-310.pyc differ
diff --git a/FlaskAPI/controllers/__pycache__/status.cpython-310.pyc b/FlaskAPI/controllers/__pycache__/status.cpython-310.pyc
new file mode 100644
index 0000000..1eb22a4
Binary files /dev/null and b/FlaskAPI/controllers/__pycache__/status.cpython-310.pyc differ
diff --git a/FlaskAPI/controllers/image.py b/FlaskAPI/controllers/image.py
new file mode 100644
index 0000000..4083088
--- /dev/null
+++ b/FlaskAPI/controllers/image.py
@@ -0,0 +1,41 @@
+from services.image import ImageService
+from static.image_helper import ImageHelper
+from flask import request, Response, Blueprint, jsonify, send_file
+
+image_blueprint = Blueprint('image_blueprint', __name__)
+image_service = ImageService()
+
+
+@image_blueprint.route('/image/blur', methods=['POST'])
+def blur_image():
+ radius = int(request.form.get('radius'))
+ image = request.files.get('file')
+
+ if radius and image:
+ return send_file(image_service.box_blur_image(image, radius),
+ mimetype='image/jpeg',
+ as_attachment=True,
+ download_name='blurred_image.jpeg')
+
+ return "Bad request", 400
+
+
+@image_blueprint.route('/image/load-small-image', methods=['GET'])
+def get_simple_image():
+ return send_file(image_service.get_simple_image(),
+ mimetype='image/png',
+ as_attachment=True,
+ download_name='small-image.png')
+
+
+@image_blueprint.route('/image/load-big-image', methods=['GET'])
+def get_big_image():
+ return send_file(image_service.get_big_image(),
+ mimetype='image/png',
+ as_attachment=True,
+ download_name='big-image.png')
+
+
+@image_blueprint.route('/image/save-big-image', methods=['POST'])
+def save_image():
+ pass
diff --git a/FlaskAPI/controllers/status.py b/FlaskAPI/controllers/status.py
new file mode 100644
index 0000000..5d777ad
--- /dev/null
+++ b/FlaskAPI/controllers/status.py
@@ -0,0 +1,19 @@
+from flask import jsonify, Blueprint
+
+status_blueprint = Blueprint('status_blueprint', __name__)
+
+
+class StatusController:
+ def __init__(self):
+ pass
+
+ def return_ok(self):
+ return jsonify(status=200)
+
+
+status_controller = StatusController()
+
+
+@status_blueprint.route('/status/ok', methods=['GET'])
+def return_ok():
+ return jsonify(status=200)
diff --git a/FlaskAPI/requirements.txt b/FlaskAPI/requirements.txt
new file mode 100644
index 0000000..20ce748
--- /dev/null
+++ b/FlaskAPI/requirements.txt
@@ -0,0 +1,3 @@
+Flask>=1.0
+gunicorn>=19.9.0
+Wand
\ No newline at end of file
diff --git a/FlaskAPI/services/__pycache__/image.cpython-310.pyc b/FlaskAPI/services/__pycache__/image.cpython-310.pyc
new file mode 100644
index 0000000..1ba3a5e
Binary files /dev/null and b/FlaskAPI/services/__pycache__/image.cpython-310.pyc differ
diff --git a/FlaskAPI/services/image.py b/FlaskAPI/services/image.py
new file mode 100644
index 0000000..6dea1da
--- /dev/null
+++ b/FlaskAPI/services/image.py
@@ -0,0 +1,69 @@
+from wand.image import Image
+
+from static.image_helper import ImageHelper
+
+
+def box_blur_image_separable(image, blurred_image, radius_x, radius_y):
+ pixels = image.get_pixels()
+ blurred_pixels = blurred_image.get_pixels()
+
+ for pixel in pixels:
+ x, y = pixel[0], pixel[1]
+
+ r_total, g_total, b_total = 0, 0, 0
+ pixel_count = 0
+ for offset_y in range(-radius_y, radius_y + 1):
+ for offset_x in range(-radius_x, radius_x + 1):
+ new_x = x + offset_x
+ new_y = y + offset_y
+
+ if 0 <= new_x < image.width and 0 <= new_y < image.height:
+ pixel_color = pixels[new_y * image.width + new_x]
+ r_total += pixel_color.red
+ g_total += pixel_color.green
+ b_total += pixel_color.blue
+ pixel_count += 1
+
+ blurred_pixel = blurred_pixels[y * image.width + x]
+ blurred_pixel.red = int(r_total / pixel_count)
+ blurred_pixel.green = int(g_total / pixel_count)
+ blurred_pixel.blue = int(b_total / pixel_count)
+
+ return blurred_image
+
+
+def save_image(file_stream):
+ with open("image.png", "wb") as file:
+ file.write(file_stream.read())
+ file.close()
+
+
+class ImageService:
+ def __init__(self):
+ pass
+
+ def box_blur_image(self, img, radius):
+ temp_path = 'temp_image.png'
+ img.save(temp_path)
+
+ with Image(filename=temp_path) as img:
+ img.blur(radius, 2)
+ blurred_temp_path = 'blurred_temp_image.png'
+ img.save(filename='blurred_temp_image.png')
+ return blurred_temp_path
+
+
+ def get_simple_image(self):
+ with ImageHelper.SimpleImage as img:
+ img = ImageHelper.SimpleImage
+ simple_image = 'simple_image.png'
+ img.save(filename='simple_image.png')
+ return simple_image
+
+
+ def get_big_image(self):
+ with ImageHelper.BigImage as img:
+ img = ImageHelper.BigImage
+ big_image = 'big_image.png'
+ img.save(filename='big_image.png')
+ return big_image
diff --git a/FlaskAPI/static/__pycache__/image_helper.cpython-310.pyc b/FlaskAPI/static/__pycache__/image_helper.cpython-310.pyc
new file mode 100644
index 0000000..f8b5084
Binary files /dev/null and b/FlaskAPI/static/__pycache__/image_helper.cpython-310.pyc differ
diff --git a/FlaskAPI/static/image_helper.py b/FlaskAPI/static/image_helper.py
new file mode 100644
index 0000000..63aba27
--- /dev/null
+++ b/FlaskAPI/static/image_helper.py
@@ -0,0 +1,17 @@
+from wand.image import Image
+
+
+class ImageHelper:
+ SimpleImage = None
+ BigImage = None
+
+ @staticmethod
+ def load_images():
+ ImageHelper.SimpleImage = Image(filename="./static/small-image.png")
+ #ImageHelper.SimpleImage.save(filename="./static/small-image.png")
+
+ ImageHelper.BigImage = Image(filename="./static/big-image.png")
+ #ImageHelper.BigImage.save(filename="./static/big-image.png")
+ pass
+
+ImageHelper.load_images()
\ No newline at end of file
diff --git a/FlaskAPI/temp_image.jpeg b/FlaskAPI/temp_image.jpeg
new file mode 100644
index 0000000..25783da
Binary files /dev/null and b/FlaskAPI/temp_image.jpeg differ