Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

subcommunities: add invitation request #1067

Merged
merged 9 commits into from
Nov 28, 2024
6 changes: 3 additions & 3 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions invenio.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ from zenodo_rdm.queryparser import word_communities, word_doi
from zenodo_rdm.subcommunities import (
ZenodoSubCommunityRequest,
ZenodoSubcommunityRequestSchema,
ZenodoSubCommunityInvitationRequest
)
from zenodo_rdm.tokens import RATSubjectSchema
from zenodo_rdm.views import frontpage_view_function
Expand Down Expand Up @@ -1049,6 +1050,9 @@ COMMUNITIES_SUB_SERVICE_SCHEMA = ZenodoSubcommunityRequestSchema
COMMUNITIES_SUB_REQUEST_CLS = ZenodoSubCommunityRequest
"""Request type for subcommunities."""

COMMUNITIES_SUB_INVITATION_REQUEST_CLS = ZenodoSubCommunityInvitationRequest
"""Request type for subcommunity invitations."""

ANNOSTOR_COMMUNITIES = {}
"""Annostor communities configuration.

Expand Down
4 changes: 4 additions & 0 deletions scripts/sleep.py
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😴

Copy link
Member

@slint slint Nov 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh no, my infamous sleep.py script for deployment shenanigans 😱

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛌

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import time

while True:
time.sleep(60 * 60)
3 changes: 2 additions & 1 deletion site/zenodo_rdm/legacy/requests/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-

Check failure on line 1 in site/zenodo_rdm/legacy/requests/utils.py

View workflow job for this annotation

GitHub Actions / Python (site, 3.9, postgresql14, opensearch2)

Black format check --- /home/runner/work/zenodo-rdm/zenodo-rdm/site/zenodo_rdm/legacy/requests/utils.py 2024-11-28 10:35:52.704725+00:00 +++ /home/runner/work/zenodo-rdm/zenodo-rdm/site/zenodo_rdm/legacy/requests/utils.py 2024-11-28 10:43:37.669462+00:00 @@ -10,12 +10,11 @@ from datetime import datetime, timedelta from invenio_access.permissions import system_identity from invenio_records.dictutils import dict_lookup from invenio_records_resources.services.uow import unit_of_work -from invenio_requests import (current_request_type_registry, - current_requests_service) +from invenio_requests import current_request_type_registry, current_requests_service from invenio_requests.resolvers.registry import ResolverRegistry from invenio_search.engine import dsl from .community_manage_record import CommunityManageRecord from .record_upgrade import LegacyRecordUpgrade

Check failure on line 1 in site/zenodo_rdm/legacy/requests/utils.py

View workflow job for this annotation

GitHub Actions / Python (site, 3.9, postgresql14, opensearch2)

isort-check from invenio_access.permissions import system_identity from invenio_records.dictutils import dict_lookup from invenio_records_resources.services.uow import unit_of_work -from invenio_requests import (current_request_type_registry, - current_requests_service) +from invenio_requests import current_request_type_registry, current_requests_service from invenio_requests.resolvers.registry import ResolverRegistry from invenio_search.engine import dsl
#
# Copyright (C) 2023 CERN.
#
Expand All @@ -12,7 +12,8 @@
from invenio_access.permissions import system_identity
from invenio_records.dictutils import dict_lookup
from invenio_records_resources.services.uow import unit_of_work
from invenio_requests import current_request_type_registry, current_requests_service
from invenio_requests import (current_request_type_registry,
current_requests_service)
from invenio_requests.resolvers.registry import ResolverRegistry
from invenio_search.engine import dsl

Expand Down
2 changes: 2 additions & 0 deletions site/zenodo_rdm/subcommunities/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-

Check failure on line 1 in site/zenodo_rdm/subcommunities/__init__.py

View workflow job for this annotation

GitHub Actions / Python (site, 3.9, postgresql14, opensearch2)

isort-check # it under the terms of the MIT License; see LICENSE file for more details. """Subcommunities implementation.""" -from .request import ZenodoSubCommunityRequest -from .request import ZenodoSubCommunityInvitationRequest +from .request import ZenodoSubCommunityInvitationRequest, ZenodoSubCommunityRequest from .schema import ZenodoSubcommunityRequestSchema __all__ = (
#
# Copyright (C) 2024 CERN.
#
Expand All @@ -7,9 +7,11 @@
"""Subcommunities implementation."""

from .request import ZenodoSubCommunityRequest
from .request import ZenodoSubCommunityInvitationRequest
from .schema import ZenodoSubcommunityRequestSchema

__all__ = (
"ZenodoSubcommunityRequestSchema",
"ZenodoSubCommunityRequest",
"ZenodoSubCommunityInvitationRequest",
)
139 changes: 127 additions & 12 deletions site/zenodo_rdm/subcommunities/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,19 @@
# it under the terms of the MIT License; see LICENSE file for more details.
"""Subcommunities request implementation for ZenodoRDM."""

import invenio_communities.notifications.builders as notifications
from invenio_access.permissions import system_identity
from invenio_communities.proxies import current_communities
from invenio_communities.subcommunities.services.request import (
AcceptSubcommunity,
AcceptSubcommunityInvitation,
CreateSubcommunityInvitation,
DeclineSubcommunity,
DeclineSubcommunityInvitation,
SubCommunityInvitationRequest,
SubCommunityRequest,
)
from invenio_notifications.services.uow import NotificationOp
from invenio_rdm_records.proxies import (
current_community_records_service,
current_rdm_records,
Expand All @@ -23,28 +30,28 @@
from marshmallow import fields


def _add_community_records(child, parent, uow):
"""Add records from child to parent."""
records = current_community_records_service.search(
system_identity, community_id=child
)
current_rdm_records.record_communities_service.bulk_add(
system_identity, parent, (x["id"] for x in records), uow=uow
)


class SubcommunityAcceptAction(AcceptSubcommunity):
"""Represents an accept action used to accept a subcommunity.

