Module upload handling works
This commit is contained in:
parent
2e70d24893
commit
ef07edb1af
@ -2,7 +2,7 @@ from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from bootstrap_modal_forms.mixins import PopRequestMixin, CreateUpdateAjaxMixin
|
from bootstrap_modal_forms.mixins import PopRequestMixin, CreateUpdateAjaxMixin
|
||||||
from django import forms
|
from django import forms
|
||||||
from .models import Module
|
from .models import Version
|
||||||
|
|
||||||
class CustomUserCreationForm(PopRequestMixin, CreateUpdateAjaxMixin,
|
class CustomUserCreationForm(PopRequestMixin, CreateUpdateAjaxMixin,
|
||||||
UserCreationForm):
|
UserCreationForm):
|
||||||
@ -17,3 +17,15 @@ class CustomAuthenticationForm(AuthenticationForm):
|
|||||||
|
|
||||||
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 Meta:
|
||||||
|
model = Version
|
||||||
|
fields = ['file']
|
||||||
|
widgets = {
|
||||||
|
'file': forms.ClearableFileInput(
|
||||||
|
attrs = {
|
||||||
|
'multiple': True
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
33
PDMI/store/migrations/0002_auto_20200425_2100.py
Normal file
33
PDMI/store/migrations/0002_auto_20200425_2100.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
18
PDMI/store/migrations/0003_module_dependencies.py
Normal file
18
PDMI/store/migrations/0003_module_dependencies.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
46
PDMI/store/migrations/0004_auto_20200425_2211.py
Normal file
46
PDMI/store/migrations/0004_auto_20200425_2211.py
Normal 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')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
21
PDMI/store/migrations/0005_module_creator.py
Normal file
21
PDMI/store/migrations/0005_module_creator.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
41
PDMI/store/migrations/0006_auto_20200426_1450.py
Normal file
41
PDMI/store/migrations/0006_auto_20200426_1450.py
Normal 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')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
17
PDMI/store/migrations/0007_remove_version_dependencies.py
Normal file
17
PDMI/store/migrations/0007_remove_version_dependencies.py
Normal 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',
|
||||||
|
),
|
||||||
|
]
|
@ -1,6 +1,40 @@
|
|||||||
from django.db import models
|
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):
|
class Module(models.Model):
|
||||||
file = models.FileField()
|
|
||||||
name = models.CharField(max_length=255)
|
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)
|
||||||
|
@ -5,9 +5,14 @@ from bootstrap_modal_forms.generic import BSModalCreateView, BSModalLoginView
|
|||||||
from .forms import CustomUserCreationForm, CustomAuthenticationForm
|
from .forms import CustomUserCreationForm, CustomAuthenticationForm
|
||||||
from django.views.generic.edit import FormView
|
from django.views.generic.edit import FormView
|
||||||
from .forms import FileFieldForm
|
from .forms import FileFieldForm
|
||||||
import os
|
|
||||||
import PDMI.settings as settings
|
|
||||||
from .response import response_mimetype, JsonResponse
|
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):
|
class SignUpView(BSModalCreateView):
|
||||||
@ -33,10 +38,49 @@ class UploadView(LoginRequiredMixin, FormView):
|
|||||||
form = self.get_form(form_class)
|
form = self.get_form(form_class)
|
||||||
files = request.FILES.getlist('file')
|
files = request.FILES.getlist('file')
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
for f in files:
|
for file in files:
|
||||||
with open(os.path.join(settings.MEDIA_ROOT, f.name), 'wb+') as destination:
|
zip_path = os.path.join(settings.MEDIA_ROOT, file.name)
|
||||||
for chunk in f.chunks():
|
extract_path = os.path.splitext(zip_path)[0]
|
||||||
destination.write(chunk)
|
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})
|
return JsonResponse({'form': True})
|
||||||
else:
|
else:
|
||||||
return JsonResponse({'form': False})
|
return JsonResponse({'form': False})
|
||||||
|
Loading…
Reference in New Issue
Block a user