import base64 import requests from django.conf import settings as s from django.core.exceptions import BadRequest from django.http import HttpResponse from django.shortcuts import redirect from bayer.models import PESCompound from epdb.logic import PackageManager from epdb.models import Pathway, Node from epdb.views import _anonymous_or_real from utilities.decorators import package_permission_required Package = s.GET_PACKAGE_MODEL() @package_permission_required() def create_pes(request, package_uuid): current_user = _anonymous_or_real(request) current_package = PackageManager.get_package_by_id(current_user, package_uuid) if request.method == "POST": if current_package.classification_level == Package.Classification.INTERNAL: raise BadRequest("Cannot create PESs for internal packages.") compound_name = request.POST.get('compound-name') compound_description = request.POST.get('compound-description') pes_link = request.POST.get('pes-link') if pes_link: try: pes_data = fetch_pes(request, pes_link) except ValueError as e: return BadRequest(f"Could not fetch PES data for {pes_link}") classification = pes_data.get("classificationLevel", "") if "secret" == classification.lower(): data_pools = pes_data.get("dataPools") if data_pools: if s.DATA_POOL_MAPPING[current_package.data_pool.name] not in data_pools: return BadRequest( f"PES data pool {s.DATA_POOL_MAPPING[current_package.data_pool.name]} not found in PES data") pes = PESCompound.create(current_package, pes_data, compound_name, compound_description) return redirect(pes.url) else: return BadRequest("Please provide a PES link.") else: pass @package_permission_required() def create_pes_node(request, package_uuid, pathway_uuid): current_user = _anonymous_or_real(request) current_package = PackageManager.get_package_by_id(current_user, package_uuid) current_pathway = Pathway.objects.get(package=current_package, uuid=pathway_uuid) if request.method == "POST": if current_package.classification_level == Package.Classification.INTERNAL: raise BadRequest("Cannot create PESs for internal packages.") compound_name = request.POST.get('compound-name') compound_description = request.POST.get('compound-description') pes_link = request.POST.get('pes-link') if pes_link: try: pes_data = fetch_pes(request, pes_link) except ValueError as e: return BadRequest(f"Could not fetch PES data for {pes_link}") classification = pes_data.get("classificationLevel", "") if "secret" == classification.lower(): data_pools = pes_data.get("dataPools") if data_pools: if s.DATA_POOL_MAPPING[current_package.data_pool.name] not in data_pools: return BadRequest( f"PES data pool {s.DATA_POOL_MAPPING[current_package.data_pool.name]} not found in PES data") pes = PESCompound.create(current_package, pes_data, compound_name, compound_description) n = Node() n.stereo_removed = False n.pathway = current_pathway n.depth = 0 n.default_node_label = pes.default_structure n.save() n.node_labels.add(pes.default_structure) n.save() return redirect(current_pathway.url) else: return BadRequest("Please provide a PES link.") else: pass def fetch_pes(request, pes_url) -> dict: from epauth.views import get_access_token_from_request token = get_access_token_from_request(request) if token: for k, v in s.PES_API_MAPPING.items(): if pes_url.startswith(k): pes_id = pes_url.split('/')[-1] if pes_id == 'dummy': import json res_data = json.load(open(s.BASE_DIR / "fixtures/pes.json")) res_data["pes_url"] = pes_url return res_data else: headers = {"Authorization": f"Bearer {token['access_token']}"} params = {"pes_reg_entity_corporate_id": pes_id} res = requests.get(v, headers=headers, params=params, proxies=s.PROXIES or None) try: res.raise_for_status() pes_data = res.json() if len(pes_data) == 0: raise ValueError(f"PES with id {pes_id} not found") res_data = pes_data[0] res_data["pes_url"] = pes_url return res_data except requests.exceptions.HTTPError as e: raise ValueError(f"Error fetching PES with id {pes_id}: {e}") else: raise ValueError(f"Unknown URL {pes_url}") else: raise ValueError("Could not fetch access token from request.") def visualize_pes(request): pes_link = request.GET.get('pesLink') if pes_link: pes_data = fetch_pes(request, pes_link) representations = pes_data.get('representations') for rep in representations: if rep.get('type') == 'color': image_data = base64.b64decode(rep.get('base64').replace("data:image/png;base64,", "")) return HttpResponse(image_data, content_type="image/png")