# -*- coding: utf-8 -*- """ invenio_tools.factory """ from base import (is_conference, is_institute, is_thesis, MSG_INV_CONF, MSG_INV_CONF_KEY, MSG_NO_CONF, MSG_NO_CONF_ID_KEY, REG_CONF, REG_OAI) from exception import CdsException from inveniostore import InvenioStore from recordconf import RecordConf from recordinst import RecordInst from recordpubli import RecordPubli from recordthesis import RecordThesis def add_conference_data(recjson): """Add the conference data to the recjson. It adds the following field and subfield:: +---------------+-----------------------------------------------+ | field | subfield | +---------------+-----------------------------------------------+ | meeting_name | closing_date, coference_code, country, date, | | | location, opening_date, year | | meeting | recid, url | +---------------+-----------------------------------------------+ Args: recjson (dict): record data (MarcJSON) Raise: CdsException: - no conference identifier and key in the recjson - conference recjson found but with a wrong identifier - conference not found """ # ........................................................................ # # Retrieve conference identifier # - the algorithm depend on the store # - for cds use aleph_linking_page # - for inspire use publication_info.cnum # conf_id, conf_key = None, None if u"aleph_linking_page" in recjson: di = recjson[u"aleph_linking_page"] conf_id = di[u"sysno"] conf_key = di[u"up_link"] elif u"publication_info" in recjson: data = recjson[u"publication_info"] data = (data if isinstance(data, list) else [data]) for di in data: if u"cnum" in di: conf_key = di[u"cnum"] break if conf_id is None and conf_key is None: raise CdsException(MSG_NO_CONF_ID_KEY) # ........................................................................ # # Get conference data # # extract the host name if u"oai" in recjson: oai = recjson[u"oai"][u"value"] elif u"FIXME_OAI" in recjson: oai = recjson[u"FIXME_OAI"][u"id"] host = REG_OAI.match(oai).group(1) # get the data if conf_id is not None: confjson = get_conference_data(host, conf_id=conf_id) else: confjson = get_conference_data(host, key=conf_key) # ........................................................................ # # Add conference data to the recjson # recjson[u"meeting_name"] = confjson[u"meeting_name"] recjson[u"meeting"] = { u"recid": confjson[u"recid"], u"url": confjson[u"url"][u"url"]} def build_record(recjson): """Transform a JSON object into a record Args: recjson (dict): record data in a JSON format. Return Record: either RecordConf, RecordInst, RecodPubli or RecordThesis Raises: """ if is_conference(recjson): add_conference_data(recjson) upcast_record = RecordConf(recjson) elif is_institute(recjson): upcast_record = RecordInst(recjson) elif is_thesis(recjson): upcast_record = RecordThesis(recjson) else: upcast_record = RecordPubli(recjson) return upcast_record def get_conference_data(host, conf_id=None, key=None): """Get the conference data identified by its id or key. Args: host (unicode): possible values are ``cds.cern.ch`` or ``inspirehep.net``. conf_id (unicode): the conference identifier in the store. This is the preferred way. key (unicode): the conference key in the store. Returns: dict: The conference data (MarcJSON). Raises: CdsException: - conference record with a wrong identifier - conference not found """ cds = InvenioStore(host) # ........................................................................ # # search by id # if conf_id is not None: recjson = cds.get_record(conf_id) if str(recjson["recid"]) != conf_id: raise CdsException(MSG_INV_CONF) return recjson # ........................................................................ # # search by key in cds.cern.ch # if key is not None and host == "cds.cern.ch": ids = cds.get_ids(p=key) for conf_id in ids: recjson = cds.get_record(conf_id) if match_conference_key(recjson, key): return recjson raise CdsException(MSG_NO_CONF) # ........................................................................ # # search by key in inspirehep.net # if key is not None and host == "inspirehep.net": key = key.replace("/", "-") if not REG_CONF.match(key): raise CdsException(MSG_INV_CONF_KEY) ids = cds.get_ids(cc="Conferences", p="111__g:%s" % key) for conf_id in ids: recjson = cds.get_record(conf_id) if match_conference_key(recjson, key): return recjson raise CdsException(MSG_NO_CONF) def match_conference_key(recjson, conf_key): """Return ``True`` when the record corresponds to a conference identified by its key. Args: recjson (dict): record formatted MarcJSON. conf_key (unicode): conference key Returns bool: """ if u"meeting_name" in recjson: for di in recjson[u"meeting_name"]: subfield = u"coference_code" if subfield in di and di[subfield] == conf_key: return True return False