190 lines
5.4 KiB
Python
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')
|
|
|