def _update_driveinfo_file(self, prefix, location_code, name=None): from calibre.utils.config import from_json, to_json if os.path.exists(os.path.join(prefix, self.DRIVEINFO)): with lopen(os.path.join(prefix, self.DRIVEINFO), 'rb') as f: try: driveinfo = json.loads(f.read(), object_hook=from_json) except: driveinfo = None driveinfo = self._update_driveinfo_record(driveinfo, prefix, location_code, name) data = json.dumps(driveinfo, default=to_json) if not isinstance(data, bytes): data = data.encode('utf-8') with lopen(os.path.join(prefix, self.DRIVEINFO), 'wb') as f: f.write(data) fsync(f) else: driveinfo = self._update_driveinfo_record({}, prefix, location_code, name) data = json.dumps(driveinfo, default=to_json) if not isinstance(data, bytes): data = data.encode('utf-8') with lopen(os.path.join(prefix, self.DRIVEINFO), 'wb') as f: f.write(data) fsync(f) return driveinfo
def _update_driveinfo_file(self, prefix, location_code, name=None): from calibre.utils.config import from_json, to_json if os.path.exists(os.path.join(prefix, self.DRIVEINFO)): with lopen(os.path.join(prefix, self.DRIVEINFO), 'rb') as f: try: driveinfo = json.loads(f.read(), object_hook=from_json) except: driveinfo = None driveinfo = self._update_driveinfo_record( driveinfo, prefix, location_code, name) data = json.dumps(driveinfo, default=to_json) if not isinstance(data, bytes): data = data.encode('utf-8') with lopen(os.path.join(prefix, self.DRIVEINFO), 'wb') as f: f.write(data) fsync(f) else: driveinfo = self._update_driveinfo_record({}, prefix, location_code, name) data = json.dumps(driveinfo, default=to_json) if not isinstance(data, bytes): data = data.encode('utf-8') with lopen(os.path.join(prefix, self.DRIVEINFO), 'wb') as f: f.write(data) fsync(f) return driveinfo
def put_file(self, infile, path, replace_file=False, end_session=True): path = self.munge_path(path) close = False if not hasattr(infile, 'read'): infile, close = lopen(infile, 'rb'), True infile.seek(0) if os.path.isdir(path): path = os.path.join(path, infile.name) if not replace_file and os.path.exists(path): raise PathError('File already exists: ' + path) dest, actual_path = case_preserving_open_file(path) with dest: try: shutil.copyfileobj(infile, dest) except OSError: print('WARNING: First attempt to send file to device failed') time.sleep(0.2) infile.seek(0) dest.seek(0) dest.truncate() shutil.copyfileobj(infile, dest) fsync(dest) # if not check_transfer(infile, dest): raise Exception('Transfer failed') if close: infile.close() return actual_path
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: with open('%s.jpg' % os.path.join(path, filename), 'wb') as coverfile: coverfile.write(coverdata[2]) fsync(coverfile)
def upload_book_cover(self, connection, book, source_id): debug_print('PRST1: Uploading/Refreshing Cover for ' + book.title) if (not book.thumbnail or isinstance(book.thumbnail, ImageWrapper) or not book.thumbnail[-1]): # If the thumbnail is an ImageWrapper instance, it refers to a book # not in the calibre library return cursor = connection.cursor() thumbnail_path = THUMBPATH%book.bookId prefix = self._main_prefix if source_id is 0 else self._card_a_prefix thumbnail_file_path = os.path.join(prefix, *thumbnail_path.split('/')) thumbnail_dir_path = os.path.dirname(thumbnail_file_path) if not os.path.exists(thumbnail_dir_path): os.makedirs(thumbnail_dir_path) with lopen(thumbnail_file_path, 'wb') as f: f.write(book.thumbnail[-1]) fsync(f) query = 'UPDATE books SET thumbnail = ? WHERE _id = ?' t = (thumbnail_path, book.bookId,) cursor.execute(query, t) connection.commit() cursor.close()
def upload_book_cover(self, connection, book, source_id): debug_print('PRST1: Uploading/Refreshing Cover for ' + book.title) if (not book.thumbnail or isinstance(book.thumbnail, ImageWrapper) or not book.thumbnail[-1]): # If the thumbnail is an ImageWrapper instance, it refers to a book # not in the calibre library return cursor = connection.cursor() thumbnail_path = THUMBPATH % book.bookId prefix = self._main_prefix if source_id is 0 else self._card_a_prefix thumbnail_file_path = os.path.join(prefix, *thumbnail_path.split('/')) thumbnail_dir_path = os.path.dirname(thumbnail_file_path) if not os.path.exists(thumbnail_dir_path): os.makedirs(thumbnail_dir_path) with open(thumbnail_file_path, 'wb') as f: f.write(book.thumbnail[-1]) fsync(f) query = 'UPDATE books SET thumbnail = ? WHERE _id = ?' t = ( thumbnail_path, book.bookId, ) cursor.execute(query, t) connection.commit() cursor.close()
def write(self): from lxml import etree for i, path in self.paths.items(): self.move_playlists_to_bottom() self.cleanup_whitespace(i) raw = etree.tostring(self.roots[i], encoding='UTF-8', xml_declaration=True) raw = raw.replace("<?xml version='1.0' encoding='UTF-8'?>", '<?xml version="1.0" encoding="UTF-8"?>') with lopen(path, 'wb') as f: f.write(raw) fsync(f) for i, path in self.ext_paths.items(): try: raw = etree.tostring(self.ext_roots[i], encoding='UTF-8', xml_declaration=True) except: continue raw = raw.replace("<?xml version='1.0' encoding='UTF-8'?>", '<?xml version="1.0" encoding="UTF-8"?>') with lopen(path, 'wb') as f: f.write(raw) fsync(f)
def upload_cover(self, path, filename, metadata, filepath): try: from PIL import Image, ImageDraw Image, ImageDraw except ImportError: import Image, ImageDraw coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: cover = Image.open(cStringIO.StringIO(coverdata[2])) else: coverdata = lopen(I('library.png'), 'rb').read() cover = Image.new('RGB', (96, 144), 'black') im = Image.open(cStringIO.StringIO(coverdata)) im.thumbnail((96, 144), Image.ANTIALIAS) x, y = im.size cover.paste(im, ((96-x)/2, (144-y)/2)) draw = ImageDraw.Draw(cover) draw.text((1, 15), metadata.get('title', _('Unknown')).encode('ascii', 'ignore')) draw.text((1, 115), metadata.get('authors', _('Unknown')).encode('ascii', 'ignore')) data = cStringIO.StringIO() cover.save(data, 'JPEG') coverdata = data.getvalue() with lopen('%s.jpg' % os.path.join(path, filename), 'wb') as coverfile: coverfile.write(coverdata) fsync(coverfile)
def upload_cover(self, path, filename, metadata, filepath): try: from PIL import Image, ImageDraw Image, ImageDraw except ImportError: import Image, ImageDraw coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: cover = Image.open(cStringIO.StringIO(coverdata[2])) else: coverdata = lopen(I('library.png'), 'rb').read() cover = Image.new('RGB', (96, 144), 'black') im = Image.open(cStringIO.StringIO(coverdata)) im.thumbnail((96, 144), Image.ANTIALIAS) x, y = im.size cover.paste(im, ((96 - x) / 2, (144 - y) / 2)) draw = ImageDraw.Draw(cover) draw.text((1, 15), metadata.get('title', _('Unknown')).encode('ascii', 'ignore')) draw.text((1, 115), metadata.get('authors', _('Unknown')).encode('ascii', 'ignore')) data = cStringIO.StringIO() cover.save(data, 'JPEG') coverdata = data.getvalue() with lopen('%s.jpg' % os.path.join(path, filename), 'wb') as coverfile: coverfile.write(coverdata) fsync(coverfile)
def sync_cover_thumbnails(self): import shutil # See https://www.mobileread.com/forums/showthread.php?t=329945 # for why this is needed if DEBUG: prints('Syncing cover thumbnails to workaround amazon cover bug') dest_dir = self.amazon_system_thumbnails_dir() src_dir = self.amazon_cover_bug_cache_dir() if not os.path.exists(dest_dir) or not os.path.exists(src_dir): return count = 0 for name, src_stat_result in get_files_in(src_dir): dest_path = os.path.join(dest_dir, name) try: dest_stat_result = os.lstat(dest_path) except OSError: needs_sync = True else: needs_sync = src_stat_result.st_size != dest_stat_result.st_size if needs_sync: count += 1 if DEBUG: prints('Restoring cover thumbnail:', name) with lopen(os.path.join(src_dir, name), 'rb') as src, lopen(dest_path, 'wb') as dest: shutil.copyfileobj(src, dest) fsync(dest) if DEBUG: prints( 'Restored {} cover thumbnails that were destroyed by Amazon'. format(count))
def put_file(self, infile, path, replace_file=False, end_session=True): path = self.munge_path(path) close = False if not hasattr(infile, 'read'): infile, close = lopen(infile, 'rb'), True infile.seek(0) if os.path.isdir(path): path = os.path.join(path, infile.name) if not replace_file and os.path.exists(path): raise PathError('File already exists: ' + path) dest, actual_path = case_preserving_open_file(path) with dest: try: shutil.copyfileobj(infile, dest) except IOError: print('WARNING: First attempt to send file to device failed') time.sleep(0.2) infile.seek(0) dest.seek(0) dest.truncate() shutil.copyfileobj(infile, dest) fsync(dest) # if not check_transfer(infile, dest): raise Exception('Transfer failed') if close: infile.close() return actual_path
def write(self): from lxml import etree for i, path in self.paths.items(): self.move_playlists_to_bottom() self.cleanup_whitespace(i) raw = etree.tostring(self.roots[i], encoding='UTF-8', xml_declaration=True) raw = raw.replace("<?xml version='1.0' encoding='UTF-8'?>", '<?xml version="1.0" encoding="UTF-8"?>') with open(path, 'wb') as f: f.write(raw) fsync(f) for i, path in self.ext_paths.items(): try: raw = etree.tostring(self.ext_roots[i], encoding='UTF-8', xml_declaration=True) except: continue raw = raw.replace("<?xml version='1.0' encoding='UTF-8'?>", '<?xml version="1.0" encoding="UTF-8"?>') with open(path, 'wb') as f: f.write(raw) fsync(f)
def write_apnx(self, mobi_file_path, apnx_path, accurate=True, page_count=0): ''' If you want a fixed number of pages (such as from a custom column) then pass in a value to page_count, otherwise a count will be estimated using either the fast or accurate algorithm. ''' import uuid apnx_meta = { 'guid': str(uuid.uuid4()).replace('-', '')[:8], 'asin': '', 'cdetype': 'EBOK', 'format': 'MOBI_7', 'acr': '' } with open(mobi_file_path, 'rb') as mf: ident = PdbHeaderReader(mf).identity() if ident != 'BOOKMOBI': # Check that this is really a MOBI file. raise Exception(_('Not a valid MOBI file. Reports identity of %s') % ident) apnx_meta['acr'] = str(PdbHeaderReader(mf).name()) # We'll need the PDB name, the MOBI version, and some metadata to make FW 3.4 happy with KF8 files... with open(mobi_file_path, 'rb') as mf: mh = MetadataHeader(mf, default_log) if mh.mobi_version == 8: apnx_meta['format'] = 'MOBI_8' else: apnx_meta['format'] = 'MOBI_7' if mh.exth is None or not mh.exth.cdetype: apnx_meta['cdetype'] = 'EBOK' else: apnx_meta['cdetype'] = str(mh.exth.cdetype) if mh.exth is None or not mh.exth.uuid: apnx_meta['asin'] = '' else: apnx_meta['asin'] = str(mh.exth.uuid) # Get the pages depending on the chosen parser pages = [] if page_count: pages = self.get_pages_exact(mobi_file_path, page_count) else: if accurate: try: pages = self.get_pages_accurate(mobi_file_path) except: # Fall back to the fast parser if we can't # use the accurate one. Typically this is # due to the file having DRM. pages = self.get_pages_fast(mobi_file_path) else: pages = self.get_pages_fast(mobi_file_path) if not pages: raise Exception(_('Could not generate page mapping.')) # Generate the APNX file from the page mapping. apnx = self.generate_apnx(pages, apnx_meta) # Write the APNX. with open(apnx_path, 'wb') as apnxf: apnxf.write(apnx) fsync(apnxf)
def write_prefix(prefix, listid): if (prefix is not None and len(booklists) > listid and isinstance(booklists[listid], self.booklist_class)): if not os.path.exists(prefix): os.makedirs(self.normalize_path(prefix)) with lopen(self.normalize_path(os.path.join(prefix, self.METADATA_CACHE)), 'wb') as f: json_codec.encode_to_file(f, booklists[listid]) fsync(f)
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, "thumbnail", None) if coverdata and coverdata[2]: coverdata = coverdata[2] else: coverdata = None with open("%s_6090.t2b" % os.path.join(path, filename), "wb") as t2bfile: t2b.write_t2b(t2bfile, coverdata) fsync(t2bfile)
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: coverdata = coverdata[2] else: coverdata = None with open('%s_6090.t2b' % os.path.join(path, filename), 'wb') as t2bfile: t2b.write_t2b(t2bfile, coverdata) fsync(t2bfile)
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, "thumbnail", None) if coverdata and coverdata[2]: dirpath = os.path.join(path, ".thumbnail") if not os.path.exists(dirpath): os.makedirs(dirpath) with open(os.path.join(dirpath, filename + ".jpg"), "wb") as coverfile: coverfile.write(coverdata[2]) fsync(coverfile)
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, "thumbnail", None) if coverdata and coverdata[2]: coverdata = coverdata[2] else: coverdata = None with open("%s.thn" % filepath, "wb") as thnfile: t4b.write_t4b(thnfile, coverdata) fsync(thnfile)
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: dirpath = os.path.join(path, '.thumbnail') if not os.path.exists(dirpath): os.makedirs(dirpath) with lopen(os.path.join(dirpath, filename+'.jpg'), 'wb') as coverfile: coverfile.write(coverdata[2]) fsync(coverfile)
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: coverdata = coverdata[2] else: coverdata = None with lopen('%s.thn' % filepath, 'wb') as thnfile: t4b.write_t4b(thnfile, coverdata) fsync(thnfile)
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: dirpath = os.path.join(path, '.thumbnail') if not os.path.exists(dirpath): os.makedirs(dirpath) with open(os.path.join(dirpath, filename+'.jpg'), 'wb') as coverfile: coverfile.write(coverdata[2]) fsync(coverfile)
def upload_cover(self, path, filename, metadata, filepath): from PIL import Image, ImageDraw coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: cover = Image.open(io.BytesIO(coverdata[2])) else: coverdata = lopen(I('library.png'), 'rb').read() cover = Image.new('RGB', (120, 160), 'black') im = Image.open(io.BytesIO(coverdata)) im.thumbnail((120, 160), Image.ANTIALIAS) x, y = im.size cover.paste(im, ((120 - x) / 2, (160 - y) / 2)) draw = ImageDraw.Draw(cover) draw.text((1, 10), metadata.get('title', _('Unknown')).encode('ascii', 'ignore')) draw.text((1, 140), metadata.get('authors', _('Unknown'))[0].encode('ascii', 'ignore')) data = io.BytesIO() cover.save(data, 'JPEG') coverdata = data.getvalue() with lopen(os.path.join(path, 'coverCache', filename + '-medium.jpg'), 'wb') as coverfile: coverfile.write(coverdata) fsync(coverfile) coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: cover = Image.open(io.BytesIO(coverdata[2])) else: coverdata = lopen(I('library.png'), 'rb').read() cover = Image.new('RGB', (52, 69), 'black') im = Image.open(io.BytesIO(coverdata)) im.thumbnail((52, 69), Image.ANTIALIAS) x, y = im.size cover.paste(im, ((52 - x) // 2, (69 - y) // 2)) cover2 = cover.resize((52, 69), Image.ANTIALIAS).convert('RGB') data = io.BytesIO() cover2.save(data, 'JPEG') coverdata = data.getvalue() with lopen(os.path.join(path, 'coverCache', filename + '-small.jpg'), 'wb') as coverfile: coverfile.write(coverdata) fsync(coverfile)
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: coverdata = coverdata[2] else: coverdata = None with lopen('%s_6090.t2b' % os.path.join(path, filename), 'wb') as t2bfile: t2b.write_t2b(t2bfile, coverdata) fsync(t2bfile)
def upload_cover(self, path, filename, metadata, filepath): try: from PIL import Image, ImageDraw Image, ImageDraw except ImportError: import Image, ImageDraw coverdata = getattr(metadata, "thumbnail", None) if coverdata and coverdata[2]: cover = Image.open(cStringIO.StringIO(coverdata[2])) else: coverdata = open(I("library.png"), "rb").read() cover = Image.new("RGB", (120, 160), "black") im = Image.open(cStringIO.StringIO(coverdata)) im.thumbnail((120, 160), Image.ANTIALIAS) x, y = im.size cover.paste(im, ((120 - x) / 2, (160 - y) / 2)) draw = ImageDraw.Draw(cover) draw.text((1, 10), metadata.get("title", _("Unknown")).encode("ascii", "ignore")) draw.text((1, 140), metadata.get("authors", _("Unknown"))[0].encode("ascii", "ignore")) data = cStringIO.StringIO() cover.save(data, "JPEG") coverdata = data.getvalue() with open(os.path.join(path, "coverCache", filename + "-medium.jpg"), "wb") as coverfile: coverfile.write(coverdata) fsync(coverfile) coverdata = getattr(metadata, "thumbnail", None) if coverdata and coverdata[2]: cover = Image.open(cStringIO.StringIO(coverdata[2])) else: coverdata = open(I("library.png"), "rb").read() cover = Image.new("RGB", (52, 69), "black") im = Image.open(cStringIO.StringIO(coverdata)) im.thumbnail((52, 69), Image.ANTIALIAS) x, y = im.size cover.paste(im, ((52 - x) / 2, (69 - y) / 2)) cover2 = cover.resize((52, 69), Image.ANTIALIAS).convert("RGB") data = cStringIO.StringIO() cover2.save(data, "JPEG") coverdata = data.getvalue() with open(os.path.join(path, "coverCache", filename + "-small.jpg"), "wb") as coverfile: coverfile.write(coverdata) fsync(coverfile)
def upload_cover(self, path, filename, metadata, filepath): try: from PIL import Image, ImageDraw Image, ImageDraw except ImportError: import Image, ImageDraw coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: cover = Image.open(cStringIO.StringIO(coverdata[2])) else: coverdata = open(I('library.png'), 'rb').read() cover = Image.new('RGB', (120,160), 'black') im = Image.open(cStringIO.StringIO(coverdata)) im.thumbnail((120, 160), Image.ANTIALIAS) x, y = im.size cover.paste(im, ((120-x)/2, (160-y)/2)) draw = ImageDraw.Draw(cover) draw.text((1, 10), metadata.get('title', _('Unknown')).encode('ascii', 'ignore')) draw.text((1, 140), metadata.get('authors', _('Unknown'))[0].encode('ascii', 'ignore')) data = cStringIO.StringIO() cover.save(data, 'JPEG') coverdata = data.getvalue() with open(os.path.join(path, 'coverCache', filename + '-medium.jpg'), 'wb') as coverfile: coverfile.write(coverdata) fsync(coverfile) coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: cover = Image.open(cStringIO.StringIO(coverdata[2])) else: coverdata = open(I('library.png'), 'rb').read() cover = Image.new('RGB', (52,69), 'black') im = Image.open(cStringIO.StringIO(coverdata)) im.thumbnail((52, 69), Image.ANTIALIAS) x, y = im.size cover.paste(im, ((52-x)/2, (69-y)/2)) cover2 = cover.resize((52, 69), Image.ANTIALIAS).convert('RGB') data = cStringIO.StringIO() cover2.save(data, 'JPEG') coverdata = data.getvalue() with open(os.path.join(path, 'coverCache', filename + '-small.jpg'), 'wb') as coverfile: coverfile.write(coverdata) fsync(coverfile)
def upload_kindle_thumbnail(self, metadata, filepath): coverdata = getattr(metadata, 'thumbnail', None) if not coverdata or not coverdata[2]: return tp = self.thumbpath_from_filepath(filepath) if tp: with lopen(tp, 'wb') as f: f.write(coverdata[2]) fsync(f)
def upload_cover(self, path, filename, metadata, filepath): if metadata.thumbnail and metadata.thumbnail[-1]: cfilepath = filepath.replace("/", os.sep) cfilepath = cfilepath.replace(os.sep + "books" + os.sep, os.sep + "covers" + os.sep, 1) pdir = os.path.dirname(cfilepath) if not os.path.exists(pdir): os.makedirs(pdir) with open(cfilepath + ".jpg", "wb") as f: f.write(metadata.thumbnail[-1]) fsync(f)
def upload_cover(self, path, filename, metadata, filepath): if metadata.thumbnail and metadata.thumbnail[-1]: cfilepath = filepath.replace('/', os.sep) cfilepath = cfilepath.replace(os.sep+'books'+os.sep, os.sep+'covers'+os.sep, 1) pdir = os.path.dirname(cfilepath) if not os.path.exists(pdir): os.makedirs(pdir) with open(cfilepath+'.jpg', 'wb') as f: f.write(metadata.thumbnail[-1]) fsync(f)
def upload_cover(self, path, filename, metadata, filepath): if metadata.thumbnail and metadata.thumbnail[-1]: cfilepath = filepath.replace('/', os.sep) cfilepath = cfilepath.replace(os.sep + 'books' + os.sep, os.sep + 'covers' + os.sep, 1) pdir = os.path.dirname(cfilepath) if not os.path.exists(pdir): os.makedirs(pdir) with lopen(cfilepath + '.jpg', 'wb') as f: f.write(metadata.thumbnail[-1]) fsync(f)
def upload_kindle_thumbnail(self, metadata, filepath): from calibre.utils.logging import default_log 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]) fsync(f)
def upload_kindle_thumbnail(self, metadata, filepath): from calibre.utils.logging import default_log 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]) fsync(f)
def upload_kindle_thumbnail(self, metadata, filepath): coverdata = getattr(metadata, 'thumbnail', None) if not coverdata or not coverdata[2]: return tp = self.thumbpath_from_filepath(filepath) if tp: with lopen(tp, 'wb') as f: f.write(coverdata[2]) fsync(f) cache_dir = self.amazon_cover_bug_cache_dir() try: os.mkdir(cache_dir) except EnvironmentError: pass with lopen(os.path.join(cache_dir, os.path.basename(tp)), 'wb') as f: f.write(coverdata[2]) fsync(f)
def upload_cover(self, path, filename, metadata, filepath): from calibre.ebooks.covers import calibre_cover2 from calibre.utils.img import scale_image coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: cover = coverdata[2] else: cover = calibre_cover2(metadata.get('title', _('Unknown')), metadata.get('authors', _('Unknown'))) cover = scale_image(cover, width=self.THUMBNAIL_HEIGHT, height=self.THUMBNAIL_HEIGHT, as_png=True)[-1] cpath = self.alex_cpath(os.path.join(path, filename)) cdir = os.path.dirname(cpath) if not os.path.exists(cdir): os.makedirs(cdir) with lopen(cpath, 'wb') as coverfile: coverfile.write(cover) fsync(coverfile)
def upload_cover(self, path, filename, metadata, filepath): from calibre.ebooks import calibre_cover from calibre.utils.magick.draw import thumbnail coverdata = getattr(metadata, 'thumbnail', None) if coverdata and coverdata[2]: cover = coverdata[2] else: cover = calibre_cover(metadata.get('title', _('Unknown')), metadata.get('authors', _('Unknown'))) cover = thumbnail(cover, width=self.THUMBNAIL_HEIGHT, height=self.THUMBNAIL_HEIGHT, fmt='png')[-1] cpath = self.alex_cpath(os.path.join(path, filename)) cdir = os.path.dirname(cpath) if not os.path.exists(cdir): os.makedirs(cdir) with open(cpath, 'wb') as coverfile: coverfile.write(cover) fsync(coverfile)
def write_cache(prefix): try: cachep = os.path.join(prefix, *(CACHE_XML.split('/'))) if not os.path.exists(cachep): dname = os.path.dirname(cachep) if not os.path.exists(dname): try: os.makedirs(dname, mode=0777) except: time.sleep(5) os.makedirs(dname, mode=0777) with lopen(cachep, 'wb') as f: f.write(u'''<?xml version="1.0" encoding="UTF-8"?> <cache xmlns="http://www.kinoma.com/FskCache/1"> </cache> '''.encode('utf8')) fsync(f) return True except: import traceback traceback.print_exc() return False
def write_cache(prefix): try: cachep = os.path.join(prefix, *(CACHE_XML.split('/'))) if not os.path.exists(cachep): dname = os.path.dirname(cachep) if not os.path.exists(dname): try: os.makedirs(dname, mode=0777) except: time.sleep(5) os.makedirs(dname, mode=0777) with open(cachep, 'wb') as f: f.write(u'''<?xml version="1.0" encoding="UTF-8"?> <cache xmlns="http://www.kinoma.com/FskCache/1"> </cache> '''.encode('utf8')) fsync(f) return True except: import traceback traceback.print_exc() return False
def __init__(self, paths, ext_paths, prefixes, use_author_sort): from lxml import etree if DEBUG: debug_print("Building XMLCache...", paths) self.paths = paths self.prefixes = prefixes self.use_author_sort = use_author_sort # Parse XML files {{{ parser = etree.XMLParser(recover=True) self.roots = {} for source_id, path in paths.items(): if source_id == 0: if not os.path.exists(path): raise DeviceError( ("The SONY XML cache %r does not exist. Try" " disconnecting and reconnecting your reader.") % repr(path) ) with open(path, "rb") as f: raw = f.read() else: raw = EMPTY_CARD_CACHE if os.access(path, os.R_OK): with open(path, "rb") as f: raw = f.read() self.roots[source_id] = etree.fromstring( xml_to_unicode(raw, strip_encoding_pats=True, assume_utf8=True, verbose=DEBUG)[0], parser=parser ) if self.roots[source_id] is None: raise Exception( ("The SONY database at %r is corrupted. Try " " disconnecting and reconnecting your reader.") % path ) self.ext_paths, self.ext_roots = {}, {} for source_id, path in ext_paths.items(): if not os.path.exists(path): try: with open(path, "wb") as f: f.write(EMPTY_EXT_CACHE) fsync(f) except: pass if os.access(path, os.W_OK): try: with open(path, "rb") as f: self.ext_roots[source_id] = etree.fromstring( xml_to_unicode(f.read(), strip_encoding_pats=True, assume_utf8=True, verbose=DEBUG)[0], parser=parser, ) self.ext_paths[source_id] = path except: pass # }}} recs = self.roots[0].xpath('//*[local-name()="records"]') if not recs: raise DeviceError( "The SONY XML database is corrupted (no" " <records>). Try disconnecting an reconnecting" " your reader." ) self.record_roots = {} self.record_roots.update(self.roots) self.record_roots[0] = recs[0] self.detect_namespaces() debug_print("Done building XMLCache...")
def __init__(self, paths, ext_paths, prefixes, use_author_sort): from lxml import etree if DEBUG: debug_print('Building XMLCache...', paths) self.paths = paths self.prefixes = prefixes self.use_author_sort = use_author_sort # Parse XML files {{{ parser = etree.XMLParser(recover=True) self.roots = {} for source_id, path in paths.items(): if source_id == 0: if not os.path.exists(path): raise DeviceError(('The SONY XML cache %r does not exist. Try' ' disconnecting and reconnecting your reader.')%repr(path)) with lopen(path, 'rb') as f: raw = f.read() else: raw = EMPTY_CARD_CACHE if os.access(path, os.R_OK): with lopen(path, 'rb') as f: raw = f.read() self.roots[source_id] = etree.fromstring(xml_to_unicode( raw, strip_encoding_pats=True, assume_utf8=True, verbose=DEBUG)[0], parser=parser) if self.roots[source_id] is None: raise Exception(('The SONY database at %r is corrupted. Try ' ' disconnecting and reconnecting your reader.')%path) self.ext_paths, self.ext_roots = {}, {} for source_id, path in ext_paths.items(): if not os.path.exists(path): try: with lopen(path, 'wb') as f: f.write(EMPTY_EXT_CACHE) fsync(f) except: pass if os.access(path, os.W_OK): try: with lopen(path, 'rb') as f: self.ext_roots[source_id] = etree.fromstring( xml_to_unicode(f.read(), strip_encoding_pats=True, assume_utf8=True, verbose=DEBUG)[0], parser=parser) self.ext_paths[source_id] = path except: pass # }}} recs = self.roots[0].xpath('//*[local-name()="records"]') if not recs: raise DeviceError('The SONY XML database is corrupted (no' ' <records>). Try disconnecting an reconnecting' ' your reader.') self.record_roots = {} self.record_roots.update(self.roots) self.record_roots[0] = recs[0] self.detect_namespaces() debug_print('Done building XMLCache...')
def main(): from calibre.utils.terminal import geometry cols = geometry()[0] parser = OptionParser(usage="usage: %prog [options] command args\n\ncommand "+ "is one of: info, books, df, ls, cp, mkdir, touch, cat, rm, eject, test_file\n\n"+ "For help on a particular command: %prog command", version=__appname__+" version: " + __version__) parser.add_option("--log-packets", help="print out packet stream to stdout. "+\ "The numbers in the left column are byte offsets that allow the packet size to be read off easily.", dest="log_packets", action="store_true", default=False) parser.remove_option("-h") parser.disable_interspersed_args() # Allow unrecognized options options, args = parser.parse_args() if len(args) < 1: parser.print_help() return 1 command = args[0] args = args[1:] dev = None scanner = DeviceScanner() scanner.scan() connected_devices = [] for d in device_plugins(): try: d.startup() except: print ('Startup failed for device plugin: %s'%d) if d.MANAGES_DEVICE_PRESENCE: cd = d.detect_managed_devices(scanner.devices) if cd is not None: connected_devices.append((cd, d)) dev = d break continue ok, det = scanner.is_device_connected(d) if ok: dev = d dev.reset(log_packets=options.log_packets, detected_device=det) connected_devices.append((det, dev)) if dev is None: print >>sys.stderr, 'Unable to find a connected ebook reader.' shutdown_plugins() return 1 for det, d in connected_devices: try: d.open(det, None) except: continue else: dev = d d.specialize_global_preferences(device_prefs) break try: if command == "df": total = dev.total_space(end_session=False) free = dev.free_space() where = ("Memory", "Card A", "Card B") print "Filesystem\tSize \tUsed \tAvail \tUse%" for i in range(3): print "%-10s\t%s\t%s\t%s\t%s"%(where[i], human_readable(total[i]), human_readable(total[i]-free[i]), human_readable(free[i]),\ str(0 if total[i]==0 else int(100*(total[i]-free[i])/(total[i]*1.)))+"%") elif command == 'eject': dev.eject() elif command == "books": print "Books in main memory:" for book in dev.books(): print book print "\nBooks on storage carda:" for book in dev.books(oncard='carda'): print book print "\nBooks on storage cardb:" for book in dev.books(oncard='cardb'): print book elif command == "mkdir": parser = OptionParser(usage="usage: %prog mkdir [options] path\nCreate a directory on the device\n\npath must begin with / or card:/") if len(args) != 1: parser.print_help() sys.exit(1) dev.mkdir(args[0]) elif command == "ls": parser = OptionParser(usage="usage: %prog ls [options] path\nList files on the device\n\npath must begin with / or card:/") parser.add_option("-l", help="In addition to the name of each file, print the file type, permissions, and timestamp (the modification time, in the local timezone). Times are local.", dest="ll", action="store_true", default=False) parser.add_option("-R", help="Recursively list subdirectories encountered. /dev and /proc are omitted", dest="recurse", action="store_true", default=False) parser.remove_option("-h") parser.add_option("-h", "--human-readable", help="show sizes in human readable format", dest="hrs", action="store_true", default=False) options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 print ls(dev, args[0], recurse=options.recurse, ll=options.ll, human_readable_size=options.hrs, cols=cols), elif command == "info": info(dev) elif command == "cp": usage="usage: %prog cp [options] source destination\nCopy files to/from the device\n\n"+\ "One of source or destination must be a path on the device. \n\nDevice paths have the form\n"+\ "dev:mountpoint/my/path\n"+\ "where mountpoint is one of / or card:/\n\n"+\ "source must point to a file for which you have read permissions\n"+\ "destination must point to a file or directory for which you have write permissions" parser = OptionParser(usage=usage) parser.add_option('-f', '--force', dest='force', action='store_true', default=False, help='Overwrite the destination file if it exists already.') options, args = parser.parse_args(args) if len(args) != 2: parser.print_help() return 1 if args[0].startswith("dev:"): outfile = args[1] path = args[0][7:] if path.endswith("/"): path = path[:-1] if os.path.isdir(outfile): outfile = os.path.join(outfile, path[path.rfind("/")+1:]) try: outfile = open(outfile, "wb") except IOError as e: print >> sys.stderr, e parser.print_help() return 1 dev.get_file(path, outfile) fsync(outfile) outfile.close() elif args[1].startswith("dev:"): try: infile = open(args[0], "rb") except IOError as e: print >> sys.stderr, e parser.print_help() return 1 try: dev.put_file(infile, args[1][7:]) except PathError as err: if options.force and 'exists' in str(err): dev.del_file(err.path, False) dev.put_file(infile, args[1][7:]) else: raise infile.close() else: parser.print_help() return 1 elif command == "cat": outfile = sys.stdout parser = OptionParser(usage="usage: %prog cat path\nShow file on the device\n\npath should point to a file on the device and must begin with /,a:/ or b:/") options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 if args[0].endswith("/"): path = args[0][:-1] else: path = args[0] outfile = sys.stdout dev.get_file(path, outfile) elif command == "rm": parser = OptionParser(usage="usage: %prog rm path\nDelete files from the device\n\npath should point to a file or empty directory on the device "+\ "and must begin with / or card:/\n\n"+\ "rm will DELETE the file. Be very CAREFUL") options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 dev.rm(args[0]) elif command == "touch": parser = OptionParser(usage="usage: %prog touch path\nCreate an empty file on the device\n\npath should point to a file on the device and must begin with /,a:/ or b:/\n\n"+ "Unfortunately, I cant figure out how to update file times on the device, so if path already exists, touch does nothing" ) options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 dev.touch(args[0]) elif command == 'test_file': parser = OptionParser(usage=("usage: %prog test_file path\n" 'Open device, copy file specified by path to device and ' 'then eject device.')) options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 path = args[0] from calibre.ebooks.metadata.meta import get_metadata mi = get_metadata(open(path, 'rb'), path.rpartition('.')[-1].lower()) print dev.upload_books([args[0]], [os.path.basename(args[0])], end_session=False, metadata=[mi]) dev.eject() else: parser.print_help() if getattr(dev, 'handle', False): dev.close() return 1 except DeviceLocked: print >> sys.stderr, "The device is locked. Use the --unlock option" except (ArgumentError, DeviceError) as e: print >>sys.stderr, e return 1 finally: shutdown_plugins() return 0
def upload_cover(self, path, filename, metadata, filepath): coverdata = getattr(metadata, "thumbnail", None) if coverdata and coverdata[2]: with open("%s.jpg" % os.path.join(path, filename), "wb") as coverfile: coverfile.write(coverdata[2]) fsync(coverfile)
def main(): from calibre.utils.terminal import geometry cols = geometry()[0] parser = OptionParser( usage="usage: %prog [options] command args\n\ncommand " + "is one of: info, books, df, ls, cp, mkdir, touch, cat, rm, eject, test_file\n\n" + "For help on a particular command: %prog command", version=__appname__ + " version: " + __version__) parser.add_option( "--log-packets", help="print out packet stream to stdout. " + "The numbers in the left column are byte offsets that allow the packet size to be read off easily.", dest="log_packets", action="store_true", default=False) parser.remove_option("-h") parser.disable_interspersed_args() # Allow unrecognized options options, args = parser.parse_args() if len(args) < 1: parser.print_help() return 1 command = args[0] args = args[1:] dev = None scanner = DeviceScanner() scanner.scan() connected_devices = [] for d in device_plugins(): try: d.startup() except: print('Startup failed for device plugin: %s' % d) if d.MANAGES_DEVICE_PRESENCE: cd = d.detect_managed_devices(scanner.devices) if cd is not None: connected_devices.append((cd, d)) dev = d break continue ok, det = scanner.is_device_connected(d) if ok: dev = d dev.reset(log_packets=options.log_packets, detected_device=det) connected_devices.append((det, dev)) if dev is None: print('Unable to find a connected ebook reader.', file=sys.stderr) shutdown_plugins() return 1 for det, d in connected_devices: try: d.open(det, None) except: continue else: dev = d d.specialize_global_preferences(device_prefs) break try: if command == "df": total = dev.total_space(end_session=False) free = dev.free_space() where = ("Memory", "Card A", "Card B") print("Filesystem\tSize \tUsed \tAvail \tUse%") for i in range(3): print("%-10s\t%s\t%s\t%s\t%s" % (where[i], human_readable( total[i]), human_readable(total[i] - free[i]), human_readable(free[i]), unicode_type(0 if total[i] == 0 else int(100 * (total[i] - free[i]) / (total[i] * 1.))) + "%")) elif command == 'eject': dev.eject() elif command == "books": print("Books in main memory:") for book in dev.books(): print(book) print("\nBooks on storage carda:") for book in dev.books(oncard='carda'): print(book) print("\nBooks on storage cardb:") for book in dev.books(oncard='cardb'): print(book) elif command == "mkdir": parser = OptionParser( usage= "usage: %prog mkdir [options] path\nCreate a folder on the device\n\npath must begin with / or card:/" ) if len(args) != 1: parser.print_help() sys.exit(1) dev.mkdir(args[0]) elif command == "ls": parser = OptionParser( usage= "usage: %prog ls [options] path\nList files on the device\n\npath must begin with / or card:/" ) parser.add_option( "-l", help= "In addition to the name of each file, print the file type, permissions, and timestamp (the modification time, in the local timezone). Times are local.", # noqa dest="ll", action="store_true", default=False) parser.add_option( "-R", help= "Recursively list subfolders encountered. /dev and /proc are omitted", dest="recurse", action="store_true", default=False) parser.remove_option("-h") parser.add_option("-h", "--human-readable", help="show sizes in human readable format", dest="hrs", action="store_true", default=False) options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 print(ls(dev, args[0], recurse=options.recurse, ll=options.ll, human_readable_size=options.hrs, cols=cols), end=' ') elif command == "info": info(dev) elif command == "cp": usage="usage: %prog cp [options] source destination\nCopy files to/from the device\n\n"+\ "One of source or destination must be a path on the device. \n\nDevice paths have the form\n"+\ "dev:mountpoint/my/path\n"+\ "where mountpoint is one of / or carda: or cardb:/\n\n"+\ "source must point to a file for which you have read permissions\n"+\ "destination must point to a file or folder for which you have write permissions" parser = OptionParser(usage=usage) parser.add_option( '-f', '--force', dest='force', action='store_true', default=False, help='Overwrite the destination file if it exists already.') options, args = parser.parse_args(args) if len(args) != 2: parser.print_help() return 1 if args[0].startswith("dev:"): outfile = args[1] path = args[0][4:] if path.endswith("/"): path = path[:-1] if os.path.isdir(outfile): outfile = os.path.join(outfile, path[path.rfind("/") + 1:]) try: outfile = lopen(outfile, "wb") except IOError as e: print(e, file=sys.stderr) parser.print_help() return 1 dev.get_file(path, outfile) fsync(outfile) outfile.close() elif args[1].startswith("dev:"): try: infile = lopen(args[0], "rb") except IOError as e: print(e, file=sys.stderr) parser.print_help() return 1 dev.put_file(infile, args[1][4:], replace_file=options.force) infile.close() else: parser.print_help() return 1 elif command == "cat": outfile = sys.stdout parser = OptionParser( usage= "usage: %prog cat path\nShow file on the device\n\npath should point to a file on the device and must begin with /,a:/ or b:/" ) options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 if args[0].endswith("/"): path = args[0][:-1] else: path = args[0] outfile = sys.stdout dev.get_file(path, outfile) elif command == "rm": parser = OptionParser( usage= "usage: %prog rm path\nDelete files from the device\n\npath should point to a file or empty folder on the device " + "and must begin with / or card:/\n\n" + "rm will DELETE the file. Be very CAREFUL") options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 dev.rm(args[0]) elif command == "touch": parser = OptionParser( usage= "usage: %prog touch path\nCreate an empty file on the device\n\npath should point to a file on the device and must begin with /,a:/ or b:/\n\n" + # noqa "Unfortunately, I cant figure out how to update file times on the device, so if path already exists, touch does nothing" ) options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 dev.touch(args[0]) elif command == 'test_file': parser = OptionParser(usage=( "usage: %prog test_file path\n" 'Open device, copy file specified by path to device and ' 'then eject device.')) options, args = parser.parse_args(args) if len(args) != 1: parser.print_help() return 1 path = args[0] from calibre.ebooks.metadata.meta import get_metadata mi = get_metadata(lopen(path, 'rb'), path.rpartition('.')[-1].lower()) print( dev.upload_books([args[0]], [os.path.basename(args[0])], end_session=False, metadata=[mi])) dev.eject() else: parser.print_help() if getattr(dev, 'handle', False): dev.close() return 1 except DeviceLocked: print("The device is locked. Use the --unlock option", file=sys.stderr) except (ArgumentError, DeviceError) as e: print(e, file=sys.stderr) return 1 finally: shutdown_plugins() return 0