Kindle driver: Upload cover thumbnails when sending books to device by USB to workaround Amazon bug of not displaying covers for sync-enabled books

This commit is contained in:
Kovid Goyal 2012-05-18 19:00:09 +05:30
parent 13f03b4b94
commit 0901845c0f
2 changed files with 45 additions and 3 deletions

View File

@ -13,6 +13,7 @@ import datetime, os, re, sys, json, hashlib
from calibre.devices.kindle.bookmark import Bookmark from calibre.devices.kindle.bookmark import Bookmark
from calibre.devices.usbms.driver import USBMS from calibre.devices.usbms.driver import USBMS
from calibre import strftime from calibre import strftime
from calibre.utils.logging import default_log
''' '''
Notes on collections: Notes on collections:
@ -324,6 +325,7 @@ class KINDLE2(KINDLE):
OPT_APNX = 0 OPT_APNX = 0
OPT_APNX_ACCURATE = 1 OPT_APNX_ACCURATE = 1
OPT_APNX_CUST_COL = 2 OPT_APNX_CUST_COL = 2
THUMBNAIL_HEIGHT = 180
def formats_to_scan_for(self): def formats_to_scan_for(self):
ans = USBMS.formats_to_scan_for(self) | {'azw3'} ans = USBMS.formats_to_scan_for(self) | {'azw3'}
@ -375,8 +377,36 @@ class KINDLE2(KINDLE):
def upload_cover(self, path, filename, metadata, filepath): def upload_cover(self, path, filename, metadata, filepath):
''' '''
Hijacking this function to write the apnx file. Upload sidecar files: cover thumbnails and page count
''' '''
# Upload the cover thumbnail
try:
self.upload_kindle_thumbnail(metadata, filepath)
except:
import traceback
traceback.print_exc()
# Upload the apnx file
self.upload_apnx(filename, metadata, filepath)
def upload_kindle_thumbnail(self, metadata, filepath):
coverdata = getattr(metadata, 'thumbnail', None)
if not coverdata or not coverdata[2]:
return
thumb_dir = os.path.join(self._main_prefix, 'system', 'thumbnails')
if not os.path.exists(thumb_dir): return
from calibre.ebooks.mobi.reader.headers import MetadataHeader
with lopen(filepath, 'rb') as f:
mh = MetadataHeader(f, default_log)
if mh.exth is None or not mh.exth.uuid or not mh.exth.cdetype:
return
thumbfile = os.path.join(thumb_dir,
'thumbnail_{uuid}_{cdetype}_portrait.jpg'.format(
uuid=mh.exth.uuid, cdetype=mh.exth.cdetype))
with open(thumbfile, 'wb') as f:
f.write(coverdata[2])
def upload_apnx(self, filename, metadata, filepath):
from calibre.devices.kindle.apnx import APNXBuilder from calibre.devices.kindle.apnx import APNXBuilder
opts = self.settings() opts = self.settings()
@ -422,6 +452,9 @@ class KINDLE_DX(KINDLE2):
PRODUCT_ID = [0x0003] PRODUCT_ID = [0x0003]
BCD = [0x0100] BCD = [0x0100]
def upload_kindle_thumbnail(self, metadata, filepath):
pass
class KINDLE_FIRE(KINDLE2): class KINDLE_FIRE(KINDLE2):
name = 'Kindle Fire Device Interface' name = 'Kindle Fire Device Interface'
@ -440,4 +473,6 @@ class KINDLE_FIRE(KINDLE2):
VENDOR_NAME = 'AMAZON' VENDOR_NAME = 'AMAZON'
WINDOWS_MAIN_MEM = 'KINDLE' WINDOWS_MAIN_MEM = 'KINDLE'
def upload_kindle_thumbnail(self, metadata, filepath):
pass

View File

@ -45,6 +45,10 @@ class EXTHHeader(object): # {{{
elif idx == 202: elif idx == 202:
self.thumbnail_offset, = struct.unpack('>L', content) self.thumbnail_offset, = struct.unpack('>L', content)
elif idx == 501: elif idx == 501:
try:
self.cdetype = content.decode('ascii')
except UnicodeDecodeError:
self.cdetype = None
# cdetype # cdetype
if content == b'EBSP': if content == b'EBSP':
if not self.mi.tags: if not self.mi.tags:
@ -109,8 +113,11 @@ class EXTHHeader(object): # {{{
self.mi.isbn = raw self.mi.isbn = raw
except: except:
pass pass
elif idx == 113: elif idx == 113: # ASIN or other id
pass # ASIN or UUID try:
self.uuid = content.decode('ascii')
except:
self.uuid = None
elif idx == 116: elif idx == 116:
self.start_offset, = struct.unpack(b'>L', content) self.start_offset, = struct.unpack(b'>L', content)
elif idx == 121: elif idx == 121: