Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions assets/less/cds-rdm/globals/site.overrides
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,27 @@
width: 100px;
}

.theme-default{
.rdm-logo{
padding: 0.3em .3em .3em 0;
}

}


.theme-default{
#invenio-nav.ui.menu .ui.menu .item.active{
background-color: #FFFFFF;
}
}

.outer-navbar {
z-index: 1;
background-color: transparent !important;

&.theme-default {
background-color: #3b4a5717 !important;
}
& > * {
z-index: 3;
position: relative;
Expand Down
15 changes: 14 additions & 1 deletion invenio.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ from datetime import datetime, timedelta
from invenio_i18n import lazy_gettext as _

from cds_rdm import schemes
from cds_rdm.communities.views import communities_home
from cds_rdm.custom_fields import CUSTOM_FIELDS, CUSTOM_FIELDS_UI, NAMESPACES
from cds_rdm.permissions import (
CDSCommunitiesPermissionPolicy,
Expand All @@ -25,7 +26,9 @@ from cds_rdm.inspire_harvester.reader import InspireHTTPReader
from cds_rdm.inspire_harvester.transformer import InspireJsonTransformer
from cds_rdm.inspire_harvester.writer import InspireWriter
from celery.schedules import crontab
from invenio_app_rdm.config import STATS_EVENTS as _APP_RDM_STATS_EVENTS, STATS_AGGREGATIONS as _APP_RDM_STATS_AGGREGATIONS, APP_RDM_ROUTES
from invenio_app_rdm.config import STATS_EVENTS as _APP_RDM_STATS_EVENTS, \
STATS_AGGREGATIONS as _APP_RDM_STATS_AGGREGATIONS, APP_RDM_ROUTES, \
RDM_COMMUNITIES_ROUTES
from invenio_vocabularies.services.custom_fields import VocabularyCF
from invenio_records_resources.services.custom_fields import KeywordCF
from invenio_rdm_records.config import (
Expand Down Expand Up @@ -463,3 +466,13 @@ _APP_RDM_STATS_EVENTS["record-view"]["params"]["suffix"] = "%Y"
# Override the index_interval to be year
_APP_RDM_STATS_AGGREGATIONS["file-download-agg"]["params"]["index_interval"] = "year"
_APP_RDM_STATS_AGGREGATIONS["record-view-agg"]["params"]["index_interval"] = "year"


# Branded Communities
# ===================


RDM_COMMUNITIES_ROUTES["community-home"] = (
"/communities/<pid_value>/",
communities_home,
)
7 changes: 7 additions & 0 deletions site/cds_rdm/communities/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019-2025 CERN.
#
# Invenio App RDM is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
"""Community views module."""
167 changes: 167 additions & 0 deletions site/cds_rdm/communities/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019-2025 CERN.
#
# CDS-RDM is free software; you can redistribute it and/or modify it
# under the terms of the MIT License; see LICENSE file for more details.
"""Community views module."""

from flask import g, redirect, request, url_for
from invenio_communities.views.communities import (
HEADER_PERMISSIONS,
render_community_theme_template,
)
from invenio_communities.views.decorators import pass_community
from invenio_rdm_records.proxies import (
current_community_records_service,
current_rdm_records,
)
from invenio_rdm_records.resources.serializers import UIJSONSerializer
from invenio_records_resources.services.errors import PermissionDeniedError


def publications_metric_blr(results):
"""Publications metric for BLR."""
resource_types = results._results.aggregations.resource_types.buckets
valid_pubication_types = [
"publication-article",
"publication-book",
"publication-section",
"publication-datamanagementplan",
]
publications = 0
for resource_type in resource_types:
if resource_type.key in valid_pubication_types:
publications += resource_type.doc_count
return publications


def images_metric_blr(results):
"""Images metric for BLR."""
resource_types = results._results.aggregations.resource_types.buckets
images = 0
for resource_type in resource_types:
if resource_type.key.startswith("image"):
images += resource_type.doc_count
return images


def treatments_metric_blr(results):
"""Treatments metric for BLR."""
resource_types = results._results.aggregations.resource_types.buckets
for resource_type in resource_types:
if resource_type.key == "publication-taxonomictreatment":
return resource_type.doc_count


def tables_metric_blr(results):
"""Tables metric for BLR."""
resource_types = results._results.aggregations.resource_types.buckets
for resource_type in resource_types:
if resource_type.key == "dataset":
return resource_type.doc_count


METRICS = {
"total_grants": {
"name": "total_grants",
"type": "cardinality",
"kwargs": {"field": "metadata.funding.award.id"},
},
"total_data": {
"name": "total_data",
"type": "sum",
"kwargs": {"field": "files.totalbytes"},
},
"total_views": {
"name": "total_views",
"type": "sum",
"kwargs": {"field": "stats.all_versions.unique_views"},
},
"total_downloads": {
"name": "total_downloads",
"type": "sum",
"kwargs": {"field": "stats.all_versions.unique_downloads"},
},
"resource_types": {
"name": "resource_types",
"type": "terms",
"kwargs": {"field": "metadata.resource_type.id"},
},
}


THEME_METRICS = {
"horizon": {"total_data": "total_data", "total_grants": "total_grants"},
"biosyslit": {
"total_views": "total_views",
"total_downloads": "total_downloads",
"publications": publications_metric_blr,
"images": images_metric_blr,
"tables": tables_metric_blr,
"treatments": treatments_metric_blr,
},
}


def _get_metric_from_search(result, metric):
"""Get metric from search result."""
return result._results.aggregations[metric].value


@pass_community(serialize=True)
def communities_home(pid_value, community, community_ui):
"""Community home page."""
query_params = request.args
collections_service = current_rdm_records.collections_service
permissions = community.has_permissions_to(HEADER_PERMISSIONS)
if not permissions["can_read"]:
raise PermissionDeniedError()

theme_enabled = community._record.theme and community._record.theme.get(
"enabled", False
)

if query_params or not theme_enabled:
url = url_for(
"invenio_app_rdm_communities.communities_detail",
pid_value=community.data["slug"],
**request.args,
)
return redirect(url)

if theme_enabled:
recent_uploads = current_community_records_service.search(
community_id=pid_value,
identity=g.identity,
params={"sort": "newest", "size": 3, "metrics": METRICS},
expand=True,
)

collections = collections_service.list_trees(g.identity, community.id, depth=0)

# TODO resultitem does not expose aggregations except labelled facets
metrics = {
"total_records": recent_uploads.total,
}
for metric, getter in THEME_METRICS.get(
community._record.theme["brand"], {}
).items():
if type(getter) == str:
metrics[metric] = _get_metric_from_search(recent_uploads, getter)
else:
metrics[metric] = getter(recent_uploads) or 0

records_ui = UIJSONSerializer().dump_list(recent_uploads.to_dict())["hits"][
"hits"
]

return render_community_theme_template(
"invenio_communities/details/home/index.html",
theme=community_ui.get("theme", {}),
community=community_ui,
permissions=permissions,
records=records_ui,
metrics=metrics,
collections=collections.to_dict(),
)
156 changes: 156 additions & 0 deletions site/cds_rdm/templates/semantic-ui/cds_rdm/macro/record_item.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
{#
Copyright (C) 2024 CERN.

CDS-RDM is free software; you can redistribute it and/or modify it
under the terms of the MIT License; see LICENSE file for more details.
#}



{% macro record_item(record=None, themed_community=None, use_theme_banner=False) %}
<li class="item">
<div class="content">
{# Compute community theme styling #}
{# FIXME: Uncomment to enable themed banner #}
{# {% set themed_community = themed_community or (
(record.parent.communities.entries or [])
| selectattr("id", "==", record.parent.communities.default)
| first
) %} #}

{% set bg_style = "" %}
{% set font_style = "" %}
{% if use_theme_banner and themed_community %}
{% set style = themed_community.get("theme", {}).get("style") %}
{% if style.primaryColor %}
{% set bg_style = "background-color: " ~ style.primaryColor ~ ";" %}
{% set font_style = "color: " ~ style.primaryColor ~ ";" %}
{% endif %}
{% endif %}

{# Themed community banner #}
{% if use_theme_banner and themed_community.theme %}
<a href="/communities/{{ themed_community.slug }}"
class="ui label themed-community-label"
style="{{ bg_style }}"
>
{{ themed_community.metadata.title }}
<img src="/api/communities/{{ themed_community.slug }}/logo" alt class="ui image themed-community-logo right-floated">
</a>
{% endif %}
{# Top labels #}
<div class="extra labels-actions">
<div class="ui small horizontal primary theme-primary label" style="{{ bg_style }}">
{{ record.ui.publication_date_l10n_long }} ({{ record.ui.version }})
</div>
<div class="ui small horizontal neutral label">
{{ record.ui.resource_type.title_l10n }}
</div>

{% set access_status_id = record.ui.access_status.get("id", "open") %}
{% set access_status = record.ui.access_status.get("title_l10n", "Open") %}
{% set access_status_icon = record.ui.access_status.get("icon", "unlock") %}

<div class="ui small horizontal label access-status {{ access_status_id }}">
<i class="icon {{ access_status_icon }}" aria-hidden="true"></i>
{{ access_status }}
</div>
</div>

{# Title #}
<div class="header theme-primary-text">
<a href="/records/{{ record.id }}" style="{{ font_style }}">
{{ record.metadata.title }}
</a>
</div>

{# Creators #}
<div class="ui item creatibutors">
{% set creators_list = record.ui.creators.creators %}
{% set creators_sliced = creators_list[:3] %}

</div>

{# Description #}
<p class="description">
{% set description = record.ui.get("description_stripped", "") %}

{{ description | truncate(length=350, end='...') }}
</p>

<div class="extra">
<div class="flex justify-space-between align-items-end">
{# Publishing details #}
{% set created_date = record.ui.created_date_l10n_long %}
{% set publishing_journal = record.ui.publishing_information.get("journal") if record.ui.publishing_information %}
<div>
<p>
<small>
{% if created_date %}
{{ _("Uploaded on")}} {{ created_date }}
{% endif %}
</small>
</p>

{# Communities list #}
<p>
<small>
{% set communities_entries = record.parent.communities.entries %}
{# Filter out the themed community #}
{% if themed_community %}
{% set communities_entries = communities_entries | rejectattr("id", "==", themed_community.id) | list %}
{% endif %}

</small>
</p>
<p>
<small>
{% if publishing_journal %}
{{ _("Published in") }} {{ publishing_journal }}
{% endif %}
</small>
</p>

{# Versions info desktop/tablet #}
{% if record.versions.index > 1 %}
{% set num_versions = record.versions.index %}
{% set text_content = _("more versions exist for this record") %}
{% if num_versions == 2 %}
{% set text_content = _("more version exist for this record") %}
{% endif %}

<p>
<small>{{ record.versions.index - 1 }} {{ text_content }}</small>
</p>
{% endif %}
</div>

{# Statistics #}
{% set downloads = record.stats.all_versions.unique_downloads %}
{% set views = record.stats.all_versions.unique_views %}
<small class="flex align-items-center">
{% if views is defined %}
<div class="ui transparent label stats-popup stats-views" aria-label="{{ _('Views') }}">
<i class="ui eye icon" aria-hidden="true"></i>
{{ views }}
<div class="ui tiny popup" aria-hidden="true">
{{ _("Views") }}
</div>
</div>
{% endif %}

{% if downloads is defined %}
<div class="ui transparent label stats-popup stats-downloads" aria-label="{{ _('Downloads') }}">
<i class="ui download icon" aria-hidden="true"></i>
{{ downloads}}
<div class="ui tiny popup" aria-hidden="true">
{{ _("Downloads") }}
</div>
</div>
{% endif %}
</small>
</div>
</div>
</div>
</li>
{% endmacro %}
Loading
Loading