def get_value(value): affiliations = [] if value.get('u'): recid = None try: recid = int(value.get('z')) except: pass affiliations = inspire_dojson_utils.remove_duplicates_from_list( utils.force_list(value.get('u'))) record = inspire_dojson_utils.get_record_ref(recid, 'institutions') affiliations = [{ 'value': aff, 'record': record } for aff in affiliations] person_recid = None if value.get('x'): try: person_recid = int(value.get('x')) except: pass inspire_id = '' if value.get('i'): inspire_id = utils.force_list(value.get('i'))[0] person_record = inspire_dojson_utils.get_record_ref( person_recid, 'authors') ret = { 'full_name': value.get('a'), 'role': value.get('e'), 'alternative_name': value.get('q'), 'inspire_id': inspire_id, 'orcid': value.get('j'), 'record': person_record, 'email': value.get('m'), 'affiliations': affiliations, 'profile': { "__url__": inspire_dojson_utils.create_profile_url(value.get('x')) }, 'curated_relation': value.get('y', 0) == 1 } # HACK: This is to workaround broken records where multiple authors # got meshed up together. if isinstance(ret['full_name'], (list, tuple)): import warnings warnings.warn( "Record with mashed-up author list! Taking first author: {}". format(value)) ret['full_name'] = ret['full_name'][0] return ret
def test_get_record_ref_with_empty_server_name(current_app): current_app.config = {} expected = 'http://inspirehep.net/api/record_type/123' result = get_record_ref(123, 'record_type') assert expected == result['$ref']
def test_get_record_ref_with_server_name_localhost(current_app): current_app.config = {'SERVER_NAME': 'localhost:5000'} expected = 'http://localhost:5000/api/record_type/123' result = get_record_ref(123, 'record_type') assert expected == result['$ref']
def test_get_record_ref_with_https_server_name(current_app): current_app.config = {'SERVER_NAME': 'https://example.com'} expected = 'https://example.com/api/record_type/123' result = get_record_ref(123, 'record_type') assert expected == result['$ref']
def test_get_record_ref_without_record_type_defaults_to_record(current_app): current_app.config = {} expected = 'http://inspirehep.net/api/record/123' result = get_record_ref(123) assert expected == result['$ref']
def test_get_record_ref_with_server_name_localhost(): config = {'SERVER_NAME': 'localhost:5000'} with patch.dict(current_app.config, config): expected = 'http://localhost:5000/api/endpoint/123' result = get_record_ref(123, 'endpoint') assert expected == result['$ref']
def test_get_record_ref_with_https_server_name(): config = {'SERVER_NAME': 'https://example.com'} with patch.dict(current_app.config, config): expected = 'https://example.com/api/endpoint/123' result = get_record_ref(123, 'endpoint') assert expected == result['$ref']
def test_get_record_ref_with_empty_server_name(): config = {} with patch.dict(current_app.config, config, clear=True): expected = 'http://inspirehep.net/api/endpoint/123' result = get_record_ref(123, 'endpoint') assert expected == result['$ref']
def test_get_record_ref_without_endpoint_defaults_to_record(): config = {} with patch.dict(current_app.config, config, clear=True): expected = 'http://inspirehep.net/api/record/123' result = get_record_ref(123) assert expected == result['$ref']
def get_value(value): affiliations = [] if value.get('u'): recid = None try: recid = int(value.get('z')) except: pass affiliations = inspire_dojson_utils.remove_duplicates_from_list( utils.force_list(value.get('u'))) record = inspire_dojson_utils.get_record_ref(recid, 'institutions') affiliations = [{'value': aff, 'record': record} for aff in affiliations] person_recid = None if value.get('x'): try: person_recid = int(value.get('x')) except: pass inspire_id = '' if value.get('i'): inspire_id = utils.force_list(value.get('i'))[0] person_record = inspire_dojson_utils.get_record_ref(person_recid, 'authors') ret = { 'full_name': value.get('a'), 'role': value.get('e'), 'alternative_name': value.get('q'), 'inspire_id': inspire_id, 'inspire_bai': value.get('w'), 'orcid': value.get('j'), 'record': person_record, 'email': value.get('m'), 'affiliations': affiliations, 'profile': {"__url__": inspire_dojson_utils.create_profile_url( value.get('x') )}, 'curated_relation': value.get('y', 0) == 1 } # HACK: This is to workaround broken records where multiple authors # got meshed up together. if isinstance(ret['full_name'], (list, tuple)): import warnings warnings.warn("Record with mashed-up author list! Taking first author: {}".format(value)) ret['full_name'] = ret['full_name'][0] return ret
def related_experiments(self, key, value): """Related experiments.""" try: recid = int(value.get('0')) except (TypeError, ValueError): recid = None return { 'name': value.get('a'), 'record': inspire_dojson_utils.get_record_ref(recid, 'experiments') }
def test_get_record_ref_server_name(current_app): # Test empty SERVER_NAME. current_app.config = {} ref = utils.get_record_ref(123, 'record_type') assert ref['$ref'].startswith('http://inspirehep.net') # Test dev SERVER_NAME. current_app.config = {'SERVER_NAME': 'localhost:5000'} ref = utils.get_record_ref(123, 'record_type') assert ref['$ref'].startswith('http://localhost:5000') # Test http prod SERVER_NAME. current_app.config = {'SERVER_NAME': 'http://inspirehep.net'} ref = utils.get_record_ref(123, 'record_type') assert ref['$ref'].startswith('http://inspirehep.net') # Test https prod SERVER_NAME. current_app.config = {'SERVER_NAME': 'https://inspirehep.net'} ref = utils.get_record_ref(123, 'record_type') assert ref['$ref'].startswith('https://inspirehep.net')
def get_value(value): recid = None if '0' in value: try: recid = int(value.get('0')) except: pass return { 'value': value.get('g'), 'record': inspire_dojson_utils.get_record_ref(recid, 'experiments') }
def succeeding_entry(self, key, value): """Succeeding Entry.""" if isinstance(value, (tuple, list)): # Too bad: there can only be one succeeding entry. value = value[0] return { 'relationship_code': value.get('r'), 'record': inspire_dojson_utils.get_record_ref( value.get('w'), 'literature'), 'isbn': value.get('z'), }
def institution(self, key, value): """Institution info.""" curated_relation = False recid = None if value.get('z') and value.get('z').isdigit(): curated_relation = True recid = int(value.get('z')) return { 'curated_relation': curated_relation, 'record': inspire_dojson_utils.get_record_ref(recid, 'isntitutions'), 'name': value.get('a'), }
def publication_info(self, key, value): """Publication info about record.""" def get_int_value(val): if val: out = utils.force_list(val)[0] if out.isdigit(): out = int(out) return out return None year = get_int_value(value.get('y')) parent_recid = get_int_value(value.get('0')) journal_recid = get_int_value(value.get('1')) conference_recid = get_int_value(value.get('2')) parent_record = inspire_dojson_utils.get_record_ref(parent_recid, 'literature') conference_record = inspire_dojson_utils.get_record_ref(conference_recid, 'conferences') journal_record = inspire_dojson_utils.get_record_ref(journal_recid, 'journals') res = { 'parent_record': parent_record, 'conference_record': conference_record, 'journal_record': journal_record, 'page_artid': value.get('c'), 'journal_issue': value.get('n'), 'conf_acronym': value.get('o'), 'journal_title': value.get('p'), 'reportnumber': value.get('r'), 'confpaper_info': value.get('t'), 'journal_volume': value.get('v'), 'cnum': utils.force_list(value.get('w')), 'pubinfo_freetext': value.get('x'), 'year': year, 'isbn': value.get('z'), 'note': value.get('m'), } return res
def thesis(self, key, value): """Get Thesis Information.""" curated_relation = False if value.get('z'): curated_relation = True return { 'defense_date': value.get('a'), 'degree_type': value.get('b'), 'university': value.get('c'), 'date': value.get('d'), 'record': inspire_dojson_utils.get_record_ref(value.get('z'), 'institutions'), 'curated_relation': curated_relation, }
def add_book_info(record, blob): """Add link to the appropriate book record.""" collections = [] if 'collections' in record: for c in record.get('collections', ''): if c.get('primary', ''): collections.append(c.get('primary').lower()) if 'bookchapter' in collections: pubinfos = force_list(blob.get("773__", [])) for pubinfo in pubinfos: if pubinfo.get('0'): record['book'] = { 'record': inspire_dojson_utils.get_record_ref( int(force_list(pubinfo.get('0'))[0]), 'literature') }
def spires_sysnos(self, key, value): """Old SPIRES number and new_recid from 970.""" value = utils.force_list(value) sysnos = [] new_recid = None for val in value: if 'a' in val: # Only append if there is something sysnos.append(val.get('a')) elif 'd' in val: new_recid = val.get('d') if new_recid is not None: # FIXME we are currently using the default /record API. Which might # resolve to a 404 response. self['new_record'] = inspire_dojson_utils.get_record_ref(new_recid) return sysnos or None
def thesis_supervisor(self, key, value): """Get thesis supervisor from object.""" value = utils.force_list(value) out = [] for val in value: out.append({ "full_name": val.get('full_name'), "record": inspire_dojson_utils.get_record_ref(val.get('external_id'), 'literature'), "affiliation": { "value": val.get('affiliation') }, }) return out
def accelerator_experiments(self, key, value): """The accelerator/experiment related to this record.""" recid = None curated_relation = False if '0' in value: try: recid = int(value.get('0')) except (TypeError, ValueError, AttributeError): pass if recid: curated_relation = True return { 'record': inspire_dojson_utils.get_record_ref(recid, 'experiments'), 'accelerator': value.get('a'), 'experiment': value.get('e'), 'curated_relation': curated_relation }
def positions(self, key, value): """Position information. Accepted values for 371__r: + senior + junior + staff + visitor + postdoc + phd + masters + undergrad In dates field you can put months in addition to years. In this case you have to follow the convention `mth-year`. For example: `10-2012`. """ curated_relation = False recid = None status = '' recid_status = utils.force_list(value.get('z')) if recid_status: for val in recid_status: if val.lower() == 'current': status = val elif type(val) is int: recid = val curated_relation = True inst = {'name': value.get('a'), 'record': inspire_dojson_utils.get_record_ref(recid, 'institutions')} return { 'institution': inst if inst['name'] else None, 'rank': value.get('r'), 'start_date': value.get('s'), 'end_date': value.get('t'), 'email': value.get('m'), 'old_email': value.get('o'), 'status': status, 'curated_relation': curated_relation, }
def get_value(value): recid = None number = '' year = '' if '0' in value: try: recid = int(value.get('0')) except: pass if 'o' in value: try: number = int(value.get('o')) except: pass if 'y' in value: try: year = int(value.get('y')) except: pass return { 'record': inspire_dojson_utils.get_record_ref(recid, 'literature'), 'texkey': value.get('1'), 'doi': value.get('a'), 'collaboration': utils.force_list(value.get('c')), 'editors': value.get('e'), 'authors': utils.force_list(value.get('h')), 'misc': utils.force_list(value.get('m')), 'number': number, 'isbn': value.get('i'), 'publisher': utils.force_list(value.get('p')), 'maintitle': value.get('q'), 'report_number': utils.force_list(value.get('r')), 'title': utils.force_list(value.get('t')), 'url': utils.force_list(value.get('u')), 'journal_pubnote': utils.force_list(value.get('s')), 'raw_reference': utils.force_list(value.get('x')), 'year': year, }
def _self_url(self, key, value): """Url of the record itself.""" self['control_number'] = value return inspire_dojson_utils.get_record_ref(value, index)
def create_author(profile): """Create a new author profile based on a given signature. The method receives a dictionary representing an author. Based on the values, it creates a dictionary in the invenio_records format. After all the fields are processed, the method calls create_record from invenio_records.api to put the new record. :param profile: A signature representing an author's to be created as a profile. Example: profile = {u'affiliations': [{u'value': u'Yerevan Phys. Inst.'}], u'alternative_name': None, u'curated_relation': False, u'email': None, u'full_name': u'Chatrchyan, Serguei', u'inspire_id': None, u'orcid': None, u'profile': u'', u'recid': None, u'role': None, u'uuid': u'd63537a8-1df4-4436-b5ed-224da5b5028c'} :return: A recid, where the new profile can be accessed. Example: "1234" """ name = profile.get('full_name') # Template of an initial record. record = {'collections': [{'primary': 'HEPNAMES'}], 'name': {'value': name}, '$schema': _get_author_schema()} # The author's email address. # Unfortunately the method will not correlate a given e-mail address # with an affiliation. if 'email' in profile: email = profile.get('email') record['positions'] = [] record['positions'].append({'email': email}) # The author can be a member of more than one affiliation. if 'affiliations' in profile: affiliations = profile.get('affiliations') if 'positions' not in record: record['positions'] = [] for affiliation in affiliations: name = affiliation.get('value') recid = affiliation.get('recid', None) if recid: record['positions'].append( {'institution': {'name': name, 'recid': recid}}) else: record['positions'].append( {'institution': {'name': name}}) # FIXME: The method should also collect the useful data # from the publication, like category field, subject, # etc. # Disconnect the signal on insert of a new record. after_record_insert.disconnect(append_new_record_to_queue) # Create a new author profile. record = InspireRecord.create(record, id_=None) # Create Inspire recid. record_pid = inspire_recid_minter(record.id, record) # Extend the new record with Inspire recid and self key. record['control_number'] = record_pid.pid_value record['self'] = inspire_dojson_utils.get_record_ref( record_pid.pid_value, 'authors') # Apply the changes. record.commit() db.session.commit() # Reconnect the disconnected signal. after_record_insert.connect(append_new_record_to_queue) # Report. logger.info("Created profile: %s", record_pid.pid_value) # Return the recid of new profile to which signatures will point to. return record_pid.pid_value
def test_get_record_ref_with_record_type(): ref = utils.get_record_ref(123, 'record_type') assert ref['$ref'].endswith('/api/record_type/123') assert utils.get_record_ref(None, 'record_type') == None
def test_get_record_ref_without_recid_returns_none(): assert get_record_ref(None, 'endpoint') is None
def create_author(profile): """Create a new author profile based on a given signature. The method receives a dictionary representing an author. Based on the values, it creates a dictionary in the invenio_records format. After all the fields are processed, the method calls create_record from invenio_records.api to put the new record. :param profile: A signature representing an author's to be created as a profile. Example: profile = {u'affiliations': [{u'value': u'Yerevan Phys. Inst.'}], u'alternative_name': None, u'curated_relation': False, u'email': None, u'full_name': u'Chatrchyan, Serguei', u'inspire_id': None, u'orcid': None, u'profile': u'', u'recid': None, u'role': None, u'uuid': u'd63537a8-1df4-4436-b5ed-224da5b5028c'} :return: A recid, where the new profile can be accessed. Example: "1234" """ name = profile.get('full_name') # Template of an initial record. record = {'collections': [{'primary': 'HEPNAMES'}], 'name': {'value': name}, '$schema': _get_author_schema()} # The author's email address. # Unfortunately the method will not correlate a given e-mail address # with an affiliation. if 'email' in profile: email = profile.get('email') record['positions'] = [] record['positions'].append({'email': email}) # The author can be a member of more than one affiliation. if 'affiliations' in profile: affiliations = profile.get('affiliations') if 'positions' not in record: record['positions'] = [] for affiliation in affiliations: name = affiliation.get('value') recid = affiliation.get('recid', None) if recid: record['positions'].append( {'institution': {'name': name, 'recid': recid}}) else: record['positions'].append( {'institution': {'name': name}}) # FIXME: The method should also collect the useful data # from the publication, like category field, subject, # etc. # Disconnect the signal on insert of a new record. after_record_insert.disconnect(append_new_record_to_queue) # Create a new author profile. record = Record.create(record, id_=None) # Create Inspire recid. record_pid = inspire_recid_minter(record.id, record) # Extend the new record with Inspire recid and self key. record['control_number'] = record_pid.pid_value record['self'] = inspire_dojson_utils.get_record_ref( record_pid.pid_value, 'authors') # Apply the changes. record.commit() db.session.commit() # Add the record to Elasticsearch. indexer = RecordIndexer() indexer.index_by_id(record_pid.object_uuid) # Reconnect the disconnected signal. after_record_insert.connect(append_new_record_to_queue) # Report. logger.info("Created profile: %s", record_pid.pid_value) # Return the recid of new profile to which signatures will point to. return record_pid.pid_value
def test_get_record_ref_without_recid_returns_none(): assert get_record_ref(None, 'record_type') is None
def test_get_record_ref_default(): ref = utils.get_record_ref(123) assert ref['$ref'].endswith('/api/record/123')
def deleted_records(self, key, value): """Recid of deleted record this record is master for.""" # FIXME we are currently using the default /record API. Which might # resolve to a 404 response. return inspire_dojson_utils.get_record_ref(value.get('a'))