diff --git a/.gitignore b/.gitignore index 2747baa..f11ba58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__ *.pyc -db.sqlite3 \ No newline at end of file +db.sqlite3 +credentials diff --git a/interface/admin.py b/interface/admin.py index 557a206..4f28ede 100644 --- a/interface/admin.py +++ b/interface/admin.py @@ -4,6 +4,22 @@ from django.contrib import admin from . import models -admin.site.register(models.Project) -admin.site.register(models.Submission) -admin.site.register(models.WikiPage) \ No newline at end of file + +class ProjectAdmin(admin.ModelAdmin): + + list_display = ['name', 'ensemble', 'deadline', 'active'] + list_filter = ['ensemble', 'active'] + +class SubmissionAdmin(admin.ModelAdmin): + list_display = ['name', 'instrument', 'date', 'complete'] + list_filter = ['project', 'complete'] + +class WikiPageAdmin(admin.ModelAdmin): + list_display = ['title', 'project'] + list_filter = ['project'] + +admin.site.register(models.Ensemble) +admin.site.register(models.Project, ProjectAdmin) +admin.site.register(models.Submission, SubmissionAdmin) +admin.site.register(models.Resource) +admin.site.register(models.WikiPage, WikiPageAdmin) \ No newline at end of file diff --git a/interface/decorators.py b/interface/decorators.py new file mode 100644 index 0000000..32f7374 --- /dev/null +++ b/interface/decorators.py @@ -0,0 +1,19 @@ +from django.http import HttpResponseRedirect + +def check_allowed(view_func): + + def _view(request, *args, **kwargs): + + request.ensemble_id = request.session.get('ensemble') + + if request.ensemble_id is None: + return HttpResponseRedirect('/register') + + return view_func(request, *args, **kwargs) + + _view.__name__ = view_func.__name__ + _view.__dict__ = view_func.__dict__ + _view.__doc__ = view_func.__doc__ + + return _view + diff --git a/interface/forms.py b/interface/forms.py new file mode 100644 index 0000000..a403abc --- /dev/null +++ b/interface/forms.py @@ -0,0 +1,8 @@ +from django.forms import ModelForm + +from .models import Submission + +class SubmissionForm(ModelForm): + class Meta: + model = Submission + fields = ['name', 'instrument', 'notes'] \ No newline at end of file diff --git a/interface/migrations/0003_auto_20200905_0118.py b/interface/migrations/0003_auto_20200905_0118.py new file mode 100644 index 0000000..ba5f49a --- /dev/null +++ b/interface/migrations/0003_auto_20200905_0118.py @@ -0,0 +1,33 @@ +# Generated by Django 3.1.1 on 2020-09-05 01:18 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('interface', '0002_auto_20200904_1004'), + ] + + operations = [ + migrations.CreateModel( + name='Ensemble', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('code', models.CharField(max_length=12)), + ('password', models.CharField(max_length=100)), + ], + ), + migrations.AddField( + model_name='project', + name='active', + field=models.BooleanField(default=True), + ), + migrations.AddField( + model_name='project', + name='ensemble', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='interface.ensemble'), + ), + ] diff --git a/interface/migrations/0004_auto_20200905_0127.py b/interface/migrations/0004_auto_20200905_0127.py new file mode 100644 index 0000000..bcc9612 --- /dev/null +++ b/interface/migrations/0004_auto_20200905_0127.py @@ -0,0 +1,34 @@ +# Generated by Django 3.1.1 on 2020-09-05 01:27 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('interface', '0003_auto_20200905_0118'), + ] + + operations = [ + migrations.AddField( + model_name='project', + name='bucket', + field=models.CharField(default='', max_length=100), + preserve_default=False, + ), + migrations.AddField( + model_name='project', + name='deadline', + field=models.DateField(blank=True, null=True), + ), + migrations.CreateModel( + name='Resource', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('uri', models.CharField(max_length=255)), + ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resources', to='interface.project')), + ], + ), + ] diff --git a/interface/migrations/0005_auto_20200905_0638.py b/interface/migrations/0005_auto_20200905_0638.py new file mode 100644 index 0000000..9b38f63 --- /dev/null +++ b/interface/migrations/0005_auto_20200905_0638.py @@ -0,0 +1,23 @@ +# Generated by Django 3.1.1 on 2020-09-05 06:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('interface', '0004_auto_20200905_0127'), + ] + + operations = [ + migrations.AddField( + model_name='submission', + name='complete', + field=models.BooleanField(default=False), + ), + migrations.AlterField( + model_name='submission', + name='date', + field=models.DateField(auto_now_add=True), + ), + ] diff --git a/interface/migrations/0006_submission_key.py b/interface/migrations/0006_submission_key.py new file mode 100644 index 0000000..4c9479f --- /dev/null +++ b/interface/migrations/0006_submission_key.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.1 on 2020-09-05 09:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('interface', '0005_auto_20200905_0638'), + ] + + operations = [ + migrations.AddField( + model_name='submission', + name='key', + field=models.CharField(blank=True, max_length=255), + ), + ] diff --git a/interface/models.py b/interface/models.py index e9c33ba..8ba4580 100644 --- a/interface/models.py +++ b/interface/models.py @@ -1,12 +1,44 @@ from django.db import models +from django.utils.text import slugify -# Create your models here. -class Project(models.Model): +import boto3 + +from datetime import datetime + +import os.path + +s3client = boto3.client('s3') + +class Ensemble(models.Model): name = models.CharField(max_length=100) + code = models.CharField(max_length=12) + password = models.CharField(max_length=100) + + def active_projects(self): + return self.projects.filter(active=True) def __str__(self): return self.name +class Project(models.Model): + name = models.CharField(max_length=100) + ensemble = models.ForeignKey(Ensemble, related_name='projects', on_delete=models.CASCADE, null=True) + active = models.BooleanField(default=True) + deadline =models.DateField(null=True, blank=True) + bucket = models.CharField(max_length=100) + + def presigned_post(self, object_name, fields={}, conditions=[], expires=3600): + key = os.path.join(slugify(self.name), object_name) + return s3client.generate_presigned_post(self.bucket, key, Fields=fields, Conditions=conditions, ExpiresIn=expires) + + def __str__(self): + return self.name + +class Resource(models.Model): + project = models.ForeignKey(Project, related_name='resources', on_delete=models.CASCADE) + name = models.CharField(max_length=100) + uri = models.CharField(max_length=255) + class WikiPage(models.Model): project = models.ForeignKey(Project, related_name='wiki_pages', on_delete=models.CASCADE) title = models.CharField(max_length=255) @@ -17,10 +49,19 @@ class WikiPage(models.Model): class Submission(models.Model): project = models.ForeignKey(Project, related_name='submissions', on_delete=models.CASCADE) - date = models.DateField(auto_created=True) + date = models.DateField(auto_now_add=True) name = models.CharField(max_length=255) instrument = models.CharField(max_length=100) notes = models.TextField(blank=True) + complete = models.BooleanField(default=False) + key = models.CharField(max_length=255, blank=True) + + def generate_key(self): + return "{}_{}_{}_${{filename}}".format( + datetime.now().isoformat(timespec='seconds').replace(':', ''), + slugify(self.name), + slugify(self.instrument) + ) def __str__(self): return f"{self.name}: {self.date}" \ No newline at end of file diff --git a/interface/templates/base.html b/interface/templates/base.html index a801535..2fa750a 100644 --- a/interface/templates/base.html +++ b/interface/templates/base.html @@ -17,16 +17,21 @@ {% block header %}