diff --git a/.gitignore b/.gitignore index 829fb00..12f382c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ test.* static teststore cache +local_storage +media \ No newline at end of file diff --git a/interface/fields.py b/interface/fields.py new file mode 100644 index 0000000..4e96092 --- /dev/null +++ b/interface/fields.py @@ -0,0 +1,4 @@ +from crispy_forms.layout import Field + +class BulmaFileUpload(Field): + template = 'bulma/file_upload.html' \ No newline at end of file diff --git a/interface/migrations/0001_initial.py b/interface/migrations/0001_squashed_0004_alter_project_event_date.py similarity index 89% rename from interface/migrations/0001_initial.py rename to interface/migrations/0001_squashed_0004_alter_project_event_date.py index c50c935..8f0729b 100644 --- a/interface/migrations/0001_initial.py +++ b/interface/migrations/0001_squashed_0004_alter_project_event_date.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.7 on 2022-11-18 09:54 +# Generated by Django 3.2.7 on 2022-11-19 10:25 import byostorage.user from django.conf import settings @@ -9,11 +9,13 @@ import interface.models class Migration(migrations.Migration): + replaces = [('interface', '0001_initial'), ('interface', '0002_alter_module_name'), ('interface', '0003_alter_ensemble_slug'), ('interface', '0004_alter_project_event_date')] + initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('byostorage', '0004_alter_userstorage_storage'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ @@ -22,7 +24,7 @@ class Migration(migrations.Migration): 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)), + ('slug', models.SlugField(editable=False, help_text='Short name for the ensemble - used for folders', max_length=100, unique=True)), ('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)')), @@ -37,7 +39,7 @@ class Migration(migrations.Migration): ('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)), + ('event_date', models.DateTimeField(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')), ], @@ -73,7 +75,7 @@ class Migration(migrations.Migration): name='Module', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.SlugField(max_length=20)), + ('name', models.SlugField(choices=[('library', 'Library'), ('submissions', 'Submissions')], max_length=20)), ('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='modules', to='interface.project')), ], ), diff --git a/interface/models.py b/interface/models.py index d7810c6..517c87c 100644 --- a/interface/models.py +++ b/interface/models.py @@ -154,53 +154,4 @@ class WikiPage(models.Model): return resolve_url('wiki', project=self.project_id, pk=self.pk) def __str__(self): - return self.title -""" -class Submission(models.Model): - 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") - notes = models.TextField(blank=True) - complete = models.BooleanField(default=False) - url = models.CharField(max_length=512, blank=True) - private = models.BooleanField(default=False) - - @property - def download_url(self): - if not self.complete: - raise RuntimeError("Submission not complete") - - if self.private: - return self.url - - params = {'Bucket': BUCKET, 'Key': self.url} - return s3client.generate_presigned_url('get_object', Params=params, ExpiresIn=3600) - - @property - def download_name(self): - uri = urlparse(self.download_url) - _, name = os.path.split(uri.path) - return name or "" - - def key_template(self): - return "submissions/{}_{}_{}_${{filename}}".format( - timezone.localtime(self.date).isoformat(timespec='seconds').replace(':', '')[:17], - slugify(self.name), - slugify(self.instrument) - ) - - @property - def short_name(self): - _, ext = os.path.splitext(self.download_name) - return "{}_{}_{}{}".format( - #timezone.localtime(self.date).strftime("%Y%m%d%H%M%S"), - slugify(self.name), - slugify(self.instrument), - self.pk, - ext - ) - - def __str__(self): - return f"{self.name}: {self.date}" -""" \ No newline at end of file + return self.title \ No newline at end of file diff --git a/interface/templates/bulma/file_upload.html b/interface/templates/bulma/file_upload.html new file mode 100644 index 0000000..2a21d4d --- /dev/null +++ b/interface/templates/bulma/file_upload.html @@ -0,0 +1,28 @@ +{% load crispy_forms_field %} + +
+
+ +
+
+ + \ No newline at end of file diff --git a/interface/templates/interface/ensemble_list.html b/interface/templates/interface/ensemble_list.html new file mode 100644 index 0000000..492fa17 --- /dev/null +++ b/interface/templates/interface/ensemble_list.html @@ -0,0 +1,41 @@ +{% extends "interface/project_base.html" %} +{% load md2 %} + +{% block page %} +
+ + + Register another + +
+ +

My Ensembles

