home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_1327 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  10.4 KB  |  335 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. __license__ = 'GPL v3'
  6. __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
  7. __docformat__ = 'restructuredtext en'
  8. import traceback
  9. from threading import Thread
  10. from Queue import Queue, Empty
  11. from functools import partial
  12. from PyQt4.Qt import QObject, Qt, pyqtSignal, QTimer, QDialog, QVBoxLayout, QTextBrowser, QLabel, QGroupBox, QDialogButtonBox
  13. from calibre.ebooks.metadata.fetch import search, get_social_metadata
  14. from calibre.gui2 import config, error_dialog
  15. from calibre.gui2.dialogs.progress import ProgressDialog
  16. from calibre.ebooks.metadata.covers import download_cover
  17. from calibre.customize.ui import get_isbndb_key
  18.  
  19. class Worker(Thread):
  20.     
  21.     def __init__(self):
  22.         Thread.__init__(self)
  23.         self.daemon = True
  24.         self.jobs = Queue()
  25.         self.results = Queue()
  26.  
  27.     
  28.     def run(self):
  29.         while True:
  30.             (id, mi) = self.jobs.get()
  31.             if not getattr(mi, 'isbn', False):
  32.                 break
  33.             
  34.             
  35.             try:
  36.                 (cdata, errors) = download_cover(mi)
  37.                 if cdata:
  38.                     self.results.put((id, mi, True, cdata))
  39.                 else:
  40.                     msg = []
  41.                     for e in errors:
  42.                         if not e[0]:
  43.                             msg.append(e[-1] + ' - ' + e[1])
  44.                             continue
  45.                     
  46.                     self.results.put((id, mi, False, '\n'.join(msg)))
  47.             continue
  48.             self.results.put((id, mi, False, traceback.format_exc()))
  49.             continue
  50.  
  51.  
  52.     
  53.     def __enter__(self):
  54.         self.start()
  55.         return self
  56.  
  57.     
  58.     def __exit__(self, *args):
  59.         self.jobs.put((False, False))
  60.  
  61.  
  62.  
  63. class DownloadMetadata(Thread):
  64.     
  65.     def __init__(self, db, ids, get_covers, set_metadata = True, get_social_metadata = True):
  66.         Thread.__init__(self)
  67.         self.daemon = True
  68.         self.metadata = { }
  69.         self.covers = { }
  70.         self.set_metadata = set_metadata
  71.         self.get_social_metadata = get_social_metadata
  72.         self.social_metadata_exceptions = []
  73.         self.db = db
  74.         self.updated = set([])
  75.         self.get_covers = get_covers
  76.         self.worker = Worker()
  77.         self.results = Queue()
  78.         self.keep_going = True
  79.         for id in ids:
  80.             self.metadata[id] = db.get_metadata(id, index_is_id = True)
  81.             self.metadata[id].rating = None
  82.         
  83.         self.total = len(ids)
  84.         if self.get_covers:
  85.             self.total += len(ids)
  86.         
  87.         self.fetched_metadata = { }
  88.         self.fetched_covers = { }
  89.         self.failures = { }
  90.         self.cover_failures = { }
  91.         self.exception = None
  92.         self.tb = None
  93.  
  94.     
  95.     def run(self):
  96.         
  97.         try:
  98.             self._run()
  99.         except Exception:
  100.             e = None
  101.             self.exception = e
  102.             self.tb = traceback.format_exc()
  103.  
  104.  
  105.     
  106.     def _run(self):
  107.         self.key = get_isbndb_key()
  108.         if not self.key:
  109.             self.key = None
  110.         
  111.         self.worker.__enter__()
  112.         
  113.         try:
  114.             for id, mi in self.metadata.items():
  115.                 args = { }
  116.                 if mi.isbn:
  117.                     args['isbn'] = mi.isbn
  118.                 elif mi.is_null('title'):
  119.                     self.failures[id] = _('Book has neither title nor ISBN')
  120.                     continue
  121.                 
  122.                 args['title'] = mi.title
  123.                 if mi.authors and mi.authors[0] != _('Unknown'):
  124.                     args['author'] = mi.authors[0]
  125.                 
  126.                 if self.key:
  127.                     args['isbndb_key'] = self.key
  128.                 
  129.                 (results, exceptions) = search(**args)
  130.                 if results:
  131.                     fmi = results[0]
  132.                     self.fetched_metadata[id] = fmi
  133.                     if self.get_covers:
  134.                         if fmi.isbn:
  135.                             self.worker.jobs.put((id, fmi))
  136.                         else:
  137.                             self.results.put((id, 'cover', False, mi.title))
  138.                     
  139.                     if not config['overwrite_author_title_metadata']:
  140.                         fmi.authors = mi.authors
  141.                         fmi.author_sort = mi.author_sort
  142.                         fmi.title = mi.title
  143.                     
  144.                     mi.smart_update(fmi)
  145.                     if mi.isbn and self.get_social_metadata:
  146.                         self.social_metadata_exceptions = get_social_metadata(mi)
  147.                         if mi.rating:
  148.                             mi.rating *= 2
  149.                         
  150.                     
  151.                     if not self.get_social_metadata:
  152.                         mi.tags = []
  153.                     
  154.                     self.results.put((id, 'metadata', True, mi.title))
  155.                 else:
  156.                     self.failures[id] = _('No matches found for this book')
  157.                     self.results.put((id, 'metadata', False, mi.title))
  158.                     self.results.put((id, 'cover', False, mi.title))
  159.                 self.commit_covers()
  160.         finally:
  161.             pass
  162.  
  163.         self.commit_covers(True)
  164.  
  165.     
  166.     def commit_covers(self, all = False):
  167.         if all:
  168.             self.worker.jobs.put((False, False))
  169.         
  170.         while True:
  171.             
  172.             try:
  173.                 (id, fmi, ok, cdata) = self.worker.results.get_nowait()
  174.                 if ok:
  175.                     self.fetched_covers[id] = cdata
  176.                     self.results.put((id, 'cover', ok, fmi.title))
  177.                 else:
  178.                     self.results.put((id, 'cover', ok, fmi.title))
  179.                     
  180.                     try:
  181.                         self.cover_failures[id] = unicode(cdata)
  182.                     except:
  183.                         self.cover_failures[id] = repr(cdata)
  184.  
  185.             continue
  186.             except Empty:
  187.                 if not all or not self.worker.is_alive():
  188.                     return None
  189.                 continue
  190.                 not self.worker.is_alive()
  191.             
  192.  
  193.             None<EXCEPTION MATCH>Empty
  194.  
  195.  
  196.  
  197. class DoDownload(QObject):
  198.     idle_process = pyqtSignal()
  199.     
  200.     def __init__(self, parent, title, db, ids, get_covers, set_metadata = True, get_social_metadata = True):
  201.         QObject.__init__(self, parent)
  202.         self.pd = ProgressDialog(title, min = 0, max = 0, parent = parent)
  203.         self.pd.canceled_signal.connect(self.cancel)
  204.         self.idle_process.connect(self.do_one, type = Qt.QueuedConnection)
  205.         self.downloader = None
  206.         self.create = partial(DownloadMetadata, db, ids, get_covers, set_metadata = set_metadata, get_social_metadata = get_social_metadata)
  207.         self.timer = QTimer(self)
  208.         self.timer.timeout.connect(self.do_one, type = Qt.QueuedConnection)
  209.         self.db = db
  210.         self.updated = set([])
  211.         self.total = len(ids)
  212.  
  213.     
  214.     def exec_(self):
  215.         self.timer.start(50)
  216.         ret = self.pd.exec_()
  217.         if getattr(self.downloader, 'exception', None) is not None and ret == self.pd.Accepted:
  218.             error_dialog(self.parent(), _('Failed'), _('Failed to download metadata'), show = True)
  219.         else:
  220.             self.show_report()
  221.         return ret
  222.  
  223.     
  224.     def cancel(self, *args):
  225.         self.timer.stop()
  226.         self.downloader.keep_going = False
  227.         self.pd.reject()
  228.  
  229.     
  230.     def do_one(self):
  231.         if self.downloader is None:
  232.             self.downloader = self.create()
  233.             self.downloader.start()
  234.             self.pd.set_min(0)
  235.             self.pd.set_max(self.downloader.total)
  236.         
  237.         
  238.         try:
  239.             r = self.downloader.results.get_nowait()
  240.             self.handle_result(r)
  241.         except Empty:
  242.             pass
  243.  
  244.         if not self.downloader.is_alive():
  245.             self.timer.stop()
  246.             while True:
  247.                 
  248.                 try:
  249.                     r = self.downloader.results.get_nowait()
  250.                     self.handle_result(r)
  251.                 continue
  252.                 except Empty:
  253.                     break
  254.                     continue
  255.                 
  256.  
  257.                 None<EXCEPTION MATCH>Empty
  258.             self.pd.accept()
  259.         
  260.  
  261.     
  262.     def handle_result(self, r):
  263.         (id_, typ, ok, title) = r
  264.         what = None if typ == 'cover' else _('metadata')
  265.         which = None if ok else _('Failed to get')
  266.         self.pd.set_msg(_('%s %s for: %s') % (which, what, title))
  267.         self.pd.value += 1
  268.  
  269.     
  270.     def set_metadata(self, id_):
  271.         mi = self.downloader.metadata[id_]
  272.         if self.downloader.set_metadata:
  273.             self.db.set_metadata(id_, mi)
  274.         
  275.         if not (self.downloader.set_metadata) and self.downloader.get_social_metadata:
  276.             if mi.rating:
  277.                 self.db.set_rating(id_, mi.rating)
  278.             
  279.             if mi.tags:
  280.                 self.db.set_tags(id_, mi.tags)
  281.             
  282.             if mi.comments:
  283.                 self.db.set_comment(id_, mi.comments)
  284.             
  285.             if mi.series:
  286.                 self.db.set_series(id_, mi.series)
  287.                 if mi.series_index is not None:
  288.                     self.db.set_series_index(id_, mi.series_index)
  289.                 
  290.             
  291.         
  292.  
  293.     
  294.     def show_report(self):
  295.         f = self.downloader.failures
  296.         cf = self.downloader.cover_failures
  297.         report = []
  298.         if f:
  299.             report.append('<h3>Failed to download metadata for the following:</h3><ol>')
  300.             for id_, err in f.items():
  301.                 mi = self.downloader.metadata[id_]
  302.                 report.append('<li><b>%s</b><pre>%s</pre></li>' % (mi.title, unicode(err)))
  303.             
  304.             report.append('</ol>')
  305.         
  306.         if cf:
  307.             report.append('<h3>Failed to download cover for the following:</h3><ol>')
  308.             for id_, err in cf.items():
  309.                 mi = self.downloader.metadata[id_]
  310.                 report.append('<li><b>%s</b><pre>%s</pre></li>' % (mi.title, unicode(err)))
  311.             
  312.             report.append('</ol>')
  313.         
  314.         if len(self.updated) != self.total or report:
  315.             d = QDialog(self.parent())
  316.             bb = QDialogButtonBox(QDialogButtonBox.Ok, parent = d)
  317.             v1 = QVBoxLayout()
  318.             d.setLayout(v1)
  319.             d.setWindowTitle(_('Done'))
  320.             v1.addWidget(QLabel(_('Successfully downloaded metadata for %d out of %d books') % (len(self.updated), self.total)))
  321.             gb = QGroupBox(_('Details'), self.parent())
  322.             v2 = QVBoxLayout()
  323.             gb.setLayout(v2)
  324.             b = QTextBrowser(self.parent())
  325.             v2.addWidget(b)
  326.             b.setHtml('\n'.join(report))
  327.             v1.addWidget(gb)
  328.             v1.addWidget(bb)
  329.             bb.accepted.connect(d.accept)
  330.             d.resize(800, 600)
  331.             d.exec_()
  332.         
  333.  
  334.  
  335.