[Feature] External Identifier/References

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#139
This commit is contained in:
2025-10-02 00:40:00 +13:00
parent 3f5bb76633
commit 7ad4112343
19 changed files with 9257 additions and 19 deletions

View File

@ -17,7 +17,7 @@ from utilities.misc import HTMLGenerator
from .logic import GroupManager, PackageManager, UserManager, SettingManager, SearchManager, EPDBURLParser
from .models import Package, GroupPackagePermission, Group, CompoundStructure, Compound, Reaction, Rule, Pathway, Node, \
EPModel, EnviFormer, MLRelativeReasoning, RuleBasedRelativeReasoning, Scenario, SimpleAmbitRule, APIToken, \
UserPackagePermission, Permission, License, User, Edge
UserPackagePermission, Permission, License, User, Edge, ExternalDatabase, ExternalIdentifier
logger = logging.getLogger(__name__)
@ -194,6 +194,7 @@ def get_base_context(request, for_user=None) -> Dict[str, Any]:
'available_settings': SettingManager.get_all_settings(current_user),
'enabled_features': s.FLAGS,
'debug': s.DEBUG,
'external_databases': ExternalDatabase.get_databases(),
},
}
@ -249,6 +250,9 @@ def copy_object(current_user, target_package: 'Package', source_object_url: str)
# Ensures that source is readable
source_package = PackageManager.get_package_by_url(current_user, source_object_url)
if source_package == target_package:
raise ValueError(f"Can't copy object {source_object_url} to the same package!")
parser = EPDBURLParser(source_object_url)
# if the url won't contain a package or is a plain package
@ -892,7 +896,11 @@ def package(request, package_uuid):
if not object_to_copy:
return error(request, 'No object to copy', 'There was no object to copy.')
copied_object = copy_object(current_user, current_package, object_to_copy)
try:
copied_object = copy_object(current_user, current_package, object_to_copy)
except ValueError as e:
return JsonResponse({'error': f"Can't copy object {object_to_copy} to the same package!"}, status=400)
return JsonResponse({'success': copied_object.url})
else:
return HttpResponseBadRequest()
@ -1043,8 +1051,8 @@ def package_compound(request, package_uuid, compound_uuid):
set_scenarios(current_user, current_compound, selected_scenarios)
return redirect(current_compound.url)
new_compound_name = request.POST.get('compound-name')
new_compound_description = request.POST.get('compound-description')
new_compound_name = request.POST.get('compound-name', '').strip()
new_compound_description = request.POST.get('compound-description', '').strip()
if new_compound_name:
current_compound.name = new_compound_name
@ -1055,6 +1063,20 @@ def package_compound(request, package_uuid, compound_uuid):
if any([new_compound_name, new_compound_description]):
current_compound.save()
return redirect(current_compound.url)
selected_database = request.POST.get('selected-database', '').strip()
external_identifier = request.POST.get('identifier', '').strip()
if selected_database and external_identifier:
db = ExternalDatabase.objects.get(id=int(selected_database))
ExternalIdentifier.objects.create(
content_object=current_compound,
database=db,
identifier_value=external_identifier,
url=db.url_pattern.format(id=external_identifier),
is_primary=False
)
return redirect(current_compound.url)
else:
return HttpResponseBadRequest()
@ -1146,12 +1168,39 @@ def package_compound_structure(request, package_uuid, compound_uuid, structure_u
else:
return HttpResponseBadRequest()
new_structure_name = request.POST.get('compound-structure-name', '').strip()
new_structure_description = request.POST.get('compound-structure-description', '').strip()
if new_structure_name:
current_structure.name = new_structure_name
if new_structure_description:
current_structure.description = new_structure_description
if any([new_structure_name, new_structure_description]):
current_structure.save()
return redirect(current_structure.url)
if 'selected-scenarios' in request.POST:
selected_scenarios = request.POST.getlist('selected-scenarios')
set_scenarios(current_user, current_structure, selected_scenarios)
return redirect(current_structure.url)
selected_database = request.POST.get('selected-database', '').strip()
external_identifier = request.POST.get('identifier', '').strip()
if selected_database and external_identifier:
db = ExternalDatabase.objects.get(id=int(selected_database))
ExternalIdentifier.objects.create(
content_object=current_structure,
database=db,
identifier_value=external_identifier,
url=db.url_pattern.format(id=external_identifier),
is_primary=False
)
return redirect(current_structure.url)
return HttpResponseBadRequest()
else:
return HttpResponseNotAllowed(['GET', ])
@ -1382,8 +1431,8 @@ def package_reaction(request, package_uuid, reaction_uuid):
set_scenarios(current_user, current_reaction, selected_scenarios)
return redirect(current_reaction.url)
new_reaction_name = request.POST.get('reaction-name')
new_reaction_description = request.POST.get('reaction-description')
new_reaction_name = request.POST.get('reaction-name', '').strip()
new_reaction_description = request.POST.get('reaction-description', '').strip()
if new_reaction_name:
current_reaction.name = new_reaction_name
@ -1394,8 +1443,22 @@ def package_reaction(request, package_uuid, reaction_uuid):
if any([new_reaction_name, new_reaction_description]):
current_reaction.save()
return redirect(current_reaction.url)
else:
return HttpResponseBadRequest()
selected_database = request.POST.get('selected-database', '').strip()
external_identifier = request.POST.get('identifier', '').strip()
if selected_database and external_identifier:
db = ExternalDatabase.objects.get(id=int(selected_database))
ExternalIdentifier.objects.create(
content_object=current_reaction,
database=db,
identifier_value=external_identifier,
url=db.url_pattern.format(id=external_identifier),
is_primary=False
)
return redirect(current_reaction.url)
return HttpResponseBadRequest()
else:
return HttpResponseNotAllowed(['GET', 'POST'])