From 4e2556ee63558d08f56c2a0992057ba81d6c4a83 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 16 Apr 2019 09:31:42 +0530 Subject: [PATCH] py3: misc fixes Connecting to a folder device and converting LRF files now work --- src/calibre/devices/smart_device_app/driver.py | 2 +- src/calibre/devices/usbms/driver.py | 2 +- src/calibre/ebooks/lrf/input.py | 11 ++++------- src/calibre/ebooks/lrf/lrfparser.py | 7 ++++--- src/calibre/ebooks/lrf/meta.py | 14 +++++--------- src/calibre/ebooks/lrf/objects.py | 4 ++-- src/calibre/ebooks/metadata/book/json_codec.py | 2 +- src/calibre/utils/ipc/job.py | 3 +++ 8 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/calibre/devices/smart_device_app/driver.py b/src/calibre/devices/smart_device_app/driver.py index 6dd7fdb250..7c0ba2ea7f 100644 --- a/src/calibre/devices/smart_device_app/driver.py +++ b/src/calibre/devices/smart_device_app/driver.py @@ -554,7 +554,7 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): else: res[k] = v from calibre.utils.config import to_json - return json.dumps([op, res], encoding='utf-8', default=to_json) + return json.dumps([op, res], default=to_json) # Network functions diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index 22aa18a6b5..806d8bd3a1 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -287,7 +287,7 @@ class USBMS(CLI, Device): # Remove books that are no longer in the filesystem. Cache contains # indices into the booklist if book not in filesystem, None otherwise # Do the operation in reverse order so indices remain valid - for idx in sorted(itervalues(bl_cache), reverse=True): + for idx in sorted(itervalues(bl_cache), reverse=True, key=lambda x: -1 if x is None else x): if idx is not None: need_sync = True del bl[idx] diff --git a/src/calibre/ebooks/lrf/input.py b/src/calibre/ebooks/lrf/input.py index b678f38cec..81b2a72ef3 100644 --- a/src/calibre/ebooks/lrf/input.py +++ b/src/calibre/ebooks/lrf/input.py @@ -12,6 +12,7 @@ from copy import deepcopy, copy from lxml import etree from calibre import guess_type +from polyglot.builtins import as_bytes class Canvas(etree.XSLTExtension): @@ -21,7 +22,7 @@ class Canvas(etree.XSLTExtension): self.styles = styles self.text_block = text_block self.log = log - self.processed = set([]) + self.processed = set() def execute(self, context, self_node, input_node, output_parent): cid = input_node.get('objid', None) @@ -298,7 +299,7 @@ class Styles(etree.XSLTExtension): return '\n\t'.join(ans) with open(name, 'wb') as f: - f.write(self.CSS) + f.write(as_bytes(self.CSS)) for (w, sel) in [(self.text_styles, 'ts'), (self.block_styles, 'bs')]: for i, s in enumerate(w): @@ -306,7 +307,7 @@ class Styles(etree.XSLTExtension): continue rsel = '.%s%d'%(sel, i) s = join(s) - f.write(rsel + ' {\n\t' + s + '\n}\n\n') + f.write(as_bytes(rsel + ' {\n\t' + s + '\n}\n\n')) def execute(self, context, self_node, input_node, output_parent): if input_node.tag == 'TextStyle': @@ -400,7 +401,3 @@ class Styles(etree.XSLTExtension): if ans not in self.text_styles: self.text_styles.append(ans) return self.text_styles.index(ans) - - - - diff --git a/src/calibre/ebooks/lrf/lrfparser.py b/src/calibre/ebooks/lrf/lrfparser.py index 4915bba235..102c4ad2d5 100644 --- a/src/calibre/ebooks/lrf/lrfparser.py +++ b/src/calibre/ebooks/lrf/lrfparser.py @@ -3,6 +3,7 @@ __copyright__ = '2008, Kovid Goyal ' '''''' import sys, array, os, re, codecs, logging +from itertools import chain from calibre import setup_cli_handlers from calibre.utils.config import OptionParser @@ -10,7 +11,7 @@ from calibre.utils.filenames import ascii_filename from calibre.ebooks.lrf.meta import LRFMetaFile from calibre.ebooks.lrf.objects import get_object, PageTree, StyleObject, \ Font, Text, TOCObject, BookAttr, ruby_tags -from polyglot.builtins import unicode_type +from polyglot.builtins import unicode_type, itervalues class LRFDocument(LRFMetaFile): @@ -45,7 +46,7 @@ class LRFDocument(LRFMetaFile): self.objects = {} self._file.seek(self.object_index_offset) obj_array = array.array("I", self._file.read(4*4*self.number_of_objects)) - if ord(array.array("i",[1]).tostring()[0])==0: # big-endian + if ord(array.array("i",[1]).tostring()[0:1])==0: # big-endian obj_array.byteswap() for i in range(self.number_of_objects): if not self.keep_parsing: @@ -77,7 +78,7 @@ class LRFDocument(LRFMetaFile): yield pt def write_files(self): - for obj in self.image_map.values() + self.font_map.values(): + for obj in chain(itervalues(self.image_map), itervalues(self.font_map)): open(obj.file, 'wb').write(obj.stream) def to_xml(self, write_files=True): diff --git a/src/calibre/ebooks/lrf/meta.py b/src/calibre/ebooks/lrf/meta.py index 555dd1d6d9..6ebb8deb04 100644 --- a/src/calibre/ebooks/lrf/meta.py +++ b/src/calibre/ebooks/lrf/meta.py @@ -47,11 +47,7 @@ class field(object): obj.pack(val, start=self._start, fmt=self._fmt) def __repr__(self): - typ = "" - if self._fmt == DWORD: - typ = "unsigned int" - if self._fmt == QWORD: - typ = "unsigned long long" + typ = {DWORD: 'unsigned int', 'QWORD': 'unsigned long long', BYTE: 'unsigned char', WORD: 'unsigned short'}.get(self._fmt, '') return "An " + typ + " stored in " + \ str(struct.calcsize(self._fmt)) + \ " bytes starting at byte " + str(self._start) @@ -63,17 +59,17 @@ class versioned_field(field): field.__init__(self, start=start, fmt=fmt) self.vfield, self.version = vfield, version - def enabled(self): - return self.vfield > self.version + def enabled(self, obj): + return self.vfield.__get__(obj) > self.version def __get__(self, obj, typ=None): - if self.enabled(): + if self.enabled(obj): return field.__get__(self, obj, typ=typ) else: return None def __set__(self, obj, val): - if not self.enabled(): + if not self.enabled(obj): raise LRFException("Trying to set disabled field") else: field.__set__(self, obj, val) diff --git a/src/calibre/ebooks/lrf/objects.py b/src/calibre/ebooks/lrf/objects.py index a6bd2c2322..dcec52221b 100644 --- a/src/calibre/ebooks/lrf/objects.py +++ b/src/calibre/ebooks/lrf/objects.py @@ -176,7 +176,7 @@ class LRFStream(LRFObject): self.stream = zlib.decompress(self.stream[4:]) if len(self.stream) != decomp_size: raise LRFParseError("Stream decompressed size is wrong!") - if stream.read(2) != '\x06\xF5': + if stream.read(2) != b'\x06\xF5': print("Warning: corrupted end-of-stream tag at %08X; skipping it"%(stream.tell()-2)) self.end_stream(None, None) @@ -850,7 +850,7 @@ class Text(LRFStream): # Is there some text before a tag? def find_first_tag(start): - pos = self.stream.find('\xf5', start) + pos = self.stream.find(b'\xf5', start) if pos == -1: return -1 try: diff --git a/src/calibre/ebooks/metadata/book/json_codec.py b/src/calibre/ebooks/metadata/book/json_codec.py index cba78f172a..1275fd407f 100644 --- a/src/calibre/ebooks/metadata/book/json_codec.py +++ b/src/calibre/ebooks/metadata/book/json_codec.py @@ -132,7 +132,7 @@ class JsonCodec(object): self.field_metadata = field_metadata or FieldMetadata() def encode_to_file(self, file_, booklist): - data = json.dumps(self.encode_booklist_metadata(booklist), indent=2, encoding='utf-8') + data = json.dumps(self.encode_booklist_metadata(booklist), indent=2) if not isinstance(data, bytes): data = data.encode('utf-8') file_.write(data) diff --git a/src/calibre/utils/ipc/job.py b/src/calibre/utils/ipc/job.py index 881575705e..ed66c78abc 100644 --- a/src/calibre/utils/ipc/job.py +++ b/src/calibre/utils/ipc/job.py @@ -126,6 +126,9 @@ class BaseJob(object): def is_running(self): return self.is_started and not self.is_finished + def __hash__(self): + return id(self) + def __eq__(self, other): return self is other