# $Id$ # $URL$ logger = logging.getLogger('meresco.availability') logger.debug("Starting logger") availabilityConfig = infra.configRoot collectionString = availabilityConfig.get('collectionList', section="collections") if collectionString == None: logger.error("No collections found!") collectionString = "NO,COLLECTIONS,FOUND" exceptionString = availabilityConfig.get('exceptionList', section="collections") if exceptionString == None: logger.error("No exceptions found!") exceptionString = "NO,EXCEPTIONS,FOUND" collections = collectionString.split("\n") exceptions = exceptionString.split("\n") #FIXME: config namespaceMap = { 'a' : 'http://drcwww.uvt.nl/~place/search%20engine/extension', 'mods': 'http://www.loc.gov/mods/v3' } data = {} documentStorageList = ['linkmethod', 'locator','series','ebook'] def initData(): for storage in documentStorageList: data[storage] = [] #FIXME inDepot hoort eigenlijk thuis in locator! def inDepot(location): global collections global exceptions # logging.debug("location:" + location) for exception in exceptions: # logging.debug("exception: " + exception) if re.match(exception+'\s',location): return False for collection in collections: # logging.debug("collection: " + collection) if re.match(collection+'\s',location): return True return False def eHoldings(mods): for copyInformation in mods.xpath("//mods:location/mods:holdingSimple/mods:copyInformation", namespaceMap): linkdbId = copyInformation.xpath('mods:note[@type="linkdbId"]/text()', namespaceMap)[0] if linkdbId: holding = copyInformation.xpath('mods:enumerationAndChronology[@unitType="1"]/text()', namespaceMap)[0] url = mods.xpath("//mods:location/mods:holdingExternal/a:copies/a:copy[@linkdbId='%s']/a:url/text()" %linkdbId, namespaceMap) if url: url = url[0] else: url = "" provider = mods.xpath("//mods:location/mods:holdingExternal/a:copies/a:copy[@linkdbId='%s']/a:template/text()" %linkdbId, namespaceMap)[0] provider = availabilityConfig.get(provider, section="providers") data['linkmethod'].append('%s %s' %(url, provider, holding)) def getLocator(recordId, mods): locator = any.createOpenURL(mods, recordId) return locator def getWorldCatQueryLink(record, language): # (Title) ti: titel # (ISBN) bn: isbn (mag zowel met als zonder streepjes) # (ISSN) n2: issn (moet met streepje, dus 1234-5678) # (Author(s)) au: auteur (mag met komma en/of punt, bijv. "Tallant, J.") # (Publication date) &fq=yr:jaar # http://tilburguniversity.worldcat.org/search?q=ti:Trust and Trustworthiness n2:0048-3893&fq=yr:2010&qt=ilr # http://tilburguniversity.worldcat.org/search?q=ti:A framework for marketing management bn:0130185256 au:Kotler&fq=yr:2001&qt=ilr url = availabilityConfig.get('queryUrl', section="worldcat", default='', language=language) #url = "//tilburguniversity.worldcat.org/search?q=" if 'Title' in record: url += "ti:" + record['Title'] if 'ISBN' in record: url += " bn:" + record['ISBN'] if 'ISSN' in record: url += " n2:" + record['ISSN'] if 'Author(s)' in record: # Verwijder "(info)" uit Author(s) url += " au:" + record['Author(s)'].split('(')[0] if 'Publication date' in record: url += "&fq=yr:" + record['Publication date'] # FIXME urlescape! linkTitle = availabilityConfig.get('searchWorldCat', section="worldcat", default='Search WorldCat', language=language) yield """ """ % { 'url' : url, 'linkTitle' : linkTitle } def getAndDisplayAvailabilityByOpenurl(recordId, ID, mods=None, resolver={}, openurl=''): if openurl: locator = openurl else: locator = getLocator(recordId, mods) if resolver: function = """resolver("%(id)s", "%(openurl)s", "%(linkicon)s", "%(linktext)s");""" %{'id': ID, 'openurl' : resolver["baseurl"] + "?" + locator.split('?')[1], 'linkicon' : resolver["linkicon"], 'linktext' : resolver['linktext']} else: function = """openurl("%(id)s", "", "%(locator)s", "unknown");""" % {'locator' : locator, 'id' : ID } yield """ """ % {'function' : function, 'id' : ID } def getAvailabilityByUitleencode(mods, genre, recordId, language='en'): displaySeries = availabilityConfig.get('displayseries', section="availDisplayText", default='Display items in series', language=language) for copyInformation in mods.xpath("//mods:location/mods:holdingSimple/mods:copyInformation", namespaceMap): uitleencode = copyInformation.xpath("mods:note[@type='status']/text()", namespaceMap) if genre == 'series' and not uitleencode: data['series'].append('%s' %(recordId.split(':')[1], displaySeries)) break ####### Er zijn ook elektronische boeken, hebben geen shelfLocator, maar een electronicLocator ####### met URL. url = "" l = copyInformation.xpath("mods:shelfLocator/text()", namespaceMap) if l: location = l[0] else: u = copyInformation.xpath("mods:electronicLocator/text()", namespaceMap) if u: url = u[0] if uitleencode and location: if location.startswith("E "): pass else: data['locator'].append(copyInformation) elif url: ebook = availabilityConfig.get('ebook', section="availabilityGroups", default='Electronic Book', language=language) data['ebook'].append('' + ebook + '') ### einde for-loop def displayAvailability(mods, genre, recordId, ID, language='en'): series = availabilityConfig.get('series', section="availabilityGroups", default='SERIES', language=language) ebook = availabilityConfig.get('ebook', section="availabilityGroups", default='Electronic Book', language=language) linkmethod = availabilityConfig.get('linkmethod', section="availabilityGroups", default='FULLTEXT', language=language) ul = False for storage in documentStorageList: title = "" if storage == 'locator' and data[storage]: locator = "" locations = "" for copyInformation in data['locator']: EPN = copyInformation.xpath("mods:note[@type='epn']/text()", namespaceMap)[0] if EPN: location = copyInformation.xpath("mods:shelfLocator/text()", namespaceMap) location = location and location[0] or '' if location: action = "stack" #FIXME doorgeven van action moet eigenlijk door locator; maar daar nog niet goed geimplementeerd if inDepot(location): action = "depot" location += "=" + action notes = copyInformation.xpath("mods:note/text()", namespaceMap) cdrom = "" for note in notes: expr = re.compile('CD[ -]ROM|DVD', re.IGNORECASE) if expr.match(note): cdrom = "cdrom" location += "^" + cdrom current = "" if genre == "journal" and ( (copyInformation.xpath("mods:enumerationAndChronology[@unitType='1']", namespaceMap) and copyInformation.xpath("mods:enumerationAndChronology[@unitType='1']/text()", namespaceMap)[0].endswith(" - ...")) or (copyInformation.xpath("mods:enumerationAndChronology[@unitType='3']", namespaceMap) and copyInformation.xpath("mods:enumerationAndChronology[@unitType='3']/text()", namespaceMap)[0].startswith("lopende jaargang"))): coll = copyInformation.xpath("mods:enumerationAndChronology[@unitType='3']/text()", namespaceMap) coll = coll and coll[0] or '' current = "current^" + coll location += "^" + current if locations: locations += ";" locations += location locator = getLocator(recordId, mods) yield """ """ %{'id':ID, 'loc':locations, 'locator':locator} elif storage == 'series' and data[storage]: title = series elif storage == 'ebook' and data[storage]: title = ebook elif storage == 'linkmethod' and data[storage]: title = linkmethod if title: # FIXME: deze structuur moet overeenkomen met die van bzv.js # daarom moeten de data doorgegeven worden aan bzv.js voor # een consistent layout. Optie is een aangepaste availability() if not ul: yield '' ul = True def main(index=0, record={}, recordId='', resolver={}, *args, **kwargs): language = getLanguage( kwargs['Headers'] ) fulltext = availabilityConfig.get('fulltext', section="availabilityGroups",default='DIRECT LINK', language=language) # logger.debug(infra.prpt('recordId',recordId)) # logger.debug(infra.prpt('record',record)) db, rid = recordId.split(':', 1) urls = 0 if 'URL(s)' in record: urls = 1 genre = '' if 'Publication type' in record: genre = record['Publication type'] mods = any.getMods(recordId) # logger.debug(infra.prpt('*mods*', mods)) # Note: 'id' is a python builtin # NOTE: 'id' IS A PYTHON BUILTIN!!!!!! ID = 'AvID' + str(index) if urls: yield '' initData() if db == "opc-uvt-nl": getAvailabilityByUitleencode(mods, genre, recordId, language=language) if 'ISSN' in record: query = "(" + record['ISSN'].replace(";", " or ") + ") and norm.genre=journal" parsetree, cqlQuery = any.parseQuery(query, '', '') total, recordIds = any.executeCQL(cqlAbstractSyntaxTree=parsetree) if total > 1: for i in recordIds: if i == recordId: continue if i.split(':', 1)[0] == "opc-uvt-nl": continue m = any.getMods(i) eHoldings(m) elif db == "linkdb-uvt-nl": eHoldings(mods) if 'ISSN' in record: query = "(" + record['ISSN'].replace(";", " or ") + ") and norm.genre=journal" parsetree, cqlQuery = any.parseQuery(query, '', '') total, recordIds = any.executeCQL(cqlAbstractSyntaxTree=parsetree) if total > 1: for i in recordIds: if i == recordId: continue m = any.getMods(i) if i.split(':', 1)[0] == "opc-uvt-nl": mods = m getAvailabilityByUitleencode(mods, genre, recordId, language=language) else: eHoldings(m) elif db == "ir-uvt-nl": yield getAndDisplayAvailabilityByOpenurl(recordId, ID + '-ourl', mods=mods, resolver=resolver) else: # not opc not linkdb not ir #createWorldCatQuery = availabilityConfig.get('createWorldCatQuery', section="worldcat", default='no') #if createWorldCatQuery == "yes" and genre != 'article': # yield getWorldCatQueryLink(record, language=language) yield getAndDisplayAvailabilityByOpenurl(recordId, ID + '-ourl', mods=mods, resolver=resolver) return # de mods van het catalogusrecord moet worden doorgegeven. yield displayAvailability(mods, genre, recordId, ID + '-ulc', language=language)