diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 068e3c1bc7..304a3770c6 100644 --- a/InvenTree/InvenTree/helpers.py +++ b/InvenTree/InvenTree/helpers.py @@ -7,6 +7,7 @@ import json import os.path from datetime import datetime from PIL import Image +import requests from wsgiref.util import FileWrapper from django.http import StreamingHttpResponse @@ -34,6 +35,68 @@ def TestIfImageURL(url): ] +def DownloadExternalFile(url, **kwargs): + """ Attempt to download an external file + + Args: + url - External URL + + """ + + result = { + 'status': False, + 'url': url, + 'file': None, + 'status_code': 200, + } + + headers = {'User-Agent': 'Mozilla/5.0'} + max_size = kwargs.get('max_size', 1048576) # 1MB default limit + + # Get the HEAD for the file + try: + head = requests.head(url, stream=True, headers=headers) + except: + result['error'] = 'Error retrieving HEAD data' + return result + + if not head.status_code == 200: + result['error'] = 'Incorrect HEAD status code' + result['status_code'] = head.status_code + return result + + try: + filesize = int(head.headers['Content-Length']) + except ValueError: + result['error'] = 'Could not decode filesize' + result['extra'] = head.headers['Content-Length'] + return result + + if filesize > max_size: + result['error'] = 'File size too large ({s})'.format(s=filesize) + return result + + # All checks have passed - download the file + + try: + request = requests.get(url, stream=True, headers=headers) + except: + result['error'] = 'Error retriving GET data' + return result + + try: + dl_file = io.StringIO(request.text) + result['status'] = True + result['file'] = dl_file + return result + except: + result['error'] = 'Could not convert downloaded data to file' + return result + + + + + def str2bool(text, test=True): """ Test if a string 'looks' like a boolean value. diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 219bd1c740..bcb803bef1 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -319,7 +319,7 @@ class UploadPartImage(AjaxView): return JsonResponse(response, status=status) elif 'image_url' in request.POST: - image_url = request.POST['image_url'] + image_url = str(request.POST['image_url']).split('?')[0] validator = URLValidator() @@ -334,6 +334,7 @@ class UploadPartImage(AjaxView): # Test the the URL at least looks like an image if not TestIfImageURL(image_url): response['error'] = 'Invalid image URL' + response['url'] = image_url return JsonResponse(response, status=400) response['error'] = 'Cannot download cross-site images (yet)' diff --git a/InvenTree/static/script/inventree/inventree.js b/InvenTree/static/script/inventree/inventree.js index 551058f101..f65a6777f4 100644 --- a/InvenTree/static/script/inventree/inventree.js +++ b/InvenTree/static/script/inventree/inventree.js @@ -16,11 +16,17 @@ function inventreeDocReady() { /* Add drag-n-drop functionality to any element * marked with the class 'dropzone' */ - $('.dropzone').on('dragenter', function() { - $(this).addClass('dragover'); + $('.dropzone').on('dragenter', function(event) { + + // TODO - Only indicate that a drop event will occur if a file is being dragged + var transfer = event.originalEvent.dataTransfer; + + if (true || isFileTransfer(transfer)) { + $(this).addClass('dragover'); + } }); - $('.dropzone').on('dragleave drop', function() { + $('.dropzone').on('dragleave drop', function(event) { $(this).removeClass('dragover'); });