예제 #1
0
    def _load_modals(self):
        modals = [
            "core_main_app/common/modals/error_page_modal.html",
            "core_explore_common_app/user/persistent_query/modal.html",
        ]

        # Add the exporters modal
        if "core_exporters_app" in settings.INSTALLED_APPS:
            modals.extend([
                "core_exporters_app/user/exporters/list/modals/list_exporters_selector.html"
            ])

        # Add the file preview modal
        if "core_file_preview_app" in settings.INSTALLED_APPS:
            modals.append("core_file_preview_app/user/file_preview_modal.html")

        # Add PID modal
        if "core_linked_records_app" in settings.INSTALLED_APPS:
            from core_linked_records_app.components.pid_settings import (
                api as pid_settings_api, )

            if pid_settings_api.get().auto_set_pid:
                modals.append(
                    "core_linked_records_app/user/sharing/explore/modal.html")

        return modals
예제 #2
0
    def patch(self, request):
        """Update settings for the PID system. Current, only works for automatically
        setting PIDs (`auto_set_pid`).

        Args:
            request:

        Returns:
        """
        if not request.user.is_superuser:
            return Response(
                {"message": "Only a superuser can use this feature."},
                status=status.HTTP_403_FORBIDDEN,
            )

        pid_settings_serializer = PidSettingsSerializer(data=request.data)

        if not pid_settings_serializer.is_valid():
            return Response({"message": "Invalid data provided"},
                            status=status.HTTP_400_BAD_REQUEST)

        pid_settings_serializer.update(pid_settings_api.get(),
                                       pid_settings_serializer.validated_data)

        return self.get(request)
예제 #3
0
def get_data_sources_html(request):
    """Gets data sources html for results

    Args:
        request:

    Returns:

    """
    try:
        # get query id
        query_id = request.GET["query_id"]

        # get query results
        query = query_api.get_by_id(query_id, request.user)

        # Check if 'core_linked_records_app' is installed and activated
        is_linked_records_installed = False
        if "core_linked_records_app" in settings.INSTALLED_APPS:
            from core_linked_records_app.components.pid_settings import (
                api as pid_settings_api,
            )

            is_linked_records_installed = pid_settings_api.get().auto_set_pid

        # set query in context
        context = {
            "linked_records_app": is_linked_records_installed,
            "exporter_app": "core_exporters_app" in settings.INSTALLED_APPS,
            "sorting_display_type": settings.SORTING_DISPLAY_TYPE,
            "data_displayed_sorting_fields": settings.DATA_DISPLAYED_SORTING_FIELDS,
            "default_date_toggle_value": settings.DEFAULT_DATE_TOGGLE_VALUE,
        }
        context.update(request)
        context.update({"query": query})

        # render html results
        html_template = loader.get_template(
            join(
                "core_explore_common_app",
                "user",
                "results",
                "data_sources_results.html",
            )
        )
        html_results_holders = html_template.render(context)

        response_dict = {"results": html_results_holders}
        return HttpResponse(json.dumps(response_dict), content_type="application/json")
    except Exception as e:
        return HttpResponseBadRequest(escape(str(e)))
예제 #4
0
def set_blob_pid(sender, document, **kwargs):
    if not pid_settings_api.get().auto_set_pid:
        return

    # Register new PID for the saved Blob.
    sub_url = reverse(
        "core_linked_records_provider_record",
        kwargs={
            "provider": "local",
            "record": settings.ID_PROVIDER_PREFIX_BLOB,
        },
    )
    pid_response = send_post_request(
        f"{settings.SERVER_URI}{sub_url}?format=json")
    blob_pid = json.loads(pid_response.content)["url"]

    blob_api.set_pid_for_blob(document.id, blob_pid)
예제 #5
0
    def get(self, request):
        """Retrieve the settings for the PID system

        Args:
            request:

        Returns:
        """
        pid_settings = pid_settings_api.get()

        return Response(
            {
                "xpath": settings.PID_XPATH,
                "format": settings.PID_FORMAT,
                "systems": list(settings.ID_PROVIDER_SYSTEMS.keys()),
                "prefixes": settings.ID_PROVIDER_PREFIXES,
                "auto_set_pid": pid_settings.auto_set_pid,
            },
            status=status.HTTP_200_OK,
        )
