Package biblio :: Package webquery :: Module xisbn
[hide private]
[frames] | no frames]

Source Code for Module biblio.webquery.xisbn

  1  #! /usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  """ 
  4  Querying WorldCat xISBN service for bibliographic information. 
  5   
  6  """ 
  7  # TODO: error-handling logic is correct? 
  8   
  9  __docformat__ = 'restructuredtext en' 
 10   
 11   
 12  ### IMPORTS ### 
 13   
 14  import re 
 15   
 16  from basewebquery import BaseWebquery 
 17  from bibrecord import BibRecord 
 18  import utils 
 19  from errors import * 
 20   
 21  __all__ = [ 
 22     'XisbnQuery', 
 23     'xisbn_py_to_bibrecord', 
 24  ] 
 25   
 26   
 27  ### CONSTANTS & DEFINES ### 
 28   
 29  XISBN_ROOTURL = 'http://xisbn.worldcat.org/webservices/xid/isbn/' 
 30   
 31  FORMATS = [ 
 32     'xml', 
 33     'html', 
 34     'json', 
 35     'python', 
 36     'ruby', 
 37     'php', 
 38     'csv', 
 39     'txt', 
 40     'bibrecord', 
 41  ] 
 42   
 43   
 44  ### IMPLEMENTATION ### 
 45   
46 -class XisbnQuery (BaseWebquery):
47
48 - def __init__ (self, timeout=5.0, limits=None):
49 """ 50 C'tor. 51 """ 52 BaseWebquery.__init__ (self, root_url=XISBN_ROOTURL, timeout=5.0, 53 limits=None)
54
55 - def query_service (self, isbn, method, format, fields=['*']):
56 """ 57 A generalised query for xISBN. 58 59 :Parameters: 60 isbn : string 61 A normalised ISBN-10 or -13. 62 method : string 63 The request type to make of xISBN. 64 format : string 65 The form for the response. 66 fields : iterable 67 A list of the fields to include in the response. 68 69 :Returns: 70 The response received from the service. 71 72 This serves a general way of accessing all the methods available for 73 xISBN. It also normalises the ISBn to a suitable form for submission. 74 75 """ 76 ## Preconditions & preparation: 77 assert (format in FORMATS), \ 78 "unrecognised format '%s', must be one of %s" % (format, FORMATS) 79 ## Main: 80 sub_url = "%(isbn)s?method=%(mthd)s&format=%(fmt)s&fl=%(flds)s" % { 81 'mthd': method, 82 'fmt': format, 83 'isbn': utils.normalize_isbn (isbn), 84 'flds': ','.join (fields), 85 } 86 return self.request (sub_url)
87
88 - def query_bibdata_by_isbn (self, isbn, format='bibrecord'):
89 """ 90 Return publication data based on ISBN. 91 92 :Parameters: 93 isbn : string 94 An ISBN-10 or ISBN-13. 95 96 :Returns: 97 Publication data in Xisbn XML format. 98 99 """ 100 ## Preconditions & preparation: 101 # select appropriate format 102 fmt_map = { 103 'bibrecord': 'python', 104 } 105 passed_fmt = fmt_map.get (format, format) 106 ## Main: 107 results = self.query_service (isbn=isbn, method='getMetadata', 108 format=passed_fmt) 109 if (format == 'bibrecord'): 110 results = xisbn_py_to_bibrecord (results) 111 ## Postconditions & return: 112 return results
113
114 - def query_editions_by_isbn (self, isbn, format='xml'):
115 """ 116 Return the editions associated with an ISBN. 117 118 :Parameters: 119 isbn : string 120 An ISBN-10 or ISBN-13. 121 format : string 122 See `query_service`. 123 124 :Returns: 125 Publication data in Xisbn XML format. 126 127 """ 128 ## Main: 129 return self.query_service (isbn=isbn, method='getEditions', 130 format=format)
131
132 - def query_isbn (self, isbn, method, format='string'):
133 """ 134 A generalised method for ISBN queries that return ISBNs. 135 136 This allows functionality to be shared among the ISBN conversion and 137 checking methods. 138 139 """ 140 ## Preconditions & preparation: 141 # check and select appropriate format 142 fmt_map = { 143 'string': 'python', 144 } 145 passed_fmt = fmt_map.get (format, format) 146 ## Main: 147 results = self.query_service (isbn=isbn, method=method, 148 format=passed_fmt) 149 if (format == 'string'): 150 results = xisbn_py_to_list (results) 151 results = [d['isbn'] for d in results] 152 ## Postconditions & return: 153 return results
154
155 - def query_isbn10_to_13 (self, isbn, format='string'):
156 ## Main: 157 return self.query_isbn (isbn=isbn, method='to13', 158 format=format)
159
160 - def query_isbn13_to_10 (self, isbn, format='string'):
161 ## Main: 162 return self.query_isbn (isbn=isbn, method='to10', 163 format=format)
164
165 - def query_fix_isbn_csum (self, isbn, format='string'):
166 ## Main: 167 return self.query_isbn (isbn=isbn, method='fixChecksum', 168 format=format)
169
170 - def query_hyphenate_isbn (self, isbn, format='string'):
171 ## Main: 172 return self.query_isbn (isbn=isbn, method='hyphen', 173 format=format)
174 175 176
177 -def xisbn_py_to_list (pytxt):
178 """ 179 Translate the Python text returned by xISBN to a list of dicts. 180 181 :Parameters: 182 pytxt : string 183 An Xisbn record in Python. 184 185 :Returns: 186 A list with a dictionary for each record. 187 188 """ 189 ## Main: 190 # convert to python structures 191 xisbn_dict = eval (pytxt) 192 # parse reply status - if the query term was unknown (but valid) return 193 # a empty list for no records 194 status = xisbn_dict.get ('stat', 'ok') 195 if (status != 'ok'): 196 if (status == 'unknownId'): 197 return [] 198 else: 199 raise QueryError ("response status was bad (%s)" % status) 200 ## Postconditions & return: 201 return xisbn_dict['list']
202 203
204 -def xisbn_py_to_bibrecord (pytxt):
205 """ 206 Translate the Python text returned by xISBN to a series of BibRecords. 207 208 :Parameters: 209 pytxt : string 210 An Xisbn record in Python. 211 212 :Returns: 213 A list of BibRecords. 214 215 """ 216 ## Main: 217 # convert to python structures 218 records = xisbn_py_to_list (pytxt) 219 # parse individual records 220 bibrecs = [] 221 for entry in records: 222 new_bib = BibRecord() 223 new_bib.publisher = entry.get ('publisher', '') 224 new_bib.lang = entry.get ('lang', '') 225 new_bib.city = entry.get ('city', '') 226 auth_str = entry.get ('author', '') 227 edited, auth_str = utils.parse_editing_info (auth_str) 228 new_bib.edited = edited 229 auth_list = utils.parse_names (auth_str) 230 new_bib.authors = auth_list 231 new_bib.year = entry.get ('year', '') 232 new_bib.id = entry.get ('isbn', [''])[0] 233 new_bib.add_ext_references ('isbn', entry.get ('isbn', [])) 234 new_bib.add_ext_references ('lccn', entry.get ('lccn', [])) 235 new_bib.add_ext_references ('oclcnum', entry.get ('oclcnum', [])) 236 new_bib.title = entry.get ('title', '') 237 form = entry.get ('form', [''])[0].upper() 238 if (form in ['BA', 'BB', 'BC']): 239 if (edited): 240 new_bib.type = 'collection' 241 else: 242 new_bib.type = 'book' 243 else: 244 # AA (Audio), DA (Digital),FA (Film), MA (Microform), VA (Video) 245 new_bib.type = 'misc' 246 bibrecs.append (new_bib) 247 ## Postconditions & return: 248 return bibrecs
249 250 251 252 ### TEST & DEBUG ### 253
254 -def _doctest ():
255 import doctest 256 doctest.testmod()
257 258 259 ### MAIN ### 260 261 if __name__ == '__main__': 262 _doctest() 263 264 265 ### END ###################################################################### 266