+ +
+{% for ensemble in object_list %} +
+
+ +
+ {% if ensemble.details %} +
+ {{ ensemble.details | markdown }} +
+ {% endif %} +
+ {% with projects=ensemble.active_projects.count %} +

{{ projects }} active project{{ projects|pluralize }}

+ {% endwith %} +
+
+
+ {% endfor %} +
+{% endblock %} \ No newline at end of file diff --git a/interface/templatetags/polyphonic.py b/interface/templatetags/polyphonic.py new file mode 100644 index 0000000..e531c37 --- /dev/null +++ b/interface/templatetags/polyphonic.py @@ -0,0 +1,14 @@ +from django import template +from django.utils import timesince + +register = template.Library() + +def roughtimesince(value): + return timesince.timesince(value, depth=1) + +register.filter('roughtimesince', roughtimesince) + +def roughtimeuntil(value): + return timesince.timeuntil(value, depth=1) + +register.filter('roughtimeuntil', roughtimeuntil) \ No newline at end of file diff --git a/interface/tests/test_submission.py b/interface/tests/test_submission.py deleted file mode 100644 index 415cdea..0000000 --- a/interface/tests/test_submission.py +++ /dev/null @@ -1,53 +0,0 @@ -from django.test import TestCase, Client - -from interface import models - -class SubmissionTestCase(TestCase): - - @staticmethod - def setUpTestData(): - e1 = models.Ensemble.objects.create(name='The Be Sharps', code="1234", passphrase='Homer') - e1.projects.create(name='Baby on Board') - e2 = models.Ensemble.objects.create(name='Lisa and the Bleeding Gums', code="2345", passphrase="Maggie") - e2.projects.create(name='Baker St') - - def setUp(self): - self.client = Client() - - def test_submission_upload(self): - response = self.client.post('/register', {'code': '12-34', 'passphrase': 'Homer'}) - self.assertRedirects(response, '/') - - response = self.client.post(f"/projects/1/submission", {'name': 'Ned', 'instrument': 'Harp', 'method': 'upload'}) - self.assertRedirects(response, '/projects/1/submission/1/upload') - - response = self.client.get(response.url) - upload = response.context['upload'] - self.assertEqual(upload['url'], f"http://localhost:9000/{models.BUCKET}") - self.assertRegex(upload['fields']['key'], r'^baby-on-board\/submissions\/[0-9T\-]+_ned_harp_\$\{filename\}$') - self.assertEqual(upload['fields']['success_action_redirect'], 'http://testserver/projects/1/submission/1/complete') - - self.assertEqual(models.Submission.objects.count(), 1) - self.assertRedirects(self.client.get(f"/projects/1/submission/1/cancel"), '/projects/1') - self.assertEqual(models.Submission.objects.count(), 0) - - def test_submission_link(self): - response = self.client.post('/register', {'code': '12-34', 'passphrase': 'Homer'}) - self.assertRedirects(response, '/') - - response = self.client.post(f"/projects/1/submission", {'name': 'Ned', 'instrument': 'Harp', 'method': 'link'}) - self.assertRedirects(response, '/projects/1/submission/1/link') - - url = 'https://drive.google.com/a/path/to/a/video.mp4#g6e6e4a23' - - response = self.client.post(f"/projects/1/submission/1/link", {'url': url}) - self.assertRedirects(response, '/projects/1/submission/1') - - response = self.client.get('/projects/1/submission/1') - self.assertContains(response, "Thankyou for your submission") - - response = self.client.get('/projects/1') - self.assertContains(response, 'Ned') - - s = models.Submission.objects.get(pk=1) - self.assertEqual(s.download_url, url) \ No newline at end of file diff --git a/library/imslp.py b/library/imslp.py new file mode 100644 index 0000000..d31f838 --- /dev/null +++ b/library/imslp.py @@ -0,0 +1,197 @@ + +from collections import namedtuple + +# taken from https://imslp.org/wiki/IMSLP:Abbreviations_for_Instruments + +ABBREVIATIONS = """ +score Score +acc Accordion +afl Alto flute +alt Alto (voice) (contralto) +arp Arpeggione +bag Bagpipe +bar Baritone (voice) +bass Bass (voice) +bbar Bass baritone (voice) +bc Continuo (Basso continuo) +bcl Bass clarinet +bell Bell (Chimes) +bfl Bass flute +bgtr Bass guitar +bjo Banjo +bn Bassoon +bob Bass oboe (Baritone oboe) +br Brass instruments +bryt Baryton +bstcl Basset clarinet +bsthn Basset horn +bug Bugle +cbcl Contrabass clarinet +cbn Contrabassoon +cch Children's chorus +cel Celesta +ch Mixed chorus +cimb Cimbalom +cit Cittern +cl Clarinet +clvd Clavichord +cm Chalumeau +conc Concertina +crh Crumhorn +crt Cornet +crtt Cornett (Zink) +cv Child's voice +db Double Bass +dlcn Dulcian +dom Domra +dulc Dulcimer +egtr Electric guitar +eh English horn (Cor anglais) +elec Electronic Instruments +epf Electric piano +eq Equal voices +erhu Erhu +euph Euphonium +fch Female chorus +fda Flute d'amore (Tenor flute) +fgh Flugelhorn +fife Fife +fl Flute +flag Flageolet +ghca Glass harmonica (Bowl organ) +gl Glockenspiel +gtr Guitar +harm Harmonium +hca Harmonica (Mouth Organ) +heck Heckelphone +hn Horn +hp Harp +hpd Harpsichord +kbd Keyboard instrument +lute Lute +lyre Lyre +mand Mandolin +mar Marimba +mch Male chorus +mez Mezzo-soprano +mus Musette +nar Narrator (Reciter) +ob Oboe +oca Ocarina +oda Oboe d'amore +om Ondes Martenot +oph Ophicleide +orch Orchestra +org Organ +oud Oud +pan Pan flute (Pan-pipes) +perc Percussion +pf Piano +pf3h Piano 3 hands +pf4h Piano 4 hands +pf5h Piano 5 hands +pf6h Piano 6 hands +pflh Piano left hand +pfped Pedal piano +pfrh Piano right hand +picc Piccolo +pipa Pipa +pk Timpani +ptpt Piccolo trumpet +reb Rebec +rec Recorder +sar Sarrusophone +sax Saxophone +sheng Sheng +shw Shawm +sit Sitar +skbt Sackbut +sop Soprano (voice) +srp Serpent +stpt Slide trumpet +str String instruments +sxh Saxhorn +syn Synthesizer +tba Tuba +tbn Trombone +ten Tenor +thrm Theremin +timp Timpani +tpt Trumpet +uch Unison chorus +uke Ukelele (Ukulele) +v Voice (solo) +va Viola +vap Viola pomposa +vc Cello +vda Viola d'amore +vib Vibraphone +vie Vielle (Hurdy-Gurdy) +viol Viol (Viola da gamba) +vlne Violone +vn Violin +vuv Vuvuzela +vv Voices (multiple soloists) +wag Wagner tuba +ww Woodwind instruments +xiao Xiao +xyl Xylophone +zith Zither +""" + +INSTRUMENTS = [] +for line in ABBREVIATIONS.split('\n'): + parts = line.strip().split(maxsplit=1) + if len(parts) < 2: continue + name, _, _ = parts[1].partition('(') + INSTRUMENTS.append((parts[0], name)) + +INSTRUMENT_LOOKUP = dict(INSTRUMENTS) +TAG_LOOKUP = dict( ( (x[1].lower(), x[0]) for x in INSTRUMENTS ) ) + +class Instrument(namedtuple('Instrument', ('name', 'variant'), defaults=[None])): + + @classmethod + def from_tag(cls, tag): + """ + >>> Instrument.from_tag('vn-1') + Instrument(name='Violin', variant='1') + >>> Instrument.from_tag('db') + Instrument(name='Double Bass', variant=None) + >>> Instrument.from_tag('Jaws Harp') + Instrument(name='Jaws Harp', variant=None) + """ + abbr, _, variant = tag.partition('-') + name = INSTRUMENT_LOOKUP.get(abbr.lower(), abbr) + + if variant: + return cls(name, variant) + return cls(name, None) + + + def abbreviate(self): + """ + >>> Instrument('Violin', 1).abbreviate() + 'vn-1' + >>> Instrument('Double Bass').abbreviate() + 'db' + """ + tag = TAG_LOOKUP.get(self.name.lower()) + if self.variant: + tag = f"{tag}-{self.variant}" + return tag + + def __str__(self): + """ + >>> str(Instrument('Violin', 1)) + 'Violin 1' + >>> str(Instrument('Double Bass')) + 'Double Bass' + """ + if self.variant: + return f"{self.name} {self.variant}" + return self.name + +if __name__ == "__main__": + import doctest + print(doctest.testmod()) \ No newline at end of file diff --git a/library/migrations/0001_initial.py b/library/migrations/0001_squashed_0006_auto_20221119_2121.py similarity index 79% rename from library/migrations/0001_initial.py rename to library/migrations/0001_squashed_0006_auto_20221119_2121.py index 56a674c..4adec22 100644 --- a/library/migrations/0001_initial.py +++ b/library/migrations/0001_squashed_0006_auto_20221119_2121.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.7 on 2022-11-18 09:54 +# Generated by Django 3.2.7 on 2022-11-19 10:24 import byostorage.user from django.conf import settings @@ -9,12 +9,14 @@ import library.models class Migration(migrations.Migration): + replaces = [('library', '0001_initial'), ('library', '0002_auto_20221118_2208'), ('library', '0003_work_composer'), ('library', '0004_auto_20221118_2223'), ('library', '0005_auto_20221118_2253'), ('library', '0006_auto_20221119_2121')] + initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('byostorage', '0004_alter_userstorage_storage'), ('interface', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ @@ -23,21 +25,11 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text='Name of the collection', max_length=255)), - ('prefix', models.SlugField(default='default', max_length=30)), - ('location', models.CharField(help_text='Physical location (institution, town...)', max_length=100)), - ('notes', models.TextField(blank=True, help_text='Publicly visible notes about collection and loans policy')), + ('prefix', models.SlugField(default='default', help_text='Folder to store works in', max_length=30)), + ('location', models.CharField(blank=True, help_text='Physical location (institution, town...)', max_length=100)), + ('notes', models.TextField(blank=True, help_text='Publicly visible notes about collection and loans policy (markdown format)')), ('administrators', models.ManyToManyField(help_text='Administrators for this collection', related_name='collections', to=settings.AUTH_USER_MODEL)), - ('storage', models.ForeignKey(blank=True, help_text='Storage for documents', null=True, on_delete=django.db.models.deletion.CASCADE, to='byostorage.userstorage')), - ], - ), - migrations.CreateModel( - name='Document', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('doctype', models.PositiveSmallIntegerField(choices=[(1, 'PDF'), (2, 'Audio'), (3, 'Video'), (4, 'Source')], default=1)), - ('upload', models.FileField(storage=byostorage.user.BYOStorage(), upload_to=library.models.doc_upload_filename)), - ('created', models.DateTimeField(auto_now_add=True)), - ('version', models.CharField(blank=True, max_length=30)), + ('storage', models.ForeignKey(blank=True, help_text='User storage for documents', null=True, on_delete=django.db.models.deletion.CASCADE, to='byostorage.userstorage')), ], ), migrations.CreateModel( @@ -59,45 +51,21 @@ class Migration(migrations.Migration): name='Work', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('slug', models.SlugField(editable=False, max_length=100)), - ('name', models.CharField(max_length=255)), - ('edition', models.CharField(blank=True, help_text='Edition details', max_length=255)), - ('composer', models.CharField(blank=True, max_length=255)), - ('orchestration', models.CharField(blank=True, help_text='IMDB format instrumentation', max_length=255)), - ('original_parts', models.JSONField(blank=True, help_text='Original printed parts', null=True)), + ('slug', models.SlugField(editable=False, help_text='Used as folder name', max_length=100)), + ('name', models.CharField(help_text='Original name of the work', max_length=255)), + ('original_parts', models.JSONField(blank=True, default=dict, help_text='Original printed parts (IMSLP format)')), ('code', models.CharField(blank=True, help_text='Collection specific code or number', max_length=100)), ('licence', models.PositiveSmallIntegerField(choices=[(2, 'Public Domain'), (4, 'Copyright Expired'), (6, 'Copyrighted'), (10, 'Internal use only')], default=6, help_text='Copyright status')), - ('max_projects', models.IntegerField(default=1, help_text='How many projects can this work be attached to')), + ('max_projects', models.IntegerField(default=1, help_text='How many active projects can this work be attached to')), ('running_time', models.DurationField(blank=True, help_text='Running time in seconds', null=True)), ('notes', models.TextField(blank=True)), ('collection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='works', to='library.collection')), ('parent', models.ForeignKey(blank=True, help_text='Arrangement of another work or part of an anthology', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='related_works', to='library.work')), ('projects', models.ManyToManyField(help_text='Current usage', related_name='works', through='library.ProjectItem', to='interface.Project')), + ('composer', models.CharField(blank=True, help_text='Surname, First Name/Initials', max_length=255)), + ('edition', models.CharField(blank=True, help_text='Edition details to distinguish multiple versions', max_length=255)), ], ), - migrations.CreateModel( - name='WorkMeta', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.SlugField(choices=[('tag', 'Tag'), ('arr', 'Arranger'), ('lyrics', 'Lyracist'), ('genre', 'Genre'), ('style', 'Style')], max_length=20)), - ('value', models.CharField(max_length=255)), - ('work', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='meta_info', to='library.work')), - ], - ), - migrations.CreateModel( - name='Section', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('tag', models.SlugField(max_length=20)), - ('start', models.SmallIntegerField(blank=True, null=True)), - ('end', models.SmallIntegerField(blank=True, null=True)), - ('notes', models.TextField(blank=True)), - ('doc', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sections', to='library.document')), - ], - options={ - 'ordering': ['doc', 'start', 'pk'], - }, - ), migrations.AddField( model_name='projectitem', name='work', @@ -115,9 +83,37 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'Ensemble access', }, ), - migrations.AddField( - model_name='document', - name='work', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='docs', to='library.work'), + migrations.CreateModel( + name='Document', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('doctype', models.PositiveSmallIntegerField(choices=[(1, 'PDF'), (2, 'Audio'), (3, 'Video'), (4, 'Source')], default=1)), + ('upload', models.FileField(storage=byostorage.user.BYOStorage(), upload_to=library.models.doc_upload_filename)), + ('created', models.DateTimeField(auto_now_add=True)), + ('version', models.CharField(blank=True, max_length=30)), + ('work', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='docs', to='library.work')), + ], + ), + migrations.CreateModel( + name='WorkMeta', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.SlugField(choices=[('tag', 'Tag'), ('arr', 'Arranger'), ('lyrics', 'Lyracist'), ('genre', 'Genre'), ('style', 'Style'), ('orchestration', 'Orchestration')], max_length=20)), + ('value', models.CharField(max_length=255)), + ('work', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='meta_info', to='library.work')), + ], + ), + migrations.CreateModel( + name='Section', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('tag', models.CharField(max_length=50)), + ('start', models.SmallIntegerField(blank=True, null=True)), + ('end', models.SmallIntegerField(blank=True, null=True)), + ('doc', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sections', to='library.document')), + ], + options={ + 'ordering': ['doc', 'start', 'pk'], + }, ), ] diff --git a/library/models.py b/library/models.py index 80bacc5..5a255ae 100644 --- a/library/models.py +++ b/library/models.py @@ -90,7 +90,7 @@ class ProjectItem(models.Model): returned = models.DateTimeField(null=True, blank=True) approved_by = models.ForeignKey('auth.User', on_delete=models.CASCADE) order = models.SmallIntegerField(default=0) - section = models.SlugField + section = models.CharField(max_length=100, blank=True) #version = models.CharField(max_length=30, blank=True, help_text="Limited to specific version tag") class Meta: diff --git a/library/templates/library/collection_list.html b/library/templates/library/collection_list.html new file mode 100644 index 0000000..01fed6a --- /dev/null +++ b/library/templates/library/collection_list.html @@ -0,0 +1,26 @@ +{% extends "interface/project_base.html" %} + +{% block page %} +

Library collections for {{ request.user }}

+ +
+{% for collection in object_list %} +
+
+
+ +

{{ collection.name }}

+
+
+
+

{{ collection.location }}, {{ collection.works.count }} items.

+
+
+
+ {% endfor %} +
+ +
+ {{ ensemble.ensemble_code }} +
+{% endblock %} \ No newline at end of file diff --git a/polyphonic/settings_default.py b/polyphonic/settings_default.py index 7e9cd63..6c6408e 100644 --- a/polyphonic/settings_default.py +++ b/polyphonic/settings_default.py @@ -31,8 +31,7 @@ ALLOWED_HOSTS = ['localhost'] # Application definition POLYPHONIC_MODULES = [ - 'library', - 'submissions' + 'library' ] INSTALLED_APPS = [ diff --git a/polyphonic/urls.py b/polyphonic/urls.py index 9ae6b5f..4cefc4b 100644 --- a/polyphonic/urls.py +++ b/polyphonic/urls.py @@ -19,7 +19,7 @@ from django.urls import path, re_path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('interface.urls')), - path('', include('submissions.urls')), + #path('', include('submissions.urls')), path('', include('library.urls')), ]