Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 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
485 changes: 484 additions & 1 deletion tests/test_contributors_views.py

Large diffs are not rendered by default.

27 changes: 19 additions & 8 deletions website/profile/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def get_profile_image_url(user, size=settings.PROFILE_IMAGE_MEDIUM):
use_ssl=True,
size=size)

def serialize_user(user, node=None, admin=False, full=False, is_profile=False, include_node_counts=False):
def serialize_user(user, node=None, admin=False, full=False, is_profile=False, include_node_counts=False, invite_date=None, include_email=False):
"""
Return a dictionary representation of a registered user.

Expand All @@ -30,7 +30,11 @@ def serialize_user(user, node=None, admin=False, full=False, is_profile=False, i
contrib = user
user = contrib.user
fullname = user.display_full_name(node=node)
idp_attrs = user.get_idp_attr()
institution = None
prefetch_cache = getattr(user, '_prefetched_objects_cache', {})
if 'affiliated_institutions' in prefetch_cache:
affiliated = list(user.affiliated_institutions.all())
institution = sorted(affiliated, key=lambda i: i.pk)[0] if affiliated else None
ret = {
'id': str(user._id),
'primary_key': user.id,
Expand All @@ -41,8 +45,11 @@ def serialize_user(user, node=None, admin=False, full=False, is_profile=False, i
'profile_image_url': user.profile_image_url(size=settings.PROFILE_IMAGE_MEDIUM),
'active': user.is_active,
'have_email': user.have_email,
'idp_email': idp_attrs.get('email'),
'affiliation': institution.name if institution else '',
'invite_date': invite_date,
}
if include_email:
ret['email'] = user.username if user.have_email else ''
if node is not None:
if admin:
flags = {
Expand Down Expand Up @@ -72,6 +79,8 @@ def serialize_user(user, node=None, admin=False, full=False, is_profile=False, i
if full:
# Add emails
if is_profile:
idp_attrs = user.get_idp_attr()
ret['idp_email'] = idp_attrs.get('email')
ret['emails'] = [
{
'address': each,
Expand Down Expand Up @@ -151,11 +160,13 @@ def serialize_user(user, node=None, admin=False, full=False, is_profile=False, i
return ret


def serialize_contributors(contribs, node, **kwargs):
return [
serialize_user(contrib, node, **kwargs)
for contrib in contribs.iterator()
]
def serialize_contributors(contribs, node, invite_dates=None, **kwargs):
result = []
for contrib in contribs:
user_obj = contrib.user if isinstance(contrib, Contributor) else contrib
date = invite_dates.get(user_obj._id) if invite_dates else None
result.append(serialize_user(contrib, node, invite_date=date, **kwargs))
return result


def serialize_visible_contributors(node):
Expand Down
55 changes: 51 additions & 4 deletions website/project/views/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,17 +520,64 @@ def node_choose_addons(auth, node, **kwargs):
node.config_addons(request.json, auth)


def _get_contributor_invite_dates(node, contributor_guids):
invite_dates = {}

# Include admin_contributor_added to cover proxy-registration additions (代理登録)
for log in NodeLog.objects.filter(
node=node,
action__in=[NodeLog.CONTRIB_ADDED, NodeLog.ADMIN_CONTRIB_ADDED],
).order_by('date').values('date', 'params'):
for user_guid in log['params'].get('contributors', []):
if isinstance(user_guid, str):
invite_dates[user_guid] = log['date'].strftime('%Y-%m-%d')

node_created = node.created.strftime('%Y-%m-%d')

# Fallback for contributors with no log entry (e.g. project creator, contributors inherited
# from a parent when creating a component). Uses the node creation date as the invite date.
for guid in contributor_guids:
if guid not in invite_dates:
invite_dates[guid] = node_created

return invite_dates


@must_be_valid_project
@must_not_be_retracted_registration
@must_have_permission(READ)
@ember_flag_is_active(features.EMBER_PROJECT_CONTRIBUTORS)
def node_contributors(auth, node, **kwargs):
ret = _view_project(node, auth, primary=True)
contribs = node.contributor_set.include('user__groups', 'user__guids', 'user__ext')
ret['contributors'] = utils.serialize_contributors(contribs, node)
is_admin = node.has_permission(auth.user, ADMIN)

contrib_includes = ['user__groups', 'user__guids', 'user__ext']
admin_includes = ['groups', 'guids', 'ext']
if is_admin:
contrib_includes.append('user__affiliated_institutions')
admin_includes.append('affiliated_institutions')

contribs = node.contributor_set.include(*contrib_includes)
admin_contribs = node.parent_admin_contributors.include(*admin_includes)

invite_dates = None
admin_invite_dates = None
if is_admin:
contribs = list(contribs)
admin_contribs = list(admin_contribs)
invite_dates = _get_contributor_invite_dates(node, [c.user._id for c in contribs])
node_created = node.created.strftime('%Y-%m-%d')
admin_invite_dates = {u._id: node_created for u in admin_contribs}

ret['contributors'] = utils.serialize_contributors(
contribs, node, invite_dates=invite_dates, include_email=is_admin
)
ret['access_requests'] = utils.serialize_access_requests(node)
admin_contribs = node.parent_admin_contributors.include('groups', 'guids', 'ext')
ret['adminContributors'] = utils.serialize_contributors(admin_contribs, node, admin=True)
ret['adminContributors'] = utils.serialize_contributors(
admin_contribs, node, admin=True,
invite_dates=admin_invite_dates, include_email=is_admin
)

return ret


Expand Down
16 changes: 13 additions & 3 deletions website/templates/project/contributors.mako
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@
data-bind="css: {sortable: ($data === 'contrib' && $root.isSortable())}" style="min-width: 100px;white-space: nowrap;">${_("Name")}
</th>
<th style="min-width: 140px;width: 200px;white-space: nowrap;"></th>
% if permissions.ADMIN in user['permissions']:
<th style="min-width: 180px;width: 220px;white-space: nowrap;">${_("E-mail")}</th>
<th style="min-width: 180px;width: 220px;white-space: nowrap;">${_("Affiliation")}</th>
<th style="min-width: 90px;width: 100px;white-space: nowrap;">${_("Invite Date")}</th>
% endif
<th style="min-width: 150px;width: 160px;white-space: nowrap;">
${_("Permissions")}
<i class="fa fa-question-circle permission-info"
Expand All @@ -192,8 +197,8 @@
data-html="true"
></i>
</th>
<th class="biblio-contrib" style="min-width:144px;white-space: nowrap;">
${_("Bibliographic Contributor")}
<th class="biblio-contrib" style="min-width:100px;width:110px;white-space: nowrap;">
${_("Bibliographic Title")}
<i class="fa fa-question-circle visibility-info"
data-toggle="popover"
data-title="${_('Bibliographic Contributor Information')}"
Expand Down Expand Up @@ -240,7 +245,7 @@
></i>
</th>
<th class="biblio-contrib">
${_("Bibliographic Contributor")}
${_("Bibliographic Title")}
<i class="fa fa-question-circle visibility-info"
data-toggle="popover"
data-title="${_('Bibliographic Contributor Information')}"
Expand Down Expand Up @@ -290,6 +295,11 @@
<a class="name-search" data-bind="text: contributor.shortname, attr:{href: profileUrl}"></a>
</span>
</td>
% if permissions.ADMIN in user['permissions']:
<td class="table-only" data-bind="text: contributor.email || '-'"></td>
<td class="table-only" data-bind="text: contributor.affiliation || '-'"></td>
<td class="table-only" data-bind="text: contributor.invite_date || '-'"></td>
% endif
<td class="permissions">
<div class="header" data-bind="visible: contributor.expanded() && $root.collapsed()"></div>
<div class="td-content" data-bind="visible: !$root.collapsed() || contributor.expanded()">
Expand Down
2 changes: 1 addition & 1 deletion website/templates/project/modal_add_contributor.mako
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@
<th width="10%"></th>
<th width="30%">${_("Name")}</th>
<th>
${_("Bibliographic Contributor")}
${_("Bibliographic Title")}
<i class="fa fa-question-circle visibility-info"
data-toggle="popover"
data-title="${_('Bibliographic Contributor Information')}"
Expand Down
4 changes: 4 additions & 0 deletions website/translations/en/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -2867,6 +2867,10 @@ msgstr ""
msgid "Bibliographic"
msgstr ""

#: website/templates/project/contributors.mako
msgid "Bibliographic Title"
msgstr "Bibliographic"

#: website/templates/project/contributors.mako:46
msgid "Non-Bibliographic"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions website/translations/ja/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -3308,6 +3308,10 @@ msgstr "目録表示メンバーの情報"
msgid "Bibliographic"
msgstr "目録で表示"

#: website/templates/project/contributors.mako
msgid "Bibliographic Title"
msgstr "目録表示"

#: website/templates/project/contributors.mako:46
msgid "Non-Bibliographic"
msgstr "目録で非表示"
Expand Down
Loading