Zenodo re-implementation of the accept action, to also move the records.
"""

def _get_community_records(self, community_id):
"""Get the records of a community."""
return current_community_records_service.search(
system_identity, community_id=community_id
)

def execute(self, identity, uow):
"""Execute approve action."""
to_be_moved = self.request.topic.resolve().id
move_to = self.request.receiver.resolve().id

# Move records
records = self._get_community_records(to_be_moved)
current_rdm_records.record_communities_service.bulk_add(
system_identity, move_to, (x["id"] for x in records), uow=uow
)
_add_community_records(to_be_moved, move_to, uow)
super().execute(identity, uow)


Expand Down Expand Up @@ -113,8 +120,116 @@ class ZenodoSubCommunityRequest(SubCommunityRequest):

available_actions = {
"delete": actions.DeleteAction,
"create": SubcommunityCreateAction,
"cancel": actions.CancelAction,
# Custom implemented actions
slint marked this conversation as resolved.
Show resolved Hide resolved
"create": SubcommunityCreateAction,
"accept": SubcommunityAcceptAction,
"decline": DeclineSubcommunity,
}


class SubcommunityInvitationCreateAction(CreateSubcommunityInvitation):
"""Represents an action to create and submit a subcommunity invitation."""

def execute(self, identity, uow):
"""Execute approve action."""
self.request["title"] = "Invitation to join the EU Open Research Repository"

# example: "May 11, 2024"
expires_at = self.request.expires_at.strftime("%B %d, %Y")
NAME = self.request.get("payload", {}).get("community-name")
ACRONYM = self.request.get("payload", {}).get("project-acronym")
self.request["description"] = (
slint marked this conversation as resolved.
Show resolved Hide resolved
"<p>We would like to invite you to join the <a href='https://zenodo.org/communities/eu/'>"
"EU Open Research Repository</a> because we have detected that your Zenodo community "
"is likely related to an EU-funded project:</br><ul><li>Zenodo community: "
f"{NAME}</li><li>EU-funded project: {ACRONYM}</li></ul>The EU Open "
"Research Repository is a Zenodo community dedicated to fostering open science "
"and enhancing the visibility and accessibility of research outputs funded by "
"the European Union. The community is managed by CERN on behalf of the European "
"Commission.</br></br><b>What does it mean to join?</b></br><ul><li><b>Indexing:</b> "
"All current and future records in your community will be automatically indexed "
"in the EU Open Research Repository increasing their visibility</li><li><b>Curation:</b> "
"All records will be subject to the EU Open Research Repository "
"<a href='https://zenodo.org/communities/eu/curation-policy'>curation policy</a>. "
"For instance, you can only deposit records in the community related to the EU-funded "
"project</li><li><b>Verified:</b> All EU project communities are marked with a "
"Verified community badge</li></ul>The EU Open Research Repository is gradually "
"being improved and by mid-2025 new submissions will automatically be checked "
"for compliance with the related open science requirements in the Horizon Europe "
"grant agreement. For more information see <a href='https://zenodo.org/communities/eu/pages/join'>"
"https://zenodo.org/communities/eu/pages/join</a>.</br></br><b>Which EU-funded projects "
"have already joined?</b></br>You can browse the "
"<a href='https://zenodo.org/communities/eu/browse/subcommunities'>EU-funded projects</a> "
"which have already already joined.</br></br><b>When should I decline the invitation "
"to join?</b></br>You should <b>decline</b> this invitation if your Zenodo community "
"is not related to the above mentioned EU-funded project, or if the community is used "
"for multiple purposes (e.g both an organisation and a project).</br></br><b>"
"Further questions?</b></br>Don't hesitate to get in <a href='https://zenodo.org/support'>"
"touch with us</a> if you have any questions.</br></br>The request will be automatically "
f"accepted on <b>{expires_at}</b> in case you do not accept or decline the request by then."
"</br></br>Your sincerely,</br>The Zenodo team"
)

super().execute(identity, uow)


class SubCommunityInvitationAcceptAction(AcceptSubcommunityInvitation):
"""Represents an accept action used to accept a subcommunity.

Zenodo re-implementation of the accept action, to also move the records.
"""

def execute(self, identity, uow):
"""Execute approve action."""
child = self.request.receiver.resolve().id
parent = self.request.created_by.resolve().id

_add_community_records(child, parent, uow)
# moving the community is handled by super()

super().execute(identity, uow)


class SubcommunityInvitationExpireAction(actions.ExpireAction):
"""Expire action."""

def execute(self, identity, uow):
"""Execute expire action."""
child = self.request.receiver.resolve().id
parent = self.request.created_by.resolve().id

_add_community_records(child, parent, uow)
slint marked this conversation as resolved.
Show resolved Hide resolved

current_communities.service.bulk_update_parent(
system_identity, [child], parent_id=parent, uow=uow
)

super().execute(identity, uow)

uow.register(
NotificationOp(
notifications.SubComInvitationExpire.build(
identity=identity, request=self.request
)
)
)


class ZenodoSubCommunityInvitationRequest(SubCommunityInvitationRequest):
"""Request from a Zenodo community to add a child community."""

payload_schema = {
"community-name": fields.String(required=True),
"project-acronym": fields.String(required=True),
}

available_actions = {
"delete": actions.DeleteAction,
"cancel": actions.CancelAction,
# Custom implemented actions
"create": SubcommunityInvitationCreateAction,
"accept": SubCommunityInvitationAcceptAction,
"decline": DeclineSubcommunityInvitation,
"expire": SubcommunityInvitationExpireAction,
}
Loading