karideo/back/src/api/data.py
2020-10-10 22:35:09 +02:00

190 lines
5.4 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2019, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
import time
import json
import os
import sys
import datetime
import time, threading
import realog.debug as debug
from aiofiles import os as async_os
from pymediainfo import MediaInfo
from sanic import Sanic
from sanic import response
from sanic import views
from sanic import Blueprint
from sanic.exceptions import ServerError
from sanic.response import file_stream
from sanic_simple_swagger import swagger_blueprint, openapi_blueprint
from sanic_simple_swagger import doc
import tools
import data_interface
import data_global_elements
import hashlib
import shutil
import random
tmp_value = 0
#curl -F 'file=@Totally_Spies.mp4;type=application/octet-stream' -H 'transfer-encoding:chunked' 127.0.0.1:15080/data -X POST -O; echo ;
def add(_app, _name_api):
elem_blueprint = Blueprint(_name_api)
"""
@elem_blueprint.get('/' + _name_api, strict_slashes=True)
@doc.summary("Show saisons")
@doc.description("Display a listing of the resource.")
@doc.produces(content_type='application/json')
async def list(request):
return response.json(data_global_elements.get_interface(_name_api).gets())
"""
dataModelBdd = [
{
"name": "id",
"type": "int",
"modifiable": False,
"creatable": False,
"can_be_null": False,
"visible": True,
},
{
"name": "size",
"type": "int",
"modifiable": False,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "sha512",
"type": "str",
"modifiable": False,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "mime_type",
"type": "str",
"modifiable": False,
"creatable": True,
"can_be_null": False,
"visible": True,
},
{
"name": "original_name",
"type": "str",
"modifiable": False,
"creatable": True,
"can_be_null": True,
"visible": False,
},
]
data_global_elements.get_interface(_name_api).set_data_model(dataModelBdd)
@elem_blueprint.get('/' + _name_api + '/exist/<sha512:string>', strict_slashes=True)
@doc.summary("check resource existance")
@doc.description("simply check if the resource is already uploaded.")
@doc.produces(content_type='application/json')
async def check_existance(request, sha512):
value = data_global_elements.get_interface(_name_api).find("sha512", sha512)
if value != None:
return response.json(value)
return response.HTTPResponse("No data found", status=404)
@elem_blueprint.post('/' + _name_api, strict_slashes=True, stream=True)
@doc.summary("send new file data")
@doc.description("Create a new data file (associated with his sha512.")
#@doc.consumes(DataModel, location='body')#, required=True)
@doc.response_success(status=201, description='If successful created')
async def create(_request):
debug.info("request streaming " + str(_request));
args_with_blank_values = _request.headers
debug.info("List arguments: " + str(args_with_blank_values));
async def streaming(_response):
global tmp_value
#debug.info("streaming " + str(_response));
total_size = 0
tmp_value += random.randint(1,50)
temporary_file = os.path.join(_app.config['REST_TMP_DATA'], str(tmp_value) + ".tmp")
if not os.path.exists(_app.config['REST_TMP_DATA']):
os.makedirs(_app.config['REST_TMP_DATA'])
if not os.path.exists(_app.config['REST_MEDIA_DATA']):
os.makedirs(_app.config['REST_MEDIA_DATA'])
file_stream = open(temporary_file,"wb")
sha1 = hashlib.sha512()
while True:
#debug.warning("ploufffff " + str(dir(_request.stream)))
body = await _request.stream.read()
if body is None:
debug.warning("empty body");
break
total_size += len(body)
debug.verbose("body " + str(len(body)) + "/" + str(total_size))
file_stream.write(body)
sha1.update(body)
file_stream.close()
print("SHA512: " + str(sha1.hexdigest()))
new_data = {
"size": total_size,
"sha512": str(sha1.hexdigest()),
'original_name': _request.headers["filename"],
'mime_type': _request.headers["mime-type"]
}
# TODO: Check if the element already exist ...
return_bdd = data_global_elements.get_interface(_name_api).post(new_data)
basic_data_path = os.path.join(_app.config['REST_MEDIA_DATA'], str(return_bdd["id"]))
if not os.path.exists(basic_data_path):
os.makedirs(basic_data_path)
destination_filename = os.path.join(basic_data_path, "data")
"""
if os.path.isfile(destination_filename) == True:
answer_data = {
"size": total_size,
"sha512": str(sha1.hexdigest()),
'filename': _request.headers["filename"],
'mime_type': _request.headers["mime-type"],
"already_exist": True,
}
await _response.write(json.dumps(answer_data, sort_keys=True, indent=4))
return
"""
# move the file
shutil.move(temporary_file, destination_filename)
# collect media info ...
media_info = MediaInfo.parse(destination_filename)
data_metafile = {
"sha512": str(sha1.hexdigest()),
"size": total_size,
'filename': _request.headers["filename"],
'mime_type': _request.headers["mime-type"],
'media_info': json.loads(media_info.to_json())
}
tools.file_write_data(os.path.join(basic_data_path, "meta.json"), json.dumps(data_metafile, sort_keys=True, indent=4))
await _response.write(json.dumps(return_bdd, sort_keys=True, indent=4))
return response.stream(streaming, content_type='application/json')