mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge remote-tracking branch 'inventree/master'
This commit is contained in:
commit
64a6ee0f3b
@ -7,6 +7,7 @@ import json
|
|||||||
import os.path
|
import os.path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
import requests
|
||||||
|
|
||||||
from wsgiref.util import FileWrapper
|
from wsgiref.util import FileWrapper
|
||||||
from django.http import StreamingHttpResponse
|
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):
|
def str2bool(text, test=True):
|
||||||
""" Test if a string 'looks' like a boolean value.
|
""" Test if a string 'looks' like a boolean value.
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ urlpatterns = [
|
|||||||
|
|
||||||
url(r'^login/', auth_views.LoginView.as_view(), name='login'),
|
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'^logout/', auth_views.LogoutView.as_view(template_name='registration/logout.html'), name='logout'),
|
||||||
|
|
||||||
url(r'^admin/', admin.site.urls, name='inventree-admin'),
|
url(r'^admin/', admin.site.urls, name='inventree-admin'),
|
||||||
|
|
||||||
url(r'^qr_code/', include(qr_code_urls, namespace='qr_code')),
|
url(r'^qr_code/', include(qr_code_urls, namespace='qr_code')),
|
||||||
|
@ -23,7 +23,6 @@ class EditCompanyForm(HelperForm):
|
|||||||
'phone',
|
'phone',
|
||||||
'email',
|
'email',
|
||||||
'contact',
|
'contact',
|
||||||
'image',
|
|
||||||
'is_customer',
|
'is_customer',
|
||||||
'is_supplier',
|
'is_supplier',
|
||||||
'notes'
|
'notes'
|
||||||
|
@ -319,7 +319,7 @@ class UploadPartImage(AjaxView):
|
|||||||
return JsonResponse(response, status=status)
|
return JsonResponse(response, status=status)
|
||||||
|
|
||||||
elif 'image_url' in request.POST:
|
elif 'image_url' in request.POST:
|
||||||
image_url = request.POST['image_url']
|
image_url = str(request.POST['image_url']).split('?')[0]
|
||||||
|
|
||||||
validator = URLValidator()
|
validator = URLValidator()
|
||||||
|
|
||||||
@ -334,6 +334,7 @@ class UploadPartImage(AjaxView):
|
|||||||
# Test the the URL at least looks like an image
|
# Test the the URL at least looks like an image
|
||||||
if not TestIfImageURL(image_url):
|
if not TestIfImageURL(image_url):
|
||||||
response['error'] = 'Invalid image URL'
|
response['error'] = 'Invalid image URL'
|
||||||
|
response['url'] = image_url
|
||||||
return JsonResponse(response, status=400)
|
return JsonResponse(response, status=400)
|
||||||
|
|
||||||
response['error'] = 'Cannot download cross-site images (yet)'
|
response['error'] = 'Cannot download cross-site images (yet)'
|
||||||
|
@ -16,11 +16,17 @@ function inventreeDocReady() {
|
|||||||
/* Add drag-n-drop functionality to any element
|
/* Add drag-n-drop functionality to any element
|
||||||
* marked with the class 'dropzone'
|
* marked with the class 'dropzone'
|
||||||
*/
|
*/
|
||||||
$('.dropzone').on('dragenter', function() {
|
$('.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');
|
$(this).addClass('dragover');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.dropzone').on('dragleave drop', function() {
|
$('.dropzone').on('dragleave drop', function(event) {
|
||||||
$(this).removeClass('dragover');
|
$(this).removeClass('dragover');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
3
Makefile
3
Makefile
@ -38,3 +38,6 @@ documentation:
|
|||||||
pip install -U -r docs/requirements.txt
|
pip install -U -r docs/requirements.txt
|
||||||
cd docs & make html
|
cd docs & make html
|
||||||
|
|
||||||
|
backup:
|
||||||
|
python InvenTree/manage.py dbbackup
|
||||||
|
python InvenTree/manage.py mediabackup
|
@ -9,4 +9,6 @@ Backup and Restore
|
|||||||
|
|
||||||
InvenTree provides database backup and restore functionality through the `django-dbbackup <https://github.com/django-dbbackup/django-dbbackup>`_ extension.
|
InvenTree provides database backup and restore functionality through the `django-dbbackup <https://github.com/django-dbbackup/django-dbbackup>`_ extension.
|
||||||
|
|
||||||
This extension allows databas models and uploaded media files to be backed up (and restored) via the command line.
|
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.
|
Loading…
Reference in New Issue
Block a user