예제 #6
0
def set_data_pid(sender, document, **kwargs):
    """Set the PID in the XML field specified in the settings. If the PID
    already exists and is valid, it is not reset.

    Params:
        sender:
        document:
        kwargs:

    Returns:
    """
    if not pid_settings_api.get().auto_set_pid:
        return

    pid_xpath = get_xpath_from_dot_notation(PID_XPATH)

    # Retrieve namespaces
    xml_tree = XSDTree.build_tree(document.xml_content)
    pid_xpath, namespaces = get_xpath_with_target_namespace(
        pid_xpath, document.template.content
    )

    try:  # Get the PID from the `pid_xpath` value
        document_pid = get_value_at_xpath(xml_tree, pid_xpath, namespaces)
        if type(document_pid) == str and document_pid.endswith(
            "/"
        ):  # Cleanup PID if it ends with a '/'
            document_pid = document_pid[:-1]
    except AssertionError:  # PID XPath not found in document
        try:  # Try to create the element at the given PID
            # Import libs that need to wait for apps to be ready
            from core_main_app.components.data import api as data_api

            modified_xml_tree = create_tree_from_xpath(pid_xpath, xml_tree, namespaces)
            set_value_at_xpath(
                modified_xml_tree, pid_xpath, "http://sample_pid.org", namespaces
            )
            document.xml_content = XSDTree.tostring(modified_xml_tree)
            data_api.check_xml_file_is_valid(document)

            # Replace the current by the modified tree (containing mock PID) and
            # force document PID to be regenerated.
            xml_tree = modified_xml_tree
            document_pid = None
        except Exception as exc:  # Cannot create PID at given XPath
            LOGGER.warning("Cannot create PID at %s: %s" % (pid_xpath, str(exc)))
            return

    # Identify provider name for registration and ensure the PID has not been
    # already defined in another document.
    provider_manager = ProviderManager()

    # Retrieve previous PID and remove it from DB.
    if document.pk is not None:
        previous_pid = system_api.get_pid_for_data(document.pk)

        previous_provider_name = provider_manager.find_provider_from_pid(previous_pid)
        previous_provider = provider_manager.get(previous_provider_name)
        previous_pid_url = previous_pid.replace(
            previous_provider.provider_url, previous_provider.local_url
        )

        previous_pid_delete_response = send_delete_request(
            "%s?format=json" % previous_pid_url
        )

        # Log any error that happen during PID deletion
        if previous_pid_delete_response.status_code != HTTP_200_OK:
            LOGGER.warning(
                "Deletion of PID %s returned %s"
                % (previous_pid, previous_pid_delete_response.status_code)
            )

    if document_pid is None or document_pid == "":  # PID field left blank
        # Select the default provider if no PID has been chosen.
        provider_name = list(settings.ID_PROVIDER_SYSTEMS.keys())[0]
        document_pid = join(
            provider_manager.get(provider_name).provider_url,
            settings.ID_PROVIDER_PREFIX_DEFAULT,
        )
    else:  # PID specified in document.
        # Check that the PID is not defined for a document other than the current
        # document.
        if system_api.is_pid_defined(document_pid) and (
            document.pk is None
            or not system_api.is_pid_defined_for_document(document_pid, document.pk)
        ):
            raise exceptions.ModelError("PID already defined for another document")

        provider_name = provider_manager.find_provider_from_pid(document_pid)

    # PID specified but not matching any possible provider URLs for the
    # generation.
    if provider_name is None:
        raise exceptions.ModelError("Invalid PID provided")

    provider = provider_manager.get(provider_name)
    registration_url = document_pid.replace(provider.provider_url, provider.local_url)

    document_pid_response = send_post_request("%s?format=json" % registration_url)

    if document_pid_response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR:
        default_error_message = "An error occurred while creating the PID"
        try:
            raise exceptions.ModelError(
                document_pid_response.json().get("message", default_error_message)
            )
        except ValueError:  # If the response is not JSON parsable
            raise exceptions.ModelError(default_error_message)

    if (
        document_pid_response.status_code != status.HTTP_201_CREATED
        and document_pid_response.status_code != status.HTTP_200_OK
        and system_api.get_data_by_pid(document_pid).pk != document.pk
    ):
        raise exceptions.ModelError("Invalid PID provided")

    # FIXME assert the value is not changed when saving
    document_pid = document_pid_response.json()["url"]

    # Set the document PID into XML data and update `xml_content`
    set_value_at_xpath(xml_tree, pid_xpath, document_pid, namespaces)
    document.xml_content = XSDTree.tostring(xml_tree)

    # Update the whole document with the updated XML content
    document.convert_to_file()
    document.convert_to_dict()
