Add error when required field is missing in .toml file

This commit is contained in:
HugoNeveux 2020-04-27 18:47:24 +02:00
parent c259c5722e
commit 564a7e8254
6 changed files with 39 additions and 26 deletions

View File

@ -4,19 +4,24 @@ from bootstrap_modal_forms.mixins import PopRequestMixin, CreateUpdateAjaxMixin
from django import forms from django import forms
from .models import Version from .models import Version
class CustomUserCreationForm(PopRequestMixin, CreateUpdateAjaxMixin, class CustomUserCreationForm(PopRequestMixin, CreateUpdateAjaxMixin,
UserCreationForm): UserCreationForm):
class Meta: class Meta:
model = User model = User
fields = ['username', 'email', 'password1', 'password2'] fields = ['username', 'email', 'password1', 'password2']
class CustomAuthenticationForm(AuthenticationForm): class CustomAuthenticationForm(AuthenticationForm):
class Meta: class Meta:
model = User model = User
fields = ['username', 'password'] fields = ['username', 'password']
class FileFieldForm(forms.Form): class FileFieldForm(forms.Form):
file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True})) file = forms.FileField(
widget=forms.ClearableFileInput(attrs={'multiple': True}))
class FileFieldForm(forms.ModelForm): class FileFieldForm(forms.ModelForm):
class Meta: class Meta:
@ -24,7 +29,7 @@ class FileFieldForm(forms.ModelForm):
fields = ['file'] fields = ['file']
widgets = { widgets = {
'file': forms.ClearableFileInput( 'file': forms.ClearableFileInput(
attrs = { attrs={
'multiple': True 'multiple': True
} }
) )

View File

@ -16,7 +16,7 @@ def upload_path(instance, filename):
class Module(models.Model): class Module(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255, unique=True)
desc = models.TextField(max_length=2048, null=True) desc = models.TextField(max_length=2048, null=True)
creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
@ -34,6 +34,7 @@ class Version(models.Model):
def __str__(self): def __str__(self):
return self.ver return self.ver
class Dependency(models.Model): class Dependency(models.Model):
version = models.ForeignKey(Version, on_delete=models.CASCADE) version = models.ForeignKey(Version, on_delete=models.CASCADE)
dep_module = models.CharField(max_length=255) dep_module = models.CharField(max_length=255)

View File

@ -37,14 +37,14 @@
{% endblock body %} {% endblock body %}
{% block extra_js %} {% block extra_js %}
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
$("#registerLink").modalForm({ $("#registerLink").modalForm({
formURL: "{% url 'signup_modal' %}" formURL: "{% url 'signup_modal' %}"
}); });
$("#loginLink").modalForm({ $("#loginLink").modalForm({
formURL: "{% url 'login_modal' %}" formURL: "{% url 'login_modal' %}"
}); });
}); });
</script> </script>
{% endblock extra_js %} {% endblock extra_js %}

View File

@ -7,9 +7,8 @@
<h1 class="display-3">PDMI Store</h1> <h1 class="display-3">PDMI Store</h1>
<!-- Search form --> <!-- Search form -->
<form class="form-inline d-flex justify-content-center md-form form-sm mt-0"> <form class="form-inline d-flex justify-content-center md-form form-sm mt-0">
<i class="fa fa-search" aria-hidden="true"></i> <i class="fa fa-search" aria-hidden="true"></i>
<input class="form-control ml-3 w-75" type="text" placeholder="Search" <input class="form-control ml-3 w-75" type="text" placeholder="Search" aria-label="Search">
aria-label="Search">
</form> </form>
</div> </div>
</div> </div>
@ -25,8 +24,8 @@
<h6 class="card-subtitle mb-2 text-muted">Card subtitle - Description</h6> <h6 class="card-subtitle mb-2 text-muted">Card subtitle - Description</h6>
<p class="card-text">Donec id elit non mi porta gravida at eget metus. Fusce dapibus, <p class="card-text">Donec id elit non mi porta gravida at eget metus. Fusce dapibus,
tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo
sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
</p> </p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p> <p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
</div> </div>
</div> </div>
@ -45,8 +44,8 @@
<h6 class="card-subtitle mb-2 text-muted">Card subtitle - Description</h6> <h6 class="card-subtitle mb-2 text-muted">Card subtitle - Description</h6>
<p class="card-text">Donec id elit non mi porta gravida at eget metus. Fusce dapibus, <p class="card-text">Donec id elit non mi porta gravida at eget metus. Fusce dapibus,
tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo
sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
</p> </p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p> <p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
</div> </div>
</div> </div>
@ -65,8 +64,8 @@
<h6 class="card-subtitle mb-2 text-muted">Card subtitle - Description</h6> <h6 class="card-subtitle mb-2 text-muted">Card subtitle - Description</h6>
<p class="card-text">Donec id elit non mi porta gravida at eget metus. Fusce dapibus, <p class="card-text">Donec id elit non mi porta gravida at eget metus. Fusce dapibus,
tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo
sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui.
</p> </p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p> <p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
</div> </div>
</div> </div>

