diff --git a/InvenTree/InvenTree/helpers.py b/InvenTree/InvenTree/helpers.py index 068e3c1bc7..25e99600cd 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,65 @@ 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/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 4038c2870a..fe8a624458 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -61,6 +61,7 @@ urlpatterns = [ url(r'^login/', auth_views.LoginView.as_view(), name='login'), url(r'^logout/', auth_views.LogoutView.as_view(template_name='registration/logout.html'), name='logout'), + url(r'^admin/', admin.site.urls, name='inventree-admin'), url(r'^qr_code/', include(qr_code_urls, namespace='qr_code')), diff --git a/InvenTree/company/forms.py b/InvenTree/company/forms.py index bf7057a1ea..679fe323ee 100644 --- a/InvenTree/company/forms.py +++ b/InvenTree/company/forms.py @@ -23,7 +23,6 @@ class EditCompanyForm(HelperForm): 'phone', 'email', 'contact', - 'image', 'is_customer', 'is_supplier', 'notes' 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'); }); diff --git a/Makefile b/Makefile index 38081570e4..c7fdddc1e2 100644 --- a/Makefile +++ b/Makefile @@ -38,3 +38,6 @@ documentation: pip install -U -r docs/requirements.txt cd docs & make html +backup: + python InvenTree/manage.py dbbackup + python InvenTree/manage.py mediabackup \ No newline at end of file diff --git a/docs/backup.rst b/docs/backup.rst index 6e36a65a1a..1976f574d2 100644 --- a/docs/backup.rst +++ b/docs/backup.rst @@ -9,4 +9,6 @@ Backup and Restore InvenTree provides database backup and restore functionality through the `django-dbbackup `_ extension. -This extension allows databas models and uploaded media files to be backed up (and restored) via the command line. \ No newline at end of file +This extension allows database models and uploaded media files to be backed up (and restored) via the command line. + +In the root InvenTre directory, run ``make backup`` to generate backup files for the database models and media files. \ No newline at end of file