예제 #7
0
    def _load_assets(self):
        assets = {
            "js": [
                {
                    "path": "core_main_app/common/js/XMLTree.js",
                    "is_raw": False
                },
                {
                    "path":
                    "core_main_app/common/js/modals/error_page_modal.js",
                    "is_raw": True,
                },
                {
                    "path": "core_main_app/common/js/debounce.js",
                    "is_raw": False
                },
                {
                    "path": "core_explore_common_app/user/js/results.js",
                    "is_raw": False
                },
                {
                    "path": "core_explore_common_app/user/js/results.raw.js",
                    "is_raw": True,
                },
                {
                    "path": "core_main_app/user/js/sharing_modal.js",
                    "is_raw": False
                },
                {
                    "path":
                    "core_explore_common_app/user/js/persistent_query_config.js",
                    "is_raw": False,
                },
                {
                    "path":
                    "core_explore_common_app/user/js/sorting_{0}_criteria.js".
                    format(settings.SORTING_DISPLAY_TYPE),
                    "is_raw":
                    False,
                },
            ],
            "css": [
                "core_main_app/common/css/XMLTree.css",
                "core_explore_common_app/user/css/query_result.css",
                "core_explore_common_app/user/css/results.css",
                "core_explore_common_app/user/css/toggle.css",
            ],
        }

        # Add assets needed for the exporters
        if "core_exporters_app" in settings.INSTALLED_APPS:
            # add all assets needed
            assets["js"].extend([{
                "path":
                "core_exporters_app/user/js/exporters/list/modals/list_exporters_selector.js",
                "is_raw": False,
            }])

        # Add assets needed for the file preview
        if "core_file_preview_app" in settings.INSTALLED_APPS:
            assets["js"].extend([{
                "path": "core_file_preview_app/user/js/file_preview.js",
                "is_raw": False,
            }])
            assets["css"].append(
                "core_file_preview_app/user/css/file_preview.css")

        # Add assets needed for the PID sharing
        if "core_linked_records_app" in settings.INSTALLED_APPS:
            from core_linked_records_app.components.pid_settings import (
                api as pid_settings_api, )

            if pid_settings_api.get().auto_set_pid:
                assets["js"].extend([{
                    "path":
                    "core_linked_records_app/user/js/sharing/explore.js",
                    "is_raw": False,
                }])
                assets["css"].append(
                    "core_linked_records_app/user/css/sharing.css")

        return assets
예제 #8
0
def build_page(data_object, display_admin_version=False):
    """Generic page building data

    Args:
        data_object:
        display_admin_version:

    Returns:
    """
    page_info = {
        "error": None,
        "context": dict(),
        "assets": dict(),
        "modals": list(),
    }

    try:
        display_xslt_selector = True
        try:
            template_xsl_rendering = template_xsl_rendering_api.get_by_template_id(
                data_object.template.id
            )
            xsl_transformation_id = (
                template_xsl_rendering.default_detail_xslt.id
                if template_xsl_rendering.default_detail_xslt
                else None
            )
            if not template_xsl_rendering.list_detail_xslt or (
                template_xsl_rendering.default_detail_xslt is not None
                and len(template_xsl_rendering.list_detail_xslt) == 1
            ):
                display_xslt_selector = False

            if xsl_transformation_id is not None:
                xsl_transformation_id = ObjectId(xsl_transformation_id)
        except Exception as exception:
            logger.warning(
                "An exception occured when retrieving XSLT: %s" % str(exception)
            )
            display_xslt_selector = False
            template_xsl_rendering = None
            xsl_transformation_id = None

        page_info["context"] = {
            "data": data_object,
            "share_pid_button": False,
            "template_xsl_rendering": template_xsl_rendering,
            "xsl_transformation_id": xsl_transformation_id,
            "can_display_selector": display_xslt_selector,
        }

        page_info["assets"] = {
            "js": [
                {"path": "core_main_app/common/js/XMLTree.js", "is_raw": False},
                {"path": "core_main_app/user/js/data/detail.js", "is_raw": False},
                {
                    "path": "core_main_app/user/js/data/change_display.js",
                    "is_raw": False,
                },
            ],
            "css": ["core_main_app/common/css/XMLTree.css"],
        }

        if "core_file_preview_app" in settings.INSTALLED_APPS:
            page_info["assets"]["js"].extend(
                [
                    {
                        "path": "core_file_preview_app/user/js/file_preview.js",
                        "is_raw": False,
                    }
                ]
            )
            page_info["assets"]["css"].append(
                "core_file_preview_app/user/css/file_preview.css"
            )
            page_info["modals"].append(
                "core_file_preview_app/user/file_preview_modal.html"
            )

        if (
            "core_linked_records_app" in settings.INSTALLED_APPS
            and not display_admin_version
        ):
            from core_linked_records_app.components.pid_settings import (
                api as pid_settings_api,
            )

            if pid_settings_api.get().auto_set_pid:
                page_info["context"]["share_pid_button"] = True
                page_info["assets"]["js"].extend(
                    [
                        {
                            "path": "core_main_app/user/js/sharing_modal.js",
                            "is_raw": False,
                        },
                        {
                            "path": "core_linked_records_app/user/js/sharing/data_detail.js",
                            "is_raw": False,
                        },
                    ]
                )
                page_info["modals"].append(
                    "core_linked_records_app/user/sharing/data_detail/modal.html"
                )
    except exceptions.DoesNotExist:
        page_info["error"] = "Data not found"
    except exceptions.ModelError:
        page_info["error"] = "Model error"
    except Exception as e:
        page_info["error"] = str(e)
    finally:
        return page_info