Page MenuHomec4science

oai1d.wml
No OneTemporary

File Metadata

Created
Tue, Mar 11, 01:06

oai1d.wml

## $Id$
## OAI interface for CDSware/MySQL written in Python compliant with OAI-PMH1.1
## This file is part of the CERN Document Server Software (CDSware).
## Copyright (C) 2002 CERN.
##
## The CDSware is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 2 of the
## License, or (at your option) any later version.
##
## The CDSware is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with CDSware; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
## read config variables:
#include "config.wml"
#include "configbis.wml"
## start Python:
<protect>#!</protect><PYTHON>
<protect>## $Id$</protect>
<protect>## DO NOT EDIT THIS FILE! IT WAS AUTOMATICALLY GENERATED FROM CDSware WML SOURCES.</protect>
"""OAI interface for CDSware/MySQL written in Python compliant with OAI-PMH1.1"""
## fill config variables:
dbhost = """<DBHOST>"""
dbname = """<DBNAME>"""
dbuser = """<DBUSER>"""
dbpass = """<DBPASS>"""
cdsname = """<CDSNAME>"""
supportemail = """<SUPPORTEMAIL>"""
runtimelogdir = """<LOGDIR>"""
htdocsurl = """<WEBURL>"""
cgibinurl = """<CGIBINURL>"""
cdspageheader = """<CDSPAGEHEADER>"""
cdspagefooter = """<CDSPAGEFOOTER>"""
## OAI config variables
oaiidprefix = """<OAIIDPREFIX>"""
oaisampleidentifier = """<OAISAMPLEIDENTIFIER>"""
oaiidentifydescription = """<OAIIDENTIFYDESCRIPTION>"""
oaiidfield = "909COo"
oaisetfield = "909COp"
lastmodified = """<: print `date +"%d %b %Y %H:%M:%S %Z"`; :>"""
<protect>
## okay, rest of the Python code goes below
#######
__version__ = "$Id$"
## import interesting modules:
try:
import cgi
import cPickle
import string
from string import split
import os
import re
import sys
import time
import MySQLdb
import md5
except ImportError, e:
print "Error: %s" % e
import sys
sys.exit(1)
## config:
dbg = 0 # are we debugging?
nb_records_in_resume = 100 # limit for items of OAI ListRecords
nb_identifiers_in_resume = 100 # limit for items of OAI ListIdentifiers
oai_rt_expire = 90000 # OAI resumptionToken expiration (seconds)
## connect to MySQL
db = MySQLdb.connect(host=dbhost, db=dbname, user=dbuser, passwd=dbpass)
cursor = db.cursor()
## precompile some often-used regexp for speed reasons:
re_amp = re.compile('&')
def encode_for_xml(s):
"Encode special chars in string so that it would be XML-compliant."
s = string.replace(s, '&', '&amp;')
s = string.replace(s, '<', '&lt;')
e = unicode(s,'latin-1','ignore').encode('utf-8','replace')
return e
def print_header(cc=cdsname):
"Prints CDS header and info on URL and date."
print "Content-type: text/html"
print """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>%s - Search Results</title>
<link rev="made" href="mailto:%s">
<link rel="stylesheet" href="%simg/cds.css">
</head>
<body>
<div class="pageheader">%s</div>
""" % (cc, supportemail, htdocsurl, cdspageheader)
def print_footer():
"Prints CDS page footer."
print """%s""" % re.sub("<\?.*\?>", "&lt;%soai1d&gt;." % cgibinurl, cdspagefooter)
def get_field(sysno, field):
"Gets list of field 'field' for the record with 'sysno' system number."
out = []
digit = field[0:2]
bx = "bib%sx" % digit
bibx = "bibrec_bib%sx" % digit
query = "SELECT bx.value FROM %s AS bx, %s AS bibx WHERE bibx.id_bibrec='%s' AND bx.id=bibx.id_bibxxx AND bx.tag='%s'" % (bx, bibx, sysno, field)
if dbg:
print_warning(query, "Debug")
cursor.execute(query)
row = cursor.fetchone()
while row:
out.append(row[0])
row = cursor.fetchone()
return out
def get_creation_date(sysno):
"Returns the creation date of the record 'sysno'."
out = ""
query = "SELECT DATE_FORMAT(creation_date,'%%Y-%%m-%%d') FROM bibrec WHERE id='%s'" % (sysno)
if dbg:
print_warning(query, "Debug")
cursor.execute(query)
row = cursor.fetchone()
if row:
out = row[0]
return out
def get_modification_date(sysno):
"Returns the date of last modification for the record 'sysno'."
out = ""
query = "SELECT DATE_FORMAT(modification_date,'%%Y-%%m-%%d') FROM bibrec WHERE id='%s'" % (sysno)
if dbg:
print_warning(query, "Debug")
cursor.execute(query)
row = cursor.fetchone()
if row:
out = row[0]
return out
def record_exists(sysno):
"Returns 1 if record with SYSNO 'sysno' exists. Returns 0 otherwise."
out = 0
query = "SELECT id FROM bibrec WHERE id='%s'" % (sysno)
if dbg:
print_warning(query, "Debug")
cursor.execute(query)
row = cursor.fetchone()
if row:
out = 1
return out
def print_warning(msg, type='Tip'):
"Prints warning message and flushes output."
print '<small class="quicknote"><strong>%s:</strong> %s</small><br>' % (type, msg)
sys.stdout.flush()
def print_record(sysno, format='marcxml'):
"Prints record 'sysno' formatted accoding to 'format'."
# sanity check:
if not record_exists(sysno):
return
if (format == "dc") or (format == "oai_dc"):
format = "xd"
# print record opening tags:
print " <record>"
print " <header>"
for id in get_field(sysno,oaiidfield):
print " <identifier>%s</identifier>" % id
print " <datestamp>%s</datestamp>" % get_modification_date(sysno)
print " </header>"
print " <metadata>"
if format == "marcxml":
## MARC21 and XML formats, possibley OAI -- they are not in "bibfmt" table; so fetch all the data from "bibXXx" tables:
if format == "marcxml":
print " <controlfield tag=\"001\">%d</controlfield>" % int(sysno)
for digit1 in range(0,10):
for digit2 in range(0,10):
bx = "bib%d%dx" % (digit1, digit2)
bibx = "bibrec_bib%d%dx" % (digit1, digit2)
query = "SELECT b.tag,b.value,bb.field_number FROM %s AS b, %s AS bb "\
"WHERE bb.id_bibrec='%s' AND b.id=bb.id_bibxxx AND b.tag LIKE '%s%%' "\
"ORDER BY bb.field_number, b.tag ASC" % (bx, bibx, sysno, str(digit1)+str(digit2))
if dbg:
print_warning(query, "Debug")
cursor.execute(query)
row = cursor.fetchone()
field_number_old = -999
field_old = ""
while row:
field, value, field_number = row[0], row[1], row[2]
ind1, ind2 = field[3], field[4]
if ind1 == "_":
ind1 = ""
if ind2 == "_":
ind2 = ""
# print field tag
if field_number != field_number_old or field[:-1] != field_old[:-1]:
if format == "m":
print "<br><strong class=\"headline\">%s&nbsp;%s</strong>" % (encode_for_xml(field[0:3]), encode_for_xml(field[3:5]))
elif format == "marcxml":
fieldid = encode_for_xml(field[0:3])
if field_number_old != -999:
print """ </datafield>"""
print """ <datafield tag="%s" ind1="%s" ind2="%s">""" % (encode_for_xml(field[0:3]), encode_for_xml(ind1), encode_for_xml(ind2))
field_number_old = field_number
field_old = field
# print subfield value
if format == "m":
print "<em class=\"headline\">$%s</em> %s" % (field[-1:], value)
elif format == "marcxml":
value = encode_for_xml(value)
print """ <subfield code="%s">%s</subfield>""" % (encode_for_xml(field[-1:]), value)
# fetch next subfield
row = cursor.fetchone()
# all fields/subfields printed in this run, so close the tag:
if (format == "marcxml") and field_number_old != -999:
print """ </datafield>"""
elif format == "xd":
# XML Dublin Core format, possibly OAI -- select only some bibXXx fields:
print """ <dc xmlns="http://purl.org/dc/elements/1.1/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://purl.org/dc/elements/1.1/
http://www.openarchives.org/OAI/1.1/dc.xsd">"""
for f in get_field(sysno, "041__a"):
print " <language>%s</language>" % f
for f in get_field(sysno, "100__a"):
print " <creator>%s</creator>" % encode_for_xml(f)
for f in get_field(sysno, "700__a"):
print " <creator>%s</creator>" % encode_for_xml(f)
for f in get_field(sysno, "245__a"):
print " <title>%s</title>" % encode_for_xml(f)
for f in get_field(sysno, "65017a"):
print " <subject>%s</subject>" % encode_for_xml(f)
for f in get_field(sysno, "8564_u"):
print " <identifier>%s</identifier>" % encode_for_xml(f)
for f in get_field(sysno, "520__a"):
print " <description>%s</description>" % encode_for_xml(f)
print " <date>%s</date>" % get_creation_date(sysno)
print " </dc>"
# print record closing tags:
print " </metadata>"
print " </record>"
def main():
"Main function which analyses the CGI request and invokes search corresponding to an OAI verb"
param = cgi.FieldStorage()
if param.has_key('verb'):
verb = param['verb'].value
if param.has_key('metadataPrefix'):
metadataPrefix = param['metadataPrefix'].value
else:
metadataPrefix = ""
if param.has_key('from'):
fromDate = param['from'].value
else:
fromDate = ""
if param.has_key('until'):
untilDate = param['until'].value
else:
untilDate = ""
if param.has_key('set'):
set = param['set'].value
else:
set = ""
if param.has_key('identifier'):
identifier = param['identifier'].value
else:
identifier = ""
if param.has_key('resumptionToken'):
resumptionToken = param['resumptionToken'].value
if metadataPrefix or fromDate or untilDate or set or identifier:
OAIError()
else:
resumptionToken = ""
if verb == "Identify":
print "Content-type: text/xml\n"
OAIIdentify()
sys.exit()
elif verb == "ListMetadataFormats":
print "Content-type: text/xml\n"
OAIListMetadataFormats(identifier,resumptionToken)
sys.exit()
elif verb == "ListRecords":
if metadataPrefix=='oai_dc' or metadataPrefix=='marcxml' or resumptionToken:
OAIListRecords(fromDate,untilDate,set,metadataPrefix,resumptionToken)
sys.exit()
else:
OAIError('MetadataPrefix missing')
sys.exit()
elif verb == "ListIdentifiers":
OAIListIdentifiers(fromDate,untilDate,set,resumptionToken)
sys.exit()
elif verb == "GetRecord":
if identifier:
if metadataPrefix=='oai_dc' or metadataPrefix=='marcxml':
print "Content-type: text/xml\n"
OAIGetRecord(identifier, metadataPrefix)
sys.exit()
else:
OAIError('MetadataPrefix Missing.')
sys.exit()
else:
OAIError('Record Identifier missing.')
sys.exit()
elif verb == "ListSets":
print "Content-type: text/xml\n"
OAIListSets(resumptionToken)
sys.exit()
else:
OAIError('Wrong OAI-verb.')
sys.exit()
else:
OAIError('OAI-verb missing.')
sys.exit()
def OAIListMetadataFormats(identifier,resumptionToken):
"Generates response to OAIListMetadataFormats verb."
responseDate = OAIGetResponseDate()
requestURL = OAIGetRequestURL()
flag = 1 # list or not depending on identifier
if identifier:
flag = 0
sysno = OAIGetSysno(identifier)
if record_exists(sysno):
flag = 1
print """<?xml version="1.0" encoding="UTF-8"?>"""
print """
<ListMetadataFormats
xmlns="http://www.openarchives.org/OAI/1.1/OAI_ListMetadataFormats"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/1.1/OAI_ListMetadataFormats
http://www.openarchives.org/OAI/1.1/OAI_ListMetadataFormats.xsd">
"""
print " <responseDate>" + responseDate + "</responseDate>"
print " <requestURL>" + requestURL + "</requestURL>"
if flag:
print """
<metadataFormat>
<metadataPrefix>oai_dc</metadataPrefix>
<schema>http://www.openarchives.org/OAI/1.1/dc.xsd</schema>
<metadataNamespace>http://purl.org/dc/elements/1.1/</metadataNamespace>
</metadataFormat>
<metadataFormat>
<metadataPrefix>marcxml</metadataPrefix>
<schema>http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd</schema>
<metadataNamespace>http://www.loc.gov/MARC21/slim</metadataNamespace>
</metadataFormat>
"""
print """
</ListMetadataFormats>
"""
def OAIListRecords(fromDate,untilDate,set,metadataPrefix,resumptionToken):
"Generates response to OAIListRecords verb."
responseDate = OAIGetResponseDate()
requestURL = OAIGetRequestURL()
sysnos = []
sysno = []
if resumptionToken:
filename = "%s/RTdata/%s" % (runtimelogdir, resumptionToken)
if os.path.exists(filename) == 0:
OAIError('ResumptionToken expired.')
print "Content-type: text/xml\n"
print """<?xml version="1.0" encoding="UTF-8"?>"""
print """
<ListRecords
xmlns="http://www.openarchives.org/OAI/1.1/OAI_ListRecords"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/1.1/OAI_ListRecords
http://www.openarchives.org/OAI/1.1/OAI_ListRecords.xsd">
"""
print " <responseDate>" + responseDate + "</responseDate>"
print " <requestURL>" + requestURL + "</requestURL>"
if resumptionToken:
sysnos = OAICacheOut(resumptionToken)
metadataPrefix = sysnos.pop()
else:
sysnos = OAIGetSysnoList(set, fromDate, untilDate + "T23:59:59Z")
i = 0
for s in sysnos:
if s:
i = i + 1
if i > nb_records_in_resume: # cache or write?
if i == nb_records_in_resume + 1: # resumptionToken?
resumptionToken = OAIGenResumptionToken()
print "<resumptionToken>%s</resumptionToken>" % resumptionToken
sysno.append(s)
else:
done = 0
for f in get_field(s, "245__a"):
if done == 0:
print_record(s, metadataPrefix)
print "</ListRecords>"
if i > nb_records_in_resume:
OAICacheClean()
sysno.append(metadataPrefix)
OAICacheIn(resumptionToken,sysno)
def OAIListSets(resumptionToken):
"Lists available sets for OAI metadata harvesting."
responseDate = OAIGetResponseDate()
requestURL = OAIGetRequestURL()
print """<?xml version="1.0" encoding="UTF-8"?>""",
print """
<ListSets
xmlns="http://www.openarchives.org/OAI/1.1/OAI_ListSets"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/1.1/OAI_ListSets
http://www.openarchives.org/OAI/1.1/OAI_ListSets.xsd">
"""
print " <responseDate>" + responseDate + "</responseDate>"
print " <requestURL>" + requestURL + "</requestURL>"
sets = get_sets()
for s in sets:
print " <set>"
print " <setSpec>%s</setSpec>" % s[0]
print " <setName>%s</setName>" % s[1]
print " </set>"
print """
</ListSets>
"""
def OAIGetRecord(identifier, metadataPrefix):
"""Returns record 'identifier' according to 'metadataPrefix' format for OAI metadata harvesting."""
responseDate = OAIGetResponseDate()
requestURL = OAIGetRequestURL()
print """<?xml version="1.0" encoding="UTF-8"?>"""
print """
<GetRecord
xmlns="http://www.openarchives.org/OAI/1.1/OAI_GetRecord"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/1.1/OAI_GetRecord
http://www.openarchives.org/OAI/1.1/OAI_GetRecord.xsd">
"""
print " <responseDate>" + responseDate + "</responseDate>"
print " <requestURL>" + requestURL + "</requestURL>"
sysno = OAIGetSysno(identifier)
if record_exists(sysno):
datestamp = get_modification_date(sysno)
print_record(sysno, metadataPrefix)
print "</GetRecord>"
def OAIListIdentifiers(fromDate,untilDate,set,resumptionToken):
"Prints OAI response to the ListIdentifiers verb."
responseDate = OAIGetResponseDate()
requestURL = OAIGetRequestURL()
sysno = []
sysnos = []
if resumptionToken:
filename = "%s/RTdata/%s" % (runtimelogdir, resumptionToken)
if os.path.exists(filename) == 0:
OAIError('ResumptionToken expired.')
print "Content-type: text/xml\n"
print """<?xml version="1.0" encoding="UTF-8"?>"""
print """
<ListIdentifiers
xmlns="http://www.openarchives.org/OAI/1.1/OAI_ListIdentifiers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/1.1/OAI_ListIdentifiers
http://www.openarchives.org/OAI/1.1/OAI_ListIdentifiers.xsd">
"""
print " <responseDate>" + responseDate + "</responseDate>"
print " <requestURL>" + requestURL + "</requestURL>"
if resumptionToken:
sysnos = OAICacheOut(resumptionToken)
else:
sysnos = OAIGetSysnoList(set, fromDate, untilDate + "T23:59:59Z")
i = 0
for s in sysnos:
if s:
i = i + 1
if i > nb_identifiers_in_resume: # cache or write?
if i == nb_identifiers_in_resume + 1: # resumptionToken?
resumptionToken = OAIGenResumptionToken()
print "<resumptionToken>%s</resumptionToken>" % resumptionToken
sysno.append(s)
else:
done = 0
for f in get_field(s, "245__a"):
if done == 0:
for id in get_field(s,oaiidfield):
print " <identifier>%s</identifier>" % id
done = 1
if i > nb_identifiers_in_resume:
OAICacheClean() # clean cache from expired resumptionTokens
OAICacheIn(resumptionToken,sysno)
print "</ListIdentifiers>"
def OAIIdentify():
"Generates response to OAIIdentify verb."
responseDate = OAIGetResponseDate()
requestURL = OAIGetRequestURL()
repositoryName = cdsname
baseURL = "%soai1d" % cgibinurl
protocolVersion = "1.1"
adminEmail = "mailto:%s" % supportemail
repositoryIdentifier = "%s" % oaiidprefix
sampleIdentifier = oaisampleidentifier
identifyDescription = oaiidentifydescription
print """<?xml version="1.0" encoding="UTF-8"?>"""
print """
<Identify
xmlns="http://www.openarchives.org/OAI/1.1/OAI_Identify"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/1.1/OAI_Identify
http://www.openarchives.org/OAI/1.1/OAI_Identify.xsd">
"""
print " <responseDate>" + responseDate + "</responseDate>"
print " <requestURL>" + requestURL + "</requestURL>"
print " <repositoryName>" + repositoryName + "</repositoryName>"
print " <baseURL>" + baseURL + "</baseURL>"
print " <protocolVersion>" + protocolVersion + "</protocolVersion>"
print " <adminEmail>" + adminEmail + "</adminEmail>"
print identifyDescription
print """
</Identify>
"""
def OAIGetRequestURL():
"Generates requestURL tag for OAI."
if os.environ.has_key('SERVER_NAME'):
server_name = os.environ['SERVER_NAME']
else:
server_name = ""
if os.environ.has_key('QUERY_STRING'):
query_string = os.environ['QUERY_STRING']
else:
query_string = ""
if os.environ.has_key('SCRIPT_NAME'):
script_name = os.environ['SCRIPT_NAME']
else:
script_name = ""
requestURL = "http://" + server_name + script_name
if query_string:
requestURL = requestURL + "?" + re_amp.sub("&amp;", query_string)
return requestURL
def OAIGetResponseDate():
"Generates responseDate tag for OAI."
if (time.timezone < 0):
zone = "+%02d:00" % (-time.timezone/3600)
elif (time.timezone > 0):
zone = "-%02d:00" % (time.timezone/3600)
else:
zone = "+00:00"
responseDate = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime()) + zone
return responseDate
def OAIError(msg="Malformed OAI request."):
"Sends OAI error status."
print "Status: 400 Bad request"
print_header()
print "<h1 class=\"headline\">OAI Error</h1>"
print "<p>%s" % msg
print """<p>See the <a href="http://www.openarchives.org/OAI/openarchivesprotocol.htm">OpenArchives protocol</a>."""
print_footer()
sys.exit()
def OAIGetSysno(identifier):
"Returns the first MySQL BIB ID for the OAI identifier 'identifier', if it exists."
sysno = None
if identifier:
query = "SELECT DISTINCT(bb.id_bibrec) FROM bib90x AS bx, bibrec_bib90x AS bb WHERE bx.tag='%s' AND bb.id_bibxxx=bx.id AND bx.value='%s'" % (oaiidfield,identifier)
if dbg:
print_warning(query, "Debug")
cursor.execute(query)
row = cursor.fetchone()
if row:
sysno = row[0]
return sysno
def OAIGetSysnoList(set, date_from, date_until):
"Returns list of system numbers for the OAI set 'set', modified from 'date_from' until 'date_until'."
out_dict = {} # dict to hold list of out sysnos as its keys
if set:
query = "SELECT DISTINCT bibx.id_bibrec FROM bib90x AS bx LEFT JOIN bibrec_bib90x AS bibx ON bx.id=bibx.id_bibxxx LEFT JOIN bibrec AS b ON b.id=bibx.id_bibrec WHERE bx.tag='%s' AND bx.value='%s'" % (oaisetfield,set)
else:
query = "SELECT DISTINCT bibx.id_bibrec FROM bib90x AS bx LEFT JOIN bibrec_bib90x AS bibx ON bx.id=bibx.id_bibxxx LEFT JOIN bibrec AS b ON b.id=bibx.id_bibrec WHERE bx.tag='%s'" % (oaiidfield)
if date_from:
query = query + " AND b.modification_date >= '%s'" % date_from
if date_until:
query = query + " AND b.modification_date <= '%s'" % date_until
if dbg:
print_warning(query, "Debug")
cursor.execute(query)
row = cursor.fetchone()
while row:
out_dict[row[0]] = 1
row = cursor.fetchone()
return out_dict.keys()
def OAIGenResumptionToken():
"Generates unique ID for resumption token management."
return md5.new(str(time.time())).hexdigest()
def OAICacheIn(resumptionToken, sysnos):
"Stores or adds sysnos in cache. Input is a string of sysnos separated by comas."
filename = "%s/RTdata/%s" % (runtimelogdir, resumptionToken)
fil = open(filename,"w")
cPickle.dump(sysnos,fil)
fil.close()
return 1
#OAICacheOut restore (string) from cache
def OAICacheOut(resumptionToken):
"Restores string of coma-separated system numbers from cache."
sysnos = []
filename = "%s/RTdata/%s" % (runtimelogdir, resumptionToken)
if OAICacheStatus(resumptionToken):
fil = open(filename,"r")
sysnos = cPickle.load(fil)
fil.close()
else:
return 0
return sysnos
def OAICacheClean():
"Removes cached resumptionTokens older than 'oai_rt_expire'."
directory = "%s/RTdata" % runtimelogdir
files = os.listdir(directory)
for f in files:
filename = directory + "/" + f
# cache entry expires when not modified during a specified period of time
if ((time.time() - os.path.getmtime(filename)) > oai_rt_expire):
os.remove(filename)
return 1
def OAICacheStatus(resumptionToken):
"Checks cache status. Returns 0 for empty, 1 for full."
filename = "%s/RTdata/%s" % (runtimelogdir, resumptionToken)
if os.path.exists(filename):
if os.path.getsize(filename) > 0:
return 1
else:
return 0
else:
return 0
def get_sets():
"Returns list of sets."
out = []
row = ['','']
cursor_bis = db.cursor()
query_bis = "SELECT setSpec,setName FROM oaiset"
cursor_bis.execute(query_bis)
row_bis = cursor_bis.fetchone()
while row_bis:
row = [row_bis[0],row_bis[1]]
out.append(row)
row_bis = cursor_bis.fetchone()
cursor_bis.close()
return out
### okay, here we go:
if __name__ == '__main__':
main()
</protect>

Event Timeline