2020-03-25 00:19:12 +01:00
|
|
|
#!/usr/bin/env python3
|
2020-03-25 21:13:45 +01:00
|
|
|
from flask import jsonify, request, abort, current_app, Response
|
2020-03-25 00:19:12 +01:00
|
|
|
from flask_classful import FlaskView
|
2020-04-29 22:01:45 +02:00
|
|
|
from minio.error import BucketAlreadyExists, BucketAlreadyOwnedByYou, ResponseError, NoSuchKey, NoSuchBucket
|
2020-03-25 04:02:26 +01:00
|
|
|
from marshmallow import ValidationError
|
2020-03-25 01:57:54 +01:00
|
|
|
from utils import storage
|
2020-03-25 04:02:26 +01:00
|
|
|
from schemas import DescriptionSchema
|
2021-08-09 16:06:09 +02:00
|
|
|
import opentracing
|
2020-03-25 00:19:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
class ObjectView(FlaskView):
|
2020-03-25 04:02:26 +01:00
|
|
|
description_schema = DescriptionSchema(many=False)
|
2020-03-25 00:19:12 +01:00
|
|
|
|
2020-03-25 21:13:45 +01:00
|
|
|
@staticmethod
|
|
|
|
def _check_existance(tag: str) -> bool: # ez aztán igen
|
|
|
|
try:
|
|
|
|
storage.connection.stat_object(current_app.config['MINIO_BUCKET_NAME'], tag)
|
|
|
|
except NoSuchKey:
|
|
|
|
return False
|
2020-04-29 22:01:45 +02:00
|
|
|
except NoSuchBucket:
|
|
|
|
return False
|
2020-03-25 21:13:45 +01:00
|
|
|
|
|
|
|
return True
|
|
|
|
|
2020-03-25 00:19:12 +01:00
|
|
|
def post(self):
|
2020-03-25 04:02:26 +01:00
|
|
|
# get important data from the request
|
2021-08-09 16:06:09 +02:00
|
|
|
with opentracing.tracer.start_active_span('parseAndValidate'):
|
|
|
|
try:
|
|
|
|
description = self.description_schema.loads(request.form.get('description'))
|
|
|
|
except ValidationError as e:
|
|
|
|
return abort(400, str(e))
|
|
|
|
|
|
|
|
# get and validate file
|
|
|
|
file = request.files['soundFile']
|
|
|
|
|
|
|
|
if file.content_type != 'audio/wave':
|
|
|
|
return abort(400, f"{file.content_type} is not audio/wave")
|
|
|
|
|
|
|
|
if file.content_length <= 0:
|
|
|
|
return abort(411, f"Content length for soundFile is not a positive integer or missing.")
|
|
|
|
|
|
|
|
with opentracing.tracer.start_active_span('ensureBuckets'):
|
|
|
|
# create bucket if necessary
|
|
|
|
try:
|
|
|
|
storage.connection.make_bucket(current_app.config['MINIO_BUCKET_NAME'])
|
|
|
|
|
|
|
|
except BucketAlreadyOwnedByYou as err:
|
|
|
|
pass
|
|
|
|
except BucketAlreadyExists as err:
|
|
|
|
pass
|
|
|
|
# Everything else should be raised
|
|
|
|
|
|
|
|
with opentracing.tracer.start_active_span('checkExistence'):
|
|
|
|
# check for conflict
|
|
|
|
if self._check_existance(description['tag']):
|
|
|
|
return abort(409)
|
|
|
|
|
|
|
|
with opentracing.tracer.start_active_span(
|
|
|
|
'minio.putObject',
|
|
|
|
tags={
|
|
|
|
"bucket": current_app.config['MINIO_BUCKET_NAME'],
|
|
|
|
"object_name": description['tag'],
|
|
|
|
"length": file.content_length
|
|
|
|
}
|
|
|
|
):
|
|
|
|
# poot file into bucket
|
|
|
|
try:
|
|
|
|
storage.connection.put_object(current_app.config['MINIO_BUCKET_NAME'], description['tag'], file,
|
|
|
|
file.content_length, content_type=file.content_type)
|
|
|
|
except ResponseError: # TODO: Check if object already exists... somehow
|
|
|
|
raise
|
2020-03-25 04:02:26 +01:00
|
|
|
|
|
|
|
return jsonify({"status": "200"}), 200 # TODO: 200 should be OK but that would be inconsistent with the errors
|
2020-03-25 21:13:45 +01:00
|
|
|
|
|
|
|
def get(self, tag: str):
|
|
|
|
|
|
|
|
# TODO: Validate tag
|
|
|
|
|
|
|
|
try:
|
|
|
|
data = storage.connection.get_object(current_app.config['MINIO_BUCKET_NAME'], tag)
|
|
|
|
except NoSuchKey:
|
2021-08-09 15:52:45 +02:00
|
|
|
return abort(404)
|
2020-03-25 21:13:45 +01:00
|
|
|
|
|
|
|
return Response(data.stream(), mimetype=data.headers['Content-type'])
|
|
|
|
|
|
|
|
def delete(self, tag: str):
|
|
|
|
|
|
|
|
# TODO: Validate tag
|
|
|
|
|
|
|
|
if not self._check_existance(tag):
|
2021-08-09 15:52:45 +02:00
|
|
|
return abort(404)
|
2020-03-25 21:13:45 +01:00
|
|
|
|
|
|
|
storage.connection.remove_object(current_app.config['MINIO_BUCKET_NAME'], tag)
|
|
|
|
|
|
|
|
return jsonify({"status": "200"}), 200
|