From 63175ce112f4343349c8ac374e911ef4046f13c9 Mon Sep 17 00:00:00 2001 From: Martin Schett Date: Sun, 29 Nov 2020 21:48:21 +0100 Subject: [PATCH] Added dropbox api support as service and cleaned up get single call --- iotclient/iot_client.py | 14 ++++- middleware/app_be/services/dropboxservice.py | 64 ++++++++++++++++++++ middleware/app_be/services/wrapperservice.py | 13 ++++ middleware/app_be/settings.py | 1 + middleware/app_be/urls.py | 2 +- middleware/app_be/views/rest_api.py | 46 +++++++++----- 6 files changed, 123 insertions(+), 17 deletions(-) create mode 100644 middleware/app_be/services/dropboxservice.py create mode 100644 middleware/app_be/services/wrapperservice.py diff --git a/iotclient/iot_client.py b/iotclient/iot_client.py index c94823c..29aa747 100644 --- a/iotclient/iot_client.py +++ b/iotclient/iot_client.py @@ -8,6 +8,8 @@ from datetime import datetime def print_response(response): print("Code: " + str(response.status_code) + "; Body: " + str(response.json())) +def unwrap_file(file_str: str) -> bytes: + return base64.b64decode(file_str) def send_image(identifier, image_path, metadata_payload): print("Sending image with identifier " + identifier) @@ -46,7 +48,17 @@ def get_image(identifier): try: response = requests.get(baseurl + get_url) - print_response(response) + payload = response.json() + print(payload['id']) + print(payload['metadata']) + b64encoded_image = unwrap_file(payload['image_data']) + goal_folder_name = "images_fetch" + path = "../../"+goal_folder_name+"/"+payload['metadata']['filename'] + goal_folder_path = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[:-3]) + os.path.sep + goal_folder_name + out = open(path, 'wb') + out.write(b64encoded_image) + out.close() + os.system(goal_folder_path + os.path.sep + payload['metadata']['filename']) except os.error: print("Error sending request") return True diff --git a/middleware/app_be/services/dropboxservice.py b/middleware/app_be/services/dropboxservice.py new file mode 100644 index 0000000..a34a707 --- /dev/null +++ b/middleware/app_be/services/dropboxservice.py @@ -0,0 +1,64 @@ +import requests +from django.conf import settings +import dropbox + + +class DropboxService: + + @staticmethod + def create_file(filename: str, file: bytes) -> bool: + """Create / save (or overwrite) an file on the dropbox storage. + + :param filename: filename + :param file: bytes representation of the file + :return: Whether file was successfully uploaded + """ + try: + dbx = dropbox.Dropbox(settings.DROPBOX_OAUTH2_ACCESS_TOKEN) + dbx.files_upload(file, settings.DROPBOX_IMAGE_FOLDER + filename) + except: + return False + return True + + @staticmethod + def read_file(filename: str) -> bytes: + """Read file on the dropbox storage. + + :param filename: filename + :return: bytes representation of the file or None on error + """ + file_bytes: bytes + try: + dbx = dropbox.Dropbox(settings.DROPBOX_OAUTH2_ACCESS_TOKEN) + f: requests.models.Response + metadata, f = dbx.files_download(settings.DROPBOX_IMAGE_FOLDER + filename) + file_bytes = f.content + if f is not None: + f.close() + except: + print("Error downloading file from dropbox") + return file_bytes + + @staticmethod + def update_file(filename: str, file: bytes) -> bool: + """Update (currently: overwrite) an file on the dropbox storage. + + :param filename: filename of the file + :param file: bytes representation of the file + :return: Whether file was successfully uploaded + """ + return DropboxService.create_file(filename, file) + + @staticmethod + def delete_file(filename: str) -> bool: + """Delete an file from the dropbox storage. + + :param filename: filename of the file + :return: Whether file was successfully deleted + """ + try: + dbx = dropbox.Dropbox(settings.DROPBOX_OAUTH2_ACCESS_TOKEN) + dbx.files_delete_v2(settings.DROPBOX_IMAGE_FOLDER + filename) + except: + return False + return True \ No newline at end of file diff --git a/middleware/app_be/services/wrapperservice.py b/middleware/app_be/services/wrapperservice.py new file mode 100644 index 0000000..bae55f6 --- /dev/null +++ b/middleware/app_be/services/wrapperservice.py @@ -0,0 +1,13 @@ +import base64 + + +class WrapperService: + + @staticmethod + def wrap_file(file_bytes: bytes) -> str: + file_encoded_b64 = base64.b64encode(file_bytes) + return file_encoded_b64.decode('utf-8') + + @staticmethod + def unwrap_file(file_str: str) -> bytes: + return base64.b64decode(file_str) \ No newline at end of file diff --git a/middleware/app_be/settings.py b/middleware/app_be/settings.py index dbd7706..a95c2d2 100644 --- a/middleware/app_be/settings.py +++ b/middleware/app_be/settings.py @@ -219,3 +219,4 @@ LOGGING = { DATA_UPLOAD_MAX_MEMORY_SIZE = 104857600 DROPBOX_OAUTH2_ACCESS_TOKEN = 'SDt1aqMQg7EAAAAAAAAAARV4CNnOSTjYLc05W2YAxIArG93DnaK9Si9VbwE-aBbQ' +DROPBOX_IMAGE_FOLDER = '/Apps/AIC Federated Storage Infrastructure/' diff --git a/middleware/app_be/urls.py b/middleware/app_be/urls.py index 1352f84..b727930 100644 --- a/middleware/app_be/urls.py +++ b/middleware/app_be/urls.py @@ -24,7 +24,7 @@ urlpatterns = [ path('admin/', admin.site.urls), url(r'^test/', TestApiClass.test_api), url(r'^image/get/all$', ImageEndpoint.image_api_get_all), - url(r'^image/get/(?P[\w-]+)$', ImageEndpoint.image_api_get_single), + url(r'^image/get/(?P[\w-]+)$', ImageEndpoint.image_api_get_single), url(r'^image/post$', ImageEndpoint.image_api_post) ] diff --git a/middleware/app_be/views/rest_api.py b/middleware/app_be/views/rest_api.py index cb8316f..54fc50b 100644 --- a/middleware/app_be/views/rest_api.py +++ b/middleware/app_be/views/rest_api.py @@ -1,14 +1,13 @@ import logging import json import base64 -import dropbox -import pymongo +from app_be.services.dropboxservice import DropboxService +from app_be.services.wrapperservice import WrapperService from app_be.views.mongo_db import MongoManager from django.http import JsonResponse from django.http import HttpRequest -from django.conf import settings from rest_framework.decorators import api_view @@ -47,44 +46,61 @@ class ImageEndpoint: @staticmethod @api_view(['GET']) - def image_api_get_single(request, id): + def image_api_get_single(request, identifier): logger.debug('Image GET single call: {}'.format(request)) instance = MongoManager.getInstance() db = instance.AIC col = db.metadata - + metadata = None try: - resp = col.find({"filename": id+".jpg"}) - print(resp[0]); + resp = col.find({"filename": identifier+".jpg"}) + metadata = resp[0] except: print("Could not find Metadata") + if metadata is None: + return JsonResponse({'Result': 'Error - could not find metadata.'}, status=404, safe=False) + else: + if '_id' in metadata: + del metadata['_id'] - return JsonResponse({'Result': 'success1', 'id': id}, safe=False) + dropbox_image_bytes = DropboxService.read_file(metadata['filename']) + + if dropbox_image_bytes is None: + return JsonResponse({'Result': 'Error - could not find image in dropbox.', 'id': identifier}, status=404, safe=False) + + payload = { + 'id': identifier, + 'metadata': metadata, + 'image_data': WrapperService.wrap_file(dropbox_image_bytes) + } + + return JsonResponse(payload, safe=False) @staticmethod @api_view(['POST']) def image_api_post(request: HttpRequest): logger.debug('Image POST call: {}'.format(request)) - payload = json.loads(request.body.decode('utf-8')) + payload = json.loads(request.body) b64encoded_image = payload['image_data'] - filename = payload['id'] + identifier = payload['id'] metadata = payload['metadata'] + filename = payload['metadata']['filename'] instance = MongoManager.getInstance() db = instance.AIC col = db.metadata - try: resp = col.insert_one(metadata) except: print("Could not insert Metadata") - decoded_image = base64.b64decode(b64encoded_image) - dbx = dropbox.Dropbox(settings.DROPBOX_OAUTH2_ACCESS_TOKEN) - dbx.files_upload(decoded_image, '/Apps/AIC Federated Storage Infrastructure/' + filename) - return JsonResponse({'Result': 'success2', 'received file': filename}, + decoded_image = WrapperService.unwrap_file(b64encoded_image) + if not DropboxService.create_file(filename, decoded_image): + print("Could not save image to dropbox") + + return JsonResponse({'id': identifier, 'filename': filename}, safe=False) # 'metadata': metadata response beinhaltet ObjectId welche nicht serializable is?