# $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 getLocator(recordId, mods):
locator = call.createOpenURL(mods, recordId)
return locator
def getAvailabilityByOpenurl(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 eHoldings(mods):
for copyInformation in mods.xpath("//mods:location/mods:holdingSimple/mods:copyInformation", namespaces=namespaceMap):
linkdbId = copyInformation.xpath('mods:note[@type="linkdbId"]/text()', namespaces=namespaceMap)[0]
if linkdbId:
holding = copyInformation.xpath('mods:enumerationAndChronology[@unitType="1"]/text()', namespaces=namespaceMap)[0]
url = mods.xpath("//mods:location/mods:holdingExternal/a:copies/a:copy[@linkdbId='%s']/a:url/text()" %linkdbId, namespaces=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, namespaces=namespaceMap)[0]
provider = availabilityConfig.get(provider, section="providers")
data['linkmethod'].append('%s %s' %(url, provider, holding))
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", namespaces=namespaceMap):
uitleencode = copyInformation.xpath("mods:note[@type='status']/text()", namespaces=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()", namespaces=namespaceMap)
if l: location = l[0]
else:
u = copyInformation.xpath("mods:electronicLocator/text()", namespaces=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()", namespaces=namespaceMap)[0]
if EPN:
location = copyInformation.xpath("mods:shelfLocator/text()", namespaces=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()", namespaces=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']", namespaces=namespaceMap) and copyInformation.xpath("mods:enumerationAndChronology[@unitType='1']/text()", namespaces=namespaceMap)[0].endswith(" - ...")) or
(copyInformation.xpath("mods:enumerationAndChronology[@unitType='3']", namespaces=namespaceMap) and copyInformation.xpath("mods:enumerationAndChronology[@unitType='3']/text()", namespaces=namespaceMap)[0].startswith("lopende jaargang"))):
coll = copyInformation.xpath("mods:enumerationAndChronology[@unitType='3']/text()", namespaces=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 ''
yield ' - %s
' %(title)
for el in data[storage]:
yield ' - %(el)s
' %{'el':el}
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 = call.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 '' % {'id' : ID}
yield '- %(title)s
' %{'title':fulltext}
for url in record['URL(s)']:
# FIXME config
yield '- '
if not isMobile(**kwargs):
yield ''
yield 'full text
' %(url)
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 = call.parseQuery(query, '', '')
results = call.executeCQL(cqlAbstractSyntaxTree=parsetree)
total = results['total']
recordIds = results['recordIds']
if total > 1:
for i in recordIds:
if i == recordId: continue
if i.split(':', 1)[0] == "opc-uvt-nl": continue
m = call.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 = call.parseQuery(query, '', '')
total, recordIds = call.executeCQL(cqlAbstractSyntaxTree=parsetree)
if total > 1:
for i in recordIds:
if i == recordId: continue
m = call.getMods(i)
if i.split(':', 1)[0] == "opc-uvt-nl":
mods = m
getAvailabilityByUitleencode(mods, genre, recordId, language=language)
else:
eHoldings(m)
else: # not opc not linkdb
if urls and (genre != 'article'): pass
else:
yield getAvailabilityByOpenurl(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)