def format_records(self, start, count, res_set, prefsyn): """ Format a 'present' response for the requested query result subset. """ #encode_charset = self.charset_name map_node = medmarc.MarcMapper() l = [] for i in xrange(start - 1, min(len(res_set), start + count - 1)): try: node = tree.getNode(res_set[i]) except tree.NoSuchNodeError: logg.debug("request for non-existant node %s", res_set[i]) continue marc21_node = map_node(node) if marc21_node is None: # no mapping => no node continue elt_external = asn1.EXTERNAL() elt_external.direct_reference = z3950.Z3950_RECSYN_USMARC_ov elt_external.encoding = ('octet-aligned', marc21_node) n = z3950.NamePlusRecord() n.name = str(node.id) n.record = ('retrievalRecord', elt_external) l.append(n) return l
def format_node(node, map_node): marc21_node = map_node(node) # None? no mapping => no node if marc21_node is not None: elt_external = asn1.EXTERNAL() elt_external.direct_reference = z3950.Z3950_RECSYN_USMARC_ov elt_external.encoding = ('octet-aligned', marc21_node) n = z3950.NamePlusRecord() n.name = unicode(node.id) n.record = ('retrievalRecord', elt_external) return n
def format_records(self, start, count, res_set, rec_syn): l = [] for i in range(start - 1, start + count - 1): elt = res_set[i] elt_external = asn1.EXTERNAL() elt_external.direct_reference = zdefs.Z3950_RECSYN_SUTRS_ov elt_external.encoding = ('single-ASN1-type', elt) n = zdefs.NamePlusRecord() n.name = 'foo' # XXX n.record = 'retrievalRecord', elt_external l.append(n) return l
def format_records(self, start, count, res_set, prefsyn): l = [] for i in range(start - 1, start + count - 1): elt = res_set[i] elt_external = asn1.EXTERNAL() elt_external.direct_reference = Z3950_RECSYN_SUTRS_ov # Not only has this text been extensively translated, but # it also prefigures Z39.50's separation of Search and Present, # once rearranged a little. strings = [ 'seek, and ye shall find; ask, and it shall be given you', u"""Car quiconque demande re\u00e7oit, qui cherche trouve, et \u00e0 quit frappe on ouvrira""", # This (next) verse has non-ASCII characters u"\u0391\u03b9\u03c4\u03b5\u03b9\u03c4\u03b5, " u"\u03ba\u03b1\u03b9 \u03b4\u03bf\u03b8\u03b7\u03c3\u03b5\u03c4\u03b1\u03b9 " + u"\u03c5\u03bc\u03b9\u03bd; \u03b6\u03b7\u03c4\u03b5\u03b9\u03c4\u03b5 " + u"\u03ba\u03b1\u03b9 \u03b5\u03c5\u03c1\u03b7\u03c3\u03b5\u03c4\u03b5", u"\u05e8\u05d0\u05d4 \u05d6\u05d4 \u05de\u05e6\u05d0\u05ea\u05d9" ] if self.charsets_in_records: encode_charset = self.charset_name else: encode_charset = 'ascii' def can_encode(s): try: s.encode(encode_charset) except UnicodeError: return 0 return 1 if self.charset_name == None: candidate_strings = [strings[0]] else: candidate_strings = [s for s in strings if can_encode(s)] # Note: this code is for debugging/testing purposes. Usually, # language/content selection should not be made on the # basis of the selected charset, and a surrogate diagnostic # should be generated if the data cannot be encoded. text = random.choice(candidate_strings) add_str = " #%d charset %s cir %d" % (elt, encode_charset, self.charsets_in_records) elt_external.encoding = ('single-ASN1-type', text + add_str) n = NamePlusRecord() n.name = 'foo' n.record = ('retrievalRecord', elt_external) l.append(n) return l
def format_one(self, rec, esn, syntax, next): elt_external = asn1.EXTERNAL() elt_external.direct_reference = zdefs.Z3950_RECSYN_SUTRS_ov elt_external.encoding = ('single-ASN1-type', str(esn) + ': ' + str(rec)) n = zdefs.NamePlusRecord() n.name = dbname n.record = ('retrievalRecord', elt_external) # we could call next(n) directly, but using reactor.callLater # helps to ensure there aren't any bugs which would be revealed # by running from callback context, and prevents stack overflow # for large Present requests. Normally, I'd expect some kind of # async call to be required to fetch the data, so 'next' should # be triggered from a deferred callback. (An errback should # correspond to a surrogate diagnostic.) if callLater: reactor.callLater(0.01, next, n) else: next(n)
def handlePresent(self, session, data): resp = PresentResponse() resp.numberOfRecordsReturned = 0 resp.presentStatus = 1 try: rsid = self.session.resultSets[data.resultSetId] if session.resultSetCache.has_key(rsid): resultset = session.resultSetCache[rsid] else: resultset = self.session.resultSetStore.fetch_resultSet( self.session, rs) f = data.resultSetStartPoint n = data.numberOfRecordsRequested recSyntax = data.preferredRecordSyntax recSynStr = '.'.join([str(x) for x in recSyntax.lst]) records = [] for x in range(f - 1, min(f + n - 1, len(resultset))): rec = resultset[x].fetch_record(session) db = resultset[x].database dbname = dbmap[db] cfg = self.session.configs.get(dbname, None) if not cfg or not cfg.transformerHash.has_key(recSynStr): # XXX: Diagnostic 239 // recsyn not supported raise ValueError("RecordSyntax not supported: %r" % (recSynStr)) else: esns = cfg.transformerHash[recSynStr] recSchema = data.recordComposition esnType = recSchema[0] if (esnType == "simple"): esn = recSchema[1][1].lower() else: raise NotImplementedError if not esns.has_key(esn): raise ValueError("%s: %s" % (esn, repr(esns))) else: txr = esns[esn] if (txr): self.log("starting transformation") if isinstance(txr, Transformer): doc = txr.process_record(session, rec) elif isinstance(txr, Workflow): doc = txr.process(session, rec) else: raise ValueError docdata = doc.get_raw(session) self.log("finished transform") else: docdata = rec.get_xml(session) r = NamePlusRecord() r.name = dbname xr = asn1.EXTERNAL() xr.direct_reference = recSyntax if (recSynStr == "1.2.840.10003.5.105"): # GRS-1 if not type(docdata) == type([]): xr.encoding = ('single-ASN1-type', [docdata]) else: xr.encoding = ('single-ASN1-type', docdata) else: xr.encoding = ('octet-aligned', docdata) r.record = ('retrievalRecord', xr) records.append(r) resp.records = ('responseRecords', records) resp.numberOfRecordsReturned = len(records) resp.nextResultSetPosition = f + len(records) resp.presentStatus = 0 # Don't want to log the full records! # self.log(resp) except Exception, err: d = self.generate_diagnostic(err) d.condition = 123 resp.records = ('nonSurrogateDiagnostic', d) resp.presentStatus = 5 resp.numberOfRecordsReturned = 0 resp.nextResultSetPosition = 0
""" typ = typ.upper() # XXX maybe replace if ... elif ... with dict mapping querytype to func if typ == 'CCL': self.typ = 'RPN' try: self.query = ccl.mk_rpn_query(query) except ccl.QuerySyntaxError, err: print "zoom raising", str(err), " for", query raise QuerySyntaxError(str(err)) elif typ == 'S-CCL': # server-side ccl self.typ = typ self.query = ('type-2', query) elif typ == 'S-CQL': # server-side cql self.typ = typ xq = asn1.EXTERNAL() xq.direct_reference = oids.Z3950_QUERY_CQL_ov xq.encoding = ('single-ASN1-type', query) self.query = ('type_104', xq) elif typ == 'CQL': # CQL to RPN transformation self.typ = 'RPN' try: q = CQLParser.parse(query) rpnq = z3950.RPNQuery() # XXX Allow Attribute Architecture somehow? rpnq.attributeSet = oids.Z3950_ATTRS_BIB1_ov rpnq.rpn = q.toRPN() self.query = ('type_1', rpnq) except SRWDiagnostics.SRWDiagnostic, err: raise err except:
def __init__ (self, typ, query): """Creates Query object. Supported query types: CCL, S-CCL, CQL, S-CQL, PQF, C2, ZSQL, CQL-TREE """ typ = typ.upper() # XXX maybe replace if ... elif ... with dict mapping querytype to func if typ == 'CCL': self.typ = 'RPN' try: self.query = ccl.mk_rpn_query (query) except ccl.QuerySyntaxError as err: raise QuerySyntaxError (str(err)) elif typ == 'S-CCL': # server-side ccl self.typ = typ self.query = ('type-2', query) elif typ == 'S-CQL': # server-side cql self.typ = typ xq = asn1.EXTERNAL() xq.direct_reference = oids.Z3950_QUERY_CQL_ov xq.encoding = ('single-ASN1-type', query) self.query = ('type_104', xq) elif typ == 'CQL': # CQL to RPN transformation self.typ = 'RPN' try: q = CQLParser.parse(query) rpnq = z3950.RPNQuery() # XXX Allow Attribute Architecture somehow? rpnq.attributeSet = oids.Z3950_ATTRS_BIB1_ov rpnq.rpn = q.toRPN() self.query = ('type_1', rpnq) except SRWDiagnostics.SRWDiagnostic as err: raise err except: raise QuerySyntaxError elif typ == 'PQF': # PQF to RPN transformation self.typ = 'RPN' try: self.query = pqf.parse(query) except: raise QuerySyntaxError elif typ == 'C2': # Cheshire2 Syntax self.typ = 'RPN' try: q = c2.parse(query) self.query = q[0] except: raise QuerySyntaxError elif typ == 'ZSQL': # External SQL self.typ = typ xq = asn1.EXTERNAL() xq.direct_reference = oids.Z3950_QUERY_SQL_ov q = z3950.SQLQuery() q.queryExpression = query xq.encoding = ('single-ASN1-type', q) self.query = ('type_104', xq) elif typ == 'CQL-TREE': # Tree to RPN self.typ = 'RPN' try: rpnq = z3950.RPNQuery() # XXX Allow Attribute Architecture rpnq.attributeSet = oids.Z3950_ATTRS_BIB1_ov rpnq.rpn = query.toRPN() self.query = ('type_1', rpnq) except SRWDiagnostics.SRWDiagnostic as err: raise err except: raise QuerySyntaxError else: raise ClientNotImplError ('%s queries not supported' % typ)