diff --git a/dev-requirements.txt b/dev-requirements.txt
index b064f29..255813d 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1 +1,2 @@
pylint==2.6.0
+django-debug-toolbar
\ No newline at end of file
diff --git a/interface/admin.py b/interface/admin.py
index d97d5a4..53bcdc7 100644
--- a/interface/admin.py
+++ b/interface/admin.py
@@ -5,14 +5,15 @@ from . import models
class EnsembleAdmin(admin.ModelAdmin):
list_display = ['name', 'ensemble_code', 'slug']
+class ModuleInline(admin.StackedInline):
+ model = models.Module
+ extra = 0
+
class ProjectAdmin(admin.ModelAdmin):
- list_display = ['name', 'ensemble', 'event_date', 'active', 'slug']
+ list_display = ['name', 'ensemble', 'event_date', 'active']
list_filter = ['ensemble', 'active']
-
-class SubmissionAdmin(admin.ModelAdmin):
- list_display = ['name', 'instrument', 'date', 'complete']
- list_filter = ['project', 'complete']
+ inlines = [ModuleInline]
class ResourceAdmin(admin.ModelAdmin):
list_display = ['name', 'media_type', 'project']
@@ -24,6 +25,5 @@ class WikiPageAdmin(admin.ModelAdmin):
admin.site.register(models.Ensemble, EnsembleAdmin)
admin.site.register(models.Project, ProjectAdmin)
-admin.site.register(models.Submission, SubmissionAdmin)
admin.site.register(models.Resource, ResourceAdmin)
admin.site.register(models.WikiPage, WikiPageAdmin)
\ No newline at end of file
diff --git a/interface/forms.py b/interface/forms.py
index bd4cb94..9e9e541 100644
--- a/interface/forms.py
+++ b/interface/forms.py
@@ -1,17 +1,46 @@
from django import forms
-from .models import Submission
+from crispy_forms.helper import FormHelper
+from crispy_forms.layout import Submit
-class CodeForm(forms.Form):
+from . import models, fields
+
+class BaseForm(forms.Form):
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.helper = self.get_form_helper()
+
+ def get_form_helper(self):
+ helper = FormHelper(self)
+ helper.add_input(Submit('submit', 'Submit', css_class='button is-link'))
+ return helper
+
+
+class ProjectForm(forms.ModelForm, BaseForm):
+
+ class Meta:
+ model = models.Project
+ fields = ['name', 'description', 'event_date']
+ widgets = {
+ 'event_date': forms.DateTimeInput(attrs={'type': 'date'})
+ }
+
+class ResourceForm(forms.ModelForm, BaseForm):
+
+ class Meta:
+ model = models.Resource
+ fields = ['name', 'media_type', 'description', 'file']
+
+ def get_form_helper(self):
+ helper = super().get_form_helper()
+ helper[3].wrap(fields.BulmaFileUpload)
+ return helper
+
+class CodeForm(BaseForm):
code = forms.CharField(max_length=14,
widget=forms.TextInput(attrs={'placeholder': 'xxx-xxx-xxx', 'inputmode': 'numeric'}))
passphrase = forms.CharField(max_length=32)
-class SubmissionForm(forms.ModelForm):
- method = forms.ChoiceField(choices=(
- ('upload', 'I need to upload a file'),
- ('link', 'I have a link from my own cloud storage provider')
- ), initial='upload')
-
- class Meta:
- model = Submission
- fields = ['name', 'instrument', 'method', 'notes']
\ No newline at end of file
+class ResourceUploadForm(forms.Form):
+ pass
+# file = S3UploadField()
\ No newline at end of file
diff --git a/interface/migrations/0001_initial.py b/interface/migrations/0001_initial.py
index b8da9cb..c50c935 100644
--- a/interface/migrations/0001_initial.py
+++ b/interface/migrations/0001_initial.py
@@ -1,7 +1,10 @@
-# Generated by Django 3.1.1 on 2020-09-04 09:59
+# Generated by Django 3.2.7 on 2022-11-18 09:54
+import byostorage.user
+from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
+import interface.models
class Migration(migrations.Migration):
@@ -9,32 +12,69 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('byostorage', '0004_alter_userstorage_storage'),
]
operations = [
+ migrations.CreateModel(
+ name='Ensemble',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(help_text='Display name', max_length=100)),
+ ('slug', models.SlugField(editable=False, help_text='Short name for the ensemble - used for folders', max_length=100)),
+ ('code', models.CharField(default=interface.models.generate_code, help_text='Ensemble registration code', max_length=9)),
+ ('passphrase', models.CharField(help_text='Used to register ensembles', max_length=100)),
+ ('details', models.TextField(blank=True, help_text='Description of the ensemble (markdown)')),
+ ('admins', models.ManyToManyField(related_name='ensembles', to=settings.AUTH_USER_MODEL)),
+ ('storage', models.ForeignKey(help_text='Default storage for this ensemble', null=True, on_delete=django.db.models.deletion.SET_NULL, to='byostorage.userstorage')),
+ ],
+ ),
migrations.CreateModel(
name='Project',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
+ ('description', models.TextField(blank=True, help_text='Markdown format')),
+ ('active', models.BooleanField(default=True)),
+ ('event_date', models.DateField(blank=True, null=True)),
+ ('owner', models.CharField(blank=True, max_length=255)),
+ ('ensemble', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='projects', to='interface.ensemble')),
],
+ options={
+ 'ordering': ['active', '-pk'],
+ },
),
migrations.CreateModel(
name='WikiPage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=255)),
('markdown', models.TextField()),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wiki_pages', to='interface.project')),
],
),
migrations.CreateModel(
- name='Submission',
+ name='Resource',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=255)),
- ('instrument', models.CharField(max_length=100)),
- ('notes', models.TextField()),
- ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submissions', to='interface.project')),
+ ('name', models.CharField(max_length=100)),
+ ('description', models.TextField(blank=True)),
+ ('file', models.FileField(storage=byostorage.user.BYOStorage(), upload_to=interface.models.resource_key)),
+ ('media_type', models.CharField(choices=[('audio', 'Audio'), ('video', 'Video'), ('general', 'General')], default='*', max_length=10)),
+ ('visible', models.BooleanField(default=True)),
+ ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resources', to='interface.project')),
+ ],
+ options={
+ 'ordering': ['-visible', '-pk'],
+ },
+ ),
+ migrations.CreateModel(
+ name='Module',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.SlugField(max_length=20)),
+ ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='modules', to='interface.project')),
],
),
]
diff --git a/interface/migrations/0001_squashed_0021_project_description.py b/interface/migrations/0001_squashed_0021_project_description.py
deleted file mode 100644
index 51bab54..0000000
--- a/interface/migrations/0001_squashed_0021_project_description.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Generated by Django 3.1.1 on 2021-03-21 23:10
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-import interface.models
-
-
-class Migration(migrations.Migration):
-
- replaces = [('interface', '0001_initial'), ('interface', '0002_auto_20200904_1004'), ('interface', '0003_auto_20200905_0118'), ('interface', '0004_auto_20200905_0127'), ('interface', '0005_auto_20200905_0638'), ('interface', '0006_submission_key'), ('interface', '0007_auto_20200906_1009'), ('interface', '0008_auto_20200906_1122'), ('interface', '0009_auto_20200907_0103'), ('interface', '0010_auto_20200907_0148'), ('interface', '0011_auto_20200907_0234'), ('interface', '0012_remove_ensemble_bucket'), ('interface', '0013_auto_20200907_1455'), ('interface', '0014_auto_20200909_1016'), ('interface', '0015_resource_media_type'), ('interface', '0016_auto_20200910_2025'), ('interface', '0017_auto_20200914_0943'), ('interface', '0018_auto_20200914_1009'), ('interface', '0019_project_owner'), ('interface', '0020_auto_20201003_2103'), ('interface', '0021_project_description')]
-
- initial = True
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Project',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=100)),
- ('active', models.BooleanField(default=True)),
- ],
- ),
- migrations.CreateModel(
- name='WikiPage',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('markdown', models.TextField()),
- ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='wiki_pages', to='interface.project')),
- ('title', models.CharField(default='', max_length=255)),
- ],
- ),
- 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(default=interface.models.generate_code, max_length=9)),
- ('passphrase', models.CharField(max_length=100)),
- ('admins', models.ManyToManyField(related_name='ensembles', to=settings.AUTH_USER_MODEL)),
- ],
- ),
- 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'),
- ),
- 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)),
- ('key', models.CharField(blank=True, max_length=255)),
- ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resources', to='interface.project')),
- ('description', models.TextField(blank=True)),
- ('media_type', models.CharField(choices=[('audio', 'Audio'), ('video', 'Video'), ('general', 'General')], default='*', max_length=10)),
- ('visible', models.BooleanField(default=True)),
- ],
- ),
- migrations.AddField(
- model_name='project',
- name='owner',
- field=models.CharField(blank=True, max_length=255),
- ),
- migrations.CreateModel(
- name='Submission',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=255)),
- ('instrument', models.CharField(max_length=100, verbose_name='Instrument / Voice')),
- ('notes', models.TextField(blank=True)),
- ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='all_submissions', to='interface.project')),
- ('date', models.DateTimeField(auto_now_add=True)),
- ('complete', models.BooleanField(default=False)),
- ('url', models.CharField(blank=True, max_length=512)),
- ('private', models.BooleanField(default=False)),
- ],
- ),
- migrations.AddField(
- model_name='project',
- name='description',
- field=models.TextField(blank=True),
- ),
- ]
diff --git a/interface/migrations/0002_auto_20200904_1004.py b/interface/migrations/0002_auto_20200904_1004.py
deleted file mode 100644
index 1aa1682..0000000
--- a/interface/migrations/0002_auto_20200904_1004.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-04 10:04
-
-from django.db import migrations, models
-import django.utils.timezone
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0001_initial'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='submission',
- name='date',
- field=models.DateField(auto_created=True, default=django.utils.timezone.now),
- preserve_default=False,
- ),
- migrations.AddField(
- model_name='wikipage',
- name='title',
- field=models.CharField(default='', max_length=255),
- preserve_default=False,
- ),
- migrations.AlterField(
- model_name='submission',
- name='notes',
- field=models.TextField(blank=True),
- ),
- ]
diff --git a/interface/migrations/0003_auto_20200905_0118.py b/interface/migrations/0003_auto_20200905_0118.py
deleted file mode 100644
index ba5f49a..0000000
--- a/interface/migrations/0003_auto_20200905_0118.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# 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
deleted file mode 100644
index bcc9612..0000000
--- a/interface/migrations/0004_auto_20200905_0127.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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
deleted file mode 100644
index 9b38f63..0000000
--- a/interface/migrations/0005_auto_20200905_0638.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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
deleted file mode 100644
index 4c9479f..0000000
--- a/interface/migrations/0006_submission_key.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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/migrations/0007_auto_20200906_1009.py b/interface/migrations/0007_auto_20200906_1009.py
deleted file mode 100644
index 87f9acd..0000000
--- a/interface/migrations/0007_auto_20200906_1009.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-06 10:09
-
-from django.db import migrations, models
-import django.db.models.deletion
-import interface.models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0006_submission_key'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='project',
- name='bucket',
- ),
- migrations.AddField(
- model_name='ensemble',
- name='bucket',
- field=models.CharField(default='', max_length=100),
- preserve_default=False,
- ),
- migrations.AlterField(
- model_name='ensemble',
- name='code',
- field=models.CharField(default=interface.models.generate_code, max_length=12),
- ),
- migrations.AlterField(
- model_name='submission',
- name='project',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='all_submissions', to='interface.project'),
- ),
- ]
diff --git a/interface/migrations/0008_auto_20200906_1122.py b/interface/migrations/0008_auto_20200906_1122.py
deleted file mode 100644
index e9f6a97..0000000
--- a/interface/migrations/0008_auto_20200906_1122.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-06 11:22
-
-from django.db import migrations, models
-import interface.models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0007_auto_20200906_1009'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='ensemble',
- old_name='password',
- new_name='passphrase',
- ),
- migrations.AlterField(
- model_name='ensemble',
- name='code',
- field=models.CharField(default=interface.models.generate_code, max_length=9),
- ),
- ]
diff --git a/interface/migrations/0009_auto_20200907_0103.py b/interface/migrations/0009_auto_20200907_0103.py
deleted file mode 100644
index 027531f..0000000
--- a/interface/migrations/0009_auto_20200907_0103.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-07 01:03
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0008_auto_20200906_1122'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='submission',
- name='key',
- ),
- migrations.AddField(
- model_name='submission',
- name='location',
- field=models.CharField(blank=True, max_length=512),
- ),
- migrations.AlterField(
- model_name='ensemble',
- name='bucket',
- field=models.CharField(max_length=255),
- ),
- ]
diff --git a/interface/migrations/0010_auto_20200907_0148.py b/interface/migrations/0010_auto_20200907_0148.py
deleted file mode 100644
index fb00411..0000000
--- a/interface/migrations/0010_auto_20200907_0148.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-07 01:48
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0009_auto_20200907_0103'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='submission',
- old_name='location',
- new_name='key',
- ),
- ]
diff --git a/interface/migrations/0011_auto_20200907_0234.py b/interface/migrations/0011_auto_20200907_0234.py
deleted file mode 100644
index 1738cc9..0000000
--- a/interface/migrations/0011_auto_20200907_0234.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-07 02:34
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0010_auto_20200907_0148'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='submission',
- name='date',
- field=models.DateTimeField(auto_now_add=True),
- ),
- ]
diff --git a/interface/migrations/0012_remove_ensemble_bucket.py b/interface/migrations/0012_remove_ensemble_bucket.py
deleted file mode 100644
index 6073ea5..0000000
--- a/interface/migrations/0012_remove_ensemble_bucket.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-07 04:53
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0011_auto_20200907_0234'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='ensemble',
- name='bucket',
- ),
- ]
diff --git a/interface/migrations/0013_auto_20200907_1455.py b/interface/migrations/0013_auto_20200907_1455.py
deleted file mode 100644
index 2afe8a8..0000000
--- a/interface/migrations/0013_auto_20200907_1455.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-07 04:55
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0012_remove_ensemble_bucket'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='resource',
- old_name='uri',
- new_name='key',
- ),
- ]
diff --git a/interface/migrations/0014_auto_20200909_1016.py b/interface/migrations/0014_auto_20200909_1016.py
deleted file mode 100644
index bf2e489..0000000
--- a/interface/migrations/0014_auto_20200909_1016.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-09 00:16
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0013_auto_20200907_1455'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='resource',
- name='description',
- field=models.TextField(blank=True),
- ),
- migrations.AlterField(
- model_name='resource',
- name='key',
- field=models.CharField(blank=True, max_length=255),
- ),
- ]
diff --git a/interface/migrations/0015_resource_media_type.py b/interface/migrations/0015_resource_media_type.py
deleted file mode 100644
index 269c3e0..0000000
--- a/interface/migrations/0015_resource_media_type.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-09 01:46
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0014_auto_20200909_1016'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='resource',
- name='media_type',
- field=models.CharField(choices=[('audio', 'Audio'), ('video', 'Video'), ('*', 'General')], default='*', max_length=10),
- ),
- ]
diff --git a/interface/migrations/0016_auto_20200910_2025.py b/interface/migrations/0016_auto_20200910_2025.py
deleted file mode 100644
index 0ee32f9..0000000
--- a/interface/migrations/0016_auto_20200910_2025.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-10 10:25
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0015_resource_media_type'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='resource',
- name='media_type',
- field=models.CharField(choices=[('audio', 'Audio'), ('video', 'Video'), ('general', 'General')], default='*', max_length=10),
- ),
- ]
diff --git a/interface/migrations/0017_auto_20200914_0943.py b/interface/migrations/0017_auto_20200914_0943.py
deleted file mode 100644
index bb2e88a..0000000
--- a/interface/migrations/0017_auto_20200914_0943.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-13 23:43
-
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('interface', '0016_auto_20200910_2025'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='ensemble',
- name='admins',
- field=models.ManyToManyField(to=settings.AUTH_USER_MODEL),
- ),
- migrations.AlterField(
- model_name='submission',
- name='instrument',
- field=models.CharField(max_length=100, verbose_name='Instrument / Voice'),
- ),
- ]
diff --git a/interface/migrations/0018_auto_20200914_1009.py b/interface/migrations/0018_auto_20200914_1009.py
deleted file mode 100644
index cf7a09e..0000000
--- a/interface/migrations/0018_auto_20200914_1009.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Generated by Django 3.1.1 on 2020-09-14 00:09
-
-from django.conf import settings
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('interface', '0017_auto_20200914_0943'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='resource',
- name='visible',
- field=models.BooleanField(default=True),
- ),
- migrations.AlterField(
- model_name='ensemble',
- name='admins',
- field=models.ManyToManyField(related_name='ensembles', to=settings.AUTH_USER_MODEL),
- ),
- ]
diff --git a/interface/migrations/0019_project_owner.py b/interface/migrations/0019_project_owner.py
deleted file mode 100644
index 14ed726..0000000
--- a/interface/migrations/0019_project_owner.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2020-10-03 09:28
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0018_auto_20200914_1009'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='project',
- name='owner',
- field=models.CharField(blank=True, max_length=255),
- ),
- ]
diff --git a/interface/migrations/0020_auto_20201003_2103.py b/interface/migrations/0020_auto_20201003_2103.py
deleted file mode 100644
index 7d594fd..0000000
--- a/interface/migrations/0020_auto_20201003_2103.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 3.1.1 on 2020-10-03 11:03
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0019_project_owner'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='submission',
- old_name='key',
- new_name='url',
- ),
- migrations.AddField(
- model_name='submission',
- name='private',
- field=models.BooleanField(default=False),
- ),
- ]
diff --git a/interface/migrations/0021_project_description.py b/interface/migrations/0021_project_description.py
deleted file mode 100644
index b2a9a1c..0000000
--- a/interface/migrations/0021_project_description.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2020-10-05 03:41
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0020_auto_20201003_2103'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='project',
- name='description',
- field=models.TextField(blank=True),
- ),
- ]
diff --git a/interface/migrations/0022_auto_20210303_2043.py b/interface/migrations/0022_auto_20210303_2043.py
deleted file mode 100644
index 3f77f10..0000000
--- a/interface/migrations/0022_auto_20210303_2043.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Generated by Django 3.1.1 on 2021-03-03 09:43
-
-from django.db import migrations, models
-from django.utils.text import slugify
-
-def create_slugs(apps, schema_editor):
- for model in ('Ensemble', 'Project'):
- M = apps.get_model('interface', model)
- for instance in M.objects.all():
- if instance.slug == '':
- instance.slug = slugify(instance.name)
- instance.save()
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0021_project_description'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='ensemble',
- name='slug',
- field=models.SlugField(default='', editable=False, max_length=100),
- preserve_default=False,
- ),
- migrations.AddField(
- model_name='project',
- name='slug',
- field=models.SlugField(default='', editable=False, max_length=100),
- preserve_default=False,
- ),
- migrations.RunPython(create_slugs)
- ]
diff --git a/interface/migrations/0023_ensemble_storage.py b/interface/migrations/0023_ensemble_storage.py
deleted file mode 100644
index ae04499..0000000
--- a/interface/migrations/0023_ensemble_storage.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Generated by Django 3.1.1 on 2021-03-12 02:56
-
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0022_auto_20210303_2043'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='ensemble',
- name='storage',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='byostorage.userstorage'),
- ),
- ]
diff --git a/interface/migrations/0024_auto_20210312_1712.py b/interface/migrations/0024_auto_20210312_1712.py
deleted file mode 100644
index 19daf29..0000000
--- a/interface/migrations/0024_auto_20210312_1712.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 3.1.1 on 2021-03-12 06:12
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0023_ensemble_storage'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='project',
- name='accept_submissions',
- field=models.BooleanField(default=False, help_text='Allow media submissions from participants'),
- ),
- migrations.AddField(
- model_name='project',
- name='has_items',
- field=models.BooleanField(default=True, help_text='Enable items to be added from the library'),
- ),
- ]
diff --git a/interface/migrations/0025_auto_20210312_1713.py b/interface/migrations/0025_auto_20210312_1713.py
deleted file mode 100644
index 5eadfaa..0000000
--- a/interface/migrations/0025_auto_20210312_1713.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Generated by Django 3.1.1 on 2021-03-12 06:13
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0024_auto_20210312_1712'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='project',
- old_name='has_items',
- new_name='enable_library',
- ),
- migrations.RenameField(
- model_name='project',
- old_name='accept_submissions',
- new_name='enable_submissions',
- ),
- ]
diff --git a/interface/migrations/0026_auto_20210313_0926.py b/interface/migrations/0026_auto_20210313_0926.py
deleted file mode 100644
index e8c6b19..0000000
--- a/interface/migrations/0026_auto_20210313_0926.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2021-03-12 22:26
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0025_auto_20210312_1713'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='project',
- old_name='deadline',
- new_name='event_date',
- ),
- ]
diff --git a/interface/migrations/0027_auto_20210322_1154.py b/interface/migrations/0027_auto_20210322_1154.py
deleted file mode 100644
index e4c8439..0000000
--- a/interface/migrations/0027_auto_20210322_1154.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2021-03-22 00:54
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0026_auto_20210313_0926'),
- ]
-
- operations = [
- migrations.AlterField(
- model_name='wikipage',
- name='title',
- field=models.CharField(max_length=255),
- ),
- ]
diff --git a/interface/migrations/0028_ensemble_details.py b/interface/migrations/0028_ensemble_details.py
deleted file mode 100644
index 0aa6ec2..0000000
--- a/interface/migrations/0028_ensemble_details.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Generated by Django 3.1.1 on 2021-05-05 05:10
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('interface', '0027_auto_20210322_1154'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='ensemble',
- name='details',
- field=models.TextField(blank=True),
- ),
- ]
diff --git a/interface/models.py b/interface/models.py
index 1804c87..d7810c6 100644
--- a/interface/models.py
+++ b/interface/models.py
@@ -4,19 +4,16 @@ from django.utils import timezone
from django.conf import settings
from django.shortcuts import resolve_url
+from byostorage.user import BYOStorage
+
import random
-import boto3
from datetime import datetime
from urllib.parse import urlparse
import os.path
-s3client = boto3.client('s3', **getattr(settings, 'S3_CREDENTIALS', {}))
-
-BUCKET = settings.AWS_BUCKET
-
MEDIA_TYPES = [
('audio', "Audio"),
('video', "Video"),
@@ -24,14 +21,14 @@ MEDIA_TYPES = [
]
def rough_date(d):
- days = (self.event_date - timezone.now().date()).days
+ days = (d - timezone.now()).days
in_past = days < 0
if in_past:
days = abs(days)
if days ==0:
return "today!"
if days >= 7:
- return in_past, "{0:d} weeks, {1:d} days".format(days / 7, days % 7)
+ return in_past, "{0:d} weeks, {1:d} days".format(int(days / 7), int(days % 7))
return in_past, f"{days} days"
@@ -39,16 +36,25 @@ def generate_code(length=9):
return "".join([ random.choice('0123456789') for _ in range(length) ])
class Ensemble(models.Model):
- name = models.CharField(max_length=100)
- code = models.CharField(max_length=9, default=generate_code)
- passphrase = models.CharField(max_length=100)
+ ''' A group that plays together
+
+ '''
+ name = models.CharField(max_length=100,
+ help_text="Display name")
+ slug = models.SlugField(max_length=100, editable=False, unique=True,
+ help_text="Short name for the ensemble - used for folders")
+ code = models.CharField(max_length=9, default=generate_code,
+ help_text="Ensemble registration code")
+ passphrase = models.CharField(max_length=100,
+ help_text="Used to register ensembles")
admins = models.ManyToManyField('auth.User', related_name='ensembles')
- slug = models.SlugField(max_length=100, editable=False)
- details = models.TextField(blank=True)
- storage = models.ForeignKey('byostorage.UserStorage', null=True, on_delete=models.SET_NULL)
+ details = models.TextField(blank=True,
+ help_text="Description of the ensemble (markdown)")
+ storage = models.ForeignKey('byostorage.UserStorage', null=True, on_delete=models.SET_NULL,
+ help_text="Default storage for this ensemble")
def active_projects(self):
- return self.projects.filter(active=True)
+ return self.projects.filter(active=True).order_by('event_date')
def ensemble_code(self):
code = str(self.code)
@@ -62,24 +68,24 @@ class Ensemble(models.Model):
def __str__(self):
return self.name
+
class Project(models.Model):
+ ''' A Project linked to an ensemble
+ '''
name = models.CharField(max_length=100)
ensemble = models.ForeignKey(Ensemble, related_name='projects', on_delete=models.CASCADE, null=True)
- description = models.TextField(blank=True)
+ description = models.TextField(blank=True,
+ help_text="Markdown format")
active = models.BooleanField(default=True)
- event_date =models.DateField(null=True, blank=True)
+ event_date =models.DateTimeField(null=True, blank=True)
owner = models.CharField(max_length=255, blank=True)
- slug = models.SlugField(max_length=100, editable=False)
- enable_library = models.BooleanField(default=True, help_text="Enable items to be added from the library")
- enable_submissions = models.BooleanField(default=False, help_text="Allow media submissions from participants")
+
+ class Meta:
+ ordering = ['active', '-pk']
@property
def submissions(self):
- return self.all_submissions.filter(complete=True).order_by('-pk')
-
- def presigned_post(self, object_name, fields=None, conditions=None, expires=3600):
- key = os.path.join(self.slug, object_name)
- return s3client.generate_presigned_post(BUCKET, key, Fields=fields or {}, Conditions=conditions or [], ExpiresIn=expires)
+ return self.all_submissions.order_by('-pk')
@property
def days(self):
@@ -87,42 +93,59 @@ class Project(models.Model):
@property
def has_happened(self):
- return self.event_date < timezone.now().date()
+ return self.event_date < timezone.now()
- def save(self):
- if not self.slug:
- self.slug = slugify(self.name)
- super(Project, self).save()
+ @property
+ def rough_date(self):
+ in_past, s = rough_date(self.event_date)
+ if in_past:
+ return f"{s} ago"
+ return f"In {s}"
+
+ @property
+ def folder(self):
+ print(f"{self.ensemble.storage_id}:{self.ensemble.slug}/{self.slug}")
+ return f"{self.ensemble.storage_id}:{self.ensemble.slug}/{self.slug}"
def __str__(self):
return self.name
+class Module(models.Model):
+ ''' Enable modules on a oriject
+ '''
+ name = models.SlugField(max_length=20, choices=[ (x, x.title()) for x in settings.POLYPHONIC_MODULES ])
+ project = models.ForeignKey(Project, related_name="modules", on_delete=models.CASCADE)
+
+def resource_key(resource, filename):
+ return f'{resource.project.folder}/resources/{filename}'
+
class Resource(models.Model):
+ ''' A viewable file resource attached to a project
+
+ e.g PDF instructions, MP3 backing track
+ '''
project = models.ForeignKey(Project, related_name='resources', on_delete=models.CASCADE)
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
- key = models.CharField(max_length=255, blank=True)
+ file = models.FileField(storage=BYOStorage(), upload_to=resource_key)
media_type = models.CharField(max_length=10, choices=MEDIA_TYPES, default='*')
visible = models.BooleanField(default=True)
- def key_template(self):
- return "{}/${{filename}}".format(slugify(self.name))
+ class Meta:
+ ordering = ['-visible', '-pk']
def accept(self):
if self.media_type == 'general':
return ".*"
return f"{self.media_type}/*"
- def presigned_url(self):
- if not self.key:
- return ""
- params = {'Bucket': BUCKET, 'Key': self.key}
- return s3client.generate_presigned_url('get_object', Params=params, ExpiresIn=3600*24)
-
def __str__(self):
return self.name
class WikiPage(models.Model):
+ ''' An editable wiki page for the project in markdown format
+
+ '''
project = models.ForeignKey(Project, related_name='wiki_pages', on_delete=models.CASCADE)
title = models.CharField(max_length=255)
markdown = models.TextField()
@@ -132,9 +155,9 @@ class WikiPage(models.Model):
def __str__(self):
return self.title
-
+"""
class Submission(models.Model):
- project = models.ForeignKey(Project, related_name='all_submissions', on_delete=models.CASCADE)
+ project = models.ForeignKey(Project, related_name='old_submissions', on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True, )
name = models.CharField(max_length=255)
instrument = models.CharField(max_length=100, verbose_name="Instrument / Voice")
@@ -180,3 +203,4 @@ class Submission(models.Model):
def __str__(self):
return f"{self.name}: {self.date}"
+"""
\ No newline at end of file
diff --git a/interface/static/interface/css/polyphonic.css b/interface/static/interface/css/polyphonic.css
index ea8351e..828ab97 100644
--- a/interface/static/interface/css/polyphonic.css
+++ b/interface/static/interface/css/polyphonic.css
@@ -1,366 +1,63 @@
+@font-face {
+ font-family: MartinHand;
+ src: url('/static/fonts/Martinhand3.ttf');
+}
:root {
- --border-color: #292929;
- --gray-blue: #667788;
- --light-blue: #c5eff7;
- --light-grey: #EEEEEE;
+ --primary: #485fc7;
}
-@font-face {
- font-family: 'Quicksand';
- src: url('../../fonts/Quicksand_Book.otf');
+.fancy {
+ font-family: MartinHand;
+ color: var(--primary);
}
-@font-face {
- font-family: 'QuicksandBold';
- src: url('../../fonts/Quicksand_Bold_Oblique.otf');
+.has-text-shadow {
+ text-shadow: 1px 1px 2px #000;
}
-.debug DIV {
- border: 1px dashed #DDD;
+.is-form-group {
+ max-width: 600px;
+ align-self: center;
}
-HTML {
- height: 100%;
+.is-centered {
+ margin: auto;
}
-BODY {
- background-image: url('../background.png');
- background-position: center top;
- background-size: 100%;
- background-repeat: no-repeat;
- margin: 0px;
- height: 100%;
- display: flex;
- align-items: flex-start;
- justify-content: center;
+.is-action {
+ cursor: pointer;
}
-.main {
- max-width: 1280px;
- margin: 10px auto;
- border: 1px solid var(--border-color);
- border-radius: 5px;
- font-family: 'Quicksand', Arial, Helvetica, sans-serif;
- font-size: 14pt;
- background-color: white;
+.menu-label {
+ color: var(--primary);
}
-.content {
- margin: 20px;
- flex-direction: column;
+.button.is-primary, .button.is-primary:hover {
+ background-color: var(--primary);
}
-.narrow {
- max-width: 500px;
- margin: 0px auto;
+A.admin-link:after {
+ content: "*";
}
-.wide {
- width: 1200px;
+TEXTAREA.input {
+ height: 400px;
}
-.collapse {
- display: flex;
- flex-direction: row;
- justify-content: space-around;
-}
-
-@media all and (max-width: 1200px) {
- .wide {
- width: 900px;
- }
-}
-
-@media all and (max-width: 900px) {
- .mdhide {
- display: none;
- }
-
- .wide {
- width: auto;
- }
-}
-
-@media all and (max-width: 700px) {
- .smhide {
- display: none;
- }
- .collapse {
- flex-direction: column;
- }
- .wide {
- width: auto;
- }
-}
-
-
-/* HEADER BAR */
-
-.navigation {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 50px;
- background-color: var(--gray-blue);
- color: var(--light-blue) !important;
-}
-
-.navigation > * {
- white-space: nowrap;
-}
-
-.navigation A,
-.navigation A:visited {
- color: var(--light-blue);
- text-decoration: none;
-}
-
-.navigation .brand {
- font-family: 'QuicksandBold', 'Quicksand', Arial, Helvetica, sans-serif;
- font-size: 1.5rem;
- margin: auto 20px;
-}
-
-UL.nav-buttons {
- display: flex;
- list-style: none;
-}
-UL.nav-buttons > LI {
- margin: 2px 10px;
-}
-
-/* FORMS */
-
-FORM.vertical {
- display: flex;
- flex-direction: column;
- max-width: 400px;
- margin: 0px auto;
-}
-
-LABEL {
- margin-top: 20px;
-}
-
-TEXTAREA {
- height: 50px;
-}
-
-INPUT[type=checkbox] {
- margin-right: auto;
-}
-
-.form-actions {
- text-align: right;
- margin-top: 20px;
-}
-
-.badge {
- display: inline-block;
- border: 1px solid var(--gray-blue);
- font-weight: bold;
- font-size: 0.9em;
- border-radius: 10px;
- padding: 4px 10px 2px;
- margin: 2px;
-}
-
-.btn {
- background-color: var(--gray-blue);
- display: inline-block;
+.control INPUT[type='file'] {
border: none;
- color: var(--light-blue);
- text-decoration: none;
- border-radius: 1em;
- font-size: 1em;
-}
-
-.btn:hover {
- cursor: pointer;
- color: white;
-}
-
-.clickable {
- cursor: pointer;
-}
-
-.action {
- margin: 0px 10px 0px 5px;
-}
-
-.pills {
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- margin-top: 40px;
-}
-
-.pills A {
- border: 1px solid var(--gray-blue);
- padding: 4px 10px 2px 10px;
- margin: 10px 5px;
- border-radius: 10px;
- white-space: nowrap;
-}
-
-.pills A:hover {
- background-color: var(--light-blue);
- text-decoration: none
-}
-
-.list-group {
- display: flex;
- flex-direction: column;
-}
-
-.list-group > * {
- border: 1px solid var(--gray-blue);
- border-radius: 10px;
- padding: 2px 20px;
- margin-top: 20px;
-}
-
-.list-group > A:hover {
- background-color: var(--light-blue);
- text-decoration: none;
-}
-
-/* PROGRESS BAR */
-
-.progress {
- display: relative;
- border: 1px solid var(--border-color);
- border-radius: 5px;
- margin: 20px 10px;
-}
-
-.progress-bar {
- width: 0%;
- height: 1.5em;
- background-color: var(--light-blue);
- border-radius: 5px;
-}
-
-.text-center {
+ width: 80%;
text-align: center;
+ margin: auto 10%;
}
-A, A:visited {
- text-decoration: none;
- color: var(--gray-blue);
- font-weight: bold;
-}
-
-A:hover {
- text-decoration: underline;
-}
-
-H1 {
- text-align: center;
-}
-
-TABLE {
- border-spacing: 0px;
-}
-
-TD, TH {
- padding: 3px 6px;
- text-align: left;
-}
-
-TABLE THEAD TR {
- background-color: var(--gray-blue);
- color: var(--light-blue);
- font-weight: bolder;
-}
-
-TABLE THEAD TH {
- padding: 5px 6px;
-}
-
-TABLE.zebra TR:nth-child(even) {
- background-color: var(--light-grey);
-}
-
-TABLE.horizontal TH {
- text-align: right;
-}
-
-TABLE.horizontal TD,
-TABLE.horizontal TH {
- padding: 5px;
-}
-
-TABLE SELECT {
- width: 100%;
-}
-
-.resource-player {
- width: 100%;
- border-radius: 10px;
- max-width: 640px;
- max-height: 640px;
- margin: 5px;
- border: 1px solid var(--border-color);
-}
-
-.dz-clickable {
- text-align: center;
-}
-.scrollable {
- max-height: 200px;
- overflow: auto;
+.project-footer {
+ position: fixed;
+ bottom: 0px;
+ right: 0px;
background-color: #EEE;
- border: 1px solid var(--border-color);
- border-radius: 10px;
- padding: 5px;
-}
-
-.admin-tools {
- float: right;
- padding: 10pt;
-}
-
-.disabled {
- background-color: #DDD;
-}
-
-.dz-image {
- width: 240px !important;
-}
-
-.dz-progress {
- width: 200px !important;
- margin-left: -100px !important;
- margin-top: 24px !important;
-}
-
-.item-table {
- border-collapse: collapse;
-}
-
-.item-table TD {
- border: 1px solid #999;
-}
-TD.select-cell {
- padding: 0px !important;
-}
-
-.select-cell SELECT {
- border: none;
- background-color: transparent;
- height: 30px;
- font-family: inherit;
- font-size: inherit;
-}
-#tag-list DIV {
- padding: 5px;
-}
-
-DIV.selected {
- background-color: var(--gray-blue);
- color: white;
- border: 1px solid #999;
- border-radius: 5px;
+ padding: 10px 10px;
+ margin-top: 30px;
+ border-top-left-radius: 6px;
}
\ No newline at end of file
diff --git a/interface/templates/base.html b/interface/templates/base.html
index e12acb2..5434f38 100644
--- a/interface/templates/base.html
+++ b/interface/templates/base.html
@@ -1,50 +1,50 @@
{% load static %}
-
+
-
+
-
+
+
{% block title %}Polyphonic{% endblock %}
+ {% block media %}{% endblock %}
-
- {% block navigation %}
-
- {% endblock %}
-
-
- {% block content %}
-
No content!
- {% endblock %}
+ {% block navigation %}
+
+
+
+
+
+ {% firstof ensemble project.ensemble %}
+
+
+
+
+
+ {% endblock %}
+
+{% block content %}
+
No content!
+{% endblock %}
diff --git a/interface/templates/interface/default_form.html b/interface/templates/interface/default_form.html
index 837c798..0e762e3 100644
--- a/interface/templates/interface/default_form.html
+++ b/interface/templates/interface/default_form.html
@@ -1,14 +1,15 @@
{% extends "interface/project_base.html" %}
+{% load crispy_forms_tags %}
+
+{% block media %}
+{{ form.media }}
+{% endblock %}
{% block page %}
-
-
{% firstof title view.title %}
-
+
{% firstof title view.title %}
+
{% endblock %}
\ No newline at end of file
diff --git a/interface/templates/interface/ensemble_project_list.html b/interface/templates/interface/ensemble_project_list.html
index 326a6d7..cbe4b15 100644
--- a/interface/templates/interface/ensemble_project_list.html
+++ b/interface/templates/interface/ensemble_project_list.html
@@ -1,22 +1,73 @@
{% extends "interface/project_base.html" %}
+{% load md2 %}
+
+{% block admin %}
+
+
+ Add new
+
+{% endblock %}
+
+
{% block page %}
-
-
Projects for {{ ensemble.name }}
-
- {% for project in ensemble.active_projects %}
-
- {{ project.name }}
-
- {% if project.deadline %}In {{ project.deadline|timeuntil }}
{% endif %}
- {% if project.works.count %}{{ project.works.count }} works
{% endif %}
- {% if project.submissions.count %}{{ project.submissions.count }} submissions
{% endif %}
-
-
- {% endfor %}
+
Projects for {{ ensemble.name }}
+
+
+{% for project in ensemble.active_projects %}
+
+
+
+
+
+
+
+
+ {{ project.description | markdown }}
+
+
+ {% if project.deadline %}In {{ project.deadline|timeuntil }}
{% endif %}
+ {% if project.works.count %}
+
+ {{ project.works.count }} works
+
+
+ {% endif %}
+ {% if project.submissions.count %}{{ project.submissions.count }} submissions
{% endif %}
+
+
+
-
-
{{ ensemble.ensemble_code }}
+{% empty %}
+
+
+
No projects currently planned
+
Go put your feet up!
+
+
+{% endfor %}
+
+
+{% if request.is_admin %}
+
+
+
+
+
+
+ Joining instructions for participants
+ URL: {{ ensemble_url }}
+ Code: {{ ensemble.ensemble_code }}
+ Passphrase: {{ ensemble.passphrase }}
+
+
+{% endif %}
+
{% endblock %}
\ No newline at end of file
diff --git a/interface/templates/interface/project_base.html b/interface/templates/interface/project_base.html
index efc5742..08f7733 100644
--- a/interface/templates/interface/project_base.html
+++ b/interface/templates/interface/project_base.html
@@ -2,40 +2,109 @@
{% block content %}
-{% if request.is_admin %}
-
-{% block admin %}
-{% endblock %}
-
-{% endif %}
-
{{ project.name }}
-{% block page %}
-No content
-{% endblock %}
+
+
+
+
+
+{% if ensemble %}
+
+{% endif %}
{% endblock %}
diff --git a/interface/templates/interface/project_detail.html b/interface/templates/interface/project_detail.html
index a75b1e3..8fc3659 100644
--- a/interface/templates/interface/project_detail.html
+++ b/interface/templates/interface/project_detail.html
@@ -1,32 +1,62 @@
{% extends "interface/project_base.html" %}
{% load md2 %}
+{% load polyphonic %}
+{% block admin %}
+
+
+ Add Page
+
+
+
+ Edit
+
+{% endblock %}
{% block page %}
-
+
{% if project.event_date %}
-
+
+ {{ project.event_date|date:"l jS F Y, g:i A" }}
{% if project.has_happened %}
- {{ project.event_date|timesince }} ago.
+ ({{ project.event_date|roughtimesince }} ago)
{% else %}
- In {{ project.event_date|timeuntil }}.
+ (in {{ project.event_date|roughtimeuntil }}...)
{% endif %}
{% endif %}
-
{{ project.description|markdown }}
-
- {% if project.owner %}
-
Project email: {{ project.owner }}
- {% endif %}
-
- {% if project.enable_submissions %}
- {% include 'submissions/project_detail.html' %}
- {% endif %}
-
- {% if project.enable_library %}
- {% include 'library/project_detail.html' %}
- {% endif %}
-
+
+ {% if project.description %}
+
{{ project.description|markdown }}
+ {% else %}
+
No description
+ {% endif %}
+
+
+
+ {% if 'library' in modules %}
+
+ {% include 'library/project_detail.html' %}
+
+ {% endif %}
+
+ {% if 'submission' in modules %}
+
+ {% include 'submissions/project_detail.html' %}
+
+ {% endif %}
+
+ {% if project.owner %}
+
+ {% if project.owner.email %}
+ The project owner is
{{ project.owner }}
+ {% else %}
+ The project owner is {{ project.owner }}.
+ {% endif %}
+
+ {% endif %}
+
+
{% endblock %}
diff --git a/interface/templates/interface/project_form.html b/interface/templates/interface/project_form.html
index a65ec70..0238b1c 100644
--- a/interface/templates/interface/project_form.html
+++ b/interface/templates/interface/project_form.html
@@ -1,15 +1,18 @@
{% extends "interface/project_base.html" %}
+{% load crispy_forms_tags %}
+
+{% block media %}
+{{ form.media }}
+{% endblock %}
{% block page %}
-
-
{{ title }}
-
{{ instructions }}
-
+
{% firstof title view.title %}
+
{% endblock %}
\ No newline at end of file
diff --git a/interface/templates/interface/project_submissions.mk b/interface/templates/interface/project_submissions.mk
deleted file mode 100644
index 7bf95c4..0000000
--- a/interface/templates/interface/project_submissions.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-
-ALL = {{ targets|join:" " }}
-
--include "local.mk"
-
-all: ${ALL}
-
-{% for s in submissions %}
-{{ s.name }}:
- curl -o $@ -L {{ s.url }}
-{% endfor %}
\ No newline at end of file
diff --git a/interface/templates/interface/register.html b/interface/templates/interface/register.html
index 26a20b0..8217796 100644
--- a/interface/templates/interface/register.html
+++ b/interface/templates/interface/register.html
@@ -1,29 +1,24 @@
{% extends "base.html" %}
+{% load crispy_forms_tags %}
{% block content %}
+
{% if not request.user.is_authenticated %}
{% endif %}
-
- {% if current %}
-
- {% endif %}
-