diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index 0897199289..fd1ccd0349 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -1645,3 +1645,33 @@ plugins += [ # }}} +if __name__ == '__main__': + # Test load speed + import subprocess, textwrap + try: + subprocess.check_call(['python', '-c', textwrap.dedent( + ''' + from __future__ import print_function + import time, sys, init_calibre + st = time.time() + import calibre.customize.builtins + t = time.time() - st + ret = 0 + + for x in ('lxml', 'calibre.ebooks.BeautifulSoup', 'uuid', + 'calibre.utils.terminfo', 'calibre.utils.magick', 'PIL', 'Image', + 'sqlite3', 'mechanize', 'httplib', 'xml'): + if x in sys.modules: + ret = 1 + print (x, 'has been loaded by a plugin') + if ret: + print ('\\nA good way to trackdown what is loading something is to run' + ' python -c "import init_calibre; import calibre.customize.builtins"') + print() + print ('Time taken to import all plugins: %.2f'%t) + sys.exit(ret) + + ''')]) + except subprocess.CalledProcessError: + raise SystemExit(1) + diff --git a/src/calibre/customize/profiles.py b/src/calibre/customize/profiles.py index 8bb0e55f5e..f6ed6ce3ec 100644 --- a/src/calibre/customize/profiles.py +++ b/src/calibre/customize/profiles.py @@ -5,7 +5,6 @@ __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' from itertools import izip -from xml.sax.saxutils import escape from calibre.customize import Plugin as _Plugin @@ -268,6 +267,7 @@ class OutputProfile(Plugin): @classmethod def tags_to_string(cls, tags): + from xml.sax.saxutils import escape return escape(', '.join(tags)) class iPadOutput(OutputProfile): diff --git a/src/calibre/devices/apple/driver.py b/src/calibre/devices/apple/driver.py index 5ed389a7b1..524a62224f 100644 --- a/src/calibre/devices/apple/driver.py +++ b/src/calibre/devices/apple/driver.py @@ -17,7 +17,6 @@ from calibre.ebooks.metadata import authors_to_string, MetaInformation, title_so from calibre.ebooks.metadata.book.base import Metadata from calibre.utils.config import config_dir, dynamic, prefs from calibre.utils.date import now, parse_date -from calibre.utils.logging import Log from calibre.utils.zipfile import ZipFile def strftime(fmt='%Y/%m/%d %H:%M:%S', dt=None): @@ -30,13 +29,18 @@ def strftime(fmt='%Y/%m/%d %H:%M:%S', dt=None): except: return _strftime(fmt, now().timetuple()) - +_log = None +def logger(): + global _log + if _log is None: + from calibre.utils.logging import ThreadSafeLog + _log = ThreadSafeLog() + return _log class AppleOpenFeedback(OpenFeedback): def __init__(self, plugin): OpenFeedback.__init__(self, u'') - self.log = plugin.log self.plugin = plugin def custom_dialog(self, parent): @@ -86,12 +90,13 @@ class AppleOpenFeedback(OpenFeedback): self.finished.connect(self.do_it) def do_it(self, return_code): + from calibre.utils.logging import default_log if return_code == self.Accepted: - self.cd.log.info(" Apple driver ENABLED") + default_log.info(" Apple driver ENABLED") dynamic[confirm_config_name(self.cd.plugin.DISPLAY_DISABLE_DIALOG)] = False else: from calibre.customize.ui import disable_plugin - self.cd.log.info(" Apple driver DISABLED") + default_log.info(" Apple driver DISABLED") disable_plugin(self.cd.plugin) return Dialog(parent, self) @@ -303,7 +308,6 @@ class ITUNES(DriverBase): iTunes= None iTunes_local_storage = None library_orphans = None - log = Log() manual_sync_mode = False path_template = 'iTunes/%s - %s.%s' plugboards = None @@ -329,7 +333,7 @@ class ITUNES(DriverBase): L{books}(oncard='cardb')). ''' if DEBUG: - self.log.info("ITUNES.add_books_to_metadata()") + logger().info("ITUNES.add_books_to_metadata()") task_count = float(len(self.update_list)) @@ -343,10 +347,10 @@ class ITUNES(DriverBase): for (j,p_book) in enumerate(self.update_list): if False: if isosx: - self.log.info(" looking for '%s' by %s uuid:%s" % + logger().info(" looking for '%s' by %s uuid:%s" % (p_book['title'],p_book['author'], p_book['uuid'])) elif iswindows: - self.log.info(" looking for '%s' by %s (%s)" % + logger().info(" looking for '%s' by %s (%s)" % (p_book['title'],p_book['author'], p_book['uuid'])) # Purge the booklist, self.cached_books @@ -356,10 +360,10 @@ class ITUNES(DriverBase): booklists[0].pop(i) if False: if isosx: - self.log.info(" removing old %s %s from booklists[0]" % + logger().info(" removing old %s %s from booklists[0]" % (p_book['title'], str(p_book['lib_book'])[-9:])) elif iswindows: - self.log.info(" removing old '%s' from booklists[0]" % + logger().info(" removing old '%s' from booklists[0]" % (p_book['title'])) # If >1 matching uuid, remove old title @@ -389,7 +393,7 @@ class ITUNES(DriverBase): # for new_book in metadata[0]: for new_book in locations[0]: if DEBUG: - self.log.info(" adding '%s' by '%s' to booklists[0]" % + logger().info(" adding '%s' by '%s' to booklists[0]" % (new_book.title, new_book.author)) booklists[0].append(new_book) @@ -414,15 +418,15 @@ class ITUNES(DriverBase): """ if not oncard: if DEBUG: - self.log.info("ITUNES:books():") + logger().info("ITUNES:books():") if self.settings().extra_customization[self.CACHE_COVERS]: - self.log.info(" Cover fetching/caching enabled") + logger().info(" Cover fetching/caching enabled") else: - self.log.info(" Cover fetching/caching disabled") + logger().info(" Cover fetching/caching disabled") # Fetch a list of books from iPod device connected to iTunes if 'iPod' in self.sources: - booklist = BookList(self.log) + booklist = BookList(logger()) cached_books = {} if isosx: @@ -513,7 +517,7 @@ class ITUNES(DriverBase): self._dump_cached_books('returning from books()',indent=2) return booklist else: - return BookList(self.log) + return BookList(logger()) def can_handle(self, device_info, debug=False): ''' @@ -550,7 +554,7 @@ class ITUNES(DriverBase): # We need to know if iTunes sees the iPad # It may have been ejected if DEBUG: - self.log.info("ITUNES.can_handle()") + logger().info("ITUNES.can_handle()") self._launch_iTunes() self.sources = self._get_sources() @@ -563,15 +567,15 @@ class ITUNES(DriverBase): attempts -= 1 time.sleep(0.5) if DEBUG: - self.log.warning(" waiting for connected iPad, attempt #%d" % (10 - attempts)) + logger().warning(" waiting for connected iPad, attempt #%d" % (10 - attempts)) else: if DEBUG: - self.log.info(' found connected iPad') + logger().info(' found connected iPad') break else: # iTunes running, but not connected iPad if DEBUG: - self.log.info(' self.ejected = True') + logger().info(' self.ejected = True') self.ejected = True return False @@ -605,26 +609,26 @@ class ITUNES(DriverBase): sys.stdout.write('.') sys.stdout.flush() if DEBUG: - self.log.info('ITUNES.can_handle_windows:\n confirming connected iPad') + logger().info('ITUNES.can_handle_windows:\n confirming connected iPad') self.ejected = False self._discover_manual_sync_mode() return True else: if DEBUG: - self.log.info("ITUNES.can_handle_windows():\n device ejected") + logger().info("ITUNES.can_handle_windows():\n device ejected") self.ejected = True return False except: # iTunes connection failed, probably not running anymore - self.log.error("ITUNES.can_handle_windows():\n lost connection to iTunes") + logger().error("ITUNES.can_handle_windows():\n lost connection to iTunes") return False finally: pythoncom.CoUninitialize() else: if DEBUG: - self.log.info("ITUNES:can_handle_windows():\n Launching iTunes") + logger().info("ITUNES:can_handle_windows():\n Launching iTunes") try: pythoncom.CoInitialize() @@ -639,19 +643,19 @@ class ITUNES(DriverBase): attempts -= 1 time.sleep(0.5) if DEBUG: - self.log.warning(" waiting for connected iPad, attempt #%d" % (10 - attempts)) + logger().warning(" waiting for connected iPad, attempt #%d" % (10 - attempts)) else: if DEBUG: - self.log.info(' found connected iPad in iTunes') + logger().info(' found connected iPad in iTunes') break else: # iTunes running, but not connected iPad if DEBUG: - self.log.info(' iDevice has been ejected') + logger().info(' iDevice has been ejected') self.ejected = True return False - self.log.info(' found connected iPad in sources') + logger().info(' found connected iPad in sources') self._discover_manual_sync_mode(wait=1.0) finally: @@ -694,11 +698,11 @@ class ITUNES(DriverBase): self.problem_msg = _("Some books not found in iTunes database.\n" "Delete using the iBooks app.\n" "Click 'Show Details' for a list.") - self.log.info("ITUNES:delete_books()") + logger().info("ITUNES:delete_books()") for path in paths: if self.cached_books[path]['lib_book']: if DEBUG: - self.log.info(" Deleting '%s' from iTunes library" % (path)) + logger().info(" Deleting '%s' from iTunes library" % (path)) if isosx: self._remove_from_iTunes(self.cached_books[path]) @@ -718,7 +722,7 @@ class ITUNES(DriverBase): self.update_needed = True self.update_msg = "Deleted books from device" else: - self.log.info(" skipping sync phase, manual_sync_mode: True") + logger().info(" skipping sync phase, manual_sync_mode: True") else: if self.manual_sync_mode: metadata = MetaInformation(self.cached_books[path]['title'], @@ -745,7 +749,7 @@ class ITUNES(DriverBase): are pending GUI jobs that need to communicate with the device. ''' if DEBUG: - self.log.info("ITUNES:eject(): ejecting '%s'" % self.sources['iPod']) + logger().info("ITUNES:eject(): ejecting '%s'" % self.sources['iPod']) if isosx: self.iTunes.eject(self.sources['iPod']) elif iswindows: @@ -774,7 +778,7 @@ class ITUNES(DriverBase): In Windows, a sync-in-progress blocks this call until sync is complete """ if DEBUG: - self.log.info("ITUNES:free_space()") + logger().info("ITUNES:free_space()") free_space = 0 if isosx: @@ -796,7 +800,7 @@ class ITUNES(DriverBase): pythoncom.CoUninitialize() break except: - self.log.error(' waiting for free_space() call to go through') + logger().error(' waiting for free_space() call to go through') return (free_space,-1,-1) @@ -806,7 +810,7 @@ class ITUNES(DriverBase): @return: (device name, device version, software version on device, mime type) """ if DEBUG: - self.log.info("ITUNES:get_device_information()") + logger().info("ITUNES:get_device_information()") return (self.sources['iPod'],'hw v1.0','sw v1.0', 'mime type normally goes here') @@ -816,7 +820,7 @@ class ITUNES(DriverBase): @param outfile: file object like C{sys.stdout} or the result of an C{open} call ''' if DEBUG: - self.log.info("ITUNES.get_file(): exporting '%s'" % path) + logger().info("ITUNES.get_file(): exporting '%s'" % path) outfile.write(open(self.cached_books[path]['lib_book'].location().path).read()) @@ -836,7 +840,7 @@ class ITUNES(DriverBase): ''' if DEBUG: - self.log.info("ITUNES.open(connected_device: %s)" % repr(connected_device)) + logger().info("ITUNES.open(connected_device: %s)" % repr(connected_device)) # Display a dialog recommending using 'Connect to iTunes' if user hasn't # previously disabled the dialog @@ -844,33 +848,33 @@ class ITUNES(DriverBase): raise AppleOpenFeedback(self) else: if DEBUG: - self.log.warning(" %s" % self.UNSUPPORTED_DIRECT_CONNECT_MODE_MESSAGE) + logger().warning(" %s" % self.UNSUPPORTED_DIRECT_CONNECT_MODE_MESSAGE) # Confirm/create thumbs archive if not os.path.exists(self.cache_dir): if DEBUG: - self.log.info(" creating thumb cache at '%s'" % self.cache_dir) + logger().info(" creating thumb cache at '%s'" % self.cache_dir) os.makedirs(self.cache_dir) if not os.path.exists(self.archive_path): - self.log.info(" creating zip archive") + logger().info(" creating zip archive") zfw = ZipFile(self.archive_path, mode='w') zfw.writestr("iTunes Thumbs Archive",'') zfw.close() else: if DEBUG: - self.log.info(" existing thumb cache at '%s'" % self.archive_path) + logger().info(" existing thumb cache at '%s'" % self.archive_path) # If enabled in config options, create/confirm an iTunes storage folder if not self.settings().extra_customization[self.USE_ITUNES_STORAGE]: self.iTunes_local_storage = os.path.join(config_dir,'iTunes storage') if not os.path.exists(self.iTunes_local_storage): if DEBUG: - self.log(" creating iTunes_local_storage at '%s'" % self.iTunes_local_storage) + logger()(" creating iTunes_local_storage at '%s'" % self.iTunes_local_storage) os.mkdir(self.iTunes_local_storage) else: if DEBUG: - self.log(" existing iTunes_local_storage at '%s'" % self.iTunes_local_storage) + logger()(" existing iTunes_local_storage at '%s'" % self.iTunes_local_storage) def remove_books_from_metadata(self, paths, booklists): ''' @@ -885,11 +889,11 @@ class ITUNES(DriverBase): as uuids are different ''' if DEBUG: - self.log.info("ITUNES.remove_books_from_metadata()") + logger().info("ITUNES.remove_books_from_metadata()") for path in paths: if DEBUG: self._dump_cached_book(self.cached_books[path], indent=2) - self.log.info(" looking for '%s' by '%s' uuid:%s" % + logger().info(" looking for '%s' by '%s' uuid:%s" % (self.cached_books[path]['title'], self.cached_books[path]['author'], self.cached_books[path]['uuid'])) @@ -897,19 +901,19 @@ class ITUNES(DriverBase): # Purge the booklist, self.cached_books, thumb cache for i,bl_book in enumerate(booklists[0]): if False: - self.log.info(" evaluating '%s' by '%s' uuid:%s" % + logger().info(" evaluating '%s' by '%s' uuid:%s" % (bl_book.title, bl_book.author,bl_book.uuid)) found = False if bl_book.uuid == self.cached_books[path]['uuid']: if False: - self.log.info(" matched with uuid") + logger().info(" matched with uuid") booklists[0].pop(i) found = True elif bl_book.title == self.cached_books[path]['title'] and \ bl_book.author[0] == self.cached_books[path]['author']: if False: - self.log.info(" matched with title + author") + logger().info(" matched with title + author") booklists[0].pop(i) found = True @@ -930,17 +934,17 @@ class ITUNES(DriverBase): thumb = None if thumb: if DEBUG: - self.log.info(" deleting '%s' from cover cache" % (thumb_path)) + logger().info(" deleting '%s' from cover cache" % (thumb_path)) zf.delete(thumb_path) else: if DEBUG: - self.log.info(" '%s' not found in cover cache" % thumb_path) + logger().info(" '%s' not found in cover cache" % thumb_path) zf.close() break else: if DEBUG: - self.log.error(" unable to find '%s' by '%s' (%s)" % + logger().error(" unable to find '%s' by '%s' (%s)" % (bl_book.title, bl_book.author,bl_book.uuid)) if False: @@ -959,7 +963,7 @@ class ITUNES(DriverBase): :detected_device: Device information from the device scanner """ if DEBUG: - self.log.info("ITUNES.reset()") + logger().info("ITUNES.reset()") if report_progress: self.set_progress_reporter(report_progress) @@ -971,7 +975,7 @@ class ITUNES(DriverBase): task does not have any progress information ''' if DEBUG: - self.log.info("ITUNES.set_progress_reporter()") + logger().info("ITUNES.set_progress_reporter()") self.report_progress = report_progress @@ -979,8 +983,8 @@ class ITUNES(DriverBase): # This method is called with the plugboard that matches the format # declared in use_plugboard_ext and a device name of ITUNES if DEBUG: - self.log.info("ITUNES.set_plugboard()") - #self.log.info(' plugboard: %s' % plugboards) + logger().info("ITUNES.set_plugboard()") + #logger().info(' plugboard: %s' % plugboards) self.plugboards = plugboards self.plugboard_func = pb_func @@ -993,11 +997,11 @@ class ITUNES(DriverBase): ''' if DEBUG: - self.log.info("ITUNES.sync_booklists()") + logger().info("ITUNES.sync_booklists()") if self.update_needed: if DEBUG: - self.log.info(' calling _update_device') + logger().info(' calling _update_device') self._update_device(msg=self.update_msg, wait=False) self.update_needed = False @@ -1020,7 +1024,7 @@ class ITUNES(DriverBase): particular device doesn't have any of these locations it should return 0. """ if DEBUG: - self.log.info("ITUNES:total_space()") + logger().info("ITUNES:total_space()") capacity = 0 if isosx: if 'iPod' in self.sources: @@ -1058,7 +1062,7 @@ class ITUNES(DriverBase): "Click 'Show Details' for a list.") if DEBUG: - self.log.info("ITUNES.upload_books()") + logger().info("ITUNES.upload_books()") if isosx: for (i,fpath) in enumerate(files): @@ -1075,8 +1079,8 @@ class ITUNES(DriverBase): # Add new_book to self.cached_books if DEBUG: - self.log.info("ITUNES.upload_books()") - self.log.info(" adding '%s' by '%s' uuid:%s to self.cached_books" % + logger().info("ITUNES.upload_books()") + logger().info(" adding '%s' by '%s' uuid:%s to self.cached_books" % (metadata[i].title, authors_to_string(metadata[i].authors), metadata[i].uuid)) @@ -1119,8 +1123,8 @@ class ITUNES(DriverBase): # Add new_book to self.cached_books if DEBUG: - self.log.info("ITUNES.upload_books()") - self.log.info(" adding '%s' by '%s' uuid:%s to self.cached_books" % + logger().info("ITUNES.upload_books()") + logger().info(" adding '%s' by '%s' uuid:%s to self.cached_books" % (metadata[i].title, authors_to_string(metadata[i].authors), metadata[i].uuid)) @@ -1157,7 +1161,7 @@ class ITUNES(DriverBase): ''' assumes pythoncom wrapper for windows ''' - self.log.info(" ITUNES._add_device_book()") + logger().info(" ITUNES._add_device_book()") if isosx: if 'iPod' in self.sources: connected_device = self.sources['iPod'] @@ -1167,12 +1171,12 @@ class ITUNES(DriverBase): break else: if DEBUG: - self.log.error(" Device|Books playlist not found") + logger().error(" Device|Books playlist not found") # Add the passed book to the Device|Books playlist added = pl.add(appscript.mactypes.File(fpath),to=pl) if False: - self.log.info(" '%s' added to Device|Books" % metadata.title) + logger().info(" '%s' added to Device|Books" % metadata.title) self._wait_for_writable_metadata(added) return added @@ -1189,7 +1193,7 @@ class ITUNES(DriverBase): break else: if DEBUG: - self.log.info(" no Books playlist found") + logger().info(" no Books playlist found") # Add the passed book to the Device|Books playlist if pl: @@ -1251,7 +1255,7 @@ class ITUNES(DriverBase): windows assumes pythoncom wrapper ''' if DEBUG: - self.log.info(" ITUNES._add_library_book()") + logger().info(" ITUNES._add_library_book()") if isosx: added = self.iTunes.add(appscript.mactypes.File(file)) @@ -1262,9 +1266,9 @@ class ITUNES(DriverBase): fa = FileArray(file_s) op_status = lib.AddFiles(fa) if DEBUG: - self.log.info(" file added to Library|Books") + logger().info(" file added to Library|Books") - self.log.info(" iTunes adding '%s'" % file) + logger().info(" iTunes adding '%s'" % file) if DEBUG: sys.stdout.write(" iTunes copying '%s' ..." % metadata.title) @@ -1318,7 +1322,7 @@ class ITUNES(DriverBase): fp = cached_book['lib_book'].Location ''' if DEBUG: - self.log.info(" ITUNES._add_new_copy()") + logger().info(" ITUNES._add_new_copy()") if fpath.rpartition('.')[2].lower() == 'epub': self._update_epub_metadata(fpath, metadata) @@ -1339,7 +1343,7 @@ class ITUNES(DriverBase): db_added = self._add_device_book(fpath, metadata) lb_added = self._add_library_book(fpath, metadata) if not lb_added and DEBUG: - self.log.warn(" failed to add '%s' to iTunes, iTunes Media folder inaccessible" % metadata.title) + logger().warn(" failed to add '%s' to iTunes, iTunes Media folder inaccessible" % metadata.title) else: lb_added = self._add_library_book(fpath, metadata) if not lb_added: @@ -1357,7 +1361,7 @@ class ITUNES(DriverBase): from PIL import Image as PILImage if DEBUG: - self.log.info(" ITUNES._cover_to_thumb()") + logger().info(" ITUNES._cover_to_thumb()") thumb = None if metadata.cover: @@ -1374,7 +1378,7 @@ class ITUNES(DriverBase): scaled, nwidth, nheight = fit_image(width, height, self.MAX_COVER_WIDTH, self.MAX_COVER_HEIGHT) if scaled: if DEBUG: - self.log.info(" cover scaled from %sx%s to %sx%s" % + logger().info(" cover scaled from %sx%s to %sx%s" % (width,height,nwidth,nheight)) img = img.resize((nwidth, nheight), PILImage.ANTIALIAS) cd = cStringIO.StringIO() @@ -1386,7 +1390,7 @@ class ITUNES(DriverBase): cover_data = cd.read() except: self.problem_titles.append("'%s' by %s" % (metadata.title, authors_to_string(metadata.authors))) - self.log.error(" error scaling '%s' for '%s'" % (metadata.cover,metadata.title)) + logger().error(" error scaling '%s' for '%s'" % (metadata.cover,metadata.title)) import traceback traceback.print_exc() @@ -1404,17 +1408,17 @@ class ITUNES(DriverBase): lb_added.artworks[1].data_.set(cover_data) except: if DEBUG: - self.log.warning(" iTunes automation interface reported an error" + logger().warning(" iTunes automation interface reported an error" " adding artwork to '%s' in the iTunes Library" % metadata.title) pass if db_added: try: db_added.artworks[1].data_.set(cover_data) - self.log.info(" writing '%s' cover to iDevice" % metadata.title) + logger().info(" writing '%s' cover to iDevice" % metadata.title) except: if DEBUG: - self.log.warning(" iTunes automation interface reported an error" + logger().warning(" iTunes automation interface reported an error" " adding artwork to '%s' on the iDevice" % metadata.title) #import traceback #traceback.print_exc() @@ -1436,7 +1440,7 @@ class ITUNES(DriverBase): lb_added.AddArtworkFromFile(tc) except: if DEBUG: - self.log.warning(" iTunes automation interface reported an error" + logger().warning(" iTunes automation interface reported an error" " when adding artwork to '%s' in the iTunes Library" % metadata.title) pass @@ -1448,7 +1452,7 @@ class ITUNES(DriverBase): elif format == 'pdf': if DEBUG: - self.log.info(" unable to set PDF cover via automation interface") + logger().info(" unable to set PDF cover via automation interface") try: # Resize for thumb @@ -1463,13 +1467,13 @@ class ITUNES(DriverBase): # Refresh the thumbnail cache if DEBUG: - self.log.info( " refreshing cached thumb for '%s'" % metadata.title) + logger().info( " refreshing cached thumb for '%s'" % metadata.title) zfw = ZipFile(self.archive_path, mode='a') thumb_path = path.rpartition('.')[0] + '.jpg' zfw.writestr(thumb_path, thumb) except: self.problem_titles.append("'%s' by %s" % (metadata.title, authors_to_string(metadata.authors))) - self.log.error(" error converting '%s' to thumb for '%s'" % (metadata.cover,metadata.title)) + logger().error(" error converting '%s' to thumb for '%s'" % (metadata.cover,metadata.title)) finally: try: zfw.close() @@ -1477,14 +1481,14 @@ class ITUNES(DriverBase): pass else: if DEBUG: - self.log.info(" no cover defined in metadata for '%s'" % metadata.title) + logger().info(" no cover defined in metadata for '%s'" % metadata.title) return thumb def _create_new_book(self,fpath, metadata, path, db_added, lb_added, thumb, format): ''' ''' if DEBUG: - self.log.info(" ITUNES._create_new_book()") + logger().info(" ITUNES._create_new_book()") this_book = Book(metadata.title, authors_to_string(metadata.authors)) this_book.datetime = time.gmtime() @@ -1533,7 +1537,7 @@ class ITUNES(DriverBase): wait is passed when launching iTunes, as it seems to need a moment to come to its senses ''' if DEBUG: - self.log.info(" ITUNES._discover_manual_sync_mode()") + logger().info(" ITUNES._discover_manual_sync_mode()") if wait: time.sleep(wait) if isosx: @@ -1545,12 +1549,12 @@ class ITUNES(DriverBase): dev_books = pl.file_tracks() break else: - self.log.error(" book_playlist not found") + logger().error(" book_playlist not found") if dev_books is not None and len(dev_books): first_book = dev_books[0] if False: - self.log.info(" determing manual mode by modifying '%s' by %s" % (first_book.name(), first_book.artist())) + logger().info(" determing manual mode by modifying '%s' by %s" % (first_book.name(), first_book.artist())) try: first_book.bpm.set(0) self.manual_sync_mode = True @@ -1558,7 +1562,7 @@ class ITUNES(DriverBase): self.manual_sync_mode = False else: if DEBUG: - self.log.info(" adding tracer to empty Books|Playlist") + logger().info(" adding tracer to empty Books|Playlist") try: added = pl.add(appscript.mactypes.File(P('tracer.epub')),to=pl) time.sleep(0.5) @@ -1581,7 +1585,7 @@ class ITUNES(DriverBase): if dev_books is not None and dev_books.Count: first_book = dev_books.Item(1) #if DEBUG: - #self.log.info(" determing manual mode by modifying '%s' by %s" % (first_book.Name, first_book.Artist)) + #logger().info(" determing manual mode by modifying '%s' by %s" % (first_book.Name, first_book.Artist)) try: first_book.BPM = 0 self.manual_sync_mode = True @@ -1589,7 +1593,7 @@ class ITUNES(DriverBase): self.manual_sync_mode = False else: if DEBUG: - self.log.info(" sending tracer to empty Books|Playlist") + logger().info(" sending tracer to empty Books|Playlist") fpath = P('tracer.epub') mi = MetaInformation('Tracer',['calibre']) try: @@ -1600,24 +1604,24 @@ class ITUNES(DriverBase): except: self.manual_sync_mode = False - self.log.info(" iTunes.manual_sync_mode: %s" % self.manual_sync_mode) + logger().info(" iTunes.manual_sync_mode: %s" % self.manual_sync_mode) def _dump_booklist(self, booklist, header=None,indent=0): ''' ''' if header: msg = '\n%sbooklist %s:' % (' '*indent,header) - self.log.info(msg) - self.log.info('%s%s' % (' '*indent,'-' * len(msg))) + logger().info(msg) + logger().info('%s%s' % (' '*indent,'-' * len(msg))) for book in booklist: if isosx: - self.log.info("%s%-40.40s %-30.30s %-10.10s %s" % + logger().info("%s%-40.40s %-30.30s %-10.10s %s" % (' '*indent,book.title, book.author, str(book.library_id)[-9:], book.uuid)) elif iswindows: - self.log.info("%s%-40.40s %-30.30s" % + logger().info("%s%-40.40s %-30.30s" % (' '*indent,book.title, book.author)) - self.log.info() + logger().info() def _dump_cached_book(self, cached_book, header=None,indent=0): ''' @@ -1625,16 +1629,16 @@ class ITUNES(DriverBase): if isosx: if header: msg = '%s%s' % (' '*indent,header) - self.log.info(msg) - self.log.info( "%s%s" % (' '*indent, '-' * len(msg))) - self.log.info("%s%-40.40s %-30.30s %-10.10s %-10.10s %s" % + logger().info(msg) + logger().info( "%s%s" % (' '*indent, '-' * len(msg))) + logger().info("%s%-40.40s %-30.30s %-10.10s %-10.10s %s" % (' '*indent, 'title', 'author', 'lib_book', 'dev_book', 'uuid')) - self.log.info("%s%-40.40s %-30.30s %-10.10s %-10.10s %s" % + logger().info("%s%-40.40s %-30.30s %-10.10s %-10.10s %s" % (' '*indent, cached_book['title'], cached_book['author'], @@ -1644,10 +1648,10 @@ class ITUNES(DriverBase): elif iswindows: if header: msg = '%s%s' % (' '*indent,header) - self.log.info(msg) - self.log.info( "%s%s" % (' '*indent, '-' * len(msg))) + logger().info(msg) + logger().info( "%s%s" % (' '*indent, '-' * len(msg))) - self.log.info("%s%-40.40s %-30.30s %s" % + logger().info("%s%-40.40s %-30.30s %s" % (' '*indent, cached_book['title'], cached_book['author'], @@ -1658,11 +1662,11 @@ class ITUNES(DriverBase): ''' if header: msg = '\n%sself.cached_books %s:' % (' '*indent,header) - self.log.info(msg) - self.log.info( "%s%s" % (' '*indent,'-' * len(msg))) + logger().info(msg) + logger().info( "%s%s" % (' '*indent,'-' * len(msg))) if isosx: for cb in self.cached_books.keys(): - self.log.info("%s%-40.40s %-30.30s %-10.10s %-10.10s %s" % + logger().info("%s%-40.40s %-30.30s %-10.10s %-10.10s %s" % (' '*indent, self.cached_books[cb]['title'], self.cached_books[cb]['author'], @@ -1671,21 +1675,21 @@ class ITUNES(DriverBase): self.cached_books[cb]['uuid'])) elif iswindows: for cb in self.cached_books.keys(): - self.log.info("%s%-40.40s %-30.30s %-4.4s %s" % + logger().info("%s%-40.40s %-30.30s %-4.4s %s" % (' '*indent, self.cached_books[cb]['title'], self.cached_books[cb]['author'], self.cached_books[cb]['format'], self.cached_books[cb]['uuid'])) - self.log.info() + logger().info() def _dump_epub_metadata(self, fpath): ''' ''' from calibre.ebooks.BeautifulSoup import BeautifulSoup - self.log.info(" ITUNES.__get_epub_metadata()") + logger().info(" ITUNES.__get_epub_metadata()") title = None author = None timestamp = None @@ -1705,11 +1709,11 @@ class ITUNES(DriverBase): if not title or not author: if DEBUG: - self.log.error(" couldn't extract title/author from %s in %s" % (opf,fpath)) - self.log.error(" title: %s author: %s timestamp: %s" % (title, author, timestamp)) + logger().error(" couldn't extract title/author from %s in %s" % (opf,fpath)) + logger().error(" title: %s author: %s timestamp: %s" % (title, author, timestamp)) else: if DEBUG: - self.log.error(" can't find .opf in %s" % fpath) + logger().error(" can't find .opf in %s" % fpath) zf.close() return (title, author, timestamp) @@ -1730,20 +1734,20 @@ class ITUNES(DriverBase): ''' ''' if DEBUG: - self.log.info("\n library_books:") + logger().info("\n library_books:") for book in library_books: - self.log.info(" %s" % book) - self.log.info() + logger().info(" %s" % book) + logger().info() def _dump_update_list(self,header=None,indent=0): if header and self.update_list: msg = '\n%sself.update_list %s' % (' '*indent,header) - self.log.info(msg) - self.log.info( "%s%s" % (' '*indent,'-' * len(msg))) + logger().info(msg) + logger().info( "%s%s" % (' '*indent,'-' * len(msg))) if isosx: for ub in self.update_list: - self.log.info("%s%-40.40s %-30.30s %-10.10s %s" % + logger().info("%s%-40.40s %-30.30s %-10.10s %s" % (' '*indent, ub['title'], ub['author'], @@ -1751,7 +1755,7 @@ class ITUNES(DriverBase): ub['uuid'])) elif iswindows: for ub in self.update_list: - self.log.info("%s%-40.40s %-30.30s" % + logger().info("%s%-40.40s %-30.30s" % (' '*indent, ub['title'], ub['author'])) @@ -1763,42 +1767,42 @@ class ITUNES(DriverBase): if iswindows: dev_books = self._get_device_books_playlist() if DEBUG: - self.log.info(" ITUNES._find_device_book()") - self.log.info(" searching for '%s' by '%s' (%s)" % + logger().info(" ITUNES._find_device_book()") + logger().info(" searching for '%s' by '%s' (%s)" % (search['title'], search['author'],search['uuid'])) attempts = 9 while attempts: # Try by uuid - only one hit if 'uuid' in search and search['uuid']: if DEBUG: - self.log.info(" searching by uuid '%s' ..." % search['uuid']) + logger().info(" searching by uuid '%s' ..." % search['uuid']) hits = dev_books.Search(search['uuid'],self.SearchField.index('All')) if hits: hit = hits[0] - self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) + logger().info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) return hit # Try by author - there could be multiple hits if search['author']: if DEBUG: - self.log.info(" searching by author '%s' ..." % search['author']) + logger().info(" searching by author '%s' ..." % search['author']) hits = dev_books.Search(search['author'],self.SearchField.index('Artists')) if hits: for hit in hits: if hit.Name == search['title']: if DEBUG: - self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) + logger().info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) return hit # Search by title if no author available if DEBUG: - self.log.info(" searching by title '%s' ..." % search['title']) + logger().info(" searching by title '%s' ..." % search['title']) hits = dev_books.Search(search['title'],self.SearchField.index('All')) if hits: for hit in hits: if hit.Name == search['title']: if DEBUG: - self.log.info(" found '%s'" % (hit.Name)) + logger().info(" found '%s'" % (hit.Name)) return hit # PDF just sent, title not updated yet, look for export pattern @@ -1807,24 +1811,24 @@ class ITUNES(DriverBase): title = re.sub(r'[^0-9a-zA-Z ]', '_', search['title']) author = re.sub(r'[^0-9a-zA-Z ]', '_', search['author']) if DEBUG: - self.log.info(" searching by name: '%s - %s'" % (title,author)) + logger().info(" searching by name: '%s - %s'" % (title,author)) hits = dev_books.Search('%s - %s' % (title,author), self.SearchField.index('All')) if hits: hit = hits[0] - self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) + logger().info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) return hit else: if DEBUG: - self.log.info(" no PDF hits") + logger().info(" no PDF hits") attempts -= 1 time.sleep(0.5) if DEBUG: - self.log.warning(" attempt #%d" % (10 - attempts)) + logger().warning(" attempt #%d" % (10 - attempts)) if DEBUG: - self.log.error(" no hits") + logger().error(" no hits") return None def _find_library_book(self, search): @@ -1833,13 +1837,13 @@ class ITUNES(DriverBase): ''' if iswindows: if DEBUG: - self.log.info(" ITUNES._find_library_book()") + logger().info(" ITUNES._find_library_book()") ''' if 'uuid' in search: - self.log.info(" looking for '%s' by %s (%s)" % + logger().info(" looking for '%s' by %s (%s)" % (search['title'], search['author'], search['uuid'])) else: - self.log.info(" looking for '%s' by %s" % + logger().info(" looking for '%s' by %s" % (search['title'], search['author'])) ''' @@ -1847,11 +1851,11 @@ class ITUNES(DriverBase): if source.Kind == self.Sources.index('Library'): lib = source if DEBUG: - self.log.info(" Library source: '%s' kind: %s" % (lib.Name, self.Sources[lib.Kind])) + logger().info(" Library source: '%s' kind: %s" % (lib.Name, self.Sources[lib.Kind])) break else: if DEBUG: - self.log.info(" Library source not found") + logger().info(" Library source not found") if lib is not None: lib_books = None @@ -1859,12 +1863,12 @@ class ITUNES(DriverBase): if pl.Kind == self.PlaylistKind.index('User') and \ pl.SpecialKind == self.PlaylistSpecialKind.index('Books'): if DEBUG: - self.log.info(" Books playlist: '%s'" % (pl.Name)) + logger().info(" Books playlist: '%s'" % (pl.Name)) lib_books = pl break else: if DEBUG: - self.log.error(" no Books playlist found") + logger().error(" no Books playlist found") attempts = 9 @@ -1872,35 +1876,35 @@ class ITUNES(DriverBase): # Find book whose Album field = search['uuid'] if 'uuid' in search and search['uuid']: if DEBUG: - self.log.info(" searching by uuid '%s' ..." % search['uuid']) + logger().info(" searching by uuid '%s' ..." % search['uuid']) hits = lib_books.Search(search['uuid'],self.SearchField.index('All')) if hits: hit = hits[0] if DEBUG: - self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) + logger().info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) return hit # Search by author if known if search['author']: if DEBUG: - self.log.info(" searching by author '%s' ..." % search['author']) + logger().info(" searching by author '%s' ..." % search['author']) hits = lib_books.Search(search['author'],self.SearchField.index('Artists')) if hits: for hit in hits: if hit.Name == search['title']: if DEBUG: - self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) + logger().info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) return hit # Search by title if no author available if DEBUG: - self.log.info(" searching by title '%s' ..." % search['title']) + logger().info(" searching by title '%s' ..." % search['title']) hits = lib_books.Search(search['title'],self.SearchField.index('All')) if hits: for hit in hits: if hit.Name == search['title']: if DEBUG: - self.log.info(" found '%s'" % (hit.Name)) + logger().info(" found '%s'" % (hit.Name)) return hit # PDF just sent, title not updated yet, look for export pattern @@ -1909,24 +1913,24 @@ class ITUNES(DriverBase): title = re.sub(r'[^0-9a-zA-Z ]', '_', search['title']) author = re.sub(r'[^0-9a-zA-Z ]', '_', search['author']) if DEBUG: - self.log.info(" searching by name: %s - %s" % (title,author)) + logger().info(" searching by name: %s - %s" % (title,author)) hits = lib_books.Search('%s - %s' % (title,author), self.SearchField.index('All')) if hits: hit = hits[0] - self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) + logger().info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer)) return hit else: if DEBUG: - self.log.info(" no PDF hits") + logger().info(" no PDF hits") attempts -= 1 time.sleep(0.5) if DEBUG: - self.log.warning(" attempt #%d" % (10 - attempts)) + logger().warning(" attempt #%d" % (10 - attempts)) if DEBUG: - self.log.error(" search for '%s' yielded no hits" % search['title']) + logger().error(" search for '%s' yielded no hits" % search['title']) return None def _generate_thumbnail(self, book_path, book): @@ -1953,18 +1957,18 @@ class ITUNES(DriverBase): thumb_data = zfr.read(thumb_path) if thumb_data == 'None': if False: - self.log.info(" ITUNES._generate_thumbnail()\n returning None from cover cache for '%s'" % title) + logger().info(" ITUNES._generate_thumbnail()\n returning None from cover cache for '%s'" % title) zfr.close() return None except: zfw = ZipFile(self.archive_path, mode='a') else: if False: - self.log.info(" returning thumb from cache for '%s'" % title) + logger().info(" returning thumb from cache for '%s'" % title) return thumb_data if DEBUG: - self.log.info(" ITUNES._generate_thumbnail('%s'):" % title) + logger().info(" ITUNES._generate_thumbnail('%s'):" % title) if isosx: # Fetch the artwork from iTunes @@ -1973,7 +1977,7 @@ class ITUNES(DriverBase): except: # If no artwork, write an empty marker to cache if DEBUG: - self.log.error(" error fetching iTunes artwork for '%s'" % title) + logger().error(" error fetching iTunes artwork for '%s'" % title) zfw.writestr(thumb_path, 'None') zfw.close() return None @@ -1990,12 +1994,12 @@ class ITUNES(DriverBase): thumb_data = thumb.getvalue() thumb.close() if False: - self.log.info(" generated thumb for '%s', caching" % title) + logger().info(" generated thumb for '%s', caching" % title) # Cache the tagged thumb zfw.writestr(thumb_path, thumb_data) except: if DEBUG: - self.log.error(" error generating thumb for '%s', caching empty marker" % book.name()) + logger().error(" error generating thumb for '%s', caching empty marker" % book.name()) self._dump_hex(data[:32]) thumb_data = None # Cache the empty cover @@ -2010,7 +2014,7 @@ class ITUNES(DriverBase): elif iswindows: if not book.Artwork.Count: if DEBUG: - self.log.info(" no artwork available for '%s'" % book.Name) + logger().info(" no artwork available for '%s'" % book.Name) zfw.writestr(thumb_path, 'None') zfw.close() return None @@ -2030,12 +2034,12 @@ class ITUNES(DriverBase): os.remove(tmp_thumb) thumb.close() if False: - self.log.info(" generated thumb for '%s', caching" % book.Name) + logger().info(" generated thumb for '%s', caching" % book.Name) # Cache the tagged thumb zfw.writestr(thumb_path, thumb_data) except: if DEBUG: - self.log.error(" error generating thumb for '%s', caching empty marker" % book.Name) + logger().error(" error generating thumb for '%s', caching empty marker" % book.Name) thumb_data = None # Cache the empty cover zfw.writestr(thumb_path,'None') @@ -2058,9 +2062,9 @@ class ITUNES(DriverBase): for file in myZipList: exploded_file_size += file.file_size if False: - self.log.info(" ITUNES._get_device_book_size()") - self.log.info(" %d items in archive" % len(myZipList)) - self.log.info(" compressed: %d exploded: %d" % (compressed_size, exploded_file_size)) + logger().info(" ITUNES._get_device_book_size()") + logger().info(" %d items in archive" % len(myZipList)) + logger().info(" compressed: %d exploded: %d" % (compressed_size, exploded_file_size)) myZip.close() return exploded_file_size @@ -2069,7 +2073,7 @@ class ITUNES(DriverBase): Assumes pythoncom wrapper for Windows ''' if DEBUG: - self.log.info("\n ITUNES._get_device_books()") + logger().info("\n ITUNES._get_device_books()") device_books = [] if isosx: @@ -2080,24 +2084,24 @@ class ITUNES(DriverBase): for pl in device.playlists(): if pl.special_kind() == appscript.k.Books: if DEBUG: - self.log.info(" Book playlist: '%s'" % (pl.name())) + logger().info(" Book playlist: '%s'" % (pl.name())) dev_books = pl.file_tracks() break else: - self.log.error(" book_playlist not found") + logger().error(" book_playlist not found") for book in dev_books: # This may need additional entries for international iTunes users if book.kind() in self.Audiobooks: if DEBUG: - self.log.info(" ignoring '%s' of type '%s'" % (book.name(), book.kind())) + logger().info(" ignoring '%s' of type '%s'" % (book.name(), book.kind())) else: if DEBUG: - self.log.info(" %-30.30s %-30.30s %-40.40s [%s]" % + logger().info(" %-30.30s %-30.30s %-40.40s [%s]" % (book.name(), book.artist(), book.album(), book.kind())) device_books.append(book) if DEBUG: - self.log.info() + logger().info() elif iswindows: if 'iPod' in self.sources: @@ -2111,24 +2115,24 @@ class ITUNES(DriverBase): if pl.Kind == self.PlaylistKind.index('User') and \ pl.SpecialKind == self.PlaylistSpecialKind.index('Books'): if DEBUG: - self.log.info(" Books playlist: '%s'" % (pl.Name)) + logger().info(" Books playlist: '%s'" % (pl.Name)) dev_books = pl.Tracks break else: if DEBUG: - self.log.info(" no Books playlist found") + logger().info(" no Books playlist found") for book in dev_books: # This may need additional entries for international iTunes users if book.KindAsString in self.Audiobooks: if DEBUG: - self.log.info(" ignoring '%s' of type '%s'" % (book.Name, book.KindAsString)) + logger().info(" ignoring '%s' of type '%s'" % (book.Name, book.KindAsString)) else: if DEBUG: - self.log.info(" %-30.30s %-30.30s %-40.40s [%s]" % (book.Name, book.Artist, book.Album, book.KindAsString)) + logger().info(" %-30.30s %-30.30s %-40.40s [%s]" % (book.Name, book.Artist, book.Album, book.KindAsString)) device_books.append(book) if DEBUG: - self.log.info() + logger().info() finally: pythoncom.CoUninitialize() @@ -2151,7 +2155,7 @@ class ITUNES(DriverBase): break else: if DEBUG: - self.log.error(" no iPad|Books playlist found") + logger().error(" no iPad|Books playlist found") return pl def _get_library_books(self): @@ -2160,7 +2164,7 @@ class ITUNES(DriverBase): Windows assumes pythoncom wrapper ''' if DEBUG: - self.log.info("\n ITUNES._get_library_books()") + logger().info("\n ITUNES._get_library_books()") library_books = {} library_orphans = {} @@ -2171,11 +2175,11 @@ class ITUNES(DriverBase): if source.kind() == appscript.k.library: lib = source if DEBUG: - self.log.info(" Library source: '%s'" % (lib.name())) + logger().info(" Library source: '%s'" % (lib.name())) break else: if DEBUG: - self.log.error(' Library source not found') + logger().error(' Library source not found') if lib is not None: lib_books = None @@ -2183,18 +2187,18 @@ class ITUNES(DriverBase): for pl in lib.playlists(): if pl.special_kind() == appscript.k.Books: if DEBUG: - self.log.info(" Books playlist: '%s'" % (pl.name())) + logger().info(" Books playlist: '%s'" % (pl.name())) break else: if DEBUG: - self.log.info(" no Library|Books playlist found") + logger().info(" no Library|Books playlist found") lib_books = pl.file_tracks() for book in lib_books: # This may need additional entries for international iTunes users if book.kind() in self.Audiobooks: if DEBUG: - self.log.info(" ignoring '%s' of type '%s'" % (book.name(), book.kind())) + logger().info(" ignoring '%s' of type '%s'" % (book.name(), book.kind())) else: # Collect calibre orphans - remnants of recipe uploads format = 'pdf' if book.kind().startswith('PDF') else 'epub' @@ -2204,31 +2208,31 @@ class ITUNES(DriverBase): if book.location() == appscript.k.missing_value: library_orphans[path] = book if False: - self.log.info(" found iTunes PTF '%s' in Library|Books" % book.name()) + logger().info(" found iTunes PTF '%s' in Library|Books" % book.name()) except: if DEBUG: - self.log.error(" iTunes returned an error returning .location() with %s" % book.name()) + logger().error(" iTunes returned an error returning .location() with %s" % book.name()) library_books[path] = book if DEBUG: - self.log.info(" %-30.30s %-30.30s %-40.40s [%s]" % + logger().info(" %-30.30s %-30.30s %-40.40s [%s]" % (book.name(), book.artist(), book.album(), book.kind())) else: if DEBUG: - self.log.info(' no Library playlists') + logger().info(' no Library playlists') else: if DEBUG: - self.log.info(' no Library found') + logger().info(' no Library found') elif iswindows: lib = None for source in self.iTunes.sources: if source.Kind == self.Sources.index('Library'): lib = source - self.log.info(" Library source: '%s' kind: %s" % (lib.Name, self.Sources[lib.Kind])) + logger().info(" Library source: '%s' kind: %s" % (lib.Name, self.Sources[lib.Kind])) break else: - self.log.error(" Library source not found") + logger().error(" Library source not found") if lib is not None: lib_books = None @@ -2237,22 +2241,22 @@ class ITUNES(DriverBase): if pl.Kind == self.PlaylistKind.index('User') and \ pl.SpecialKind == self.PlaylistSpecialKind.index('Books'): if DEBUG: - self.log.info(" Books playlist: '%s'" % (pl.Name)) + logger().info(" Books playlist: '%s'" % (pl.Name)) lib_books = pl.Tracks break else: if DEBUG: - self.log.error(" no Library|Books playlist found") + logger().error(" no Library|Books playlist found") else: if DEBUG: - self.log.error(" no Library playlists found") + logger().error(" no Library playlists found") try: for book in lib_books: # This may need additional entries for international iTunes users if book.KindAsString in self.Audiobooks: if DEBUG: - self.log.info(" ignoring %-30.30s of type '%s'" % (book.Name, book.KindAsString)) + logger().info(" ignoring %-30.30s of type '%s'" % (book.Name, book.KindAsString)) else: format = 'pdf' if book.KindAsString.startswith('PDF') else 'epub' path = self.path_template % (book.Name, book.Artist,format) @@ -2262,14 +2266,14 @@ class ITUNES(DriverBase): if not book.Location: library_orphans[path] = book if False: - self.log.info(" found iTunes PTF '%s' in Library|Books" % book.Name) + logger().info(" found iTunes PTF '%s' in Library|Books" % book.Name) library_books[path] = book if DEBUG: - self.log.info(" %-30.30s %-30.30s %-40.40s [%s]" % (book.Name, book.Artist, book.Album, book.KindAsString)) + logger().info(" %-30.30s %-30.30s %-40.40s [%s]" % (book.Name, book.Artist, book.Album, book.KindAsString)) except: if DEBUG: - self.log.info(" no books in library") + logger().info(" no books in library") self.library_orphans = library_orphans return library_books @@ -2314,7 +2318,7 @@ class ITUNES(DriverBase): # If more than one connected iDevice, remove all from list to prevent driver initialization if kinds.count('iPod') > 1: if DEBUG: - self.log.error(" %d connected iPod devices detected, calibre supports a single connected iDevice" % kinds.count('iPod')) + logger().error(" %d connected iPod devices detected, calibre supports a single connected iDevice" % kinds.count('iPod')) while kinds.count('iPod'): index = kinds.index('iPod') kinds.pop(index) @@ -2334,7 +2338,7 @@ class ITUNES(DriverBase): ''' ''' if DEBUG: - self.log.info(" ITUNES:_launch_iTunes():\n Instantiating iTunes") + logger().info(" ITUNES:_launch_iTunes():\n Instantiating iTunes") if isosx: ''' @@ -2344,7 +2348,7 @@ class ITUNES(DriverBase): running_apps = appscript.app('System Events') if not 'iTunes' in running_apps.processes.name(): if DEBUG: - self.log.info( "ITUNES:_launch_iTunes(): Launching iTunes" ) + logger().info( "ITUNES:_launch_iTunes(): Launching iTunes" ) try: self.iTunes = iTunes= appscript.app('iTunes', hide=True) except: @@ -2366,16 +2370,16 @@ class ITUNES(DriverBase): if os.path.exists(media_dir): self.iTunes_media = media_dir else: - self.log.error(" could not confirm valid iTunes.media_dir from %s" % 'com.apple.itunes') - self.log.error(" media_dir: %s" % media_dir) + logger().error(" could not confirm valid iTunes.media_dir from %s" % 'com.apple.itunes') + logger().error(" media_dir: %s" % media_dir) ''' if DEBUG: - self.log.info(" %s %s" % (__appname__, __version__)) - self.log.info(" [OSX %s - %s (%s), driver version %d.%d.%d]" % + logger().info(" %s %s" % (__appname__, __version__)) + logger().info(" [OSX %s - %s (%s), driver version %d.%d.%d]" % (self.iTunes.name(), self.iTunes.version(), self.initial_status, self.version[0],self.version[1],self.version[2])) - self.log.info(" calibre_library_path: %s" % self.calibre_library_path) + logger().info(" calibre_library_path: %s" % self.calibre_library_path) if iswindows: ''' @@ -2428,19 +2432,19 @@ class ITUNES(DriverBase): if os.path.exists(media_dir): self.iTunes_media = media_dir elif hasattr(string,'parent'): - self.log.error(" could not extract valid iTunes.media_dir from %s" % self.iTunes.LibraryXMLPath) - self.log.error(" %s" % string.parent.prettify()) - self.log.error(" '%s' not found" % media_dir) + logger().error(" could not extract valid iTunes.media_dir from %s" % self.iTunes.LibraryXMLPath) + logger().error(" %s" % string.parent.prettify()) + logger().error(" '%s' not found" % media_dir) else: - self.log.error(" no media dir found: string: %s" % string) + logger().error(" no media dir found: string: %s" % string) ''' if DEBUG: - self.log.info(" %s %s" % (__appname__, __version__)) - self.log.info(" [Windows %s - %s (%s), driver version %d.%d.%d]" % + logger().info(" %s %s" % (__appname__, __version__)) + logger().info(" [Windows %s - %s (%s), driver version %d.%d.%d]" % (self.iTunes.Windows[0].name, self.iTunes.Version, self.initial_status, self.version[0],self.version[1],self.version[2])) - self.log.info(" calibre_library_path: %s" % self.calibre_library_path) + logger().info(" calibre_library_path: %s" % self.calibre_library_path) def _purge_orphans(self,library_books, cached_books): ''' @@ -2449,16 +2453,16 @@ class ITUNES(DriverBase): This occurs when the user deletes a book in iBooks while disconnected ''' if DEBUG: - self.log.info(" ITUNES._purge_orphans()") + logger().info(" ITUNES._purge_orphans()") #self._dump_library_books(library_books) - #self.log.info(" cached_books:\n %s" % "\n ".join(cached_books.keys())) + #logger().info(" cached_books:\n %s" % "\n ".join(cached_books.keys())) for book in library_books: if isosx: if book not in cached_books and \ str(library_books[book].description()).startswith(self.description_prefix): if DEBUG: - self.log.info(" '%s' not found on iDevice, removing from iTunes" % book) + logger().info(" '%s' not found on iDevice, removing from iTunes" % book) btr = { 'title':library_books[book].name(), 'author':library_books[book].artist(), 'lib_book':library_books[book]} @@ -2467,19 +2471,19 @@ class ITUNES(DriverBase): if book not in cached_books and \ library_books[book].Description.startswith(self.description_prefix): if DEBUG: - self.log.info(" '%s' not found on iDevice, removing from iTunes" % book) + logger().info(" '%s' not found on iDevice, removing from iTunes" % book) btr = { 'title':library_books[book].Name, 'author':library_books[book].Artist, 'lib_book':library_books[book]} self._remove_from_iTunes(btr) if DEBUG: - self.log.info() + logger().info() def _remove_existing_copy(self, path, metadata): ''' ''' if DEBUG: - self.log.info(" ITUNES._remove_existing_copy()") + logger().info(" ITUNES._remove_existing_copy()") if self.manual_sync_mode: # Delete existing from Device|Books, add to self.update_list @@ -2491,16 +2495,16 @@ class ITUNES(DriverBase): self.update_list.append(self.cached_books[book]) if DEBUG: - self.log.info( " deleting device book '%s'" % (metadata.title)) + logger().info( " deleting device book '%s'" % (metadata.title)) self._remove_from_device(self.cached_books[book]) if DEBUG: - self.log.info(" deleting library book '%s'" % metadata.title) + logger().info(" deleting library book '%s'" % metadata.title) self._remove_from_iTunes(self.cached_books[book]) break else: if DEBUG: - self.log.info(" '%s' not in cached_books" % metadata.title) + logger().info(" '%s' not in cached_books" % metadata.title) else: # Delete existing from Library|Books, add to self.update_list # for deletion from booklist[0] during add_books_to_metadata @@ -2510,35 +2514,35 @@ class ITUNES(DriverBase): self.cached_books[book]['author'] == authors_to_string(metadata.authors)): self.update_list.append(self.cached_books[book]) if DEBUG: - self.log.info( " deleting library book '%s'" % metadata.title) + logger().info( " deleting library book '%s'" % metadata.title) self._remove_from_iTunes(self.cached_books[book]) break else: if DEBUG: - self.log.info(" '%s' not found in cached_books" % metadata.title) + logger().info(" '%s' not found in cached_books" % metadata.title) def _remove_from_device(self, cached_book): ''' Windows assumes pythoncom wrapper ''' if DEBUG: - self.log.info(" ITUNES._remove_from_device()") + logger().info(" ITUNES._remove_from_device()") if isosx: if DEBUG: - self.log.info(" deleting '%s' from iDevice" % cached_book['title']) + logger().info(" deleting '%s' from iDevice" % cached_book['title']) try: cached_book['dev_book'].delete() except: - self.log.error(" error deleting '%s'" % cached_book['title']) + logger().error(" error deleting '%s'" % cached_book['title']) elif iswindows: hit = self._find_device_book(cached_book) if hit: if DEBUG: - self.log.info(" deleting '%s' from iDevice" % cached_book['title']) + logger().info(" deleting '%s' from iDevice" % cached_book['title']) hit.Delete() else: if DEBUG: - self.log.warning(" unable to remove '%s' by '%s' (%s) from device" % + logger().warning(" unable to remove '%s' by '%s' (%s) from device" % (cached_book['title'],cached_book['author'],cached_book['uuid'])) def _remove_from_iTunes(self, cached_book): @@ -2546,34 +2550,34 @@ class ITUNES(DriverBase): iTunes does not delete books from storage when removing from database via automation ''' if DEBUG: - self.log.info(" ITUNES._remove_from_iTunes():") + logger().info(" ITUNES._remove_from_iTunes():") if isosx: ''' Manually remove the book from iTunes storage ''' try: fp = cached_book['lib_book'].location().path if DEBUG: - self.log.info(" processing %s" % fp) + logger().info(" processing %s" % fp) if fp.startswith(prefs['library_path']): - self.log.info(" '%s' stored in calibre database, not removed" % cached_book['title']) + logger().info(" '%s' stored in calibre database, not removed" % cached_book['title']) elif not self.settings().extra_customization[self.USE_ITUNES_STORAGE] and \ fp.startswith(self.iTunes_local_storage) and \ os.path.exists(fp): # Delete the copy in iTunes_local_storage os.remove(fp) if DEBUG: - self.log(" removing from iTunes_local_storage") + logger()(" removing from iTunes_local_storage") else: # Delete from iTunes Media folder if os.path.exists(fp): os.remove(fp) if DEBUG: - self.log.info(" deleting from iTunes storage") + logger().info(" deleting from iTunes storage") author_storage_path = os.path.split(fp)[0] try: os.rmdir(author_storage_path) if DEBUG: - self.log.info(" removing empty author directory") + logger().info(" removing empty author directory") except: author_files = os.listdir(author_storage_path) if '.DS_Store' in author_files: @@ -2581,23 +2585,23 @@ class ITUNES(DriverBase): if not author_files: os.rmdir(author_storage_path) if DEBUG: - self.log.info(" removing empty author directory") + logger().info(" removing empty author directory") else: - self.log.info(" '%s' does not exist at storage location" % cached_book['title']) + logger().info(" '%s' does not exist at storage location" % cached_book['title']) except: # We get here if there was an error with .location().path if DEBUG: - self.log.info(" '%s' not found in iTunes storage" % cached_book['title']) + logger().info(" '%s' not found in iTunes storage" % cached_book['title']) # Delete the book from the iTunes database try: self.iTunes.delete(cached_book['lib_book']) if DEBUG: - self.log.info(" removing from iTunes database") + logger().info(" removing from iTunes database") except: if DEBUG: - self.log.info(" unable to remove from iTunes database") + logger().info(" unable to remove from iTunes database") elif iswindows: ''' @@ -2615,43 +2619,43 @@ class ITUNES(DriverBase): if book: if DEBUG: - self.log.info(" processing %s" % fp) + logger().info(" processing %s" % fp) if fp.startswith(prefs['library_path']): - self.log.info(" '%s' stored in calibre database, not removed" % cached_book['title']) + logger().info(" '%s' stored in calibre database, not removed" % cached_book['title']) elif not self.settings().extra_customization[self.USE_ITUNES_STORAGE] and \ fp.startswith(self.iTunes_local_storage) and \ os.path.exists(fp): # Delete the copy in iTunes_local_storage os.remove(fp) if DEBUG: - self.log(" removing from iTunes_local_storage") + logger()(" removing from iTunes_local_storage") else: # Delete from iTunes Media folder if os.path.exists(fp): os.remove(fp) if DEBUG: - self.log.info(" deleting from iTunes storage") + logger().info(" deleting from iTunes storage") author_storage_path = os.path.split(fp)[0] try: os.rmdir(author_storage_path) if DEBUG: - self.log.info(" removing empty author directory") + logger().info(" removing empty author directory") except: pass else: - self.log.info(" '%s' does not exist at storage location" % cached_book['title']) + logger().info(" '%s' does not exist at storage location" % cached_book['title']) else: if DEBUG: - self.log.info(" '%s' not found in iTunes storage" % cached_book['title']) + logger().info(" '%s' not found in iTunes storage" % cached_book['title']) # Delete the book from the iTunes database try: book.Delete() if DEBUG: - self.log.info(" removing from iTunes database") + logger().info(" removing from iTunes database") except: if DEBUG: - self.log.info(" unable to remove from iTunes database") + logger().info(" unable to remove from iTunes database") def title_sorter(self, title): return re.sub('^\s*A\s+|^\s*The\s+|^\s*An\s+', '', title).rstrip() @@ -2663,7 +2667,7 @@ class ITUNES(DriverBase): from lxml import etree if DEBUG: - self.log.info(" ITUNES._update_epub_metadata()") + logger().info(" ITUNES._update_epub_metadata()") # Fetch plugboard updates metadata_x = self._xform_metadata_via_plugboard(metadata, 'epub') @@ -2691,17 +2695,17 @@ class ITUNES(DriverBase): metadata.timestamp = datetime.datetime(old_ts.year, old_ts.month, old_ts.day, old_ts.hour, old_ts.minute, old_ts.second, old_ts.microsecond+1, old_ts.tzinfo) if DEBUG: - self.log.info(" existing timestamp: %s" % metadata.timestamp) + logger().info(" existing timestamp: %s" % metadata.timestamp) else: metadata.timestamp = now() if DEBUG: - self.log.info(" add timestamp: %s" % metadata.timestamp) + logger().info(" add timestamp: %s" % metadata.timestamp) else: metadata.timestamp = now() if DEBUG: - self.log.warning(" missing block in OPF file") - self.log.info(" add timestamp: %s" % metadata.timestamp) + logger().warning(" missing block in OPF file") + logger().info(" add timestamp: %s" % metadata.timestamp) zf_opf.close() @@ -2731,7 +2735,7 @@ class ITUNES(DriverBase): Trigger a sync, wait for completion ''' if DEBUG: - self.log.info(" ITUNES:_update_device():\n %s" % msg) + logger().info(" ITUNES:_update_device():\n %s" % msg) if isosx: self.iTunes.update() @@ -2777,7 +2781,7 @@ class ITUNES(DriverBase): ''' ''' if DEBUG: - self.log.info(" ITUNES._update_iTunes_metadata()") + logger().info(" ITUNES._update_iTunes_metadata()") STRIP_TAGS = re.compile(r'<[^<]*?/?>') @@ -2829,8 +2833,8 @@ class ITUNES(DriverBase): # If title_sort applied in plugboard, that overrides using series/index as title_sort if metadata_x.series and self.settings().extra_customization[self.USE_SERIES_AS_CATEGORY]: if DEBUG: - self.log.info(" ITUNES._update_iTunes_metadata()") - self.log.info(" using Series name '%s' as Genre" % metadata_x.series) + logger().info(" ITUNES._update_iTunes_metadata()") + logger().info(" using Series name '%s' as Genre" % metadata_x.series) # Format the index as a sort key index = metadata_x.series_index @@ -2854,7 +2858,7 @@ class ITUNES(DriverBase): break if db_added: - self.log.warning(" waiting for db_added to become writeable ") + logger().warning(" waiting for db_added to become writeable ") time.sleep(1.0) # If no title_sort plugboard tweak, create sort_name from series/index if metadata.title_sort == metadata_x.title_sort: @@ -2874,7 +2878,7 @@ class ITUNES(DriverBase): elif metadata_x.tags is not None: if DEBUG: - self.log.info(" %susing Tag as Genre" % + logger().info(" %susing Tag as Genre" % "no Series name available, " if self.settings().extra_customization[self.USE_SERIES_AS_CATEGORY] else '') for tag in metadata_x.tags: if self._is_alpha(tag[0]): @@ -2897,7 +2901,7 @@ class ITUNES(DriverBase): lb_added.Year = metadata_x.pubdate.year if db_added: - self.log.warning(" waiting for db_added to become writeable ") + logger().warning(" waiting for db_added to become writeable ") time.sleep(1.0) db_added.Name = metadata_x.title db_added.Album = metadata_x.title @@ -2924,7 +2928,7 @@ class ITUNES(DriverBase): db_added.AlbumRating = (metadata_x.rating*10) except: if DEBUG: - self.log.warning(" iTunes automation interface reported an error" + logger().warning(" iTunes automation interface reported an error" " setting AlbumRating on iDevice") # Set Genre from first alpha tag, overwrite with series if available @@ -2933,7 +2937,7 @@ class ITUNES(DriverBase): if metadata_x.series and self.settings().extra_customization[self.USE_SERIES_AS_CATEGORY]: if DEBUG: - self.log.info(" using Series name as Genre") + logger().info(" using Series name as Genre") # Format the index as a sort key index = metadata_x.series_index integer = int(index) @@ -2949,13 +2953,13 @@ class ITUNES(DriverBase): lb_added.TrackNumber = metadata_x.series_index except: if DEBUG: - self.log.warning(" iTunes automation interface reported an error" + logger().warning(" iTunes automation interface reported an error" " setting TrackNumber in iTunes") try: lb_added.EpisodeNumber = metadata_x.series_index except: if DEBUG: - self.log.warning(" iTunes automation interface reported an error" + logger().warning(" iTunes automation interface reported an error" " setting EpisodeNumber in iTunes") # If no plugboard transform applied to tags, change the Genre/Category to Series @@ -2977,13 +2981,13 @@ class ITUNES(DriverBase): db_added.TrackNumber = metadata_x.series_index except: if DEBUG: - self.log.warning(" iTunes automation interface reported an error" + logger().warning(" iTunes automation interface reported an error" " setting TrackNumber on iDevice") try: db_added.EpisodeNumber = metadata_x.series_index except: if DEBUG: - self.log.warning(" iTunes automation interface reported an error" + logger().warning(" iTunes automation interface reported an error" " setting EpisodeNumber on iDevice") # If no plugboard transform applied to tags, change the Genre/Category to Series @@ -2997,7 +3001,7 @@ class ITUNES(DriverBase): elif metadata_x.tags is not None: if DEBUG: - self.log.info(" using Tag as Genre") + logger().info(" using Tag as Genre") for tag in metadata_x.tags: if self._is_alpha(tag[0]): if lb_added: @@ -3011,8 +3015,8 @@ class ITUNES(DriverBase): Ensure iDevice metadata is writable. Direct connect mode only ''' if DEBUG: - self.log.info(" ITUNES._wait_for_writable_metadata()") - self.log.warning(" %s" % self.UNSUPPORTED_DIRECT_CONNECT_MODE_MESSAGE) + logger().info(" ITUNES._wait_for_writable_metadata()") + logger().warning(" %s" % self.UNSUPPORTED_DIRECT_CONNECT_MODE_MESSAGE) attempts = 9 while attempts: @@ -3026,40 +3030,40 @@ class ITUNES(DriverBase): attempts -= 1 time.sleep(delay) if DEBUG: - self.log.warning(" waiting %.1f seconds for iDevice metadata to become writable (attempt #%d)" % + logger().warning(" waiting %.1f seconds for iDevice metadata to become writable (attempt #%d)" % (delay, (10 - attempts))) else: if DEBUG: - self.log.error(" failed to write device metadata") + logger().error(" failed to write device metadata") def _xform_metadata_via_plugboard(self, book, format): ''' Transform book metadata from plugboard templates ''' if DEBUG: - self.log.info(" ITUNES._xform_metadata_via_plugboard()") + logger().info(" ITUNES._xform_metadata_via_plugboard()") if self.plugboard_func: pb = self.plugboard_func(self.DEVICE_PLUGBOARD_NAME, format, self.plugboards) newmi = book.deepcopy_metadata() newmi.template_to_attribute(book, pb) if pb is not None and DEBUG: - #self.log.info(" transforming %s using %s:" % (format, pb)) - self.log.info(" title: '%s' %s" % (book.title, ">>> '%s'" % + #logger().info(" transforming %s using %s:" % (format, pb)) + logger().info(" title: '%s' %s" % (book.title, ">>> '%s'" % newmi.title if book.title != newmi.title else '')) - self.log.info(" title_sort: %s %s" % (book.title_sort, ">>> %s" % + logger().info(" title_sort: %s %s" % (book.title_sort, ">>> %s" % newmi.title_sort if book.title_sort != newmi.title_sort else '')) - self.log.info(" authors: %s %s" % (book.authors, ">>> %s" % + logger().info(" authors: %s %s" % (book.authors, ">>> %s" % newmi.authors if book.authors != newmi.authors else '')) - self.log.info(" author_sort: %s %s" % (book.author_sort, ">>> %s" % + logger().info(" author_sort: %s %s" % (book.author_sort, ">>> %s" % newmi.author_sort if book.author_sort != newmi.author_sort else '')) - self.log.info(" language: %s %s" % (book.language, ">>> %s" % + logger().info(" language: %s %s" % (book.language, ">>> %s" % newmi.language if book.language != newmi.language else '')) - self.log.info(" publisher: %s %s" % (book.publisher, ">>> %s" % + logger().info(" publisher: %s %s" % (book.publisher, ">>> %s" % newmi.publisher if book.publisher != newmi.publisher else '')) - self.log.info(" tags: %s %s" % (book.tags, ">>> %s" % + logger().info(" tags: %s %s" % (book.tags, ">>> %s" % newmi.tags if book.tags != newmi.tags else '')) else: if DEBUG: - self.log(" matching plugboard not found") + logger()(" matching plugboard not found") else: newmi = book @@ -3082,7 +3086,7 @@ class ITUNES_ASYNC(ITUNES): def __init__(self,path): if DEBUG: - self.log.info("ITUNES_ASYNC:__init__()") + logger().info("ITUNES_ASYNC:__init__()") if isosx and appscript is None: self.connected = False @@ -3124,15 +3128,15 @@ class ITUNES_ASYNC(ITUNES): """ if not oncard: if DEBUG: - self.log.info("ITUNES_ASYNC:books()") + logger().info("ITUNES_ASYNC:books()") if self.settings().extra_customization[self.CACHE_COVERS]: - self.log.info(" Cover fetching/caching enabled") + logger().info(" Cover fetching/caching enabled") else: - self.log.info(" Cover fetching/caching disabled") + logger().info(" Cover fetching/caching disabled") # Fetch a list of books from iTunes - booklist = BookList(self.log) + booklist = BookList(logger()) cached_books = {} if isosx: @@ -3228,7 +3232,7 @@ class ITUNES_ASYNC(ITUNES): return booklist else: - return BookList(self.log) + return BookList(logger()) def eject(self): ''' @@ -3236,7 +3240,7 @@ class ITUNES_ASYNC(ITUNES): are pending GUI jobs that need to communicate with the device. ''' if DEBUG: - self.log.info("ITUNES_ASYNC:eject()") + logger().info("ITUNES_ASYNC:eject()") self.iTunes = None self.connected = False @@ -3251,7 +3255,7 @@ class ITUNES_ASYNC(ITUNES): particular device doesn't have any of these locations it should return -1. """ if DEBUG: - self.log.info("ITUNES_ASYNC:free_space()") + logger().info("ITUNES_ASYNC:free_space()") free_space = 0 if isosx: s = os.statvfs(os.sep) @@ -3268,7 +3272,7 @@ class ITUNES_ASYNC(ITUNES): @return: (device name, device version, software version on device, mime type) """ if DEBUG: - self.log.info("ITUNES_ASYNC:get_device_information()") + logger().info("ITUNES_ASYNC:get_device_information()") return ('iTunes','hw v1.0','sw v1.0', 'mime type normally goes here') @@ -3291,33 +3295,33 @@ class ITUNES_ASYNC(ITUNES): we need to talk to iTunes to discover if there's a connected iPod ''' if DEBUG: - self.log.info("ITUNES_ASYNC.open(connected_device: %s)" % repr(connected_device)) + logger().info("ITUNES_ASYNC.open(connected_device: %s)" % repr(connected_device)) # Confirm/create thumbs archive if not os.path.exists(self.cache_dir): if DEBUG: - self.log.info(" creating thumb cache '%s'" % self.cache_dir) + logger().info(" creating thumb cache '%s'" % self.cache_dir) os.makedirs(self.cache_dir) if not os.path.exists(self.archive_path): - self.log.info(" creating zip archive") + logger().info(" creating zip archive") zfw = ZipFile(self.archive_path, mode='w') zfw.writestr("iTunes Thumbs Archive",'') zfw.close() else: if DEBUG: - self.log.info(" existing thumb cache at '%s'" % self.archive_path) + logger().info(" existing thumb cache at '%s'" % self.archive_path) # If enabled in config options, create/confirm an iTunes storage folder if not self.settings().extra_customization[self.USE_ITUNES_STORAGE]: self.iTunes_local_storage = os.path.join(config_dir,'iTunes storage') if not os.path.exists(self.iTunes_local_storage): if DEBUG: - self.log(" creating iTunes_local_storage at '%s'" % self.iTunes_local_storage) + logger()(" creating iTunes_local_storage at '%s'" % self.iTunes_local_storage) os.mkdir(self.iTunes_local_storage) else: if DEBUG: - self.log(" existing iTunes_local_storage at '%s'" % self.iTunes_local_storage) + logger()(" existing iTunes_local_storage at '%s'" % self.iTunes_local_storage) def sync_booklists(self, booklists, end_session=True): ''' @@ -3328,7 +3332,7 @@ class ITUNES_ASYNC(ITUNES): ''' if DEBUG: - self.log.info("ITUNES_ASYNC.sync_booklists()") + logger().info("ITUNES_ASYNC.sync_booklists()") # Inform user of any problem books if self.problem_titles: @@ -3342,7 +3346,7 @@ class ITUNES_ASYNC(ITUNES): ''' ''' if DEBUG: - self.log.info("ITUNES_ASYNC:unmount_device()") + logger().info("ITUNES_ASYNC:unmount_device()") self.connected = False class BookList(list): diff --git a/src/calibre/devices/cybook/t2b.py b/src/calibre/devices/cybook/t2b.py index 7aaeeb63d7..fc0c772bf7 100644 --- a/src/calibre/devices/cybook/t2b.py +++ b/src/calibre/devices/cybook/t2b.py @@ -5,7 +5,6 @@ Write a t2b file to disk. ''' import StringIO -from PIL import Image DEFAULT_T2B_DATA = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x0f\xff\xff\xff\xf0\xff\x0f\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf8\x00\x00\xff\xff\xff\xf0\xff\x0f\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe0\xff\xf0\xff\xff\xff\xf0\xff\xff\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc3\xff\xff\xff\xff\xff\xf0\xff\xff\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x07\xff\xff\xfc\x00?\xf0\xff\x0f\xc3\x00?\xf0\xc0\xfe\x00?\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xf0<\x0f\xf0\xff\x0f\xc0,\x0f\xf0\x0e\xf0,\x0f\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xc3\xf0\xff\x0f\xc0\xff\x0f\xf0\xff\xf0\xff\xc7\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\xff\xc3\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc3\xff\xc3\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xff\x00\x03\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc3\xff\xc3\xff\xff\xff\xff\xff\xff\xff\x0f\xff\xff\xf0\x1f\xc3\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc0\x00\x03\xff\xff\xff\xff\xff\xff\xff\x0b\xff\xff\xf0\xff\xc3\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc3\xff\xff\xf3\xff\xc3\xf0\xff\x0f\xc3\xff\xc3\xf0\xff\xc3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\xff\xfc\xf0\xff\x03\xf0\xff\x0f\xc0\xff\x0f\xf0\xff\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x0f\x00\xf08\x03\xf0\xff\x0f\xc0,\x0f\xf0\xff\xf0\x1f\x03\xff\xff\xff\xff\xff\xff\xff\xff\x00\x0f\xfc\x00\xc3\xf0\xff\x0f\xc3\x00?\xf0\xff\xff\x00\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x0f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\xfe\x94\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\x00\x00\x0f\xff\xff\xff\xff\xff\xff\xfc\x7f\xfe\x94\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x0f\xff\xfe\xa9@\xff\xff\xff\xff\xff\xff\xfc?\xfe\xa4\xff\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xe9P\xff\xff\xff\xff\xff\xff\xfe/\xfe\xa8\xff\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xf9T\xff\xff\xff\xff\xf0@\x00+\xfa\xa8?\xff\xff\xff\xff\xff\xff\xff\xfc\xbf\xff\xff\xf9T\xff\xff\xff\xff\xcb\xe4}*\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfc\xbf\xff\xff\xe9T\xff\xff\xff\xff\xc7\xe4\xfd\x1a\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfc\xaf\xea\xaa\xa6\xa4\xff@\x00\x0f\xc3\xe8\xfe\x1a\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4\x00\x7f\xfe\x90\x03\xe8\xfe\n\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4?\xff\xff\xa5C\xe8\xfe\x06\xaa\xaa?\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4?\xff\xff\xeaC\xe8\xbe\x06\xaa\xaa\x0f\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4/\xff\xff\xea\x82\xe8j\x06\xaa\xaa\x0f\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4/\xff\xff\xaa\x82\xe8*F\xaa\xaa\x8f\xff\xff\xff\xff\xff\xff\xff\xfcj\x95UZ\xa4+\xff\xfe\xaa\x82\xe8*\x86\xaa\xaa\x8f\xff\xff\x80\xff\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8*\x86\xaa\xaa\x8f\xf0\x00T?\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8*\x81\xaa\xaa\x8c\x03\xff\x95?\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8*\x81\xaa\xaa\x80\xbf\xff\x95?\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8*\x81\xaa\xaa\x9b\xff\xff\x95\x0f\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8\x1a\x81\xaa\xaa\x9a\xff\xfe\x95\x0f\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xe8\n\x81\xaa\xaa\xa6\xbf\xfeUO\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xa8\n\x91j\xaa\xa5\xaa\xa9ZO\xff\xff\xff\xfcj\x95UV\xa4\x1a\xfa\xaa\xaa\x82\xa8\n\xa0j\xaa\xa5Z\x95ZO\xff\xff\xff\xfcj\x95UV\xa4*\xfa\xaa\xaa\x82\xa9\n\xa0j\xaa\xa5UUZC\xff\xff\xff\xfcj\x95UV\xa4*\xfa\xaa\xaa\x82\xaa\n\xa0j\xaa\xa4UUZS\xff\xff\xff\xfcZ\x95UV\xa4*\xfa\xaa\xaa\x82\xaa\n\xa0j\xaa\xa4UUZS\xff\xff\xff\xfcZ\x95UU\xa4*\xfa\xaa\xaa\x82\xaa\n\xa0j\xaa\xa8UUVS\xff\xff\xff\xfcZ\x95UU\xa4*\xea\xaa\xaa\x82\xaa\x06\xa0Z\xaa\xa8UUV\x93\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x81\xaa\x02\xa0\x1a\xaa\xa8UUV\x90\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa\x02\xa0\x1a\xaa\xa8\x15UU\x94\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa"\xa0\x1a\xaa\xa8\x15UU\x94\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa2\xa4\x16\xaa\xa8\x15UU\x94\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa2\xa8\x16\xa6\xa9\x15UU\x94\xff\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x80\xaa2\xa8\x16\xa6\xa9\x05UUT?\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x84\xaa2\xa8\x16\xaa\xaa\x05UUU?\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x88\xaa2\xa8\x06\xaa\xaa\x05UUU?\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa1\xa8\xc5\xaa\xaa\x05UUU?\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa0\xa8E\xa9\xaa\x05UUU/\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa<\xa8\x05\xa9\xaaAUUU\x0f\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa<\xa8\x05\xa9\xaaAUUUO\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa<\xa9\x05\xaa\xaaAUUUO\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x1c\xaa\x01\xaa\xaa\x81UUUO\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x0c\xaa\x01\xaa\xaa\x81UUUO\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x0c\xaa1j\xaa\x80UUUC\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x0cj1jj\x90UUUS\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x0c*1jj\x90UUUS\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaaL*1jj\xa0UUUS\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x8f* j\xaa\xa0\x15UUS\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x8f*@j\xaa\xa0\x15UUP\xff\xff\xfcZ\x95UU\xa4*\xaa\xaa\xaa\x8c\xaa\x8f*\x8cZ\xaa\xa1\x15UUT\xff\xff\xfcZ\x95UU\xa4j\xaa\xaa\xaa\x8c\xaa\x8f*\x8cZ\x9a\xa0\x15UUT\xff\xff\xfcZ\x95UU\xa4j\xaa\xaa\xaa\x8c\xaa\x8f*\x8cZ\x9a\xa0\x15UUT\xff\xff\xfcZ\x95UU\xa4j\xaa\xaa\xaa\x8c\xaa\x8f\x1a\x8cZ\x9a\xa4\x15UUT?\xff\xfcZ\x95UU\x94j\xaa\xaa\xaa\x8cj\x8f\n\x8cVj\xa4\x05UU\xa4?\xff\xfcVUUU\xa4j\xaa\xaa\xaa\x8cj\x8fJ\x8c\x16\xaa\xa8\xc5UZ\xa5?\xff\xfcUUUV\xa4j\xaa\xaa\xaa\x8cj\x8f\xca\x8f\x16\xaa\xa8\xc5V\xaa\xa5?\xff\xfcUj\xaa\xaa\xa4j\xaa\xaa\xaa\x8cj\x8f\xca\x8f\x1a\xaa\xa8\x05Z\xaaU?\xff\xfcV\xaa\xaa\xaa\xa5j\xaa\xaa\xaa\x8e*\x8f\xca\x83\x1a\xaa\xa4\x01eUU?\xff\xfcZ\xaa\xaa\xaa\xa5j\xaa\xaa\xaa\x8f*\x8f\xca\x83\x1a\xa5U\x01U\x00\x00\x0f\xff\xfcUUUUUZ\xaa\xaa\xaaO%\x8f\xc6\x93\x15\x00\x001@\x0f\xff\xff\xff\xfcP\x00\x00\x00\x15\x00\x00\x00\x00\x0f\x00\x07\xc0\x03\x00\xff\xff0\x1f\xff\xff\xff\xff\xfc\x00\xff\xff\xf8\x00?\xff\xff\xff\x0f?\xc7\xc3\xf7\x0f\xff\xff\xf1\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xf4\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' @@ -18,7 +17,7 @@ def reduce_color(c): return 2 else: return 3 - + def i2b(n): return "".join([str((n >> y) & 1) for y in range(1, -1, -1)]) @@ -27,12 +26,13 @@ def write_t2b(t2bfile, coverdata=None): t2bfile is a file handle ready to write binary data to disk. coverdata is a string representation of a JPEG file. ''' + from PIL import Image if coverdata != None: coverdata = StringIO.StringIO(coverdata) cover = Image.open(coverdata).convert("L") cover.thumbnail((96, 144), Image.ANTIALIAS) t2bcover = Image.new('L', (96, 144), 'white') - + x, y = cover.size t2bcover.paste(cover, ((96-x)/2, (144-y)/2)) diff --git a/src/calibre/devices/kobo/bookmark.py b/src/calibre/devices/kobo/bookmark.py index 8e199f77a6..afb392403d 100644 --- a/src/calibre/devices/kobo/bookmark.py +++ b/src/calibre/devices/kobo/bookmark.py @@ -7,7 +7,6 @@ __docformat__ = 'restructuredtext en' import os from contextlib import closing -import sqlite3 as sqlite class Bookmark(): # {{{ ''' @@ -32,7 +31,7 @@ class Bookmark(): # {{{ def get_bookmark_data(self): ''' Return the timestamp and last_read_location ''' - + import sqlite3 as sqlite user_notes = {} self.timestamp = os.path.getmtime(self.path) with closing(sqlite.connect(self.db_path)) as connection: diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 0bc578155d..f68ea8feff 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -6,7 +6,6 @@ __copyright__ = '2010, Timothy Legge and Kovid Goyal ]+encoding\s*=\s*[\'"](.*?)[\'"][^<>]*>', @@ -34,8 +33,13 @@ def substitute_entites(raw): _CHARSET_ALIASES = { "macintosh" : "mac-roman", "x-sjis" : "shift-jis" } +def detect(*args, **kwargs): + from chardet import detect + return detect(*args, **kwargs) + def force_encoding(raw, verbose, assume_utf8=False): from calibre.constants import preferred_encoding + try: chardet = detect(raw[:1024*50]) except: diff --git a/src/calibre/ebooks/conversion/plugins/pdf_input.py b/src/calibre/ebooks/conversion/plugins/pdf_input.py index 0a3821c584..be0150834b 100644 --- a/src/calibre/ebooks/conversion/plugins/pdf_input.py +++ b/src/calibre/ebooks/conversion/plugins/pdf_input.py @@ -7,8 +7,6 @@ __docformat__ = 'restructuredtext en' import os from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation -from calibre.constants import plugins -pdfreflow, pdfreflow_err = plugins['pdfreflow'] class PDFInput(InputFormatPlugin): @@ -29,6 +27,9 @@ class PDFInput(InputFormatPlugin): ]) def convert_new(self, stream, accelerators): + from calibre.constants import plugins + pdfreflow, pdfreflow_err = plugins['pdfreflow'] + from calibre.ebooks.pdf.reflow import PDFDocument from calibre.utils.cleantext import clean_ascii_chars if pdfreflow_err: diff --git a/src/calibre/ebooks/epub/fix/epubcheck.py b/src/calibre/ebooks/epub/fix/epubcheck.py index 9e812e1cf4..0029868c23 100644 --- a/src/calibre/ebooks/epub/fix/epubcheck.py +++ b/src/calibre/ebooks/epub/fix/epubcheck.py @@ -6,7 +6,6 @@ __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' from calibre.ebooks.epub.fix import ePubFixer, InvalidEpub -from calibre.utils.date import parse_date, strptime class Epubcheck(ePubFixer): @@ -35,6 +34,8 @@ class Epubcheck(ePubFixer): return 'epubcheck' def fix_pubdates(self): + from calibre.utils.date import parse_date, strptime + dirtied = False opf = self.container.opf for dcdate in opf.xpath('//dc:date', diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index 286bcee9d0..0312a7db6a 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -710,7 +710,7 @@ class Metadata(object): fmt('Title sort', self.title_sort) if self.authors: fmt('Author(s)', authors_to_string(self.authors) + \ - ((' [' + self.author_sort + ']') + ((' [' + self.author_sort + ']') if self.author_sort and self.author_sort != _('Unknown') else '')) if self.publisher: fmt('Publisher', self.publisher) diff --git a/src/calibre/ebooks/metadata/book/json_codec.py b/src/calibre/ebooks/metadata/book/json_codec.py index a14e18569a..c0c3900a5d 100644 --- a/src/calibre/ebooks/metadata/book/json_codec.py +++ b/src/calibre/ebooks/metadata/book/json_codec.py @@ -12,7 +12,6 @@ from calibre.ebooks.metadata.book import SERIALIZABLE_FIELDS from calibre.constants import filesystem_encoding, preferred_encoding from calibre.library.field_metadata import FieldMetadata from calibre.utils.date import parse_date, isoformat, UNDEFINED_DATE, local_tz -from calibre.utils.magick import Image from calibre import isbytestring # Translate datetimes to and from strings. The string form is the datetime in @@ -37,6 +36,8 @@ def encode_thumbnail(thumbnail): ''' Encode the image part of a thumbnail, then return the 3 part tuple ''' + from calibre.utils.magick import Image + if thumbnail is None: return None if not isinstance(thumbnail, (tuple, list)): diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index cae31abe09..3d08b96c5f 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -12,19 +12,14 @@ from urllib import urlencode from threading import Thread from Queue import Queue, Empty -from lxml.html import tostring from calibre import as_unicode from calibre.ebooks.metadata import check_isbn from calibre.ebooks.metadata.sources.base import (Source, Option, fixcase, fixauthors) -from calibre.utils.cleantext import clean_ascii_chars -from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.metadata.book.base import Metadata -from calibre.library.comments import sanitize_comments_html from calibre.utils.date import parse_date from calibre.utils.localization import canonicalize_lang -from calibre.utils.soupparser import fromstring class Worker(Thread): # Get details {{{ @@ -43,6 +38,8 @@ class Worker(Thread): # Get details {{{ self.browser = browser.clone_browser() self.cover_url = self.amazon_id = self.isbn = None self.domain = domain + from lxml.html import tostring + self.tostring = tostring months = { 'de': { @@ -176,6 +173,10 @@ class Worker(Thread): # Get details {{{ self.log.exception('get_details failed for url: %r'%self.url) def get_details(self): + from calibre.utils.cleantext import clean_ascii_chars + from calibre.utils.soupparser import fromstring + from calibre.ebooks.chardet import xml_to_unicode + try: raw = self.browser.open_novisit(self.url, timeout=self.timeout).read().strip() except Exception as e: @@ -210,7 +211,7 @@ class Worker(Thread): # Get details {{{ errmsg = root.xpath('//*[@id="errorMessage"]') if errmsg: msg = 'Failed to parse amazon details page: %r'%self.url - msg += tostring(errmsg, method='text', encoding=unicode).strip() + msg += self.tostring(errmsg, method='text', encoding=unicode).strip() self.log.error(msg) return @@ -322,10 +323,10 @@ class Worker(Thread): # Get details {{{ tdiv = root.xpath('//h1[contains(@class, "parseasinTitle")]')[0] actual_title = tdiv.xpath('descendant::*[@id="btAsinTitle"]') if actual_title: - title = tostring(actual_title[0], encoding=unicode, + title = self.tostring(actual_title[0], encoding=unicode, method='text').strip() else: - title = tostring(tdiv, encoding=unicode, method='text').strip() + title = self.tostring(tdiv, encoding=unicode, method='text').strip() return re.sub(r'[(\[].*[)\]]', '', title).strip() def parse_authors(self, root): @@ -337,7 +338,7 @@ class Worker(Thread): # Get details {{{ ''') for x in aname: x.tail = '' - authors = [tostring(x, encoding=unicode, method='text').strip() for x + authors = [self.tostring(x, encoding=unicode, method='text').strip() for x in aname] authors = [a for a in authors if a] return authors @@ -356,6 +357,8 @@ class Worker(Thread): # Get details {{{ return float(m.group(1))/float(m.group(3)) * 5 def parse_comments(self, root): + from calibre.library.comments import sanitize_comments_html + desc = root.xpath('//div[@id="productDescription"]/*[@class="content"]') if desc: desc = desc[0] @@ -365,7 +368,7 @@ class Worker(Thread): # Get details {{{ for a in desc.xpath('descendant::a[@href]'): del a.attrib['href'] a.tag = 'span' - desc = tostring(desc, method='html', encoding=unicode).strip() + desc = self.tostring(desc, method='html', encoding=unicode).strip() # Encoding bug in Amazon data U+fffd (replacement char) # in some examples it is present in place of ' @@ -602,6 +605,11 @@ class Amazon(Source): Note this method will retry without identifiers automatically if no match is found with identifiers. ''' + from lxml.html import tostring + from calibre.utils.cleantext import clean_ascii_chars + from calibre.utils.soupparser import fromstring + from calibre.ebooks.chardet import xml_to_unicode + query, domain = self.create_query(log, title=title, authors=authors, identifiers=identifiers) if query is None: diff --git a/src/calibre/ebooks/metadata/sources/base.py b/src/calibre/ebooks/metadata/sources/base.py index 9ae8902671..4c334f4e46 100644 --- a/src/calibre/ebooks/metadata/sources/base.py +++ b/src/calibre/ebooks/metadata/sources/base.py @@ -12,7 +12,6 @@ from future_builtins import map from calibre import browser, random_user_agent from calibre.customize import Plugin -from calibre.utils.logging import ThreadSafeLog, FileStream from calibre.utils.config import JSONConfig from calibre.utils.titlecase import titlecase from calibre.utils.icu import capitalize, lower, upper @@ -34,6 +33,7 @@ msprefs.defaults['fewer_tags'] = True msprefs.defaults['cover_priorities'] = {'Google':2} def create_log(ostream=None): + from calibre.utils.logging import ThreadSafeLog, FileStream log = ThreadSafeLog(level=ThreadSafeLog.DEBUG) log.outputs = [FileStream(ostream)] return log diff --git a/src/calibre/ebooks/metadata/sources/douban.py b/src/calibre/ebooks/metadata/sources/douban.py index 06e874e8ca..6857d62d4d 100644 --- a/src/calibre/ebooks/metadata/sources/douban.py +++ b/src/calibre/ebooks/metadata/sources/douban.py @@ -12,14 +12,10 @@ from urllib import urlencode from functools import partial from Queue import Queue, Empty -from lxml import etree from calibre.ebooks.metadata import check_isbn from calibre.ebooks.metadata.sources.base import Source from calibre.ebooks.metadata.book.base import Metadata -from calibre.ebooks.chardet import xml_to_unicode -from calibre.utils.date import parse_date, utcnow -from calibre.utils.cleantext import clean_ascii_chars from calibre import as_unicode NAMESPACES = { @@ -28,22 +24,6 @@ NAMESPACES = { 'db': 'http://www.douban.com/xmlns/', 'gd': 'http://schemas.google.com/g/2005' } -XPath = partial(etree.XPath, namespaces=NAMESPACES) -total_results = XPath('//openSearch:totalResults') -start_index = XPath('//openSearch:startIndex') -items_per_page = XPath('//openSearch:itemsPerPage') -entry = XPath('//atom:entry') -entry_id = XPath('descendant::atom:id') -title = XPath('descendant::atom:title') -description = XPath('descendant::atom:summary') -publisher = XPath("descendant::db:attribute[@name='publisher']") -isbn = XPath("descendant::db:attribute[@name='isbn13']") -date = XPath("descendant::db:attribute[@name='pubdate']") -creator = XPath("descendant::db:attribute[@name='author']") -booktag = XPath("descendant::db:tag/attribute::name") -rating = XPath("descendant::gd:rating/attribute::average") -cover_url = XPath("descendant::atom:link[@rel='image']/attribute::href") - def get_details(browser, url, timeout): # {{{ try: if Douban.DOUBAN_API_KEY and Douban.DOUBAN_API_KEY != '': @@ -61,6 +41,25 @@ def get_details(browser, url, timeout): # {{{ # }}} def to_metadata(browser, log, entry_, timeout): # {{{ + from lxml import etree + from calibre.ebooks.chardet import xml_to_unicode + from calibre.utils.date import parse_date, utcnow + from calibre.utils.cleantext import clean_ascii_chars + + XPath = partial(etree.XPath, namespaces=NAMESPACES) + entry = XPath('//atom:entry') + entry_id = XPath('descendant::atom:id') + title = XPath('descendant::atom:title') + description = XPath('descendant::atom:summary') + publisher = XPath("descendant::db:attribute[@name='publisher']") + isbn = XPath("descendant::db:attribute[@name='isbn13']") + date = XPath("descendant::db:attribute[@name='pubdate']") + creator = XPath("descendant::db:attribute[@name='author']") + booktag = XPath("descendant::db:tag/attribute::name") + rating = XPath("descendant::gd:rating/attribute::average") + cover_url = XPath("descendant::atom:link[@rel='image']/attribute::href") + + def get_text(extra, x): try: ans = x(extra) @@ -275,6 +274,7 @@ class Douban(Source): def get_all_details(self, br, log, entries, abort, # {{{ result_queue, timeout): + from lxml import etree for relevance, i in enumerate(entries): try: ans = to_metadata(br, log, i, timeout) @@ -298,6 +298,13 @@ class Douban(Source): def identify(self, log, result_queue, abort, title=None, authors=None, # {{{ identifiers={}, timeout=30): + from lxml import etree + from calibre.ebooks.chardet import xml_to_unicode + from calibre.utils.cleantext import clean_ascii_chars + + XPath = partial(etree.XPath, namespaces=NAMESPACES) + entry = XPath('//atom:entry') + query = self.create_query(log, title=title, authors=authors, identifiers=identifiers) if not query: diff --git a/src/calibre/ebooks/metadata/sources/google.py b/src/calibre/ebooks/metadata/sources/google.py index f9c43d86cc..3962afcb5e 100644 --- a/src/calibre/ebooks/metadata/sources/google.py +++ b/src/calibre/ebooks/metadata/sources/google.py @@ -12,8 +12,6 @@ from urllib import urlencode from functools import partial from Queue import Queue, Empty -from lxml import etree - from calibre.ebooks.metadata import check_isbn from calibre.ebooks.metadata.sources.base import Source from calibre.ebooks.metadata.book.base import Metadata @@ -29,23 +27,6 @@ NAMESPACES = { 'dc' : 'http://purl.org/dc/terms', 'gd' : 'http://schemas.google.com/g/2005' } -XPath = partial(etree.XPath, namespaces=NAMESPACES) - -total_results = XPath('//openSearch:totalResults') -start_index = XPath('//openSearch:startIndex') -items_per_page = XPath('//openSearch:itemsPerPage') -entry = XPath('//atom:entry') -entry_id = XPath('descendant::atom:id') -creator = XPath('descendant::dc:creator') -identifier = XPath('descendant::dc:identifier') -title = XPath('descendant::dc:title') -date = XPath('descendant::dc:date') -publisher = XPath('descendant::dc:publisher') -subject = XPath('descendant::dc:subject') -description = XPath('descendant::dc:description') -language = XPath('descendant::dc:language') -rating = XPath('descendant::gd:rating[@average]') - def get_details(browser, url, timeout): # {{{ try: raw = browser.open_novisit(url, timeout=timeout).read() @@ -61,6 +42,24 @@ def get_details(browser, url, timeout): # {{{ # }}} def to_metadata(browser, log, entry_, timeout): # {{{ + from lxml import etree + XPath = partial(etree.XPath, namespaces=NAMESPACES) + + # total_results = XPath('//openSearch:totalResults') + # start_index = XPath('//openSearch:startIndex') + # items_per_page = XPath('//openSearch:itemsPerPage') + entry = XPath('//atom:entry') + entry_id = XPath('descendant::atom:id') + creator = XPath('descendant::dc:creator') + identifier = XPath('descendant::dc:identifier') + title = XPath('descendant::dc:title') + date = XPath('descendant::dc:date') + publisher = XPath('descendant::dc:publisher') + subject = XPath('descendant::dc:subject') + description = XPath('descendant::dc:description') + language = XPath('descendant::dc:language') + rating = XPath('descendant::gd:rating[@average]') + def get_text(extra, x): try: @@ -266,6 +265,7 @@ class GoogleBooks(Source): def get_all_details(self, br, log, entries, abort, # {{{ result_queue, timeout): + from lxml import etree for relevance, i in enumerate(entries): try: ans = to_metadata(br, log, i, timeout) @@ -289,6 +289,10 @@ class GoogleBooks(Source): def identify(self, log, result_queue, abort, title=None, authors=None, # {{{ identifiers={}, timeout=30): + from lxml import etree + XPath = partial(etree.XPath, namespaces=NAMESPACES) + entry = XPath('//atom:entry') + query = self.create_query(log, title=title, authors=authors, identifiers=identifiers) if not query: diff --git a/src/calibre/ebooks/metadata/sources/isbndb.py b/src/calibre/ebooks/metadata/sources/isbndb.py index 1da7f906bb..7e15ad275e 100644 --- a/src/calibre/ebooks/metadata/sources/isbndb.py +++ b/src/calibre/ebooks/metadata/sources/isbndb.py @@ -9,12 +9,9 @@ __docformat__ = 'restructuredtext en' from urllib import quote -from lxml import etree from calibre.ebooks.metadata import check_isbn from calibre.ebooks.metadata.sources.base import Source, Option -from calibre.ebooks.chardet import xml_to_unicode -from calibre.utils.cleantext import clean_ascii_chars from calibre.utils.icu import lower from calibre.ebooks.metadata.book.base import Metadata @@ -122,6 +119,7 @@ class ISBNDB(Source): result_queue.put(result) def parse_feed(self, feed, seen, orig_title, orig_authors, identifiers): + from lxml import etree def tostring(x): if x is None: @@ -198,6 +196,10 @@ class ISBNDB(Source): def make_query(self, q, abort, title=None, authors=None, identifiers={}, max_pages=10, timeout=30): + from lxml import etree + from calibre.ebooks.chardet import xml_to_unicode + from calibre.utils.cleantext import clean_ascii_chars + page_num = 1 parser = etree.XMLParser(recover=True, no_network=True) br = self.browser diff --git a/src/calibre/ebooks/metadata/sources/overdrive.py b/src/calibre/ebooks/metadata/sources/overdrive.py index 1164567ff5..bb1bbb9d42 100755 --- a/src/calibre/ebooks/metadata/sources/overdrive.py +++ b/src/calibre/ebooks/metadata/sources/overdrive.py @@ -9,18 +9,14 @@ __docformat__ = 'restructuredtext en' ''' Fetch metadata using Overdrive Content Reserve ''' -import re, random, mechanize, copy, json +import re, random, copy, json from threading import RLock from Queue import Queue, Empty -from lxml import html from calibre.ebooks.metadata import check_isbn from calibre.ebooks.metadata.sources.base import Source, Option from calibre.ebooks.metadata.book.base import Metadata -from calibre.ebooks.chardet import xml_to_unicode -from calibre.library.comments import sanitize_comments_html -from calibre.utils.soupparser import fromstring ovrdrv_data_cache = {} cache_lock = RLock() @@ -80,6 +76,7 @@ class OverDrive(Source): def download_cover(self, log, result_queue, abort, # {{{ title=None, authors=None, identifiers={}, timeout=30): + import mechanize cached_url = self.get_cached_cover_url(identifiers) if cached_url is None: log.info('No cached cover found, running identify') @@ -170,6 +167,7 @@ class OverDrive(Source): this page attempts to set a cookie that Mechanize doesn't like copy the cookiejar to a separate instance and make a one-off request with the temp cookiejar ''' + import mechanize goodcookies = br._ua_handlers['_cookies'].cookiejar clean_cj = mechanize.CookieJar() cookies_to_copy = [] @@ -187,6 +185,7 @@ class OverDrive(Source): br.set_cookiejar(clean_cj) def overdrive_search(self, br, log, q, title, author): + import mechanize # re-initialize the cookiejar to so that it's clean clean_cj = mechanize.CookieJar() br.set_cookiejar(clean_cj) @@ -303,6 +302,7 @@ class OverDrive(Source): return '' def overdrive_get_record(self, br, log, q, ovrdrv_id): + import mechanize search_url = q+'SearchResults.aspx?ReserveID={'+ovrdrv_id+'}' results_url = q+'SearchResults.svc/GetResults?sEcho=1&iColumns=18&sColumns=ReserveID%2CTitle%2CSubtitle%2CEdition%2CSeries%2CPublisher%2CFormat%2CFormatID%2CCreators%2CThumbImage%2CShortDescription%2CWorldCatLink%2CExcerptLink%2CCreatorFile%2CSortTitle%2CAvailableToLibrary%2CAvailableToRetailer%2CRelevancyRank&iDisplayStart=0&iDisplayLength=10&sSearch=&bEscapeRegex=true&iSortingCols=1&iSortCol_0=17&sSortDir_0=asc' @@ -393,6 +393,11 @@ class OverDrive(Source): def get_book_detail(self, br, metadata_url, mi, ovrdrv_id, log): + from lxml import html + from calibre.ebooks.chardet import xml_to_unicode + from calibre.utils.soupparser import fromstring + from calibre.library.comments import sanitize_comments_html + try: raw = br.open_novisit(metadata_url).read() except Exception, e: diff --git a/src/calibre/ebooks/metadata/sources/ozon.py b/src/calibre/ebooks/metadata/sources/ozon.py index de45e0b8db..d40e43d582 100644 --- a/src/calibre/ebooks/metadata/sources/ozon.py +++ b/src/calibre/ebooks/metadata/sources/ozon.py @@ -6,15 +6,11 @@ __copyright__ = '2011, Roman Mukhin ' __docformat__ = 'restructuredtext en' import re -import urllib2 import datetime from urllib import quote_plus from Queue import Queue, Empty -from lxml import etree, html + from calibre import as_unicode - -from calibre.ebooks.chardet import xml_to_unicode - from calibre.ebooks.metadata import check_isbn from calibre.ebooks.metadata.sources.base import Source from calibre.ebooks.metadata.book.base import Metadata @@ -43,6 +39,7 @@ class Ozon(Source): isbnRegex = re.compile(isbnPattern) def get_book_url(self, identifiers): # {{{ + import urllib2 ozon_id = identifiers.get('ozon', None) res = None if ozon_id: @@ -81,6 +78,9 @@ class Ozon(Source): def identify(self, log, result_queue, abort, title=None, authors=None, identifiers={}, timeout=30): # {{{ + from lxml import etree + from calibre.ebooks.chardet import xml_to_unicode + if not self.is_configured(): return query = self.create_query(log, title=title, authors=authors, identifiers=identifiers) @@ -283,6 +283,9 @@ class Ozon(Source): # }}} def get_book_details(self, log, metadata, timeout): # {{{ + from lxml import html, etree + from calibre.ebooks.chardet import xml_to_unicode + url = self.get_book_url(metadata.get_identifiers())[2] raw = self.browser.open_novisit(url, timeout=timeout).read() diff --git a/src/calibre/library/catalogs/bibtex.py b/src/calibre/library/catalogs/bibtex.py index 1815940931..b959f22eac 100644 --- a/src/calibre/library/catalogs/bibtex.py +++ b/src/calibre/library/catalogs/bibtex.py @@ -12,7 +12,6 @@ from types import StringType, UnicodeType from calibre import (strftime) from calibre.customize import CatalogPlugin from calibre.library.catalogs import FIELDS, TEMPLATE_ALLOWED_FIELDS -from calibre.utils.logging import default_log as log from calibre.customize.conversion import DummyReporter from calibre.constants import preferred_encoding @@ -113,6 +112,7 @@ class BIBTEX(CatalogPlugin): from calibre.utils.bibtex import BibTeX from calibre.library.save_to_disk import preprocess_template from calibre.utils.date import now as nowf + from calibre.utils.logging import default_log as log def create_bibtex_entry(entry, fields, mode, template_citation, bibtexdict, db, citation_bibtex=True, calibre_files=True): diff --git a/src/calibre/library/catalogs/csv_xml.py b/src/calibre/library/catalogs/csv_xml.py index a09084889b..f4a05d86a9 100644 --- a/src/calibre/library/catalogs/csv_xml.py +++ b/src/calibre/library/catalogs/csv_xml.py @@ -10,7 +10,6 @@ from collections import namedtuple from calibre.customize import CatalogPlugin from calibre.library.catalogs import FIELDS -from calibre.utils.logging import default_log as log from calibre.customize.conversion import DummyReporter class CSV_XML(CatalogPlugin): @@ -52,6 +51,7 @@ class CSV_XML(CatalogPlugin): from calibre.utils.date import isoformat from calibre.utils.html2text import html2text from lxml import etree + from calibre.utils.logging import default_log as log self.fmt = path_to_output.rpartition('.')[2] self.notification = notification diff --git a/src/calibre/library/catalogs/epub_mobi.py b/src/calibre/library/catalogs/epub_mobi.py index 97669f6ad8..cdc27b5e60 100644 --- a/src/calibre/library/catalogs/epub_mobi.py +++ b/src/calibre/library/catalogs/epub_mobi.py @@ -14,7 +14,6 @@ from calibre import strftime from calibre.constants import DEBUG from calibre.customize import CatalogPlugin from calibre.customize.conversion import OptionRecommendation, DummyReporter -from calibre.utils.logging import default_log as log Option = namedtuple('Option', 'option, default, dest, action, help') @@ -161,6 +160,8 @@ class EPUB_MOBI(CatalogPlugin): def run(self, path_to_output, opts, db, notification=DummyReporter()): from calibre.library.catalogs.epub_mobi_builder import CatalogBuilder + from calibre.utils.logging import default_log as log + opts.log = log opts.fmt = self.fmt = path_to_output.rpartition('.')[2] diff --git a/src/calibre/utils/date.py b/src/calibre/utils/date.py index faac8795d4..8741cb6a9e 100644 --- a/src/calibre/utils/date.py +++ b/src/calibre/utils/date.py @@ -10,7 +10,6 @@ import re from datetime import datetime, time from functools import partial -from dateutil.parser import parse from dateutil.tz import tzlocal, tzutc from calibre import strftime @@ -71,6 +70,7 @@ def parse_date(date_string, assume_utc=False, as_utc=True, default=None): :param default: Missing fields are filled in from default. If None, the current date is used. ''' + from dateutil.parser import parse if not date_string: return UNDEFINED_DATE if default is None: