mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Test that uploaded image is an image file, return error otherwise
- New javascript function inventreeFileUpload
This commit is contained in:
parent
c88149b9aa
commit
bb702367b6
@ -5,11 +5,21 @@ Provides helper functions used throughout the InvenTree project
|
|||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
from wsgiref.util import FileWrapper
|
from wsgiref.util import FileWrapper
|
||||||
from django.http import StreamingHttpResponse
|
from django.http import StreamingHttpResponse
|
||||||
|
|
||||||
|
|
||||||
|
def TestIfImage(img):
|
||||||
|
""" Test if an image file is indeed an image """
|
||||||
|
try:
|
||||||
|
Image.open(img).verify()
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
@ -78,7 +78,6 @@ class EditPartForm(HelperForm):
|
|||||||
'purchaseable',
|
'purchaseable',
|
||||||
'salable',
|
'salable',
|
||||||
'notes',
|
'notes',
|
||||||
'image',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@
|
|||||||
{
|
{
|
||||||
accept_text: 'Activate',
|
accept_text: 'Activate',
|
||||||
accept: function() {
|
accept: function() {
|
||||||
inventreeUpdate(
|
inventreePut(
|
||||||
"{% url 'api-part-detail' part.id %}",
|
"{% url 'api-part-detail' part.id %}",
|
||||||
{
|
{
|
||||||
active: true,
|
active: true,
|
||||||
@ -176,7 +176,7 @@
|
|||||||
{
|
{
|
||||||
accept_text: 'Deactivate',
|
accept_text: 'Deactivate',
|
||||||
accept: function() {
|
accept: function() {
|
||||||
inventreeUpdate(
|
inventreePut(
|
||||||
"{% url 'api-part-detail' part.id %}",
|
"{% url 'api-part-detail' part.id %}",
|
||||||
{
|
{
|
||||||
active: false,
|
active: false,
|
||||||
|
@ -108,47 +108,22 @@
|
|||||||
|
|
||||||
var files = transfer.files;
|
var files = transfer.files;
|
||||||
|
|
||||||
console.log('dropped');
|
|
||||||
|
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
var file = files[0];
|
var file = files[0];
|
||||||
|
|
||||||
var formData = new FormData();
|
inventreeFileUpload(
|
||||||
|
|
||||||
var token = getCookie('csrftoken');
|
|
||||||
|
|
||||||
formData.append('file', file);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
beforeSend: function(xhr, settings) {
|
|
||||||
xhr.setRequestHeader('X-CSRFToken', token);
|
|
||||||
},
|
|
||||||
url: "{% url 'part-image-upload' part.id %}",
|
|
||||||
type: 'POST',
|
|
||||||
data: formData,
|
|
||||||
processData: false,
|
|
||||||
contentType: false,
|
|
||||||
success: function(data, status, xhr) {
|
|
||||||
//location.reload();
|
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
console.log('Error uploading thumbnail: ' + status);
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
|
||||||
inventreeUpdate(
|
|
||||||
"{% url 'part-image-upload' part.id %}",
|
"{% url 'part-image-upload' part.id %}",
|
||||||
formData,
|
file,
|
||||||
|
{},
|
||||||
{
|
{
|
||||||
method: 'POST',
|
success: function(data, status, xhr) {
|
||||||
dataType: 'json',
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
showAlertDialog('Error uploading image', renderErrorMessage(xhr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
*/
|
|
||||||
|
|
||||||
console.log('submitted');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -30,7 +30,7 @@ from .forms import EditSupplierPartForm
|
|||||||
from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView
|
from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView
|
||||||
from InvenTree.views import QRCodeView
|
from InvenTree.views import QRCodeView
|
||||||
|
|
||||||
from InvenTree.helpers import DownloadFile, str2bool
|
from InvenTree.helpers import DownloadFile, str2bool, TestIfImage
|
||||||
|
|
||||||
|
|
||||||
class PartIndex(ListView):
|
class PartIndex(ListView):
|
||||||
@ -275,22 +275,29 @@ class UploadPartImage(AjaxView):
|
|||||||
model = Part
|
model = Part
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
||||||
|
response = {}
|
||||||
|
status = 200
|
||||||
|
|
||||||
try:
|
try:
|
||||||
part = Part.objects.get(pk=kwargs.get('pk'))
|
part = Part.objects.get(pk=kwargs.get('pk'))
|
||||||
except Part.DoesNotExist:
|
except Part.DoesNotExist:
|
||||||
error_dict = {
|
response['error'] = 'Part not found'
|
||||||
'error': 'Part not found',
|
|
||||||
}
|
|
||||||
return JsonResponse(error_dict, status=404)
|
return JsonResponse(error_dict, status=404)
|
||||||
|
|
||||||
print("Files:", request.FILES)
|
|
||||||
uploaded_file = request.FILES['file']
|
uploaded_file = request.FILES['file']
|
||||||
|
|
||||||
response_dict = {
|
if TestIfImage(uploaded_file):
|
||||||
'success': 'File was uploaded successfully',
|
part.image = uploaded_file
|
||||||
}
|
part.clean()
|
||||||
|
part.save()
|
||||||
|
|
||||||
return JsonResponse(response_dict, status=200)
|
response['success'] = 'File was uploaded successfully'
|
||||||
|
else:
|
||||||
|
response['error'] = 'Not a valid image file'
|
||||||
|
status = 400
|
||||||
|
|
||||||
|
return JsonResponse(response, status=status)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,7 +42,49 @@ function inventreeGet(url, filters={}, options={}) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function inventreeUpdate(url, data={}, options={}) {
|
function inventreeFileUpload(url, file, data={}, options={}) {
|
||||||
|
/* Upload a file via AJAX using the FormData approach.
|
||||||
|
*
|
||||||
|
* Note that the following AJAX parameters are required for FormData upload
|
||||||
|
*
|
||||||
|
* processData: false
|
||||||
|
* contentType: false
|
||||||
|
*/
|
||||||
|
|
||||||
|
// CSRF cookie token
|
||||||
|
var csrftoken = getCookie('csrftoken');
|
||||||
|
|
||||||
|
var data = new FormData();
|
||||||
|
|
||||||
|
data.append('file', file);
|
||||||
|
|
||||||
|
return $.ajax({
|
||||||
|
beforeSend: function(xhr, settings) {
|
||||||
|
xhr.setRequestHeader('X-CSRFToken', csrftoken);
|
||||||
|
},
|
||||||
|
url: url,
|
||||||
|
method: 'POST',
|
||||||
|
data: data,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(data, status, xhr) {
|
||||||
|
console.log('Uploaded file - ' + file.name);
|
||||||
|
|
||||||
|
if (options.success) {
|
||||||
|
options.success(data, status, xhr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.log('Error uploading file: ' + status);
|
||||||
|
|
||||||
|
if (options.error) {
|
||||||
|
options.error(xhr, status, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function inventreePut(url, data={}, options={}) {
|
||||||
|
|
||||||
var method = options.method || 'PUT';
|
var method = options.method || 'PUT';
|
||||||
|
|
||||||
@ -93,9 +135,9 @@ function getCompanies(filters={}, options={}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateStockItem(pk, data, final=false) {
|
function updateStockItem(pk, data, final=false) {
|
||||||
return inventreeUpdate('/api/stock/' + pk + '/', data, final);
|
return inventreePut('/api/stock/' + pk + '/', data, final);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePart(pk, data, final=false) {
|
function updatePart(pk, data, final=false) {
|
||||||
return inventreeUpdate('/api/part/' + pk + '/', data, final);
|
return inventreePut('/api/part/' + pk + '/', data, final);
|
||||||
}
|
}
|
@ -41,7 +41,7 @@ function toggleStar(options) {
|
|||||||
if (response.length == 0) {
|
if (response.length == 0) {
|
||||||
// Zero length response = star does not exist
|
// Zero length response = star does not exist
|
||||||
// So let's add one!
|
// So let's add one!
|
||||||
inventreeUpdate(
|
inventreePut(
|
||||||
url,
|
url,
|
||||||
{
|
{
|
||||||
part: options.part,
|
part: options.part,
|
||||||
@ -57,7 +57,7 @@ function toggleStar(options) {
|
|||||||
} else {
|
} else {
|
||||||
var pk = response[0].pk;
|
var pk = response[0].pk;
|
||||||
// There IS a star (delete it!)
|
// There IS a star (delete it!)
|
||||||
inventreeUpdate(
|
inventreePut(
|
||||||
url + pk + "/",
|
url + pk + "/",
|
||||||
{
|
{
|
||||||
},
|
},
|
||||||
|
@ -141,7 +141,7 @@ function updateStock(items, options={}) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inventreeUpdate("/api/stock/stocktake/",
|
inventreePut("/api/stock/stocktake/",
|
||||||
{
|
{
|
||||||
'action': options.action,
|
'action': options.action,
|
||||||
'items[]': stocktake,
|
'items[]': stocktake,
|
||||||
@ -226,7 +226,7 @@ function moveStockItems(items, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doMove(location, parts, notes) {
|
function doMove(location, parts, notes) {
|
||||||
inventreeUpdate("/api/stock/move/",
|
inventreePut("/api/stock/move/",
|
||||||
{
|
{
|
||||||
location: location,
|
location: location,
|
||||||
'parts[]': parts,
|
'parts[]': parts,
|
||||||
|
Loading…
Reference in New Issue
Block a user