-
Notifications
You must be signed in to change notification settings - Fork 36
Add venue profile validation for invite assignment #2572
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
base: master
Are you sure you want to change the base?
Changes from 5 commits
3616db6
fac00fc
81bbf7b
a5cee13
147daa1
ce98253
68dcb36
6593141
bc1defd
3fb889a
2fb1b44
872b2f0
d31bf3b
2a1fe72
a19c1a3
7be2c90
9ac7803
406dfec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -97,6 +97,7 @@ def __init__(self, client, venue_id, support_user): | |||||||||
| self.iThenticate_plagiarism_check_exclude_custom_sections = False | ||||||||||
| self.iThenticate_plagiarism_check_exclude_small_matches = 8 | ||||||||||
| self.comment_notification_threshold = None | ||||||||||
| self.invited_reviewer_profile_minimum_requirements = {} | ||||||||||
|
|
||||||||||
| def get_id(self): | ||||||||||
| return self.venue_id | ||||||||||
|
|
@@ -1373,6 +1374,19 @@ def poll_ithenticate_for_status(self): | |||||||||
| @classmethod | ||||||||||
| def check_new_profiles(Venue, client): | ||||||||||
|
|
||||||||||
| def send_incomplete_profile_notification(venue_group, edge, submission, user_profile): | ||||||||||
| ## Send email to reviewer | ||||||||||
| subject=f"[{venue_group.content['subtitle']['value']}] Incomplete profile for paper {submission.number}" | ||||||||||
| message =f'''Hi {{{{fullname}}}}, | ||||||||||
| You have accepted the invitation to review the paper number: {submission.number}, title: {submission.content['title']['value']}. | ||||||||||
|
|
||||||||||
| However, your profile was found to be incomplete according to {venue_group.content['subtitle']['value']} standards and the assignment is pending your profile completion. Please review your venue's profile requirements and update your profile. | ||||||||||
|
|
||||||||||
| If you have any questions, please contact us as info@openreview.net. | ||||||||||
|
|
||||||||||
| OpenReview Team''' | ||||||||||
| response = client.post_message(subject, [edge.tail], message, invitation=venue_group.content['meta_invitation_id']['value'], signature=venue_group.id, replyTo=venue_group.content['contact']['value'], sender=venue_group.content['message_sender']['value']) | ||||||||||
|
|
||||||||||
| def mark_as_conflict(venue_group, edge, submission, user_profile): | ||||||||||
| edge.label='Conflict Detected' | ||||||||||
| edge.tail=user_profile.id | ||||||||||
|
|
@@ -1474,29 +1488,35 @@ def mark_as_accepted(venue_group, edge, submission, user_profile, invite_assignm | |||||||||
| active_venues = client.get_group('active_venues').members | ||||||||||
|
|
||||||||||
| for venue_id in active_venues: | ||||||||||
| # Create new client for each venue | ||||||||||
|
melisabok marked this conversation as resolved.
|
||||||||||
| venue_client = openreview.api.OpenReviewClient( | ||||||||||
| baseurl=openreview.tools.get_base_urls(client)[1], | ||||||||||
| token=client.token | ||||||||||
| ) | ||||||||||
| venue_client.impersonate(venue_id) | ||||||||||
|
|
||||||||||
| venue_group = client.get_group(venue_id) | ||||||||||
| venue_group = venue_client.get_group(venue_id) | ||||||||||
|
|
||||||||||
| if hasattr(venue_group, 'domain') and venue_group.content: | ||||||||||
|
|
||||||||||
| print(f'Check active venue {venue_group.id}') | ||||||||||
|
|
||||||||||
| edge_invitations = client.get_all_invitations(prefix=venue_id, type='edge') | ||||||||||
| edge_invitations = venue_client.get_all_invitations(prefix=venue_id, type='edge') | ||||||||||
| invite_assignment_invitations = [inv.id for inv in edge_invitations if inv.id.endswith('Invite_Assignment')] | ||||||||||
|
|
||||||||||
| for invite_assignment_invitation_id in invite_assignment_invitations: | ||||||||||
|
|
||||||||||
| ## check if it is expired? | ||||||||||
| invite_assignment_invitation = openreview.tools.get_invitation(client, invite_assignment_invitation_id) | ||||||||||
| invite_assignment_invitation = openreview.tools.get_invitation(venue_client, invite_assignment_invitation_id) | ||||||||||
|
|
||||||||||
| if invite_assignment_invitation: | ||||||||||
| grouped_edges = client.get_grouped_edges(invitation=invite_assignment_invitation.id, label='Pending Sign Up', groupby='tail') | ||||||||||
| grouped_edges = venue_client.get_grouped_edges(invitation=invite_assignment_invitation.id, label='Pending Sign Up', groupby='tail') | ||||||||||
| print('Pending sign up edges found', len(grouped_edges)) | ||||||||||
|
|
||||||||||
| for grouped_edge in grouped_edges: | ||||||||||
|
|
||||||||||
| tail = grouped_edge['id']['tail'] | ||||||||||
| profiles=openreview.tools.get_profiles(client, [tail], with_publications=True, with_relations=True) | ||||||||||
| profiles=openreview.tools.get_profiles(venue_client, [tail], with_publications=True, with_relations=True) | ||||||||||
|
|
||||||||||
| if profiles and profiles[0].active: | ||||||||||
|
|
||||||||||
|
|
@@ -1508,33 +1528,73 @@ def mark_as_accepted(venue_group, edge, submission, user_profile, invite_assignm | |||||||||
| for edge in edges: | ||||||||||
|
|
||||||||||
| edge = openreview.api.Edge.from_json(edge) | ||||||||||
| submission=client.get_note(id=edge.head) | ||||||||||
| submission=venue_client.get_note(id=edge.head) | ||||||||||
|
|
||||||||||
| if submission.content['venueid']['value'] == venue_group.content.get('submission_venue_id', {}).get('value'): | ||||||||||
|
|
||||||||||
| ## Check if there is already an accepted edge for that profile id | ||||||||||
| accepted_edges = client.get_edges(invitation=invite_assignment_invitation.id, label='Accepted', head=submission.id, tail=user_profile.id) | ||||||||||
| accepted_edges = venue_client.get_edges(invitation=invite_assignment_invitation.id, label='Accepted', head=submission.id, tail=user_profile.id) | ||||||||||
|
|
||||||||||
| if not accepted_edges: | ||||||||||
| ## Check if the user was invited again with a profile id | ||||||||||
| invitation_edges = client.get_edges(invitation=invite_assignment_invitation.id, label='Invitation Sent', head=submission.id, tail=user_profile.id) | ||||||||||
| invitation_edges = venue_client.get_edges(invitation=invite_assignment_invitation.id, label='Invitation Sent', head=submission.id, tail=user_profile.id) | ||||||||||
| if invitation_edges: | ||||||||||
| invitation_edge = invitation_edges[0] | ||||||||||
| print(f'User invited twice, remove double invitation edge {invitation_edge.id}') | ||||||||||
| invitation_edge.ddate = openreview.tools.datetime_millis(datetime.datetime.now()) | ||||||||||
| client.post_edge(invitation_edge) | ||||||||||
| venue_client.post_edge(invitation_edge) | ||||||||||
|
|
||||||||||
| ## Check venue profile requirements | ||||||||||
| min_requirements = venue_group.content.get('invited_reviewer_profile_minimum_requirements', {}).get('value') | ||||||||||
|
melisabok marked this conversation as resolved.
Outdated
|
||||||||||
| is_incomplete = False | ||||||||||
|
|
||||||||||
| if min_requirements: | ||||||||||
| # { content.relations: 2, content.dblp: true, active: true } | ||||||||||
| for profile_path, expected_value in min_requirements.items(): | ||||||||||
| path_items = profile_path.split('.') | ||||||||||
| actual_value = user_profile | ||||||||||
|
|
||||||||||
| ## Resolve actual value from the profile | ||||||||||
| for item in path_items: | ||||||||||
| if isinstance(actual_value, openreview.Profile): | ||||||||||
| actual_value = getattr(actual_value, item, None) | ||||||||||
| elif isinstance(actual_value, dict): | ||||||||||
| actual_value = actual_value.get(item) | ||||||||||
| else: | ||||||||||
| ## Can't traverse, but more items to resolve | ||||||||||
| actual_value = None | ||||||||||
|
|
||||||||||
| if actual_value is None: | ||||||||||
| break | ||||||||||
|
|
||||||||||
| ## Check against requirement | ||||||||||
| ## Check number of entries | ||||||||||
| if type(expected_value) == int: | ||||||||||
| if not actual_value or not isinstance(actual_value, list) or len(actual_value) < expected_value: | ||||||||||
| is_incomplete = True | ||||||||||
| break | ||||||||||
| ## Check if field exists in profile (e.g. links) | ||||||||||
| elif expected_value is True and not actual_value: | ||||||||||
| is_incomplete = True | ||||||||||
| break | ||||||||||
| else: | ||||||||||
| print(f'Invalid path: {profile_path}') | ||||||||||
|
enrubio marked this conversation as resolved.
Outdated
|
||||||||||
|
|
||||||||||
| if is_incomplete: | ||||||||||
|
||||||||||
| if is_incomplete: | |
| if is_incomplete: | |
| edge.tail = user_profile.id | |
| venue_client.post_edge(edge) |
Uh oh!
There was an error while loading. Please reload this page.