diff --git a/bayer/__init__.py b/bayer/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/bayer/admin.py b/bayer/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/bayer/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/bayer/apps.py b/bayer/apps.py new file mode 100644 index 00000000..3821be18 --- /dev/null +++ b/bayer/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BayerConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'bayer' diff --git a/bayer/migrations/0001_initial.py b/bayer/migrations/0001_initial.py new file mode 100644 index 00000000..a9d11d9a --- /dev/null +++ b/bayer/migrations/0001_initial.py @@ -0,0 +1,35 @@ +# Generated by Django 5.2.7 on 2026-03-06 10:51 + +import django.utils.timezone +import model_utils.fields +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Package', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')), + ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')), + ('uuid', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='UUID of this object')), + ('name', models.TextField(default='no name', verbose_name='Name')), + ('description', models.TextField(default='no description', verbose_name='Descriptions')), + ('url', models.TextField(null=True, unique=True, verbose_name='URL')), + ('kv', models.JSONField(blank=True, default=dict, null=True)), + ('reviewed', models.BooleanField(default=False, verbose_name='Reviewstatus')), + ('classification_level', models.IntegerField(choices=[(0, 'Internal'), (10, 'Restricted'), (20, 'Secret')], default=10)), + ], + options={ + 'db_table': 'epdb_package', + }, + ), + ] diff --git a/bayer/migrations/0002_initial.py b/bayer/migrations/0002_initial.py new file mode 100644 index 00000000..6a5a15d8 --- /dev/null +++ b/bayer/migrations/0002_initial.py @@ -0,0 +1,22 @@ +# Generated by Django 5.2.7 on 2026-03-06 10:51 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('bayer', '0001_initial'), + ('epdb', '0019_remove_scenario_additional_information_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='package', + name='license', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='epdb.license', verbose_name='License'), + ), + ] diff --git a/bayer/migrations/__init__.py b/bayer/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/bayer/models.py b/bayer/models.py new file mode 100644 index 00000000..07f499da --- /dev/null +++ b/bayer/models.py @@ -0,0 +1,95 @@ +from typing import List + +from django.conf import settings as s +from django.db import models +from django.db.models import QuerySet + +from epdb.models import ( + EnviPathModel, + ParallelRule, + SequentialRule, + SimpleAmbitRule, + SimpleRDKitRule, +) + + +class Package(EnviPathModel): + reviewed = models.BooleanField(verbose_name="Reviewstatus", default=False) + license = models.ForeignKey( + "epdb.License", on_delete=models.SET_NULL, blank=True, null=True, verbose_name="License" + ) + + class Classification(models.IntegerChoices): + INTERNAL = 0, "Internal" + RESTRICTED = 10 , "Restricted" + SECRET = 20, "Secret" + + classification_level = models.IntegerField( + choices=Classification, + default=Classification.RESTRICTED, + ) + + def delete(self, *args, **kwargs): + # explicitly handle related Rules + for r in self.rules.all(): + r.delete() + super().delete(*args, **kwargs) + + def __str__(self): + return f"{self.name} (pk={self.pk})" + + @property + def compounds(self) -> QuerySet: + return self.compound_set.all() + + @property + def rules(self) -> QuerySet: + return self.rule_set.all() + + @property + def reactions(self) -> QuerySet: + return self.reaction_set.all() + + @property + def pathways(self) -> QuerySet: + return self.pathway_set.all() + + @property + def scenarios(self) -> QuerySet: + return self.scenario_set.all() + + @property + def models(self) -> QuerySet: + return self.epmodel_set.all() + + def _url(self): + return "{}/package/{}".format(s.SERVER_URL, self.uuid) + + def get_applicable_rules(self) -> List["Rule"]: + """ + Returns a ordered set of rules where the following applies: + 1. All Composite will be added to result + 2. All SimpleRules will be added if theres no CompositeRule present using the SimpleRule + Ordering is based on "url" field. + """ + rules = [] + rule_qs = self.rules + + reflected_simple_rules = set() + + for r in rule_qs: + if isinstance(r, ParallelRule) or isinstance(r, SequentialRule): + rules.append(r) + for sr in r.simple_rules.all(): + reflected_simple_rules.add(sr) + + for r in rule_qs: + if isinstance(r, SimpleAmbitRule) or isinstance(r, SimpleRDKitRule): + if r not in reflected_simple_rules: + rules.append(r) + + rules = sorted(rules, key=lambda x: x.url) + return rules + + class Meta: + db_table = "epdb_package" \ No newline at end of file diff --git a/bayer/templates/actions/objects/compound.html b/bayer/templates/actions/objects/compound.html new file mode 100644 index 00000000..e69de29b diff --git a/bayer/templates/objects/package.html b/bayer/templates/objects/package.html new file mode 100644 index 00000000..82d07567 --- /dev/null +++ b/bayer/templates/objects/package.html @@ -0,0 +1,97 @@ +{% extends "framework_modern.html" %} + +{% block content %} + + {% block action_modals %} + {% include "modals/objects/edit_package_modal.html" %} + {% include "modals/objects/edit_package_permissions_modal.html" %} + {% include "modals/objects/publish_package_modal.html" %} + {% include "modals/objects/set_license_modal.html" %} + {% include "modals/objects/export_package_modal.html" %} + {% include "modals/objects/generic_delete_modal.html" %} + {% endblock action_modals %} + +
{{ package.description|safe }}
+ +