GwR revisions

This commit is contained in:
GRiker 2010-06-08 03:32:47 -06:00
parent 045a893d20
commit d268786eeb

View File

@ -48,7 +48,7 @@ class ITUNES(DevicePlugin):
supported_platforms = ['osx','windows'] supported_platforms = ['osx','windows']
author = 'GRiker' author = 'GRiker'
#: The version of this plugin as a 3-tuple (major, minor, revision) #: The version of this plugin as a 3-tuple (major, minor, revision)
version = (0, 4, 0) version = (0, 4, 11)
OPEN_FEEDBACK_MESSAGE = _( OPEN_FEEDBACK_MESSAGE = _(
'Apple device detected, launching iTunes, please wait ...') 'Apple device detected, launching iTunes, please wait ...')
@ -221,7 +221,10 @@ class ITUNES(DevicePlugin):
for (i,book) in enumerate(device_books): for (i,book) in enumerate(device_books):
this_book = Book(book.name(), book.artist()) this_book = Book(book.name(), book.artist())
this_book.path = self.path_template % (book.name(), book.artist()) this_book.path = self.path_template % (book.name(), book.artist())
this_book.datetime = parse_date(str(book.date_added())).timetuple() try:
this_book.datetime = parse_date(str(book.date_added())).timetuple()
except:
pass
this_book.db_id = None this_book.db_id = None
this_book.device_collections = [] this_book.device_collections = []
this_book.library_id = library_books[this_book.path] if this_book.path in library_books else None this_book.library_id = library_books[this_book.path] if this_book.path in library_books else None
@ -251,7 +254,10 @@ class ITUNES(DevicePlugin):
for (i,book) in enumerate(device_books): for (i,book) in enumerate(device_books):
this_book = Book(book.Name, book.Artist) this_book = Book(book.Name, book.Artist)
this_book.path = self.path_template % (book.Name, book.Artist) this_book.path = self.path_template % (book.Name, book.Artist)
this_book.datetime = parse_date(str(book.DateAdded)).timetuple() try:
this_book.datetime = parse_date(str(book.DateAdded)).timetuple()
except:
pass
this_book.db_id = None this_book.db_id = None
this_book.device_collections = [] this_book.device_collections = []
this_book.library_id = library_books[this_book.path] if this_book.path in library_books else None this_book.library_id = library_books[this_book.path] if this_book.path in library_books else None
@ -630,7 +636,7 @@ class ITUNES(DevicePlugin):
:detected_device: Device information from the device scanner :detected_device: Device information from the device scanner
""" """
if DEBUG: if DEBUG:
self.log.info("ITUNE.reset()") self.log.info("ITUNES.reset()")
def set_progress_reporter(self, report_progress): def set_progress_reporter(self, report_progress):
''' '''
@ -810,7 +816,10 @@ class ITUNES(DevicePlugin):
# Create a new Book # Create a new Book
this_book = Book(metadata[i].title, metadata[i].author[0]) this_book = Book(metadata[i].title, metadata[i].author[0])
this_book.datetime = parse_date(str(added.date_added())).timetuple() try:
this_book.datetime = parse_date(str(added.date_added())).timetuple()
except:
pass
this_book.db_id = None this_book.db_id = None
this_book.device_collections = [] this_book.device_collections = []
this_book.library_id = added this_book.library_id = added
@ -868,9 +877,10 @@ class ITUNES(DevicePlugin):
if lib is not None: if lib is not None:
lib_books = None lib_books = None
for pl in lib.Playlists: for pl in lib.Playlists:
if self.PlaylistKind[pl.Kind] == 'User' and self.PlaylistSpecialKind[pl.SpecialKind] == 'Books': if pl.Kind == self.PlaylistKind.index('User') and \
pl.SpecialKind == self.PlaylistSpecialKind.index('Books'):
if DEBUG: if DEBUG:
self.log.info(" Books playlist: '%s' special_kind: '%s'" % (pl.Name, self.PlaylistSpecialKind[pl.SpecialKind])) self.log.info(" Books playlist: '%s'" % (pl.Name))
lib_books = pl lib_books = pl
break break
else: else:
@ -924,14 +934,17 @@ class ITUNES(DevicePlugin):
# Add to iTunes Library|Books # Add to iTunes Library|Books
if isinstance(file,PersistentTemporaryFile): if isinstance(file,PersistentTemporaryFile):
op_status = lib_books.AddFile(file._name) op_status = lib_books.AddFile(file._name)
self.log.info("ITUNES.upload_books():\n iTunes adding '%s'" % file._name) if DEBUG:
self.log.info("ITUNES.upload_books():\n iTunes adding '%s'" % file._name)
else: else:
op_status = lib_books.AddFile(file) op_status = lib_books.AddFile(file)
self.log.info(" iTunes adding '%s'" % file) if DEBUG:
self.log.info(" iTunes adding '%s'" % file)
if DEBUG: if DEBUG:
sys.stdout.write(" iTunes copying '%s' ..." % metadata[i].title) sys.stdout.write(" iTunes copying '%s' ..." % metadata[i].title)
sys.stdout.flush() sys.stdout.flush()
while op_status.InProgress: while op_status.InProgress:
time.sleep(0.5) time.sleep(0.5)
if DEBUG: if DEBUG:
@ -947,7 +960,7 @@ class ITUNES(DevicePlugin):
if DEBUG: if DEBUG:
sys.stdout.write(" waiting for handle to '%s' ..." % metadata[i].title) sys.stdout.write(" waiting for handle to '%s' ..." % metadata[i].title)
sys.stdout.flush() sys.stdout.flush()
while not op_status.Tracks: while op_status.Tracks is None:
time.sleep(0.5) time.sleep(0.5)
if DEBUG: if DEBUG:
sys.stdout.write('.') sys.stdout.write('.')
@ -960,80 +973,83 @@ class ITUNES(DevicePlugin):
added = self._find_library_book( added = self._find_library_book(
{'title': metadata[i].title,'author': metadata[i].author[0]}) {'title': metadata[i].title,'author': metadata[i].author[0]})
if not added: if added:
self.log.error("ITUNES.upload_books():\n could not find added book in iTunes") thumb = None
# Use cover data as artwork
if metadata[i].cover:
if added.Artwork.Count:
added.Artwork.Item(1).SetArtworkFromFile(metadata[i].cover)
else:
added.AddArtworkFromFile(metadata[i].cover)
thumb = None try:
# Use cover data as artwork # Resize for thumb
if metadata[i].cover: width = metadata[i].thumbnail[0]
if added.Artwork.Count: height = metadata[i].thumbnail[1]
added.Artwork.Item(1).SetArtworkFromFile(metadata[i].cover) im = PILImage.open(metadata[i].cover)
else: im = im.resize((width, height), PILImage.ANTIALIAS)
added.AddArtworkFromFile(metadata[i].cover) of = cStringIO.StringIO()
im.convert('RGB').save(of, 'JPEG')
thumb = of.getvalue()
# Refresh the thumbnail cache
if DEBUG:
self.log.info( " refreshing cached thumb for '%s'" % metadata[i].title)
archive_path = os.path.join(self.cache_dir, "thumbs.zip")
zfw = zipfile.ZipFile(archive_path, mode='a')
thumb_path = path.rpartition('.')[0] + '.jpg'
zfw.writestr(thumb_path, thumb)
zfw.close()
except:
self.problem_titles.append("'%s' by %s" % (metadata[i].title, metadata[i].author[0]))
self.log.error("ITUNES.upload_books():\n error converting '%s' to thumb for '%s'" % (metadata[i].cover,metadata[i].title))
# Create a new Book
this_book = Book(metadata[i].title, metadata[i].author[0])
try: try:
# Resize for thumb this_book.datetime = parse_date(str(added.DateAdded)).timetuple()
width = metadata[i].thumbnail[0]
height = metadata[i].thumbnail[1]
im = PILImage.open(metadata[i].cover)
im = im.resize((width, height), PILImage.ANTIALIAS)
of = cStringIO.StringIO()
im.convert('RGB').save(of, 'JPEG')
thumb = of.getvalue()
# Refresh the thumbnail cache
if DEBUG:
self.log.info( " refreshing cached thumb for '%s'" % metadata[i].title)
archive_path = os.path.join(self.cache_dir, "thumbs.zip")
zfw = zipfile.ZipFile(archive_path, mode='a')
thumb_path = path.rpartition('.')[0] + '.jpg'
zfw.writestr(thumb_path, thumb)
zfw.close()
except: except:
self.problem_titles.append("'%s' by %s" % (metadata[i].title, metadata[i].author[0])) pass
self.log.error("ITUNES.upload_books():\n error converting '%s' to thumb for '%s'" % (metadata[i].cover,metadata[i].title)) this_book.db_id = None
this_book.device_collections = []
this_book.library_id = added
this_book.path = path
this_book.size = added.Size # Updated later from actual storage size
this_book.thumbnail = thumb
this_book.iTunes_id = added
# Create a new Book new_booklist.append(this_book)
this_book = Book(metadata[i].title, metadata[i].author[0])
this_book.datetime = parse_date(str(added.DateAdded)).timetuple()
this_book.db_id = None
this_book.device_collections = []
this_book.library_id = added
this_book.path = path
this_book.size = added.Size # Updated later from actual storage size
this_book.thumbnail = thumb
this_book.iTunes_id = added
new_booklist.append(this_book) # Flesh out the iTunes metadata
if metadata[i].comments:
added.Comment = (strip_tags.sub('',metadata[i].comments))
added.Description = ("added by calibre %s" % strftime('%Y-%m-%d %H:%M:%S'))
added.Enabled = True
if metadata[i].rating:
added.AlbumRating = (metadata[i].rating*10)
added.SortArtist = (metadata[i].author_sort.title())
added.SortName = (this_book.title_sorter)
# Flesh out the iTunes metadata # Set genre from metadata
if metadata[i].comments: # iTunes grabs the first dc:subject from the opf metadata,
added.Comment = (strip_tags.sub('',metadata[i].comments)) # But we can manually override with first tag starting with alpha
added.Description = ("added by calibre %s" % strftime('%Y-%m-%d %H:%M:%S')) for tag in metadata[i].tags:
added.Enabled = True if self._is_alpha(tag[0]):
if metadata[i].rating: added.Category = (tag)
added.AlbumRating = (metadata[i].rating*10) break
added.SortArtist = (metadata[i].author_sort.title())
added.SortName = (this_book.title_sorter)
# Set genre from metadata # Add new_book to self.cached_paths
# iTunes grabs the first dc:subject from the opf metadata, self.cached_books[this_book.path] = {
# But we can manually override with first tag starting with alpha 'title': metadata[i].title,
for tag in metadata[i].tags: 'author': metadata[i].author[0],
if self._is_alpha(tag[0]): 'lib_book': added
added.Category = (tag) }
break
# Add new_book to self.cached_paths # Report progress
self.cached_books[this_book.path] = { if self.report_progress is not None:
'title': metadata[i].title, self.report_progress(i+1/file_count, _('%d of %d') % (i+1, file_count))
'author': metadata[i].author[0], else:
'lib_book': added self.log.error("ITUNES.upload_books():\n could not find added book in iTunes")
}
# Report progress
if self.report_progress is not None:
self.report_progress(i+1/file_count, _('%d of %d') % (i+1, file_count))
finally: finally:
pythoncom.CoUninitialize() pythoncom.CoUninitialize()
@ -1148,9 +1164,10 @@ class ITUNES(DevicePlugin):
if lib is not None: if lib is not None:
lib_books = None lib_books = None
for pl in lib.Playlists: for pl in lib.Playlists:
if self.PlaylistKind[pl.Kind] == 'User' and self.PlaylistSpecialKind[pl.SpecialKind] == 'Books': if pl.Kind == self.PlaylistKind.index('User') and \
pl.SpecialKind == self.PlaylistSpecialKind.index('Books'):
if DEBUG: if DEBUG:
self.log.info(" Books playlist: '%s' special_kind: '%s'" % (pl.Name, self.PlaylistSpecialKind[pl.SpecialKind])) self.log.info(" Books playlist: '%s'" % (pl.Name))
lib_books = pl lib_books = pl
break break
else: else:
@ -1163,7 +1180,7 @@ class ITUNES(DevicePlugin):
hits = lib_books.Search(cached_book['author'],SearchField.index('Artists')) hits = lib_books.Search(cached_book['author'],SearchField.index('Artists'))
if hits: if hits:
for hit in hits: for hit in hits:
#self.log.info(" evaluating '%s' by %s" % (hit.Name, hit.Artist)) self.log.info(" evaluating '%s' by %s" % (hit.Name, hit.Artist))
if hit.Name == cached_book['title']: if hit.Name == cached_book['title']:
self.log.info(" matched '%s' by %s" % (hit.Name, hit.Artist)) self.log.info(" matched '%s' by %s" % (hit.Name, hit.Artist))
return hit return hit
@ -1173,7 +1190,7 @@ class ITUNES(DevicePlugin):
self.log.warning(" attempt #%d" % (10 - attempts)) self.log.warning(" attempt #%d" % (10 - attempts))
if DEBUG: if DEBUG:
self.log.error(" search yielded no hits") self.log.error(" search for '%s' yielded no hits" % cached_book['title'])
return None return None
def _generate_thumbnail(self, book_path, book): def _generate_thumbnail(self, book_path, book):
@ -1277,18 +1294,21 @@ class ITUNES(DevicePlugin):
for pl in device.playlists(): for pl in device.playlists():
if pl.special_kind() == appscript.k.Books: if pl.special_kind() == appscript.k.Books:
if DEBUG: if DEBUG:
self.log.info(" Book playlist: '%s' special_kind: '%s'" % (pl.name(), pl.special_kind())) self.log.info(" Book playlist: '%s'" % (pl.name()))
books = pl.file_tracks() books = pl.file_tracks()
break break
else: else:
self.log.error(" book_playlist not found") self.log.error(" book_playlist not found")
for book in books: for book in books:
if book.kind() in ['Book','Protected book']: # This may need additional entries for international iTunes users
device_books.append(book) if book.kind() in ['MPEG audio file']:
if DEBUG:
self.log.info(" ignoring '%s' of type '%s'" % (book.name(), book.kind()))
else: else:
if DEBUG: if DEBUG:
self.log.info(" ignoring '%s' of type '%s'" % (book.name(), book.kind())) self.log.info(" adding %-30.30s [%s]" % (book.name(), book.kind()))
device_books.append(book)
elif iswindows: elif iswindows:
if 'iPod' in self.sources: if 'iPod' in self.sources:
@ -1299,9 +1319,10 @@ class ITUNES(DevicePlugin):
dev_books = None dev_books = None
for pl in device.Playlists: for pl in device.Playlists:
if self.PlaylistKind[pl.Kind] == 'User' and self.PlaylistSpecialKind[pl.SpecialKind] == 'Books': if pl.Kind == self.PlaylistKind.index('User') and \
pl.SpecialKind == self.PlaylistSpecialKind.index('Books'):
if DEBUG: if DEBUG:
self.log.info(" Books playlist: '%s' special_kind: '%s'" % (pl.Name, self.PlaylistSpecialKind[pl.SpecialKind])) self.log.info(" Books playlist: '%s'" % (pl.Name))
dev_books = pl.Tracks dev_books = pl.Tracks
break break
else: else:
@ -1309,10 +1330,14 @@ class ITUNES(DevicePlugin):
self.log.info(" no Books playlist found") self.log.info(" no Books playlist found")
for book in dev_books: for book in dev_books:
if book.KindAsString in ['Book','Protected book']: # This may need additional entries for international iTunes users
device_books.append(book) if book.KindAsString in ['MPEG audio file']:
if DEBUG:
self.log.info(" ignoring '%s' of type '%s'" % (book.Name, book.KindAsString))
else: else:
self.log.info(" ignoring '%s' of type %s" % (book.Name, book.KindAsString)) if DEBUG:
self.log.info(" adding %-30.30s [%s]" % (book.Name, book.KindAsString))
device_books.append(book)
finally: finally:
pythoncom.CoUninitialize() pythoncom.CoUninitialize()
@ -1334,7 +1359,7 @@ class ITUNES(DevicePlugin):
if source.kind() == appscript.k.library: if source.kind() == appscript.k.library:
lib = source lib = source
if DEBUG: if DEBUG:
self.log.info(" Library source: '%s' kind: %s" % (lib.name(), lib.kind())) self.log.info(" Library source: '%s'" % (lib.name()))
break break
else: else:
if DEBUG: if DEBUG:
@ -1342,22 +1367,33 @@ class ITUNES(DevicePlugin):
if lib is not None: if lib is not None:
lib_books = None lib_books = None
for pl in lib.playlists(): if lib.playlists():
if pl.special_kind() == appscript.k.Books: for pl in lib.playlists():
if DEBUG: if pl.special_kind() == appscript.k.Books:
self.log.info(" Books playlist: '%s' special_kind: '%s'" % (pl.name(), pl.special_kind())) if DEBUG:
break self.log.info(" Books playlist: '%s'" % (pl.name()))
lib_books = pl.file_tracks() break
for book in lib_books:
if book.kind() in ['Book','Protected book']:
path = self.path_template % (book.name(), book.artist())
library_books[path] = book
else: else:
if DEBUG: if DEBUG:
self.log.info(" ignoring library book of type '%s'" % book.kind()) self.log.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 ['MPEG audio file']:
if DEBUG:
self.log.info(" ignoring '%s' of type '%s'" % (book.name(), book.kind()))
else:
if DEBUG:
self.log.info(" adding %-30.30s [%s]" % (book.name(), book.kind()))
path = self.path_template % (book.name(), book.artist())
library_books[path] = book
else:
if DEBUG:
self.log.info('No Library playlists')
else: else:
if DEBUG: if DEBUG:
self.log.info('ITUNES._get_library_books():\n No Books playlist') self.log.info(' no Library found')
elif iswindows: elif iswindows:
lib = None lib = None
@ -1374,23 +1410,32 @@ class ITUNES(DevicePlugin):
if lib is not None: if lib is not None:
lib_books = None lib_books = None
for pl in lib.Playlists: if lib.Playlists is not None:
if self.PlaylistKind[pl.Kind] == 'User' and self.PlaylistSpecialKind[pl.SpecialKind] == 'Books': for pl in lib.Playlists:
if DEBUG: if pl.Kind == self.PlaylistKind.index('User') and \
self.log.info(" Books playlist: '%s' special_kind: '%s'" % (pl.Name, self.PlaylistSpecialKind[pl.SpecialKind])) pl.SpecialKind == self.PlaylistSpecialKind.index('Books'):
lib_books = pl.Tracks if DEBUG:
break self.log.info(" Books playlist: '%s'" % (pl.Name))
else: lib_books = pl.Tracks
if DEBUG: break
self.log.error(" no Books playlist found")
for book in lib_books:
if book.KindAsString in ['Book','Protected book']:
path = self.path_template % (book.Name, book.Artist)
library_books[path] = book
else: else:
if DEBUG: if DEBUG:
self.log.info(" ignoring '%s' of type %s" % (book.Name, book.KindAsString)) self.log.error(" no Library|Books playlist found")
else:
if DEBUG:
self.log.error(" no Library playlists found")
for book in lib_books:
# This may need additional entries for international iTunes users
if book.KindAsString in ['MPEG audio file']:
if DEBUG:
self.log.info(" ignoring %-30.30s of type '%s'" % (book.Name, book.KindAsString))
else:
if DEBUG:
self.log.info(" adding %-30.30s [%s]" % (book.Name, book.KindAsString))
path = self.path_template % (book.Name, book.Artist)
library_books[path] = book
finally: finally:
pythoncom.CoUninitialize() pythoncom.CoUninitialize()