diff --git a/beat/web/databases/__init__.py b/beat/web/databases/__init__.py index 93a15eb13994a4273d1626fb9e0113696b6fb263..e02b17d61b4a852e86e2da01954be6715046aae8 100644 --- a/beat/web/databases/__init__.py +++ b/beat/web/databases/__init__.py @@ -25,4 +25,4 @@ # # ############################################################################### -default_app_config = 'beat.web.databases.apps.DatabasesConfig' +default_app_config = "beat.web.databases.apps.DatabasesConfig" diff --git a/beat/web/databases/admin.py b/beat/web/databases/admin.py index 261c0f36aeba4e27414b2a61cf25cf311c2e8515..5af35497aba64ae2ba0339ee12bbd030c10b212a 100755 --- a/beat/web/databases/admin.py +++ b/beat/web/databases/admin.py @@ -25,11 +25,18 @@ # # ############################################################################### +import simplejson as json from django import forms from django.contrib import admin from django.core.files.base import ContentFile - +from ..common.admin import notify_by_email +from ..common.models import Shareable +from ..common.texts import Messages +from ..ui.forms import CodeMirrorJSONFileField +from ..ui.forms import CodeMirrorPythonFileField +from ..ui.forms import CodeMirrorRSTFileField +from ..ui.forms import NameField from .models import Database as DatabaseModel from .models import DatabaseProtocol as DatabaseProtocolModel from .models import DatabaseSet as DatabaseSetModel @@ -38,20 +45,6 @@ from .models import DatabaseSetTemplate as DatabaseSetTemplateModel from .models import DatabaseSetTemplateOutput as DatabaseSetTemplateOutputModel from .models import validate_database -from ..ui.forms import ( - CodeMirrorJSONFileField, - CodeMirrorRSTFileField, - CodeMirrorPythonFileField, - NameField, -) - -from ..common.texts import Messages -from ..common.admin import notify_by_email -from ..common.models import Shareable - -import simplejson as json - - # ------------------------------------------------ diff --git a/beat/web/databases/api.py b/beat/web/databases/api.py index b076cb2ec4d35daf45c3dd1722907f2c4ff810f3..0763fda57db6bdd9de807d8033179f2afc450c2a 100755 --- a/beat/web/databases/api.py +++ b/beat/web/databases/api.py @@ -25,26 +25,24 @@ # # ############################################################################### -import os import json import logging +import os -from rest_framework.response import Response -from rest_framework import permissions as drf_permissions from rest_framework import exceptions as drf_exceptions +from rest_framework import permissions as drf_permissions from rest_framework import views - -from .models import Database -from .models import DatabaseSetTemplate - -from .serializers import DatabaseSerializer, DatabaseCreationSerializer +from rest_framework.response import Response from ..common import is_true from ..common import permissions as beat_permissions from ..common.api import ListCreateBaseView from ..common.utils import ensure_html - from ..dataformats.serializers import ReferencedDataFormatSerializer +from .models import Database +from .models import DatabaseSetTemplate +from .serializers import DatabaseCreationSerializer +from .serializers import DatabaseSerializer logger = logging.getLogger(__name__) diff --git a/beat/web/databases/apps.py b/beat/web/databases/apps.py index fd94461ab2849a1702de37129f7232f0690b97ad..64bdd0887ae9030166167f1ced80bd4326ca7fba 100644 --- a/beat/web/databases/apps.py +++ b/beat/web/databases/apps.py @@ -25,13 +25,16 @@ # # ############################################################################### -from ..common.apps import CommonAppConfig from django.utils.translation import ugettext_lazy as _ +from ..common.apps import CommonAppConfig + + class DatabasesConfig(CommonAppConfig): - name = 'beat.web.databases' - verbose_name = _('Databases') + name = "beat.web.databases" + verbose_name = _("Databases") def ready(self): super(DatabasesConfig, self).ready() - from . import signals + + from . import signals # noqa: F401 diff --git a/beat/web/databases/exceptions.py b/beat/web/databases/exceptions.py index d49916f3cef3126b98b971cade8dbabf5d928e93..23f16d2d60c32d64210dc4deb9fd1dc95dee5d00 100644 --- a/beat/web/databases/exceptions.py +++ b/beat/web/databases/exceptions.py @@ -28,8 +28,8 @@ """ Database specific exceptions """ - from ..common.exceptions import BaseCreationError + class DatabaseCreationError(BaseCreationError): pass diff --git a/beat/web/databases/migrations/0001_initial.py b/beat/web/databases/migrations/0001_initial.py index c4f746df379e16e8f70cdabecf5d5de6e9d96baf..15a26287fcaaa9a18981241bf14abc38dc9ca710 100644 --- a/beat/web/databases/migrations/0001_initial.py +++ b/beat/web/databases/migrations/0001_initial.py @@ -27,99 +27,269 @@ from __future__ import unicode_literals -from django.db import migrations, models -import beat.web.code.models -import beat.web.databases.models from django.conf import settings +from django.db import migrations +from django.db import models + +import beat.web.code.models import beat.web.common.models +import beat.web.databases.models class Migration(migrations.Migration): dependencies = [ - ('dataformats', '0001_initial'), + ("dataformats", "0001_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('team', '0001_initial'), + ("team", "0001_initial"), ] operations = [ migrations.CreateModel( - name='Database', + name="Database", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('sharing', models.CharField(default='P', max_length=1, choices=[('P', 'Private'), ('S', 'Shared'), ('A', 'Public'), ('U', 'Usable')])), - ('name', models.CharField(help_text='The name for this object (space-like characters will be automatically replaced by dashes)', max_length=200)), - ('version', models.PositiveIntegerField(default=1, help_text='The version of this object (an integer starting from 1)')), - ('short_description', models.CharField(default='', help_text='Describe the object succinctly (try to keep it under 80 characters)', max_length=100, blank=True)), - ('creation_date', models.DateTimeField(auto_now_add=True, verbose_name='Creation date')), - ('hash', models.CharField(help_text='Hashed value of the object contents (<a href="https://docs.python.org/2/library/hashlib.html">SHA256, hexadecimal digest</a>). This field is auto-generated and managed by the platform.', max_length=64, editable=False)), - ('declaration_file', models.FileField(db_column='declaration', upload_to=beat.web.common.models.get_contribution_declaration_filename, storage=beat.web.databases.models.DatabaseStorage(), max_length=200, blank=True, null=True)), - ('description_file', models.FileField(db_column='description', upload_to=beat.web.common.models.get_contribution_description_filename, storage=beat.web.databases.models.DatabaseStorage(), max_length=200, blank=True, null=True)), - ('source_code_file', models.FileField(db_column='source_code', upload_to=beat.web.code.models.get_contribution_source_code_filename, storage=beat.web.databases.models.DatabaseStorage(), max_length=200, blank=True, null=True)), - ('fork_of', models.ForeignKey(related_name='forks', blank=True, to='databases.Database', null=True, on_delete=models.SET_NULL)), - ('previous_version', models.ForeignKey(related_name='next_versions', blank=True, to='databases.Database', null=True, on_delete=models.CASCADE)), - ('shared_with', models.ManyToManyField(related_name='shared_databases', to=settings.AUTH_USER_MODEL, blank=True)), - ('shared_with_team', models.ManyToManyField(related_name='shared_databases', to='team.Team', blank=True)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ( + "sharing", + models.CharField( + default="P", + max_length=1, + choices=[ + ("P", "Private"), + ("S", "Shared"), + ("A", "Public"), + ("U", "Usable"), + ], + ), + ), + ( + "name", + models.CharField( + help_text="The name for this object (space-like characters will be automatically replaced by dashes)", + max_length=200, + ), + ), + ( + "version", + models.PositiveIntegerField( + default=1, + help_text="The version of this object (an integer starting from 1)", + ), + ), + ( + "short_description", + models.CharField( + default="", + help_text="Describe the object succinctly (try to keep it under 80 characters)", + max_length=100, + blank=True, + ), + ), + ( + "creation_date", + models.DateTimeField( + auto_now_add=True, verbose_name="Creation date" + ), + ), + ( + "hash", + models.CharField( + help_text='Hashed value of the object contents (<a href="https://docs.python.org/2/library/hashlib.html">SHA256, hexadecimal digest</a>). This field is auto-generated and managed by the platform.', + max_length=64, + editable=False, + ), + ), + ( + "declaration_file", + models.FileField( + db_column="declaration", + upload_to=beat.web.common.models.get_contribution_declaration_filename, + storage=beat.web.databases.models.DatabaseStorage(), + max_length=200, + blank=True, + null=True, + ), + ), + ( + "description_file", + models.FileField( + db_column="description", + upload_to=beat.web.common.models.get_contribution_description_filename, + storage=beat.web.databases.models.DatabaseStorage(), + max_length=200, + blank=True, + null=True, + ), + ), + ( + "source_code_file", + models.FileField( + db_column="source_code", + upload_to=beat.web.code.models.get_contribution_source_code_filename, + storage=beat.web.databases.models.DatabaseStorage(), + max_length=200, + blank=True, + null=True, + ), + ), + ( + "fork_of", + models.ForeignKey( + related_name="forks", + blank=True, + to="databases.Database", + null=True, + on_delete=models.SET_NULL, + ), + ), + ( + "previous_version", + models.ForeignKey( + related_name="next_versions", + blank=True, + to="databases.Database", + null=True, + on_delete=models.CASCADE, + ), + ), + ( + "shared_with", + models.ManyToManyField( + related_name="shared_databases", + to=settings.AUTH_USER_MODEL, + blank=True, + ), + ), + ( + "shared_with_team", + models.ManyToManyField( + related_name="shared_databases", to="team.Team", blank=True + ), + ), ], ), migrations.CreateModel( - name='DatabaseOutput', + name="DatabaseOutput", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=200)), - ('dataformat', models.ForeignKey(related_name='database_outputs', to='dataformats.DataFormat', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=200)), + ( + "dataformat", + models.ForeignKey( + related_name="database_outputs", + to="dataformats.DataFormat", + on_delete=models.CASCADE, + ), + ), ], ), migrations.CreateModel( - name='DatabaseProtocol', + name="DatabaseProtocol", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=200, blank=True)), - ('database', models.ForeignKey(related_name='protocols', to='databases.Database', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=200, blank=True)), + ( + "database", + models.ForeignKey( + related_name="protocols", + to="databases.Database", + on_delete=models.CASCADE, + ), + ), ], - options={ - 'ordering': ['name'], - }, + options={"ordering": ["name"]}, ), migrations.CreateModel( - name='DatabaseSet', + name="DatabaseSet", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=200, blank=True)), - ('protocol', models.ForeignKey(related_name='sets', to='databases.DatabaseProtocol', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(max_length=200, blank=True)), + ( + "protocol", + models.ForeignKey( + related_name="sets", + to="databases.DatabaseProtocol", + on_delete=models.CASCADE, + ), + ), ], ), migrations.CreateModel( - name='DatabaseSetTemplate', + name="DatabaseSetTemplate", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(unique=True, max_length=200)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("name", models.CharField(unique=True, max_length=200)), ], ), migrations.AddField( - model_name='databaseset', - name='template', - field=models.ForeignKey(related_name='sets', to='databases.DatabaseSetTemplate', on_delete=models.CASCADE), + model_name="databaseset", + name="template", + field=models.ForeignKey( + related_name="sets", + to="databases.DatabaseSetTemplate", + on_delete=models.CASCADE, + ), ), migrations.AddField( - model_name='databaseoutput', - name='template', - field=models.ForeignKey(related_name='outputs', to='databases.DatabaseSetTemplate', on_delete=models.CASCADE), + model_name="databaseoutput", + name="template", + field=models.ForeignKey( + related_name="outputs", + to="databases.DatabaseSetTemplate", + on_delete=models.CASCADE, + ), ), migrations.AlterUniqueTogether( - name='databaseset', - unique_together=set([('protocol', 'name', 'template')]), + name="databaseset", unique_together=set([("protocol", "name", "template")]), ), migrations.AlterUniqueTogether( - name='databaseprotocol', - unique_together=set([('database', 'name')]), + name="databaseprotocol", unique_together=set([("database", "name")]), ), migrations.AlterUniqueTogether( - name='databaseoutput', - unique_together=set([('template', 'name', 'dataformat')]), + name="databaseoutput", + unique_together=set([("template", "name", "dataformat")]), ), migrations.AlterUniqueTogether( - name='database', - unique_together=set([('name', 'version')]), + name="database", unique_together=set([("name", "version")]), ), ] diff --git a/beat/web/databases/migrations/0002_scheduler_addons.py b/beat/web/databases/migrations/0002_scheduler_addons.py index 4e9fe7730a13d272c124dba88c1e581f787e614d..b7202d09898f18832071f10ccad8a2494e7f6572 100644 --- a/beat/web/databases/migrations/0002_scheduler_addons.py +++ b/beat/web/databases/migrations/0002_scheduler_addons.py @@ -23,31 +23,32 @@ # with the BEAT platform. If not, see http://www.gnu.org/licenses/. # # # ############################################################################### - from __future__ import unicode_literals -from django.db import migrations, models +import logging -from ...common.models import get_declaration +from django.db import migrations +from django.db import models +from ...common.models import get_declaration from ..models import validate_database -import logging logger = logging.getLogger(__name__) def refresh_databases(apps, schema_editor): - '''Refreshes each database so datasets/outputs are recreated''' + """Refreshes each database so datasets/outputs are recreated""" Database = apps.get_model("databases", "Database") DatabaseSetOutput = apps.get_model("databases", "DatabaseSetOutput") Database.declaration = property(get_declaration) - Database.fullname = lambda self: '%s/%d' % (self.name, self.version) + Database.fullname = lambda self: "%s/%d" % (self.name, self.version) - if Database.objects.count(): print('') + if Database.objects.count(): + print("") - for db in Database.objects.order_by('id'): + for db in Database.objects.order_by("id"): print("Refreshing protocols for database `%s'..." % db.fullname()) core = validate_database(db.declaration) core.name = db.fullname() @@ -55,36 +56,62 @@ def refresh_databases(apps, schema_editor): for set in proto.sets.all(): for output in set.template.outputs.all(): try: - DatabaseSetOutput(template=output, set=set, - hash=core.hash_output(proto.name, set.name, - output.name)).save() + DatabaseSetOutput( + template=output, + set=set, + hash=core.hash_output(proto.name, set.name, output.name), + ).save() except KeyError: - logger.warn('Database output %s/%d.%s.%s.%s does ' \ - 'not exist' % (db.name, db.version, proto.name, - set.name, output.name)) + logger.warn( + "Database output %s/%d.%s.%s.%s does " + "not exist" + % (db.name, db.version, proto.name, set.name, output.name) + ) continue class Migration(migrations.Migration): dependencies = [ - ('dataformats', '0001_initial'), - ('databases', '0001_initial'), + ("dataformats", "0001_initial"), + ("databases", "0001_initial"), ] operations = [ - migrations.RenameModel('DatabaseOutput', 'DatabaseSetTemplateOutput'), + migrations.RenameModel("DatabaseOutput", "DatabaseSetTemplateOutput"), migrations.AlterUniqueTogether( - name='databasesettemplateoutput', - unique_together=set([('template', 'name')]), + name="databasesettemplateoutput", + unique_together=set([("template", "name")]), ), migrations.CreateModel( - name='DatabaseSetOutput', + name="DatabaseSetOutput", fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('hash', models.CharField(unique=True, max_length=64)), - ('set', models.ForeignKey(related_name='outputs', to='databases.DatabaseSet', on_delete=models.CASCADE)), - ('template', models.ForeignKey(related_name='instances', to='databases.DatabaseSetTemplateOutput', on_delete=models.CASCADE)), + ( + "id", + models.AutoField( + verbose_name="ID", + serialize=False, + auto_created=True, + primary_key=True, + ), + ), + ("hash", models.CharField(unique=True, max_length=64)), + ( + "set", + models.ForeignKey( + related_name="outputs", + to="databases.DatabaseSet", + on_delete=models.CASCADE, + ), + ), + ( + "template", + models.ForeignKey( + related_name="instances", + to="databases.DatabaseSetTemplateOutput", + on_delete=models.CASCADE, + ), + ), ], ), migrations.RunPython(refresh_databases), diff --git a/beat/web/databases/migrations/0003_auto_20160704_1316.py b/beat/web/databases/migrations/0003_auto_20160704_1316.py index 575732e942c2085e146b3697b3c75e0c1ff578b5..deb0e0444de508aa9f72abe602a35ff5076af03c 100644 --- a/beat/web/databases/migrations/0003_auto_20160704_1316.py +++ b/beat/web/databases/migrations/0003_auto_20160704_1316.py @@ -8,12 +8,11 @@ from django.db import migrations class Migration(migrations.Migration): dependencies = [ - ('databases', '0002_scheduler_addons'), + ("databases", "0002_scheduler_addons"), ] operations = [ migrations.AlterModelOptions( - name='database', - options={'ordering': ['name', '-version']}, + name="database", options={"ordering": ["name", "-version"]}, ), ] diff --git a/beat/web/databases/migrations/0004_beat_backend_python_1_5_x.py b/beat/web/databases/migrations/0004_beat_backend_python_1_5_x.py index 35960a975d955dcf8a600f0075bf1465193de8d5..3aac3b1490ddf7a6dc03594548ca808b63748d02 100644 --- a/beat/web/databases/migrations/0004_beat_backend_python_1_5_x.py +++ b/beat/web/databases/migrations/0004_beat_backend_python_1_5_x.py @@ -2,24 +2,22 @@ # Generated by Django 1.9.13 on 2018-01-25 09:06 from __future__ import unicode_literals -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): dependencies = [ - ('databases', '0003_auto_20160704_1316'), + ("databases", "0003_auto_20160704_1316"), ] operations = [ - migrations.RemoveField( - model_name='databasesetoutput', - name='hash', - ), + migrations.RemoveField(model_name="databasesetoutput", name="hash",), migrations.AddField( - model_name='databaseset', - name='hash', - field=models.CharField(default='', max_length=64), + model_name="databaseset", + name="hash", + field=models.CharField(default="", max_length=64), preserve_default=False, ), ] diff --git a/beat/web/databases/migrations/0005_databaseset_data_migration.py b/beat/web/databases/migrations/0005_databaseset_data_migration.py index 44a24f1c840357d8442504e1f56b9a3d9fcbbdd4..4dc4fa249ceef4fd3bcd466549c978d57c415a7f 100644 --- a/beat/web/databases/migrations/0005_databaseset_data_migration.py +++ b/beat/web/databases/migrations/0005_databaseset_data_migration.py @@ -2,33 +2,42 @@ # Generated by Django 1.9.13 on 2018-01-25 09:06 from __future__ import unicode_literals -from django.db import migrations, models +from django.db import migrations from beat.backend.python.hash import hashDataset def compute_hashes(apps, schema_editor): - '''Refreshes each database so datasets/outputs are recreated''' + """Refreshes each database so datasets/outputs are recreated""" DatabaseSet = apps.get_model("databases", "DatabaseSet") if DatabaseSet.objects.count(): - print('') - - for db_set in DatabaseSet.objects.order_by('id'): - print("Computing hashes for database set '%s/%d/%s/%s'..." % \ - (db_set.protocol.database.name, db_set.protocol.database.version, - db_set.protocol.name, db_set.name)) - - db_set.hash = hashDataset('%s/%d' % (db_set.protocol.database.name, db_set.protocol.database.version), - db_set.protocol.name, db_set.name) + print("") + + for db_set in DatabaseSet.objects.order_by("id"): + print( + "Computing hashes for database set '%s/%d/%s/%s'..." + % ( + db_set.protocol.database.name, + db_set.protocol.database.version, + db_set.protocol.name, + db_set.name, + ) + ) + + db_set.hash = hashDataset( + "%s/%d" % (db_set.protocol.database.name, db_set.protocol.database.version), + db_set.protocol.name, + db_set.name, + ) db_set.save() class Migration(migrations.Migration): dependencies = [ - ('databases', '0004_beat_backend_python_1_5_x'), + ("databases", "0004_beat_backend_python_1_5_x"), ] operations = [ diff --git a/beat/web/databases/migrations/0006_databaseset_hash_unique.py b/beat/web/databases/migrations/0006_databaseset_hash_unique.py index 8ce33badee0597b74533ae8b930218e7847362e5..51dab6b5c20d0924ddfca8615636c7a158d0f1a6 100644 --- a/beat/web/databases/migrations/0006_databaseset_hash_unique.py +++ b/beat/web/databases/migrations/0006_databaseset_hash_unique.py @@ -2,19 +2,20 @@ # Generated by Django 1.9.13 on 2018-01-25 09:06 from __future__ import unicode_literals -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): dependencies = [ - ('databases', '0005_databaseset_data_migration'), + ("databases", "0005_databaseset_data_migration"), ] operations = [ migrations.AlterField( - model_name='databaseset', - name='hash', + model_name="databaseset", + name="hash", field=models.CharField(max_length=64, unique=True), preserve_default=False, ), diff --git a/beat/web/databases/migrations/0007_add_accessibility_date.py b/beat/web/databases/migrations/0007_add_accessibility_date.py index 802aa1bcd0b7e903e6d51b88638784a6f78aff4d..d128d33a77a664e95182896c5fc0fbcab8c5c640 100644 --- a/beat/web/databases/migrations/0007_add_accessibility_date.py +++ b/beat/web/databases/migrations/0007_add_accessibility_date.py @@ -2,7 +2,8 @@ # Generated by Django 1.11.25 on 2020-02-12 11:22 from __future__ import unicode_literals -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): diff --git a/beat/web/databases/models.py b/beat/web/databases/models.py index bc51fa22a63f0078daf978aa9f0a674d81f30415..6df73c4ce799a1b3831bdac4ae6d4c591c5cedf3 100755 --- a/beat/web/databases/models.py +++ b/beat/web/databases/models.py @@ -26,38 +26,32 @@ ############################################################################### import os - -import simplejson - from datetime import datetime -from django.db import models +import simplejson from django.conf import settings -from django.urls import reverse +from django.db import models from django.db.models import Q +from django.urls import reverse import beat.core.database from beat.backend.python.hash import hashDataset -from ..dataformats.models import DataFormat - +from ..code.models import get_contribution_source_code_filename +from ..code.models import get_source_code +from ..code.models import set_source_code +from ..common import storage from ..common.models import Versionable from ..common.models import VersionableManager -from ..common.storage import OverwriteStorage -from ..common import storage - from ..common.models import get_contribution_declaration_filename from ..common.models import get_contribution_description_filename -from ..code.models import get_contribution_source_code_filename - -from ..common.models import get_description -from ..common.models import set_description from ..common.models import get_declaration -from ..common.models import set_declaration from ..common.models import get_declaration_string -from ..code.models import get_source_code -from ..code.models import set_source_code - +from ..common.models import get_description +from ..common.models import set_declaration +from ..common.models import set_description +from ..common.storage import OverwriteStorage +from ..dataformats.models import DataFormat # ---------------------------------------------------------- diff --git a/beat/web/databases/serializers.py b/beat/web/databases/serializers.py index 56d35a078887d1bb3633ce1830f33aaafa062f7a..c6c3ff4598d869d175b7b8754977dbf10d077d7f 100644 --- a/beat/web/databases/serializers.py +++ b/beat/web/databases/serializers.py @@ -26,16 +26,14 @@ ############################################################################### from django.conf import settings - from rest_framework import serializers -from ..common.serializers import VersionableSerializer -from ..common import fields as beat_fields +import beat.core.database -from .models import Database +from ..common import fields as beat_fields +from ..common.serializers import VersionableSerializer from .exceptions import DatabaseCreationError - -import beat.core.database +from .models import Database class DatabaseSerializer(VersionableSerializer): diff --git a/beat/web/databases/signals.py b/beat/web/databases/signals.py index 8732721847a19858f54ae6762b378a4d4b2e8705..8dde23a02afb94818b261d43d37133092d6b8ba6 100755 --- a/beat/web/databases/signals.py +++ b/beat/web/databases/signals.py @@ -30,11 +30,12 @@ from django.db import models from django.dispatch import receiver from ..dataformats.models import DataFormat - -from .models import Database, DatabaseProtocol, DatabaseSet -from .models import DatabaseSetTemplate, DatabaseSetTemplateOutput +from .models import Database +from .models import DatabaseProtocol +from .models import DatabaseSet from .models import DatabaseSetOutput - +from .models import DatabaseSetTemplate +from .models import DatabaseSetTemplateOutput from .models import validate_database @@ -94,18 +95,17 @@ def refresh_protocols(sender, instance, **kwargs): core.name = instance.fullname() protocols = DatabaseProtocol.objects.filter( - database__name=instance.name, - database__version=instance.version, + database__name=instance.name, database__version=instance.version, ) existing = set((k.name, k.set_template_basename()) for k in protocols) - new_objects = set([(k,v['template']) for k,v in core.protocols.items()]) + new_objects = set([(k, v["template"]) for k, v in core.protocols.items()]) for protocol_name, template in existing - new_objects: # notice: no need to worry, this will clean-up all the rest protocols.get(name__iexact=protocol_name).delete() - json_protocols = dict([(k,v) for k,v in core.protocols.items()]) + json_protocols = dict([(k, v) for k, v in core.protocols.items()]) for protocol_name, template in new_objects - existing: protocol = DatabaseProtocol(name=protocol_name, database=instance) @@ -114,12 +114,12 @@ def refresh_protocols(sender, instance, **kwargs): json_protocol = json_protocols[protocol_name] # creates all the template sets, outputs, etc for the first time - for set_attr in json_protocol['sets']: + for set_attr in json_protocol["sets"]: - tset_name = json_protocol['template'] + '__' + set_attr['template'] + tset_name = json_protocol["template"] + "__" + set_attr["template"] dataset_template = DatabaseSetTemplate.objects.filter(name=tset_name) - if not dataset_template: #create + if not dataset_template: # create dataset_template = DatabaseSetTemplate(name=tset_name) dataset_template.save() else: @@ -127,78 +127,70 @@ def refresh_protocols(sender, instance, **kwargs): # Create the database set dataset = DatabaseSet.objects.filter( - name = set_attr['name'], - template = dataset_template, - protocol = protocol, + name=set_attr["name"], template=dataset_template, protocol=protocol, ) - if not dataset: #create + if not dataset: # create dataset = DatabaseSet.objects.create( - name = set_attr['name'], - template = dataset_template, - protocol = protocol, + name=set_attr["name"], + template=dataset_template, + protocol=protocol, ) # Create the database set template output - for output_name, format_name in set_attr['outputs'].items(): - if len(format_name.split('/')) != 3: + for output_name, format_name in set_attr["outputs"].items(): + if len(format_name.split("/")) != 3: raise SyntaxError( - "Dataformat should be named following the " \ - "style `<username>/<format>/<version>', the " \ + "Dataformat should be named following the " + "style `<username>/<format>/<version>', the " "value `%s' is not valid" % (format_name,) ) - (author, name, version) = format_name.split('/') + (author, name, version) = format_name.split("/") dataformats = DataFormat.objects.filter( - author__username=author, - name=name, - version=version, + author__username=author, name=name, version=version, ) # TODO: Remove this when validation works (see comments) if len(dataformats) != 1: raise SyntaxError( - "Could not find dataformat named `%s' to set" \ - "output `%s' of template `%s' for protocol" \ - "`%s' of database `%s'", ( + "Could not find dataformat named `%s' to set" + "output `%s' of template `%s' for protocol" + "`%s' of database `%s'", + ( format_name, - output_name, - dataset_template.name, - protocol_name, - instance.name, - ) + output_name, + dataset_template.name, + protocol_name, + instance.name, + ), ) return - database_template_output = \ - DatabaseSetTemplateOutput.objects.filter( + database_template_output = DatabaseSetTemplateOutput.objects.filter( + name=output_name, + template=dataset_template, + dataformat=dataformats[0], + ) + + if not database_template_output: # create + database_template_output = DatabaseSetTemplateOutput( name=output_name, template=dataset_template, dataformat=dataformats[0], ) - - if not database_template_output: # create - database_template_output = \ - DatabaseSetTemplateOutput( - name=output_name, - template=dataset_template, - dataformat=dataformats[0], - ) database_template_output.save() else: - database_template_output = \ - database_template_output[0] + database_template_output = database_template_output[0] # Create the database set output - dataset_output = \ - DatabaseSetOutput.objects.filter(template=database_template_output, - set=dataset, - ) + dataset_output = DatabaseSetOutput.objects.filter( + template=database_template_output, set=dataset, + ) - if not dataset_output: # create + if not dataset_output: # create dataset_output = DatabaseSetOutput( - template=database_template_output, - set=dataset, + template=database_template_output, set=dataset, ) dataset_output.save() @@ -210,8 +202,9 @@ def refresh_protocols(sender, instance, **kwargs): @receiver(models.signals.post_delete, sender=DatabaseSet) def delete_empty_template_sets(sender, **kwargs): - instance = kwargs['instance'] + instance = kwargs["instance"] try: - if not instance.template.sets.all(): instance.template.delete() - except: + if not instance.template.sets.all(): + instance.template.delete() + except Exception: # nosec pass diff --git a/beat/web/databases/templates/databases/list.html b/beat/web/databases/templates/databases/list.html index 8eb2bc1742e38f5ddecc56312bedf11941e78e25..82918f6199789a71294411edfe718341d87556f4 100644 --- a/beat/web/databases/templates/databases/list.html +++ b/beat/web/databases/templates/databases/list.html @@ -2,21 +2,21 @@ {% comment %} * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ * Contact: beat.support@idiap.ch - * + * * This file is part of the beat.web module of the BEAT platform. - * + * * Commercial License Usage * Licensees holding valid commercial BEAT licenses may use this file in * accordance with the terms contained in a written agreement between you * and Idiap. For further information contact tto@idiap.ch - * + * * Alternatively, this file may be used under the terms of the GNU Affero * Public License version 3 as published by the Free Software and appearing * in the file LICENSE.AGPL included in the packaging of this file. * The BEAT platform is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. - * + * * You should have received a copy of the GNU Affero Public License along * with the BEAT platform. If not, see http://www.gnu.org/licenses/. {% endcomment %} diff --git a/beat/web/databases/templates/databases/panels/actions.html b/beat/web/databases/templates/databases/panels/actions.html index 3d231514a4058a56bd2ad3cf30e2aca4d4944acd..5bd21774ba1b752250ef2635a93fb04e43852d42 100644 --- a/beat/web/databases/templates/databases/panels/actions.html +++ b/beat/web/databases/templates/databases/panels/actions.html @@ -1,21 +1,21 @@ {% comment %} * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ * Contact: beat.support@idiap.ch - * + * * This file is part of the beat.web module of the BEAT platform. - * + * * Commercial License Usage * Licensees holding valid commercial BEAT licenses may use this file in * accordance with the terms contained in a written agreement between you * and Idiap. For further information contact tto@idiap.ch - * + * * Alternatively, this file may be used under the terms of the GNU Affero * Public License version 3 as published by the Free Software and appearing * in the file LICENSE.AGPL included in the packaging of this file. * The BEAT platform is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. - * + * * You should have received a copy of the GNU Affero Public License along * with the BEAT platform. If not, see http://www.gnu.org/licenses/. {% endcomment %} diff --git a/beat/web/databases/templates/databases/panels/table.html b/beat/web/databases/templates/databases/panels/table.html index f0e0c3a8fda4263444d785bcedb17b06cecbf599..1a16d0eaf8b1c73b6bfbca736f7307252e893fb8 100644 --- a/beat/web/databases/templates/databases/panels/table.html +++ b/beat/web/databases/templates/databases/panels/table.html @@ -1,21 +1,21 @@ {% comment %} * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ * Contact: beat.support@idiap.ch - * + * * This file is part of the beat.web module of the BEAT platform. - * + * * Commercial License Usage * Licensees holding valid commercial BEAT licenses may use this file in * accordance with the terms contained in a written agreement between you * and Idiap. For further information contact tto@idiap.ch - * + * * Alternatively, this file may be used under the terms of the GNU Affero * Public License version 3 as published by the Free Software and appearing * in the file LICENSE.AGPL included in the packaging of this file. * The BEAT platform is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. - * + * * You should have received a copy of the GNU Affero Public License along * with the BEAT platform. If not, see http://www.gnu.org/licenses/. {% endcomment %} diff --git a/beat/web/databases/templatetags/database_tags.py b/beat/web/databases/templatetags/database_tags.py index c12366b44d4b0c1d7396de11951722d89c2bf676..fb476bf7dd6f014438eabe547bd0f00c0460c24f 100644 --- a/beat/web/databases/templatetags/database_tags.py +++ b/beat/web/databases/templatetags/database_tags.py @@ -28,13 +28,12 @@ from django import template - register = template.Library() -@register.inclusion_tag('databases/panels/table.html', takes_context=True) +@register.inclusion_tag("databases/panels/table.html", takes_context=True) def database_table(context, objects, id): - '''Composes a database list table + """Composes a database list table This panel primarily exists for user's database list page. @@ -44,18 +43,14 @@ def database_table(context, objects, id): id: The HTML id to set on the generated table. This is handy for the filter functionality normally available on list pages. - ''' + """ - return dict( - request=context['request'], - objects=objects, - panel_id=id, - ) + return dict(request=context["request"], objects=objects, panel_id=id,) -@register.inclusion_tag('databases/panels/actions.html', takes_context=True) +@register.inclusion_tag("databases/panels/actions.html", takes_context=True) def database_actions(context, object, display_count): - '''Composes the action buttons for a particular database + """Composes the action buttons for a particular database This panel primarily exists for showing action buttons for a given database taking into consideration it is being displayed for a given user. @@ -68,9 +63,5 @@ def database_actions(context, object, display_count): display the number of protocols as a button (useful for the list view) - ''' - return dict( - request=context['request'], - object=object, - display_count=display_count, - ) + """ + return dict(request=context["request"], object=object, display_count=display_count,) diff --git a/beat/web/databases/tests.py b/beat/web/databases/tests.py index bd04208f3ac5f306a58ad7afeba13f4d6c5ef9b6..53b11da9223f7adfea074f3d8a77b15e0978574f 100644 --- a/beat/web/databases/tests.py +++ b/beat/web/databases/tests.py @@ -26,20 +26,17 @@ ############################################################################### import json +from datetime import datetime +from datetime import timedelta -from datetime import datetime, timedelta - -from django.contrib.auth.models import User from django.conf import settings +from django.contrib.auth.models import User from django.urls import reverse -from .models import Database - -from ..dataformats.models import DataFormat - from ..common.testutils import BaseTestCase from ..common.testutils import tearDownModule # noqa test runner will call it - +from ..dataformats.models import DataFormat +from .models import Database TEST_PWD = "1234" # nosec diff --git a/beat/web/databases/views.py b/beat/web/databases/views.py index b2e22661ff6f14fe271bf932755d341adb9ab823..66a5431d8023f2ae77fc9c91b432ed1484c5d4c7 100644 --- a/beat/web/databases/views.py +++ b/beat/web/databases/views.py @@ -39,30 +39,31 @@ def view(request, name, version=None): if version is not None: version = int(version) - database = Database.objects.for_user(request.user, True).get(name__iexact=name, - version=version) + database = Database.objects.for_user(request.user, True).get( + name__iexact=name, version=version + ) else: - database = Database.objects.for_user(request.user, True).filter(name__iexact=name).order_by('-version')[0] - except: + database = ( + Database.objects.for_user(request.user, True) + .filter(name__iexact=name) + .order_by("-version")[0] + ) + except Database.DoesNotExist: raise Http404 # Render the page - return render(request, - 'databases/view.html', - {'database': database}) + return render(request, "databases/view.html", {"database": database}) def ls(request): - '''List all accessible databases to the request user''' + """List all accessible databases to the request user""" # orders databases so that the latest information is displayed first - objects = Database.objects.for_user(request.user, True).order_by('-creation_date') + objects = Database.objects.for_user(request.user, True).order_by("-creation_date") objects = Database.filter_latest_versions(objects) - return render(request, - 'databases/list.html', - dict( - objects=objects, - author=request.user, - owner=True, - )) + return render( + request, + "databases/list.html", + dict(objects=objects, author=request.user, owner=True,), + )