#!/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/', 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')