PDMI/PDMI/store/views.py

101 lines
4.7 KiB
Python

from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render
from django.urls import reverse_lazy
from bootstrap_modal_forms.generic import BSModalCreateView, BSModalLoginView
from .forms import CustomUserCreationForm, CustomAuthenticationForm
from django.views.generic.edit import FormView
from .forms import FileFieldForm
from .response import response_mimetype, JsonResponse
from .models import Module, Version, Dependency
from PDMI import settings
from packaging.specifiers import SpecifierSet
from django.http import HttpResponse
import os
import zipfile
import toml
import shutil
import magic
class SignUpView(BSModalCreateView):
form_class = CustomUserCreationForm
template_name = 'store/signup_modal.html'
success_message = 'Success: Sign up succeeded. You can now Log in.'
success_url = reverse_lazy('store_front_page')
class CustomLoginView(BSModalLoginView):
authentication_form = CustomAuthenticationForm
template_name = 'store/login_modal.html'
success_message = 'Success: You were successfully logged in.'
extra_content = dict(success_url=reverse_lazy('index'))
REQUIRED_FIELDS = ['name', 'description', 'version', 'bot_version']
class UploadView(LoginRequiredMixin, FormView):
form_class = FileFieldForm
template_name = 'store/upload.html'
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
files = request.FILES.getlist('file')
if form.is_valid():
for file in files:
zip_path = os.path.join(settings.MEDIA_ROOT, file.name)
extract_path = os.path.splitext(zip_path)[0]
with open(zip_path, "wb+") as f: # Writing archive
for chunk in file.chunks():
f.write(chunk)
# Check if uploaded file is a zip archive
if magic.from_file(zip_path, mime=True) != 'application/zip':
print(magic.from_file(zip_path))
os.remove(zip_path)
return JsonResponse({'error': 'You must upload a zip archive.'}, status=500)
with zipfile.ZipFile(zip_path, 'r') as zip: # Unzip archive
zip.extractall(extract_path)
with open(os.path.join(extract_path, 'infos.toml'), 'r') as f:
# Reading and parsing toml file
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 {required_field}\
is missing.'}, status=500)
shutil.rmtree(extract_path)
os.remove(zip_path)
if Module.objects.filter(name=module_info['name'].lower(),
creator=request.user):
# If module exists
module = Module.objects.get(name=module_info['name'].lower(),
creator=request.user)
else:
# Else, creating module
module = Module(name=module_info['name'].lower(),
desc=module_info['description'],
creator=request.user)
if Version.objects.filter(module=module, ver=module_info['version']).exists():
# If version already exists, edit existing version
version = Version.objects.get(
module=module, ver=module_info['version'])
version.file = file
version.metamodule = module_info['metamodule']
version.bot_ver = module_info['bot_version']
else:
version = Version(module=module, ver=module_info['version'],
bot_ver=module_info['bot_version'],
metamodule=module_info['metamodule'],
file=file)
module.save()
version.save()
for dependency in module_info['dependencies']:
if not Dependency.objects.filter(version=version, dep_module=dependency,
dep_version=module_info['dependencies'][dependency]).exists():
dep = Dependency(version=version, dep_module=dependency,
dep_version=module_info['dependencies'][dependency])
dep.save()
return JsonResponse({'form': True})
else:
return JsonResponse({'form': False})