GwR wip apple driver updates

This commit is contained in:
GRiker 2010-10-05 03:53:38 -07:00
parent b57222a01c
commit d8f64b400e
4 changed files with 111 additions and 71 deletions

View File

@ -68,6 +68,8 @@ class ITUNES(DriverBase):
Delete: Delete:
delete_books() delete_books()
remove_books_from_metadata() remove_books_from_metadata()
use_plugboard_ext()
set_plugboard()
sync_booklists() sync_booklists()
card_prefix() card_prefix()
free_space() free_space()
@ -76,6 +78,8 @@ class ITUNES(DriverBase):
set_progress_reporter() set_progress_reporter()
upload_books() upload_books()
add_books_to_metadata() add_books_to_metadata()
use_plugboard_ext()
set_plugboard()
set_progress_reporter() set_progress_reporter()
sync_booklists() sync_booklists()
card_prefix() card_prefix()
@ -817,12 +821,12 @@ class ITUNES(DriverBase):
self.report_progress = report_progress self.report_progress = report_progress
def set_plugboard(self, pb): def set_plugboard(self, pb):
# This method is called with the plugboard that matches the above # This method is called with the plugboard that matches the format
# format and the current device name. # declared in use_plugboard_ext and a device name of ITUNES
if DEBUG: if DEBUG:
self.log.info("ITUNES.set_plugboard()") self.log.info("ITUNES.set_plugboard()")
if pb is not None:
self.log.info(' using plugboard %s' % pb) self.log.info(' using plugboard %s' % pb)
if pb is not None:
self.plugboard = pb self.plugboard = pb
def sync_booklists(self, booklists, end_session=True): def sync_booklists(self, booklists, end_session=True):
@ -836,10 +840,6 @@ class ITUNES(DriverBase):
if DEBUG: if DEBUG:
self.log.info("ITUNES.sync_booklists()") self.log.info("ITUNES.sync_booklists()")
# booklists[0] should contain enough info to call
# self._update_iTunes_metadata(metadata[i], db_added, lb_added, this_book)
# from here using the plugboard data as the metadata
if self.update_needed: if self.update_needed:
if DEBUG: if DEBUG:
self.log.info(' calling _update_device') self.log.info(' calling _update_device')
@ -875,7 +875,7 @@ class ITUNES(DriverBase):
return (capacity,-1,-1) return (capacity,-1,-1)
def upload_books(self, files, names, on_card=None, end_session=True, def upload_books(self, files, names, on_card=None, end_session=True,
metadata=None, plugboards=None): metadata=None):
''' '''
Upload a list of books to the device. If a file already Upload a list of books to the device. If a file already
exists on the device, it should be replaced. exists on the device, it should be replaced.
@ -906,7 +906,6 @@ class ITUNES(DriverBase):
self.log.info("ITUNES.upload_books()") self.log.info("ITUNES.upload_books()")
self._dump_files(files, header='upload_books()',indent=2) self._dump_files(files, header='upload_books()',indent=2)
self._dump_update_list(header='upload_books()',indent=2) self._dump_update_list(header='upload_books()',indent=2)
self.log.info(" plugboards: %s" % plugboards)
if isosx: if isosx:
for (i,file) in enumerate(files): for (i,file) in enumerate(files):
@ -994,10 +993,10 @@ class ITUNES(DriverBase):
return (new_booklist, [], []) return (new_booklist, [], [])
def use_plugboard_ext(self): def use_plugboard_ext(self):
''' Declare which plugboard extensions we care about ''' ''' Declare which plugboard extension we care about '''
if DEBUG:
self.log.info("ITUNES.use_plugboard_ext()")
ext = 'epub' ext = 'epub'
if DEBUG:
self.log.info("ITUNES.use_plugboard_ext(): declaring %s" % ext)
return ext return ext
@ -2601,75 +2600,84 @@ class ITUNES(DriverBase):
if DEBUG: if DEBUG:
self.log.info(" ITUNES._update_iTunes_metadata()") self.log.info(" ITUNES._update_iTunes_metadata()")
strip_tags = re.compile(r'<[^<]*?/?>') STRIP_TAGS = re.compile(r'<[^<]*?/?>')
# Update metadata from plugboard
# If self.plugboard is None (no transforms), original metadata is returned intact
metadata_x = self._xform_metadata_via_plugboard(metadata)
if isosx: if isosx:
if lb_added: if lb_added:
lb_added.album.set(metadata.title) lb_added.album.set(metadata_x.title)
lb_added.artist.set(authors_to_string(metadata.authors)) lb_added.artist.set(authors_to_string(metadata_x.authors))
lb_added.composer.set(metadata.uuid) lb_added.composer.set(metadata_x.uuid)
lb_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S'))) lb_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
lb_added.enabled.set(True) lb_added.enabled.set(True)
lb_added.sort_artist.set(metadata.author_sort.title()) lb_added.sort_artist.set(metadata_x.author_sort.title())
lb_added.sort_name.set(this_book.title_sorter) lb_added.sort_name.set(this_book.title_sorter)
if this_book.format == 'pdf': if this_book.format == 'pdf':
lb_added.name.set(metadata.title) lb_added.name.set(metadata.title)
elif this_book.format == 'epub':
lb_added.name.set(metadata_x.title)
if db_added: if db_added:
db_added.album.set(metadata.title) db_added.album.set(metadata_x.title)
db_added.artist.set(authors_to_string(metadata.authors)) db_added.artist.set(authors_to_string(metadata_x.authors))
db_added.composer.set(metadata.uuid) db_added.composer.set(metadata_x.uuid)
db_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S'))) db_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
db_added.enabled.set(True) db_added.enabled.set(True)
db_added.sort_artist.set(metadata.author_sort.title()) db_added.sort_artist.set(metadata_x.author_sort.title())
db_added.sort_name.set(this_book.title_sorter) db_added.sort_name.set(this_book.title_sorter)
if this_book.format == 'pdf': if this_book.format == 'pdf':
db_added.name.set(metadata.title) db_added.name.set(metadata.title)
elif this_book.format == 'epub':
db_added.name.set(metadata_x.title)
if metadata.comments: if metadata_x.comments:
if lb_added: if lb_added:
lb_added.comment.set(strip_tags.sub('',metadata.comments)) lb_added.comment.set(STRIP_TAGS.sub('',metadata_x.comments))
if db_added: if db_added:
db_added.comment.set(strip_tags.sub('',metadata.comments)) db_added.comment.set(STRIP_TAGS.sub('',metadata_x.comments))
if metadata.rating: if metadata_x.rating:
if lb_added: if lb_added:
lb_added.rating.set(metadata.rating*10) lb_added.rating.set(metadata_x.rating*10)
# iBooks currently doesn't allow setting rating ... ? # iBooks currently doesn't allow setting rating ... ?
try: try:
if db_added: if db_added:
db_added.rating.set(metadata.rating*10) db_added.rating.set(metadata_x.rating*10)
except: except:
pass pass
# Set genre from series if available, else first alpha tag # Set genre from series if available, else first alpha tag
# Otherwise iTunes grabs the first dc:subject from the opf metadata # Otherwise iTunes grabs the first dc:subject from the opf metadata
if metadata.series and self.settings().read_metadata: if metadata_x.series and self.settings().read_metadata:
if DEBUG: if DEBUG:
self.log.info(" using Series name as Genre") self.log.info(" using Series name as Genre")
# Format the index as a sort key # Format the index as a sort key
index = metadata.series_index index = metadata_x.series_index
integer = int(index) integer = int(index)
fraction = index-integer fraction = index-integer
series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0')) series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0'))
if lb_added: if lb_added:
lb_added.sort_name.set("%s %s" % (metadata.series, series_index)) lb_added.sort_name.set("%s %s" % (metadata_x.series, series_index))
lb_added.genre.set(metadata.series) lb_added.genre.set(metadata_x.series)
lb_added.episode_ID.set(metadata.series) lb_added.episode_ID.set(metadata_x.series)
lb_added.episode_number.set(metadata.series_index) lb_added.episode_number.set(metadata_x.series_index)
if db_added: if db_added:
db_added.sort_name.set("%s %s" % (metadata.series, series_index)) db_added.sort_name.set("%s %s" % (metadata_x.series, series_index))
db_added.genre.set(metadata.series) db_added.genre.set(metadata_x.series)
db_added.episode_ID.set(metadata.series) db_added.episode_ID.set(metadata_x.series)
db_added.episode_number.set(metadata.series_index) db_added.episode_number.set(metadata_x.series_index)
elif metadata.tags: elif metadata_x.tags:
if DEBUG: if DEBUG:
self.log.info(" %susing Tag as Genre" % self.log.info(" %susing Tag as Genre" %
"no Series name available, " if self.settings().read_metadata else '') "no Series name available, " if self.settings().read_metadata else '')
for tag in metadata.tags: for tag in metadata_x.tags:
if self._is_alpha(tag[0]): if self._is_alpha(tag[0]):
if lb_added: if lb_added:
lb_added.genre.set(tag) lb_added.genre.set(tag)
@ -2679,40 +2687,44 @@ class ITUNES(DriverBase):
elif iswindows: elif iswindows:
if lb_added: if lb_added:
lb_added.Album = metadata.title lb_added.Album = metadata_x.title
lb_added.Artist = authors_to_string(metadata.authors) lb_added.Artist = authors_to_string(metadata_x.authors)
lb_added.Composer = metadata.uuid lb_added.Composer = metadata_x.uuid
lb_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S'))) lb_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
lb_added.Enabled = True lb_added.Enabled = True
lb_added.SortArtist = (metadata.author_sort.title()) lb_added.SortArtist = (metadata_x.author_sort.title())
lb_added.SortName = (this_book.title_sorter) lb_added.SortName = (this_book.title_sorter)
if this_book.format == 'pdf': if this_book.format == 'pdf':
lb_added.Name = metadata.title lb_added.Name = metadata.title
elif this_book.format == 'epub':
lb_added.Name = metadata_x.title
if db_added: if db_added:
db_added.Album = metadata.title db_added.Album = metadata_x.title
db_added.Artist = authors_to_string(metadata.authors) db_added.Artist = authors_to_string(metadata_x.authors)
db_added.Composer = metadata.uuid db_added.Composer = metadata_x.uuid
db_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S'))) db_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
db_added.Enabled = True db_added.Enabled = True
db_added.SortArtist = (metadata.author_sort.title()) db_added.SortArtist = (metadata_x.author_sort.title())
db_added.SortName = (this_book.title_sorter) db_added.SortName = (this_book.title_sorter)
if this_book.format == 'pdf': if this_book.format == 'pdf':
db_added.Name = metadata.title db_added.Name = metadata.title
elif this_book.format == 'epub':
db_added.Name = metadata_x.title
if metadata.comments: if metadata_x.comments:
if lb_added: if lb_added:
lb_added.Comment = (strip_tags.sub('',metadata.comments)) lb_added.Comment = (STRIP_TAGS.sub('',metadata_x.comments))
if db_added: if db_added:
db_added.Comment = (strip_tags.sub('',metadata.comments)) db_added.Comment = (STRIP_TAGS.sub('',metadata_x.comments))
if metadata.rating: if metadata_x.rating:
if lb_added: if lb_added:
lb_added.AlbumRating = (metadata.rating*10) lb_added.AlbumRating = (metadata_x.rating*10)
# iBooks currently doesn't allow setting rating ... ? # iBooks currently doesn't allow setting rating ... ?
try: try:
if db_added: if db_added:
db_added.AlbumRating = (metadata.rating*10) db_added.AlbumRating = (metadata_x.rating*10)
except: except:
if DEBUG: if DEBUG:
self.log.warning(" iTunes automation interface reported an error" self.log.warning(" iTunes automation interface reported an error"
@ -2722,36 +2734,36 @@ class ITUNES(DriverBase):
# Otherwise iBooks uses first <dc:subject> from opf # Otherwise iBooks uses first <dc:subject> from opf
# iTunes balks on setting EpisodeNumber, but it sticks (9.1.1.12) # iTunes balks on setting EpisodeNumber, but it sticks (9.1.1.12)
if metadata.series and self.settings().read_metadata: if metadata_x.series and self.settings().read_metadata:
if DEBUG: if DEBUG:
self.log.info(" using Series name as Genre") self.log.info(" using Series name as Genre")
# Format the index as a sort key # Format the index as a sort key
index = metadata.series_index index = metadata_x.series_index
integer = int(index) integer = int(index)
fraction = index-integer fraction = index-integer
series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0')) series_index = '%04d%s' % (integer, str('%0.4f' % fraction).lstrip('0'))
if lb_added: if lb_added:
lb_added.SortName = "%s %s" % (metadata.series, series_index) lb_added.SortName = "%s %s" % (metadata_x.series, series_index)
lb_added.Genre = metadata.series lb_added.Genre = metadata_x.series
lb_added.EpisodeID = metadata.series lb_added.EpisodeID = metadata_x.series
try: try:
lb_added.EpisodeNumber = metadata.series_index lb_added.EpisodeNumber = metadata_x.series_index
except: except:
pass pass
if db_added: if db_added:
db_added.SortName = "%s %s" % (metadata.series, series_index) db_added.SortName = "%s %s" % (metadata_x.series, series_index)
db_added.Genre = metadata.series db_added.Genre = metadata_x.series
db_added.EpisodeID = metadata.series db_added.EpisodeID = metadata_x.series
try: try:
db_added.EpisodeNumber = metadata.series_index db_added.EpisodeNumber = metadata_x.series_index
except: except:
if DEBUG: if DEBUG:
self.log.warning(" iTunes automation interface reported an error" self.log.warning(" iTunes automation interface reported an error"
" setting EpisodeNumber on iDevice") " setting EpisodeNumber on iDevice")
elif metadata.tags: elif metadata_x.tags:
if DEBUG: if DEBUG:
self.log.info(" using Tag as Genre") self.log.info(" using Tag as Genre")
for tag in metadata.tags: for tag in metadata_x.tags:
if self._is_alpha(tag[0]): if self._is_alpha(tag[0]):
if lb_added: if lb_added:
lb_added.Genre = tag lb_added.Genre = tag
@ -2759,6 +2771,25 @@ class ITUNES(DriverBase):
db_added.Genre = tag db_added.Genre = tag
break break
def _xform_metadata_via_plugboard(self, book):
''' Transform book metadata from plugboard templates '''
if DEBUG:
self.log.info("ITUNES._update_metadata_from_plugboard()")
if self.plugboard is not None:
newmi = book.deepcopy_metadata()
newmi.template_to_attribute(book, self.plugboard)
if DEBUG:
if book.title != newmi.title:
self.log.info(" .title (original): %s" % book.title)
self.log.info(" .title (templated): %s" % newmi.title)
else:
self.log.info(" .title (no change): %s" % book.title)
else:
newmi = book
return newmi
class ITUNES_ASYNC(ITUNES): class ITUNES_ASYNC(ITUNES):
''' '''
This subclass allows the user to interact directly with iTunes via a menu option This subclass allows the user to interact directly with iTunes via a menu option
@ -3043,7 +3074,7 @@ class BookList(list):
class Book(Metadata): class Book(Metadata):
''' '''
A simple class describing a book in the iTunes Books Library. A simple class describing a book in the iTunes Books Library.
- See ebooks.metadata.__init__ for all fields See ebooks.metadata.book.base
''' '''
def __init__(self,title,author): def __init__(self,title,author):

View File

@ -148,6 +148,11 @@ class Metadata(object):
object.__setattr__(m, '_data', copy.deepcopy(object.__getattribute__(self, '_data'))) object.__setattr__(m, '_data', copy.deepcopy(object.__getattribute__(self, '_data')))
return m return m
def deepcopy_metadata(self):
m = Metadata(None)
object.__setattr__(m, '_data', copy.deepcopy(object.__getattribute__(self, '_data')))
return m
def get(self, field, default=None): def get(self, field, default=None):
try: try:
return self.__getattribute__(field) return self.__getattribute__(field)

View File

@ -345,6 +345,11 @@ class DeviceManager(Thread): # {{{
def _upload_books(self, files, names, on_card=None, metadata=None, plugboards=None): def _upload_books(self, files, names, on_card=None, metadata=None, plugboards=None):
'''Upload books to device: ''' '''Upload books to device: '''
if hasattr(self.connected_device, 'use_plugboard_ext') and \
callable(self.connected_device.use_plugboard_ext):
ext = self.connected_device.use_plugboard_ext()
if ext is not None:
self.connected_device.set_plugboard(self.find_plugboard(ext, plugboards))
if metadata and files and len(metadata) == len(files): if metadata and files and len(metadata) == len(files):
for f, mi in zip(files, metadata): for f, mi in zip(files, metadata):
if isinstance(f, unicode): if isinstance(f, unicode):

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>707</width> <width>931</width>
<height>340</height> <height>389</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -23,7 +23,7 @@ Use this dialog to define a 'plugboard' for a format (or all formats) and a devi
Often templates will contain simple references to composite columns, but this is not necessary. You can use any template in a source box that you can use elsewhere in calibre. Often templates will contain simple references to composite columns, but this is not necessary. You can use any template in a source box that you can use elsewhere in calibre.
One possible use for a plugboard is to alter the title to contain series informaton. Another would be to change the author sort, something that mobi users might do to force it to use the ';' that the kindle requires. A third would be to specify the language.</string> One possible use for a plugboard is to alter the title to contain series information. Another would be to change the author sort, something that mobi users might do to force it to use the ';' that the kindle requires. A third would be to specify the language.</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::PlainText</enum> <enum>Qt::PlainText</enum>
@ -41,8 +41,7 @@ One possible use for a plugboard is to alter the title to contain series informa
</widget> </widget>
</item> </item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
<widget class="QLabel" name="device_label"> <widget class="QLabel" name="device_label"/>
</widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="3" column="0" colspan="2">
<widget class="Line" name="line"> <widget class="Line" name="line">