mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
GwR wip
This commit is contained in:
parent
fa3d694113
commit
a726347e2b
@ -5,19 +5,21 @@ __copyright__ = '2010, Gregory Riker'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
|
||||||
import cStringIO, ctypes, os, re, shutil, subprocess, sys, tempfile, time, zipfile
|
import cStringIO, ctypes, datetime, os, re, shutil, subprocess, sys, tempfile, time
|
||||||
|
|
||||||
from calibre.constants import DEBUG
|
from calibre.constants import DEBUG
|
||||||
from calibre import fit_image
|
from calibre import fit_image
|
||||||
from calibre.constants import isosx, iswindows
|
from calibre.constants import isosx, iswindows
|
||||||
|
from calibre.devices.errors import UserFeedback
|
||||||
from calibre.devices.interface import DevicePlugin
|
from calibre.devices.interface import DevicePlugin
|
||||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
from calibre.ebooks.BeautifulSoup import BeautifulSoup, Tag
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.library.server.utils import strftime
|
from calibre.library.server.utils import strftime
|
||||||
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.utils.config import Config, config_dir
|
from calibre.utils.config import Config, config_dir
|
||||||
from calibre.utils.date import parse_date
|
from calibre.utils.date import isoformat, now, parse_date, strptime
|
||||||
from calibre.utils.logging import Log
|
from calibre.utils.logging import Log
|
||||||
from calibre.devices.errors import UserFeedback
|
from calibre.utils.zipfile import safe_replace, ZipFile
|
||||||
|
|
||||||
from PIL import Image as PILImage
|
from PIL import Image as PILImage
|
||||||
|
|
||||||
@ -31,6 +33,8 @@ if isosx:
|
|||||||
|
|
||||||
if iswindows:
|
if iswindows:
|
||||||
import pythoncom, win32com.client
|
import pythoncom, win32com.client
|
||||||
|
from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
||||||
|
|
||||||
|
|
||||||
class ITUNES(DevicePlugin):
|
class ITUNES(DevicePlugin):
|
||||||
'''
|
'''
|
||||||
@ -633,7 +637,7 @@ class ITUNES(DevicePlugin):
|
|||||||
|
|
||||||
if not os.path.exists(archive_path):
|
if not os.path.exists(archive_path):
|
||||||
self.log.info(" creating zip archive")
|
self.log.info(" creating zip archive")
|
||||||
zfw = zipfile.ZipFile(archive_path, mode='w')
|
zfw = ZipFile(archive_path, mode='w')
|
||||||
zfw.writestr("iTunes Thumbs Archive",'')
|
zfw.writestr("iTunes Thumbs Archive",'')
|
||||||
zfw.close()
|
zfw.close()
|
||||||
else:
|
else:
|
||||||
@ -786,7 +790,7 @@ class ITUNES(DevicePlugin):
|
|||||||
for (i,file) in enumerate(files):
|
for (i,file) in enumerate(files):
|
||||||
path = self.path_template % (metadata[i].title, metadata[i].author[0])
|
path = self.path_template % (metadata[i].title, metadata[i].author[0])
|
||||||
self._remove_existing_copies(path,file,metadata[i])
|
self._remove_existing_copies(path,file,metadata[i])
|
||||||
fpath = self._get_fpath(file)
|
fpath = self._get_fpath(file, touch=True)
|
||||||
db_added, lb_added = self._add_new_copy(fpath, metadata[i])
|
db_added, lb_added = self._add_new_copy(fpath, metadata[i])
|
||||||
thumb = self._cover_to_thumb(path, metadata[i], lb_added, db_added)
|
thumb = self._cover_to_thumb(path, metadata[i], lb_added, db_added)
|
||||||
this_book = self._create_new_book(fpath, metadata[i], path, db_added, lb_added, thumb)
|
this_book = self._create_new_book(fpath, metadata[i], path, db_added, lb_added, thumb)
|
||||||
@ -813,8 +817,16 @@ class ITUNES(DevicePlugin):
|
|||||||
for (i,file) in enumerate(files):
|
for (i,file) in enumerate(files):
|
||||||
path = self.path_template % (metadata[i].title, metadata[i].author[0])
|
path = self.path_template % (metadata[i].title, metadata[i].author[0])
|
||||||
self._remove_existing_copies(path,file,metadata[i])
|
self._remove_existing_copies(path,file,metadata[i])
|
||||||
fpath = self._get_fpath(file)
|
fpath = self._get_fpath(file, touch=True)
|
||||||
db_added, lb_added = self._add_new_copy(fpath, metadata[i])
|
db_added, lb_added = self._add_new_copy(fpath, metadata[i])
|
||||||
|
|
||||||
|
if self.manual_sync_mode and not db_added:
|
||||||
|
# Problem finding added book, probably title/author change needing to be written to metadata
|
||||||
|
self.problem_msg = ("Title and/or author metadata mismatch with uploaded books.\n"
|
||||||
|
"Convert epub - epub to update edited metadata before uploading.\n"
|
||||||
|
"Click 'Show Details...' for affected books.")
|
||||||
|
self.problem_titles.append("'%s' by %s" % (metadata[i].title, metadata[i].author[0]))
|
||||||
|
|
||||||
thumb = self._cover_to_thumb(path, metadata[i], lb_added, db_added)
|
thumb = self._cover_to_thumb(path, metadata[i], lb_added, db_added)
|
||||||
this_book = self._create_new_book(fpath, metadata[i], path, db_added, lb_added, thumb)
|
this_book = self._create_new_book(fpath, metadata[i], path, db_added, lb_added, thumb)
|
||||||
new_booklist.append(this_book)
|
new_booklist.append(this_book)
|
||||||
@ -843,9 +855,11 @@ class ITUNES(DevicePlugin):
|
|||||||
|
|
||||||
return (new_booklist, [], [])
|
return (new_booklist, [], [])
|
||||||
|
|
||||||
|
|
||||||
# Private methods
|
# Private methods
|
||||||
def _add_device_book(self,fpath, metadata):
|
def _add_device_book(self,fpath, metadata):
|
||||||
'''
|
'''
|
||||||
|
assumes pythoncom wrapper for windows
|
||||||
'''
|
'''
|
||||||
self.log.info(" ITUNES._add_device_book()")
|
self.log.info(" ITUNES._add_device_book()")
|
||||||
if isosx:
|
if isosx:
|
||||||
@ -867,69 +881,69 @@ class ITUNES(DevicePlugin):
|
|||||||
|
|
||||||
elif iswindows:
|
elif iswindows:
|
||||||
if 'iPod' in self.sources:
|
if 'iPod' in self.sources:
|
||||||
try:
|
connected_device = self.sources['iPod']
|
||||||
pythoncom.CoInitialize()
|
device = self.iTunes.sources.ItemByName(connected_device)
|
||||||
connected_device = self.sources['iPod']
|
|
||||||
device = self.iTunes.sources.ItemByName(connected_device)
|
|
||||||
|
|
||||||
added = None
|
added = None
|
||||||
for pl in device.Playlists:
|
for pl in device.Playlists:
|
||||||
if pl.Kind == self.PlaylistKind.index('User') and \
|
if pl.Kind == self.PlaylistKind.index('User') and \
|
||||||
pl.SpecialKind == self.PlaylistSpecialKind.index('Books'):
|
pl.SpecialKind == self.PlaylistSpecialKind.index('Books'):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" no Books playlist found")
|
self.log.info(" no Books playlist found")
|
||||||
|
|
||||||
# Add the passed book to the Device|Books playlist
|
# Add the passed book to the Device|Books playlist
|
||||||
if pl:
|
if pl:
|
||||||
'''
|
file_s = ctypes.c_char_p(fpath)
|
||||||
added = pl.AddFile(fpath)
|
FileArray = ctypes.c_char_p * 1
|
||||||
if DEBUG:
|
fa = FileArray(file_s)
|
||||||
self.log.info(" adding '%s' to device" % fpath)
|
op_status = pl.AddFiles(fa)
|
||||||
'''
|
|
||||||
file_s = ctypes.c_char_p(fpath)
|
|
||||||
FileArray = ctypes.c_char_p * 1
|
|
||||||
fa = FileArray(file_s)
|
|
||||||
op_status = pl.AddFiles(fa)
|
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
sys.stdout.write(" uploading '%s' to device ..." % metadata.title)
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
while op_status.InProgress:
|
||||||
|
time.sleep(0.5)
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
sys.stdout.write(" uploading '%s' to device ..." % metadata.title)
|
sys.stdout.write('.')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
if DEBUG:
|
||||||
|
sys.stdout.write("\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
while op_status.InProgress:
|
# This doesn't seem to work with device, just Library
|
||||||
|
if False:
|
||||||
|
if DEBUG:
|
||||||
|
sys.stdout.write(" waiting for handle to added '%s' ..." % metadata.title)
|
||||||
|
sys.stdout.flush()
|
||||||
|
while not op_status.Tracks:
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
sys.stdout.write('.')
|
sys.stdout.write('.')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
sys.stdout.write("\n")
|
print
|
||||||
sys.stdout.flush()
|
added = op_status.Tracks[0]
|
||||||
|
else:
|
||||||
|
# This approach simply scans Library|Books for the book we just added
|
||||||
|
|
||||||
# This doesn't seem to work with device, just Library
|
# Try the calibre metadata first
|
||||||
if False:
|
db_added = self._find_device_book(
|
||||||
if DEBUG:
|
{'title': metadata.title,
|
||||||
sys.stdout.write(" waiting for handle to added '%s' ..." % metadata.title)
|
'author': metadata.authors[0],
|
||||||
sys.stdout.flush()
|
'source': 'calibre'})
|
||||||
while op_status.Tracks is None:
|
|
||||||
time.sleep(0.5)
|
|
||||||
if DEBUG:
|
|
||||||
sys.stdout.write('.')
|
|
||||||
sys.stdout.flush()
|
|
||||||
if DEBUG:
|
|
||||||
print
|
|
||||||
added = op_status.Tracks[0]
|
|
||||||
else:
|
|
||||||
# This approach simply scans Library|Books for the book we just added
|
|
||||||
added = self._find_device_book(
|
|
||||||
{'title': metadata.title,
|
|
||||||
'author': metadata.author[0]})
|
|
||||||
return added
|
|
||||||
|
|
||||||
finally:
|
# If that fails, try the epub metadata
|
||||||
pythoncom.CoUninitialize()
|
if not db_added:
|
||||||
|
title, author = self._get_epub_metadata(fpath)
|
||||||
return added
|
db_added = self._find_device_book(
|
||||||
|
{'title': title,
|
||||||
|
'author': author,
|
||||||
|
'source': 'epub'})
|
||||||
|
return db_added
|
||||||
|
|
||||||
def _add_library_book(self,file, metadata):
|
def _add_library_book(self,file, metadata):
|
||||||
'''
|
'''
|
||||||
@ -1061,7 +1075,7 @@ class ITUNES(DevicePlugin):
|
|||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info( " refreshing cached thumb for '%s'" % metadata.title)
|
self.log.info( " refreshing cached thumb for '%s'" % metadata.title)
|
||||||
archive_path = os.path.join(self.cache_dir, "thumbs.zip")
|
archive_path = os.path.join(self.cache_dir, "thumbs.zip")
|
||||||
zfw = zipfile.ZipFile(archive_path, mode='a')
|
zfw = ZipFile(archive_path, mode='a')
|
||||||
thumb_path = path.rpartition('.')[0] + '.jpg'
|
thumb_path = path.rpartition('.')[0] + '.jpg'
|
||||||
zfw.writestr(thumb_path, thumb)
|
zfw.writestr(thumb_path, thumb)
|
||||||
zfw.close()
|
zfw.close()
|
||||||
@ -1168,7 +1182,11 @@ class ITUNES(DevicePlugin):
|
|||||||
self.manual_sync_mode = True
|
self.manual_sync_mode = True
|
||||||
except:
|
except:
|
||||||
self.manual_sync_mode = False
|
self.manual_sync_mode = False
|
||||||
self.log.info(" iTunes.manual_sync_mode: %s" % self.manual_sync_mode)
|
if DEBUG:
|
||||||
|
self.log.info(" iTunes.manual_sync_mode: %s" % self.manual_sync_mode)
|
||||||
|
else:
|
||||||
|
if DEBUG:
|
||||||
|
self.log.error(" no books on iDevice, can't determine manual sync mode")
|
||||||
|
|
||||||
def _dump_booklist(self, booklist, header=None):
|
def _dump_booklist(self, booklist, header=None):
|
||||||
'''
|
'''
|
||||||
@ -1291,24 +1309,24 @@ class ITUNES(DevicePlugin):
|
|||||||
ub['author']))
|
ub['author']))
|
||||||
self.log.info()
|
self.log.info()
|
||||||
|
|
||||||
def _find_device_book(self, cached_book):
|
def _find_device_book(self, search):
|
||||||
'''
|
'''
|
||||||
Windows-only method to get a handle to device book in the current pythoncom session
|
Windows-only method to get a handle to device book in the current pythoncom session
|
||||||
'''
|
'''
|
||||||
if iswindows:
|
if iswindows:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" ITUNES._find_device_book()")
|
self.log.info(" ITUNES._find_device_book()")
|
||||||
self.log.info(" looking for '%s' by %s" % (cached_book['title'], cached_book['author']))
|
self.log.info(" searching for '%s' by %s (%s metadata)" %
|
||||||
|
(search['title'], search['author'], search['source']))
|
||||||
|
|
||||||
dev_books = self._get_device_books_playlist()
|
dev_books = self._get_device_books_playlist()
|
||||||
attempts = 9
|
attempts = 9
|
||||||
while attempts:
|
while attempts:
|
||||||
# Find book whose Artist field = cached_book['author']
|
hits = dev_books.Search(search['author'],self.SearchField.index('Artists'))
|
||||||
hits = dev_books.Search(cached_book['author'],self.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 == search['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
|
||||||
attempts -= 1
|
attempts -= 1
|
||||||
@ -1317,7 +1335,8 @@ 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 for '%s' yielded no hits" % cached_book['title'])
|
self.log.error(" search for '%s' using %s metadata yielded no hits" %
|
||||||
|
(search['title'], search['source']))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _find_library_book(self, cached_book):
|
def _find_library_book(self, cached_book):
|
||||||
@ -1382,11 +1401,11 @@ class ITUNES(DevicePlugin):
|
|||||||
thumb_path = book_path.rpartition('.')[0] + '.jpg'
|
thumb_path = book_path.rpartition('.')[0] + '.jpg'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
zfr = zipfile.ZipFile(archive_path)
|
zfr = ZipFile(archive_path)
|
||||||
thumb_data = zfr.read(thumb_path)
|
thumb_data = zfr.read(thumb_path)
|
||||||
zfr.close()
|
zfr.close()
|
||||||
except:
|
except:
|
||||||
zfw = zipfile.ZipFile(archive_path, mode='a')
|
zfw = ZipFile(archive_path, mode='a')
|
||||||
else:
|
else:
|
||||||
return thumb_data
|
return thumb_data
|
||||||
|
|
||||||
@ -1445,7 +1464,7 @@ class ITUNES(DevicePlugin):
|
|||||||
'''
|
'''
|
||||||
Calculate the exploded size of file
|
Calculate the exploded size of file
|
||||||
'''
|
'''
|
||||||
myZip = zipfile.ZipFile(file,'r')
|
myZip = ZipFile(file,'r')
|
||||||
myZipList = myZip.infolist()
|
myZipList = myZip.infolist()
|
||||||
exploded_file_size = 0
|
exploded_file_size = 0
|
||||||
for file in myZipList:
|
for file in myZipList:
|
||||||
@ -1542,7 +1561,31 @@ class ITUNES(DevicePlugin):
|
|||||||
self.log.error(" no iPad|Books playlist found")
|
self.log.error(" no iPad|Books playlist found")
|
||||||
return pl
|
return pl
|
||||||
|
|
||||||
def _get_fpath(self,file):
|
def _get_epub_metadata(self, fpath):
|
||||||
|
'''
|
||||||
|
Return the original title and author from the .OPF file in the epub bundle
|
||||||
|
'''
|
||||||
|
self.log.info(" ITUNES.__get_epub_metadata()")
|
||||||
|
title = None
|
||||||
|
author = None
|
||||||
|
zf = ZipFile(fpath,'r')
|
||||||
|
fnames = zf.namelist()
|
||||||
|
opf = [x for x in fnames if '.opf' in x][0]
|
||||||
|
if opf:
|
||||||
|
opf_raw = cStringIO.StringIO(zf.read(opf)).getvalue()
|
||||||
|
soup = BeautifulSoup(opf_raw)
|
||||||
|
title = soup.find('dc:title').renderContents()
|
||||||
|
author = soup.find('dc:creator').renderContents()
|
||||||
|
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" % (title, author))
|
||||||
|
else:
|
||||||
|
if DEBUG:
|
||||||
|
self.log.error(" can't find .opf in %s" % fpath)
|
||||||
|
return title, author
|
||||||
|
|
||||||
|
def _get_fpath(self,file, touch=False):
|
||||||
'''
|
'''
|
||||||
If the database copy will be deleted after upload, we have to
|
If the database copy will be deleted after upload, we have to
|
||||||
use file (the PersistentTemporaryFile), which will be around until
|
use file (the PersistentTemporaryFile), which will be around until
|
||||||
@ -1555,6 +1598,8 @@ class ITUNES(DevicePlugin):
|
|||||||
if not getattr(fpath, 'deleted_after_upload', False):
|
if not getattr(fpath, 'deleted_after_upload', False):
|
||||||
if getattr(file, 'orig_file_path', None) is not None:
|
if getattr(file, 'orig_file_path', None) is not None:
|
||||||
fpath = file.orig_file_path
|
fpath = file.orig_file_path
|
||||||
|
if touch:
|
||||||
|
self._touch_epub(fpath)
|
||||||
elif getattr(file, 'name', None) is not None:
|
elif getattr(file, 'name', None) is not None:
|
||||||
fpath = file.name
|
fpath = file.name
|
||||||
else:
|
else:
|
||||||
@ -1958,6 +2003,58 @@ class ITUNES(DevicePlugin):
|
|||||||
|
|
||||||
book.Delete()
|
book.Delete()
|
||||||
|
|
||||||
|
def _touch_epub(self, fpath):
|
||||||
|
'''
|
||||||
|
Touch calibre:timestamp in OPF to force iBooks to recache
|
||||||
|
'''
|
||||||
|
self.log.info(" ITUNES._touch_epub()")
|
||||||
|
|
||||||
|
title = None
|
||||||
|
author = None
|
||||||
|
zf = ZipFile(fpath,'r')
|
||||||
|
fnames = zf.namelist()
|
||||||
|
opf = [x for x in fnames if '.opf' in x][0]
|
||||||
|
if opf:
|
||||||
|
opf_raw = cStringIO.StringIO(zf.read(opf)).getvalue()
|
||||||
|
soup = BeautifulSoup(opf_raw)
|
||||||
|
md = soup.find('metadata')
|
||||||
|
ots = ts = md.find('meta',attrs={'name':'calibre:timestamp'})
|
||||||
|
if ts:
|
||||||
|
# Touch existing calibre timestamp
|
||||||
|
timestamp = ts['content']
|
||||||
|
# old_ts = datetime.datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S.%f+00:00")
|
||||||
|
# new_ts = datetime.datetime(old_ts.year, old_ts.month, old_ts.day, old_ts.hour, old_ts.minute,
|
||||||
|
# old_ts.second, old_ts.microsecond+1)
|
||||||
|
# ts['content'] = new_ts.strftime("%Y-%m-%dT%H:%M:%S.%f+00:00")
|
||||||
|
old_ts = strptime(timestamp,"%Y-%m-%dT%H:%M:%S.%f+00:00")
|
||||||
|
new_ts = datetime.datetime(old_ts.year, old_ts.month, old_ts.day, old_ts.hour,
|
||||||
|
old_ts.minute, old_ts.second, old_ts.microsecond+1)
|
||||||
|
ts['content'] = new_ts.strftime("%Y-%m-%dT%H:%M:%S.%f+00:00")
|
||||||
|
if DEBUG:
|
||||||
|
self.log.info(" touching existing calibre:timestamp in %s" % opf)
|
||||||
|
self.log.info(" %s" % ots)
|
||||||
|
self.log.info(" %s" % ts)
|
||||||
|
else:
|
||||||
|
# Create new calibre timestamp
|
||||||
|
if True:
|
||||||
|
print "existing metadata:\n%s" % md.prettify()
|
||||||
|
else:
|
||||||
|
ts = Tag(soup,'meta')
|
||||||
|
ts['name'] = 'calibre:timestamp'
|
||||||
|
ts['content'] = isoformat(now())
|
||||||
|
md.insert(len(md),ts)
|
||||||
|
if DEBUG:
|
||||||
|
self.log.info(" adding calibre:timestamp to %s" % opf)
|
||||||
|
self.log.info(" %s" % ts)
|
||||||
|
zfo = open(fpath,'r+b')
|
||||||
|
safe_replace(zfo, opf, cStringIO.StringIO(soup))
|
||||||
|
|
||||||
|
else:
|
||||||
|
if DEBUG:
|
||||||
|
self.log.error(" can't find .opf in %s" % fpath)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _update_device(self, msg='', wait=True):
|
def _update_device(self, msg='', wait=True):
|
||||||
'''
|
'''
|
||||||
Trigger a sync, wait for completion
|
Trigger a sync, wait for completion
|
||||||
@ -2014,6 +2111,24 @@ class ITUNES(DevicePlugin):
|
|||||||
strip_tags = re.compile(r'<[^<]*?/?>')
|
strip_tags = re.compile(r'<[^<]*?/?>')
|
||||||
|
|
||||||
if isosx:
|
if isosx:
|
||||||
|
if lb_added:
|
||||||
|
lb_added.album.set(metadata.title)
|
||||||
|
lb_added.artist.set(metadata.authors[0])
|
||||||
|
lb_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
|
lb_added.enabled.set(True)
|
||||||
|
lb_added.name.set(metadata.title)
|
||||||
|
lb_added.sort_artist.set(metadata.author_sort.title())
|
||||||
|
lb_added.sort_name.set(this_book.title_sorter)
|
||||||
|
|
||||||
|
if db_added:
|
||||||
|
db_added.album.set(metadata.title)
|
||||||
|
db_added.artist.set(metadata.authors[0])
|
||||||
|
db_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
|
db_added.enabled.set(True)
|
||||||
|
db_added.name.set(metadata.title)
|
||||||
|
db_added.sort_artist.set(metadata.author_sort.title())
|
||||||
|
db_added.sort_name.set(this_book.title_sorter)
|
||||||
|
|
||||||
if metadata.comments:
|
if metadata.comments:
|
||||||
if lb_added:
|
if lb_added:
|
||||||
lb_added.comment.set(strip_tags.sub('',metadata.comments))
|
lb_added.comment.set(strip_tags.sub('',metadata.comments))
|
||||||
@ -2030,31 +2145,46 @@ class ITUNES(DevicePlugin):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if lb_added:
|
# Set genre from series if available, else first alpha tag
|
||||||
lb_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
# Otherwise iTunes grabs the first dc:subject from the opf metadata,
|
||||||
lb_added.enabled.set(True)
|
if metadata.series:
|
||||||
lb_added.sort_artist.set(metadata.author_sort.title())
|
if lb_added:
|
||||||
lb_added.sort_name.set(this_book.title_sorter)
|
lb_added.genre.set(metadata.series)
|
||||||
|
lb_added.episode_ID.set(metadata.series)
|
||||||
if db_added:
|
lb_added.episode_number.set(metadata.series_index)
|
||||||
db_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
if db_added:
|
||||||
db_added.enabled.set(True)
|
db_added.genre.set(metadata.series)
|
||||||
db_added.sort_artist.set(metadata.author_sort.title())
|
db_added.episode_ID.set(metadata.series)
|
||||||
db_added.sort_name.set(this_book.title_sorter)
|
db_added.episode_number.set(metadata.series_index)
|
||||||
|
else:
|
||||||
# Set genre from metadata
|
for tag in metadata.tags:
|
||||||
# iTunes grabs the first dc:subject from the opf metadata,
|
if self._is_alpha(tag[0]):
|
||||||
# But we can manually override with first tag starting with alpha
|
if lb_added:
|
||||||
for tag in metadata.tags:
|
lb_added.genre.set(tag)
|
||||||
if self._is_alpha(tag[0]):
|
if db_added:
|
||||||
if lb_added:
|
db_added.genre.set(tag)
|
||||||
lb_added.genre.set(tag)
|
break
|
||||||
if db_added:
|
|
||||||
db_added.genre.set(tag)
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
elif iswindows:
|
elif iswindows:
|
||||||
|
if lb_added:
|
||||||
|
lb_added.Album = metadata.title
|
||||||
|
lb_added.Artist = metadata.authors[0]
|
||||||
|
lb_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
|
lb_added.Enabled = True
|
||||||
|
lb_added.Name = metadata.title
|
||||||
|
lb_added.SortArtist = (metadata.author_sort.title())
|
||||||
|
lb_added.SortName = (this_book.title_sorter)
|
||||||
|
|
||||||
|
if db_added:
|
||||||
|
# Album, Artist and Name are changed in _add_device_book()
|
||||||
|
db_added.Album = metadata.title
|
||||||
|
db_added.Artist = metadata.authors[0]
|
||||||
|
db_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
|
db_added.Enabled = True
|
||||||
|
db_added.Name = metadata.title
|
||||||
|
db_added.SortArtist = (metadata.author_sort.title())
|
||||||
|
db_added.SortName = (this_book.title_sorter)
|
||||||
|
|
||||||
if metadata.comments:
|
if metadata.comments:
|
||||||
if lb_added:
|
if lb_added:
|
||||||
lb_added.Comment = (strip_tags.sub('',metadata.comments))
|
lb_added.Comment = (strip_tags.sub('',metadata.comments))
|
||||||
@ -2071,27 +2201,42 @@ class ITUNES(DevicePlugin):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if lb_added:
|
# Set Category from first alpha tag, overwrite with series if available
|
||||||
lb_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
# Otherwise iBooks uses first <dc:subject> from opf
|
||||||
lb_added.Enabled = True
|
# iTunes balks on setting EpisodeNumber, but it sticks (9.1.1.12)
|
||||||
lb_added.SortArtist = (metadata.author_sort.title())
|
|
||||||
lb_added.SortName = (this_book.title_sorter)
|
|
||||||
|
|
||||||
if db_added:
|
if metadata.tags:
|
||||||
db_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
if DEBUG:
|
||||||
db_added.SortArtist = (metadata.author_sort.title())
|
self.log.info(" setting Category from metadata.tags")
|
||||||
db_added.SortName = (this_book.title_sorter)
|
for tag in metadata.tags:
|
||||||
|
if self._is_alpha(tag[0]):
|
||||||
|
if lb_added:
|
||||||
|
lb_added.Category = tag
|
||||||
|
if db_added:
|
||||||
|
db_added.Category = tag
|
||||||
|
break
|
||||||
|
|
||||||
# Set genre from metadata
|
if metadata.series:
|
||||||
# iTunes grabs the first dc:subject from the opf metadata,
|
if DEBUG:
|
||||||
# But we can manually override with first tag starting with alpha
|
self.log.info(" setting Category from metadata.series")
|
||||||
for tag in metadata.tags:
|
if lb_added:
|
||||||
if self._is_alpha(tag[0]):
|
if DEBUG:
|
||||||
if lb_added:
|
self.log.info(" setting lb_added from metadata.series")
|
||||||
lb_added.Category = (tag)
|
lb_added.Category = metadata.series
|
||||||
if db_added:
|
lb_added.EpisodeID = metadata.series
|
||||||
db_added.Category = (tag)
|
try:
|
||||||
break
|
lb_added.EpisodeNumber = metadata.series_index
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if db_added:
|
||||||
|
if DEBUG:
|
||||||
|
self.log.info(" setting db_added from metadata.series")
|
||||||
|
db_added.Category = metadata.series
|
||||||
|
db_added.EpisodeID = metadata.series
|
||||||
|
try:
|
||||||
|
db_added.EpisodeNumber = metadata.series_index
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
class BookList(list):
|
class BookList(list):
|
||||||
'''
|
'''
|
||||||
|
Loading…
x
Reference in New Issue
Block a user