def test_get_conflicts(self, client, helpers): helpers.create_user('*****@*****.**', 'First', 'Last') user_profile = client.get_profile(email_or_id='*****@*****.**') conflicts = openreview.tools.get_conflicts([user_profile], user_profile) assert conflicts assert conflicts[0] == '*****@*****.**' helpers.create_user('*****@*****.**', 'First', 'Last') user_profile = client.get_profile(email_or_id='*****@*****.**') conflicts = openreview.tools.get_conflicts([user_profile], user_profile) assert conflicts assert conflicts[0] == '*****@*****.**' helpers.create_user('*****@*****.**', 'First', 'Last') user2_profile = client.get_profile(email_or_id='*****@*****.**') conflicts = openreview.tools.get_conflicts([user2_profile], user_profile) assert len(conflicts) == 0 profile1 = openreview.Profile(id='Test_Conflict1', content={ 'emails': ['*****@*****.**'], 'history': [{ 'institution': { 'domain': '*****@*****.**' } }] }) profile2 = openreview.Profile(id='Test_Conflict2', content={ 'emails': ['*****@*****.**'], 'history': [{ 'institution': { 'domain': '*****@*****.**' } }] }) conflicts = openreview.tools.get_conflicts([profile1], profile2) assert len(conflicts) == 1 assert conflicts[0] == 'cmu.edu'
def main(): args = parser.parse_args() ## Initialize the client library with username and password. client = openreview.Client(baseurl=args.baseurl, username=args.username, password=args.password) init_source_groups(client) # get list of files in directory or list is just one file dirpath = args.directory if os.path.isdir(dirpath): file_names = os.listdir(dirpath) else: file_names = [dirpath.split('/')[-1]] dirpath = dirpath[:-len(file_names[0])] # initialize counts num_new = 0 num_updates = 0 total_files = len(file_names) file_count = 0 one_percent = total_files//100.0 if one_percent < 1: one_percent = 1 profiles_by_id, profiles_by_email = get_all_profiles(client) for filename in file_names: file_count = print_status(file_count, total_files, one_percent, filename) new_profile_content = load_json_file(dirpath, filename) if new_profile_content: main_email = new_profile_content['emails'][0] if main_email in profiles_by_email.keys(): # profile exists, add new reference existing_profile = profiles_by_email[main_email] profile = openreview.Profile(referent=existing_profile.id, invitation=existing_profile.invitation, signatures=[source_id], writers=[source_id], content=new_profile_content) profile = client.update_profile(profile) ''' except openreview.OpenReviewException as e: print("OpenReviewException {}".format(e)) print(id)''' num_updates += 1 else: # profile doesn't exist, try creating it try: tools.create_profile(client, main_email, new_profile_content['names'][0]['first'], new_profile_content['names'][0]['last'], middle=new_profile_content['names'][0]['middle'], allow_duplicates=True) num_new += 1 except openreview.OpenReviewException as e: # can be unhappy if name includes parenthesis etc # in this case it is OK to skip it print("Error with {} {}".format(filename, e)) continue
def test_replace_members_with_ids(self, client, test_client): posted_group = client.post_group( openreview.Group( id='test.org', readers=['everyone'], writers=['~Super_User1'], signatures=['~Super_User1'], signatories=['~Super_User1'], members=['*****@*****.**', '~Test_User1', '~Another_Name1'])) assert posted_group client.post_profile( openreview.Profile(referent='~Test_User1', signatures=['~Test_User1'], content={ 'names': [{ 'first': 'Another', 'last': 'Name', 'username': '******' }] })) replaced_group = openreview.tools.replace_members_with_ids( client, posted_group) assert replaced_group assert replaced_group.members == ['~Test_User1'] posted_group = client.post_group( openreview.Group(id='test.org', readers=['everyone'], writers=['~Super_User1'], signatures=['~Super_User1'], signatories=['~Super_User1'], members=[ '~Super_User1', '~Another_Name1', '*****@*****.**' ])) replaced_group = openreview.tools.replace_members_with_ids( client, posted_group) assert replaced_group assert replaced_group.members == [ '~Super_User1', '~Test_User1', '*****@*****.**' ] # Test to assert that member is removed while running replace members on a group has a member that is an invalid profile invalid_member_group = client.add_members_to_group( replaced_group, '~Invalid_Profile1') assert len(invalid_member_group.members) == 4 assert '~Invalid_Profile1' in invalid_member_group.members replaced_group = openreview.tools.replace_members_with_ids( client, invalid_member_group) assert len(replaced_group.members) == 3 assert '~Invalid_Profile1' not in invalid_member_group.members
def _get_profiles(client, ids_or_emails): ''' Helper function that repeatedly queries for profiles, given IDs and emails. Useful for getting more Profiles than the server will return by default (1000) ''' ids = [] emails = [] for member in ids_or_emails: if '~' in member: ids.append(member) else: emails.append(member) profiles = [] profile_by_email = {} batch_size = 100 for i in range(0, len(ids), batch_size): batch_ids = ids[i:i + batch_size] batch_profiles = client.search_profiles(ids=batch_ids) profiles.extend(batch_profiles) for j in range(0, len(emails), batch_size): batch_emails = emails[j:j + batch_size] batch_profile_by_email = client.search_profiles(emails=batch_emails) profile_by_email.update(batch_profile_by_email) for email in emails: profiles.append( profile_by_email.get( email, openreview.Profile(id=email, content={ 'emails': [email], 'preferredEmail': email }))) return profiles
def create_profile(client, email, first, last, middle=None, allow_duplicates=False): ''' Given email, first name, last name, and middle name (optional), creates and returns a user profile. If a profile with the same name exists, and allow_duplicates is False, an exception is raised. If a profile with the same name exists and allow_duplicates is True, a profile is created with the next largest number (e.g. if ~Michael_Spector1 exists, ~Michael_Spector2 will be created) ''' profile = get_profile(client, email) if not profile: # validate the name with just first and last names, # and also with first, middle, and last. # this is so that we catch more potential collisions; # let the caller decide what to do with false positives. username_response_FL_only = client.get_tildeusername(first, last, None) username_response_full = client.get_tildeusername(first, last, middle) # the username in each response will end with 1 # if profiles don't exist for those names username_FL_unclaimed = username_response_FL_only['username'].endswith( '1') username_full_unclaimed = username_response_full['username'].endswith( '1') if all([username_FL_unclaimed, username_full_unclaimed]): profile_exists = False else: profile_exists = True tilde_id = username_response_full['username'] if (not profile_exists) or allow_duplicates: tilde_group = openreview.Group(id=tilde_id, signatures=[super_user_id], signatories=[tilde_id], readers=[tilde_id], writers=[super_user_id], members=[email]) email_group = openreview.Group(id=email, signatures=[super_user_id], signatories=[email], readers=[email], writers=[super_user_id], members=[tilde_id]) profile_content = { 'emails': [email], 'preferredEmail': email, 'names': [{ 'first': first, 'middle': middle, 'last': last, 'username': tilde_id }] } client.post_group(tilde_group) client.post_group(email_group) profile = client.post_profile( openreview.Profile(id=tilde_id, content=profile_content)) return profile else: raise openreview.OpenReviewException( 'Failed to create new profile {tilde_id}: There is already a profile with the name: \"{first} {middle} {last}\"' .format(first=first, middle=middle, last=last, tilde_id=tilde_id)) else: raise openreview.OpenReviewException( 'There is already a profile with this email address: {}'.format( email))
def main(): ## Initialize the client library with username and password client = openreview.Client(baseurl=args.baseurl, username=args.username, password=args.password) submissions = list(openreview.tools.iterget_notes(client, invitation='ICLR.cc/2019/Conference/-/Blind_Submission')) decision_info = load_decisions(client) profile_info = {} # get all profile information ahead by first listing all authors needed authors = [] for note in submissions: if note.forum in decision_info: authors.extend(note.content['authorids']) # remove duplicates authors = list(set(authors)) # get all associated profiles profiles = client.get_profiles(authors) for email in profiles: author = email profile = profiles[email] if author not in profile_info: profile_info = load_profile(profile_info, author, profile) ## Initialize output file name file_name = 'ICLR_decisions.xlsx' if args.ofile!=None: file_name = args.ofile # Create a workbook and add a worksheet. workbook = xlsxwriter.Workbook(file_name) worksheet = workbook.add_worksheet() # Start from the first cell. Rows and columns are zero indexed. row = 0 col = 0 # write the header header = ['Unique Id', 'Paper Number', 'Title', 'Decision', 'Abstract', 'Keywords', 'External URL', 'Author Count', 'Last Name', 'Middle Initial', 'First Name', 'Email', 'Institution', 'Department', 'Last Name', 'Middle Initial', 'First Name', 'Email', 'Institution', 'Department'] for item in header: worksheet.write(row, col, item) col += 1 row +=1 for note in submissions: if note.forum in decision_info: # paper data col = 0 worksheet.write(row, col, note.forum) col += 1 worksheet.write(row, col, note.number) col += 1 worksheet.write(row, col, note.content['title']) col += 1 worksheet.write(row, col, decision_info[note.forum]) col += 1 worksheet.write(row, col, note.content['abstract']) col += 1 worksheet.write(row, col, json.dumps(note.content['keywords'])) col += 1 worksheet.write(row, col, note.content['pdf']) col += 1 # author data worksheet.write(row, col, len(note.content['authorids'])) col += 1 for index, author in enumerate(note.content['authorids']): if author not in profile_info: ## A hack to get profiles that are missed by get_profiles try: profile_note = client.get_profile(author) profile = openreview.Profile(content = profile_note.content) profile_info = load_profile(profile_info, author, profile) except openreview.OpenReviewException as e: # cannot find author_id in profile notes e =1 name_elements = note.content['authors'][index].split(' ') profile_info[author] = {'first': '', 'mi': '', 'last': ''} profile_info[author]['first'] = name_elements[0] profile_info[author]['last'] = name_elements[-1] profile_info[author]['mi'] = '' profile_info[author]['email'] = author profile_info[author]['institute'] = '' if (len(name_elements) > 2): profile_info[author]['mi'] = ' '.join(name_elements[1:-1]) if author in profile_info: worksheet.write(row, col, profile_info[author]['last']) col += 1 worksheet.write(row, col, profile_info[author]['mi']) col += 1 worksheet.write(row, col, profile_info[author]['first']) col += 1 worksheet.write(row, col, profile_info[author]['email']) col += 1 worksheet.write(row, col, profile_info[author]['institute']) # skipping department col += 2 else: # skip names col += 3 worksheet.write(row, col, author) # skipping institute and department col += 3 row += 1 workbook.close()