View File

@ -8,8 +8,8 @@
{% block body %} {% block body %}
<main> <main>
<div class="container pt-5"> <div class="container pt-5">
<div class="alert alert-danger alert-dismissible fade show" id="errorZone" style="display:none;"> <div class="alert alert-danger alert-dismissible" id="errorZone" style="display:none;">
<a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a> <a href="#" class="close" onclick="$('.alert').hide();">&times;</a>
</div> </div>
<form class="dropzone" enctype="multipart/form-data" method="post" id="multiFileUpload"> <form class="dropzone" enctype="multipart/form-data" method="post" id="multiFileUpload">
<div class="fallback"> <div class="fallback">
@ -67,6 +67,7 @@ $('#multiFileUpload').dropzone({
}); });
this.on("error", function(file, message) { this.on("error", function(file, message) {
console.log(message); console.log(message);
$('.alert').html('');
$('#errorZone').append(message.error); $('#errorZone').append(message.error);
$('#errorZone').show(); $('#errorZone').show();
}); });

View File

@ -31,6 +31,8 @@ class CustomLoginView(BSModalLoginView):
extra_content = dict(success_url=reverse_lazy('index')) extra_content = dict(success_url=reverse_lazy('index'))
REQUIRED_FIELDS = ['name', 'description', 'version', 'bot_version']
class UploadView(LoginRequiredMixin, FormView): class UploadView(LoginRequiredMixin, FormView):
form_class = FileFieldForm form_class = FileFieldForm
template_name = 'store/upload.html' template_name = 'store/upload.html'
@ -46,6 +48,7 @@ class UploadView(LoginRequiredMixin, FormView):
with open(zip_path, "wb+") as f: # Writing archive with open(zip_path, "wb+") as f: # Writing archive
for chunk in file.chunks(): for chunk in file.chunks():
f.write(chunk) f.write(chunk)
# Check if uploaded file is a zip archive
if magic.from_file(zip_path, mime=True) != 'application/zip': if magic.from_file(zip_path, mime=True) != 'application/zip':
print(magic.from_file(zip_path)) print(magic.from_file(zip_path))
os.remove(zip_path) os.remove(zip_path)
@ -56,6 +59,10 @@ class UploadView(LoginRequiredMixin, FormView):
with open(os.path.join(extract_path, 'infos.toml'), 'r') as f: with open(os.path.join(extract_path, 'infos.toml'), 'r') as f:
# Reading and parsing toml file # Reading and parsing toml file
module_info = toml.loads(f.read()) module_info = toml.loads(f.read())
for required_field in REQUIRED_FIELDS:
if not required_field in module_info.keys():
return JsonResponse({'error': f'Field <strong>{required_field}\
</strong> is missing.'}, status=500)
shutil.rmtree(extract_path) shutil.rmtree(extract_path)
os.remove(zip_path) os.remove(zip_path)
if Module.objects.filter(name=module_info['name'].lower(), if Module.objects.filter(name=module_info['name'].lower(),
@ -84,9 +91,9 @@ class UploadView(LoginRequiredMixin, FormView):
version.save() version.save()
for dependency in module_info['dependencies']: for dependency in module_info['dependencies']:
if not Dependency.objects.filter(version=version, dep_module=dependency, if not Dependency.objects.filter(version=version, dep_module=dependency,
dep_version=module_info['dependencies'][dependency]).exists(): dep_version=module_info['dependencies'][dependency]).exists():
dep = Dependency(version=version, dep_module=dependency, dep = Dependency(version=version, dep_module=dependency,
dep_version=module_info['dependencies'][dependency]) dep_version=module_info['dependencies'][dependency])
dep.save() dep.save()
return JsonResponse({'form': True}) return JsonResponse({'form': True})
else: else: