home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_961 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  6.7 KB  |  192 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
  6. import sys
  7. import socket
  8. import os
  9. import re
  10. from lxml import html
  11. import mechanize
  12. from calibre import browser, prints
  13. from calibre.utils.config import OptionParser
  14. from calibre.ebooks.BeautifulSoup import BeautifulSoup
  15. OPENLIBRARY = 'http://covers.openlibrary.org/b/isbn/%s-L.jpg?default=false'
  16.  
  17. class HeadRequest(mechanize.Request):
  18.     
  19.     def get_method(self):
  20.         return 'HEAD'
  21.  
  22.  
  23.  
  24. def check_for_cover(isbn, timeout = 5):
  25.     br = browser()
  26.     br.set_handle_redirect(False)
  27.     
  28.     try:
  29.         br.open_novisit(HeadRequest(OPENLIBRARY % isbn), timeout = timeout)
  30.         return True
  31.     except Exception:
  32.         e = None
  33.         if callable(getattr(e, 'getcode', None)) and e.getcode() == 302:
  34.             return True
  35.     except:
  36.         e.getcode() == 302
  37.  
  38.     return False
  39.  
  40.  
  41. class LibraryThingError(Exception):
  42.     pass
  43.  
  44.  
  45. class ISBNNotFound(LibraryThingError):
  46.     pass
  47.  
  48.  
  49. class ServerBusy(LibraryThingError):
  50.     pass
  51.  
  52.  
  53. def login(br, username, password, force = True):
  54.     br.open('http://www.librarything.com')
  55.     br.select_form('signup')
  56.     br['formusername'] = username
  57.     br['formpassword'] = password
  58.     br.submit()
  59.  
  60.  
  61. def cover_from_isbn(isbn, timeout = 5, username = None, password = None):
  62.     src = None
  63.     br = browser()
  64.     
  65.     try:
  66.         return (br.open(OPENLIBRARY % isbn, timeout = timeout).read(), 'jpg')
  67.     except:
  68.         pass
  69.  
  70.     if username and password:
  71.         
  72.         try:
  73.             login(br, username, password, force = False)
  74.  
  75.     
  76.     
  77.     try:
  78.         src = br.open_novisit('http://www.librarything.com/isbn/' + isbn, timeout = timeout).read().decode('utf-8', 'replace')
  79.     except Exception:
  80.         err = None
  81.         if isinstance(getattr(err, 'args', [
  82.             None])[0], socket.timeout):
  83.             err = LibraryThingError(_('LibraryThing.com timed out. Try again later.'))
  84.         
  85.         raise err
  86.  
  87.     s = BeautifulSoup(src)
  88.     url = s.find('td', attrs = {
  89.         'class': 'left' })
  90.     if url is None:
  91.         if s.find('div', attrs = {
  92.             'class': 'highloadwarning' }) is not None:
  93.             raise ServerBusy(_('Could not fetch cover as server is experiencing high load. Please try again later.'))
  94.         s.find('div', attrs = {
  95.             'class': 'highloadwarning' }) is not None
  96.         raise ISBNNotFound('ISBN: ' + isbn + _(' not found.'))
  97.     url is None
  98.     url = url.find('img')
  99.     if url is None:
  100.         raise LibraryThingError(_('LibraryThing.com server error. Try again later.'))
  101.     url is None
  102.     url = re.sub('_S[XY]\\d+', '', url['src'])
  103.     cover_data = br.open_novisit(url).read()
  104.     return (cover_data, url.rpartition('.')[-1])
  105.  
  106.  
  107. def option_parser():
  108.     parser = OptionParser(usage = _('\n%prog [options] ISBN\n\nFetch a cover image/social metadata for the book identified by ISBN from LibraryThing.com\n'))
  109.     parser.add_option('-u', '--username', default = None, help = 'Username for LibraryThing.com')
  110.     parser.add_option('-p', '--password', default = None, help = 'Password for LibraryThing.com')
  111.     return parser
  112.  
  113.  
  114. def get_social_metadata(title, authors, publisher, isbn, username = None, password = None):
  115.     MetaInformation = MetaInformation
  116.     import calibre.ebooks.metadata
  117.     mi = MetaInformation(title, authors)
  118.     if isbn:
  119.         br = browser()
  120.         if username and password:
  121.             
  122.             try:
  123.                 login(br, username, password, force = False)
  124.  
  125.         
  126.         raw = br.open_novisit('http://www.librarything.com/isbn/' + isbn).read()
  127.         if not raw:
  128.             return mi
  129.         root = html.fromstring(raw)
  130.         h1 = root.xpath('//div[@class="headsummary"]/h1')
  131.         if h1 and not (mi.title):
  132.             mi.title = html.tostring(h1[0], method = 'text', encoding = unicode)
  133.         
  134.         h2 = root.xpath('//div[@class="headsummary"]/h2/a')
  135.         h3 = root.xpath('//div[@class="headsummary"]/h3/a')
  136.         if h3:
  137.             match = None
  138.             for h in h3:
  139.                 series = html.tostring(h, method = 'text', encoding = unicode)
  140.                 match = re.search('(.+) \\((.+)\\)', series)
  141.                 if match is not None:
  142.                     break
  143.                     continue
  144.                 None if h2 and not (mi.authors) else []
  145.             
  146.             if match is not None:
  147.                 mi.series = match.group(1).strip()
  148.                 match = re.search('[0-9.]+', match.group(2))
  149.                 si = 1
  150.                 if match is not None:
  151.                     si = float(match.group())
  152.                 
  153.                 mi.series_index = si
  154.             
  155.         
  156.         span = root.xpath('//table[@class="wsltable"]/tr[@class="wslcontent"]/td[4]//span')
  157.         if span:
  158.             raw = html.tostring(span[0], method = 'text', encoding = unicode)
  159.             match = re.search('([0-9.]+)', raw)
  160.             if match is not None:
  161.                 rating = float(match.group())
  162.                 if rating > 0 and rating <= 5:
  163.                     mi.rating = rating
  164.                 
  165.             
  166.         
  167.     
  168.     return mi
  169.  
  170.  
  171. def main(args = sys.argv):
  172.     parser = option_parser()
  173.     (opts, args) = parser.parse_args(args)
  174.     if len(args) != 2:
  175.         parser.print_help()
  176.         return 1
  177.     isbn = args[1]
  178.     mi = get_social_metadata('', [], '', isbn)
  179.     prints(mi)
  180.     (cover_data, ext) = cover_from_isbn(isbn, username = opts.username, password = opts.password)
  181.     if not ext:
  182.         ext = 'jpg'
  183.     
  184.     oname = os.path.abspath(isbn + '.' + ext)
  185.     open(oname, 'w').write(cover_data)
  186.     print 'Cover saved to file', oname
  187.     return 0
  188.  
  189. if __name__ == '__main__':
  190.     sys.exit(main())
  191.  
  192.