Module upload handling works

This commit is contained in:
HugoNeveux 2020-04-26 17:15:45 +02:00
parent 2e70d24893
commit ef07edb1af
9 changed files with 275 additions and 9 deletions

View File

@ -2,7 +2,7 @@ from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.models import User
from bootstrap_modal_forms.mixins import PopRequestMixin, CreateUpdateAjaxMixin
from django import forms
from .models import Module
from .models import Version
class CustomUserCreationForm(PopRequestMixin, CreateUpdateAjaxMixin,
UserCreationForm):
@ -17,3 +17,15 @@ class CustomAuthenticationForm(AuthenticationForm):
class FileFieldForm(forms.Form):
file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
class FileFieldForm(forms.ModelForm):
class Meta:
model = Version
fields = ['file']
widgets = {
'file': forms.ClearableFileInput(
attrs = {
'multiple': True
}
)
}

View File

@ -0,0 +1,33 @@
# Generated by Django 3.0 on 2020-04-25 21:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('store', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='module',
name='bot_ver',
field=models.CharField(max_length=10, null=True),
),
migrations.AddField(
model_name='module',
name='metamodule',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='module',
name='ver',
field=models.CharField(max_length=10, null=True),
),
migrations.AlterField(
model_name='module',
name='desc',
field=models.TextField(max_length=2048, null=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0 on 2020-04-25 21:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('store', '0002_auto_20200425_2100'),
]
operations = [
migrations.AddField(
model_name='module',
name='dependencies',
field=models.ManyToManyField(related_name='_module_dependencies_+', to='store.Module'),
),
]

View File

@ -0,0 +1,46 @@
# Generated by Django 3.0 on 2020-04-25 22:11
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('store', '0003_module_dependencies'),
]
operations = [
migrations.RemoveField(
model_name='module',
name='bot_ver',
),
migrations.RemoveField(
model_name='module',
name='dependencies',
),
migrations.RemoveField(
model_name='module',
name='file',
),
migrations.RemoveField(
model_name='module',
name='metamodule',
),
migrations.RemoveField(
model_name='module',
name='ver',
),
migrations.CreateModel(
name='Version',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ver', models.CharField(max_length=10, null=True)),
('bot_ver', models.CharField(max_length=10, null=True)),
('metamodule', models.BooleanField(default=False)),
('file', models.FileField(upload_to='')),
('dependencies', models.ManyToManyField(related_name='_version_dependencies_+', to='store.Version')),
('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.Module')),
],
),
]

View File

@ -0,0 +1,21 @@
# Generated by Django 3.0 on 2020-04-26 12:17
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('store', '0004_auto_20200425_2211'),
]
operations = [
migrations.AddField(
model_name='module',
name='creator',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,41 @@
# Generated by Django 3.0 on 2020-04-26 14:50
from django.db import migrations, models
import django.db.models.deletion
import store.models
class Migration(migrations.Migration):
dependencies = [
('store', '0005_module_creator'),
]
operations = [
migrations.AlterField(
model_name='version',
name='bot_ver',
field=models.CharField(default='~=0.1.0', max_length=15),
preserve_default=False,
),
migrations.AlterField(
model_name='version',
name='file',
field=models.FileField(upload_to=store.models.upload_path),
),
migrations.AlterField(
model_name='version',
name='ver',
field=models.CharField(default='0.1.0', max_length=15),
preserve_default=False,
),
migrations.CreateModel(
name='Dependency',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('dep_module', models.CharField(max_length=255)),
('dep_version', models.CharField(max_length=15)),
('version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.Version')),
],
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 3.0 on 2020-04-26 14:51
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('store', '0006_auto_20200426_1450'),
]
operations = [
migrations.RemoveField(
model_name='version',
name='dependencies',
),
]

View File

@ -1,6 +1,40 @@
from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver
import PDMI.settings as settings
import os
from django.contrib.auth.models import User
def upload_path(instance, filename):
path = os.path.join(
'modules', instance.module.name.lower(), instance.ver, filename)
if os.path.isfile(os.path.join(settings.MEDIA_ROOT, path)):
# Delete file if already exists
os.remove(os.path.join(settings.MEDIA_ROOT, path))
return path
class Module(models.Model):
file = models.FileField()
name = models.CharField(max_length=255)
desc = models.TextField(max_length=2048)
desc = models.TextField(max_length=2048, null=True)
creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.name
class Version(models.Model):
module = models.ForeignKey(Module, on_delete=models.CASCADE)
ver = models.CharField(max_length=15)
bot_ver = models.CharField(max_length=15)
metamodule = models.BooleanField(default=False)
file = models.FileField(upload_to=upload_path)
def __str__(self):
return self.ver
class Dependency(models.Model):
version = models.ForeignKey(Version, on_delete=models.CASCADE)
dep_module = models.CharField(max_length=255)
dep_version = models.CharField(max_length=15)

View File

@ -5,9 +5,14 @@ from bootstrap_modal_forms.generic import BSModalCreateView, BSModalLoginView
from .forms import CustomUserCreationForm, CustomAuthenticationForm
from django.views.generic.edit import FormView
from .forms import FileFieldForm
import os
import PDMI.settings as settings
from .response import response_mimetype, JsonResponse
from .models import Module, Version, Dependency
from PDMI import settings
from packaging.specifiers import SpecifierSet
import os
import zipfile
import toml
import shutil
class SignUpView(BSModalCreateView):
@ -33,10 +38,49 @@ class UploadView(LoginRequiredMixin, FormView):
form = self.get_form(form_class)
files = request.FILES.getlist('file')
if form.is_valid():
for f in files:
with open(os.path.join(settings.MEDIA_ROOT, f.name), 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
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)
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())
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']).count() > 0:
# 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]).count() > 0:
dep = Dependency(version=version, dep_module=dependency,
dep_version=module_info['dependencies'][dependency])
dep.save()
return JsonResponse({'form': True})
else:
return JsonResponse({'form': False})