diff --git a/bco-tool/app/services/custom_bco_db.py b/bco-tool/app/services/custom_bco_db.py new file mode 100644 index 0000000..6308ff9 --- /dev/null +++ b/bco-tool/app/services/custom_bco_db.py @@ -0,0 +1,45 @@ +from typing import Dict +import requests +import json + +class CustomBcoDB(): + def __init__(self, host_url: str, credentials: dict): + self.__host_url__ = host_url + self.__credentials__ = credentials + + def upload(self) -> Dict[str, str]: + try: + with open("app/schemas/biocompute_export.json", "r") as file: + file_content = json.load(file) + + headers = { + "Content-type": "application/json; charset=UTF-8", + } + + if self.__credentials__ and len(self.__credentials__) > 0: + headers.update(self.__credentials__) + + response = requests.post( + url=self.__host_url__, + data=json.dumps({ "contents": file_content }), + headers=headers + ) + + if response.status_code == 200: + print("File uploaded to Custom BCO DB") + return { + "code": 200, + "message": "File uploaded to Custom BCO DB", + } + else: + print("Failed to update file to Custom BCO DB", response.__dict__) + return { + "code": response.status_code, + "message": "Failed to update file to Custom BCO DB" + } + except Exception as e: + print(f"Error uploading to Custom BCO DB -- {repr(e)}") + return { + "code": 500, + "message": "Internal server error" + } diff --git a/bco-tool/app/static/exportfile_custom_bco_db.js b/bco-tool/app/static/exportfile_custom_bco_db.js new file mode 100644 index 0000000..3afc9c0 --- /dev/null +++ b/bco-tool/app/static/exportfile_custom_bco_db.js @@ -0,0 +1,101 @@ +$(document).ready(function() { + bindEvents(); + + function bindEvents() { + // config to show toast on top center + toastr.options = { "positionClass": "toast-top-center" }; + + // enable/disable the submit button if url is changed + $("#bco_custom_db_url").on("input", (event) => { + $(".btn-submit-custom-bco-db").prop("disabled", !event.target.value); + }); + + // handle event when clicking on the "add/remove credential" button + $(document).on('click', '.btn-add-credential', addCredential); + $(document).on('click', '.btn-remove-credential', removeCredential); + + // handle event when clicking on the submit button + $('.btn-submit-custom-bco-db').on('click', exportFileToCustomBcoDb); + } + + function exportFileToCustomBcoDb(event) { + const btnSubmit = event.target; + const url = $("#bco_custom_db_url").val(); + + if (!url) { + return toastr.error("Please enter data for all fields to upload custom BCO database"); + } + + const setSubmitting = (isSubmitting) => { + if (isSubmitting) { + btnSubmit.disabled = true; + btnSubmit.innerHTML = "Submitting..."; + } else { + btnSubmit.disabled = false; + btnSubmit.innerHTML = "Submit"; + } + }; + + // submit form data + setSubmitting(true); + $.ajax({ + type: "POST", + headers: { "X-CSRFToken": getCookie("csrftoken") }, + url: "export_to_custom_bco_db", + contentType: "application/json; charset=utf-8", + data: JSON.stringify({ + url, + credentials: getCredentials(), + }), + success: (message) => { + toastr.success(message) + setSubmitting(false); + $("#bco_custom_db_export_container").modal("hide"); + }, + error: (err) => { + toastr.error(err.responseText || err.statusText || "Error when exporting file to custom BCO database"); + setSubmitting(false); + }, + }); + } + + function addCredential() { + const credentialContainer = $("#credentials-container"); + const credentialRow = $("
") + .css("display", "flex") + .css("gap", "10px") + .addClass("mb-2") + .html(` + + + + `); + credentialContainer.append(credentialRow); + } + + function removeCredential() { + const button = $(this); + const credentialRow = button.parent(); + credentialRow.remove(); + } + + function getCredentials() { + const credentials = {}; + + $("#credentials-container > div").each(function() { + const credentialKey = $(this).find("input[placeholder='key']").val(); + const credentialValue = $(this).find("input[placeholder='value']").val(); + + if (credentialKey && credentialValue) { + credentials[credentialKey] = credentialValue; + } + }); + + return credentials; + } +}); diff --git a/bco-tool/app/static/scripts.js b/bco-tool/app/static/scripts.js index d7fa931..90aee18 100644 --- a/bco-tool/app/static/scripts.js +++ b/bco-tool/app/static/scripts.js @@ -522,6 +522,9 @@ $(document).ready(function() { $("#user_token").val("") $('#bco_db_export_container').modal('show') } + else if (export_option == "Custom BCO DB") { + $('#bco_custom_db_export_container').modal('show'); + } else if (export_option=="PFDA BCO File"){ $("#pfda_export_space_selector_div").css("visibility", "hidden") $("#pfda_export_folder_selector_div").css("visibility", "hidden") diff --git a/bco-tool/app/static/styles.css b/bco-tool/app/static/styles.css index ed6af88..e12e431 100644 --- a/bco-tool/app/static/styles.css +++ b/bco-tool/app/static/styles.css @@ -284,6 +284,9 @@ border-color: #007bff; background-color: #f8f9fa; } + .rounded-lg { + border-radius: 0.5rem; + } /* .lorem{ content: '-'; } */ diff --git a/bco-tool/app/templates/base.html b/bco-tool/app/templates/base.html index 36a4a67..20e1f14 100644 --- a/bco-tool/app/templates/base.html +++ b/bco-tool/app/templates/base.html @@ -35,6 +35,11 @@ + + + + + @@ -75,6 +80,8 @@ BCO Repository precisionFDA + + Custom BCO database @@ -125,6 +132,7 @@ {% include "exportfile_dna_nexus.html" %} {% include "exportfile_pfda.html" %} {% include "exportfile_bco_db.html" %} + {% include "exportfile_custom_bco_db.html" %} {% include "description_modal.html" %} {% include "image_zoom_modal.html" %} diff --git a/bco-tool/app/templates/exportfile_custom_bco_db.html b/bco-tool/app/templates/exportfile_custom_bco_db.html new file mode 100644 index 0000000..c3e08e7 --- /dev/null +++ b/bco-tool/app/templates/exportfile_custom_bco_db.html @@ -0,0 +1,97 @@ +{% load static %} +{% block file_uploader %} +{% csrf_token %} + + +{% endblock %} diff --git a/bco-tool/app/views.py b/bco-tool/app/views.py index e2a0abb..039acfd 100644 --- a/bco-tool/app/views.py +++ b/bco-tool/app/views.py @@ -5,6 +5,7 @@ from collections import OrderedDict from app.services.bco_db import BcoDB +from app.services.custom_bco_db import CustomBcoDB from app.services.cwl import CWL from app.services.dataservices.bco_data_service import \ BcoDataService, ComparisonBcoDataService @@ -20,7 +21,7 @@ from django.contrib import messages from django.core.files.base import ContentFile from django.core.files.storage import default_storage -from django.http import HttpResponse, JsonResponse, QueryDict +from django.http import HttpResponse, HttpResponseNotAllowed, HttpResponseServerError, JsonResponse, QueryDict from django.shortcuts import render from django.views.decorators.csrf import csrf_protect from script import CompileWorkflow @@ -1287,6 +1288,25 @@ def export_to_bco_db(request): except Exception as e: return HttpResponse(status=400) +def export_to_custom_bco_db(request) -> HttpResponse: + if request.method != "POST": + return HttpResponseNotAllowed(permitted_methods="POST") + + try: + # create biocompute_export.json file + create_export_bco() + + # get request data + requestData = json.loads(request.body) + url = requestData.get("url") + credentials = requestData.get("credentials") + + # call request + response = CustomBcoDB(host_url=url, credentials=credentials).upload() + return HttpResponse(status=response.get("code"), content=response.get("message")) + except Exception as e: + return HttpResponseServerError() + def save_bco_editor(request): try: if request.method == "POST": diff --git a/bco-tool/bconexus/settings.py b/bco-tool/bconexus/settings.py index 743805f..e48622c 100644 --- a/bco-tool/bconexus/settings.py +++ b/bco-tool/bconexus/settings.py @@ -26,7 +26,7 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = [] +ALLOWED_HOSTS = ["*"] # Application definition @@ -102,7 +102,7 @@ "formatter": 'formatter_1', "class": "logging.handlers.RotatingFileHandler", "filename": "./Logs/user.log", - "maxBytes":10485760, + "maxBytes":10485760, "backupCount":1 }, }, diff --git a/bco-tool/bconexus/urls.py b/bco-tool/bconexus/urls.py index bcf0e49..3e0fa8e 100644 --- a/bco-tool/bconexus/urls.py +++ b/bco-tool/bconexus/urls.py @@ -91,6 +91,7 @@ path('export_dowload_bco', export_dowload_bco, name='export_dowload_bco'), path('export_bco_to_dnanexus', export_bco_to_dnanexus, name='export_bco_to_dnanexus'), path('export_to_bco_db', export_to_bco_db, name='export_to_bco_db'), + path('export_to_custom_bco_db', export_to_custom_bco_db, name='export_to_custom_bco_db'), path('search', search, name='search'), path('save_bco_editor',save_bco_editor, name='save_bco_editor'), path('validate_bco_editor',validate_bco_editor, name='validate_bco_editor'), diff --git a/bco-tool/requirements.txt b/bco-tool/requirements.txt index cf73428..30d0817 100644 --- a/bco-tool/requirements.txt +++ b/bco-tool/requirements.txt @@ -111,3 +111,4 @@ xhtml2pdf==0.2.1 xlrd==1.2.0 xtermcolor==1.3 zipp==3.1.0 +tzdata==2024.1 \ No newline at end of file diff --git a/bco-tool/requirements_latest.txt b/bco-tool/requirements_latest.txt index 045b163..0ca9915 100644 --- a/bco-tool/requirements_latest.txt +++ b/bco-tool/requirements_latest.txt @@ -36,3 +36,4 @@ urllib3==1.26.10 websocket-client==0.54.0 xdg==5.1.1 zipp==3.8.1 +tzdata==2024.1 \ No newline at end of file