From 35c319f115656182addca7030340dd9b713adfc1 Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Wed, 19 Jan 2011 15:00:52 +0000 Subject: [PATCH 1/2] Fix bug in bulk edit CC enum types where if all but the last are None, the combo box shows the last value and the others cannot be set. --- src/calibre/gui2/custom_column_widgets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index d80909c4bb..58985d1121 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -599,7 +599,7 @@ class BulkEnumeration(BulkBase, Enumeration): value = None ret_value = None dialog_shown = False - for book_id in book_ids: + for i,book_id in enumerate(book_ids): val = self.db.get_custom(book_id, num=self.col_id, index_is_id=True) if val and val not in self.col_metadata['display']['enum_values']: if not dialog_shown: @@ -610,7 +610,7 @@ class BulkEnumeration(BulkBase, Enumeration): show=True, show_copy_button=False) dialog_shown = True ret_value = ' nochange ' - elif value is not None and value != val: + elif (value is not None and value != val) or (val and i != 0): ret_value = ' nochange ' value = val if ret_value is None: From e008ff22b71f1b3b4beddb74e0df3ba45c562f25 Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Wed, 19 Jan 2011 15:08:30 +0000 Subject: [PATCH 2/2] Fix #8451: Error Communicating with Device when sending covers. --- src/calibre/devices/prs505/driver.py | 17 +++++++++++++---- src/calibre/devices/usbms/device.py | 11 +++++++---- src/calibre/utils/filenames.py | 28 +++++++++++++++++++++------- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 874fbe4b10..234093a164 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -201,10 +201,13 @@ class PRS505(USBMS): self._card_b_prefix if idx == 2 \ else self._main_prefix for book in bl: - p = os.path.join(prefix, book.lpath) - self._upload_cover(os.path.dirname(p), - os.path.splitext(os.path.basename(p))[0], - book, p) + try: + p = os.path.join(prefix, book.lpath) + self._upload_cover(os.path.dirname(p), + os.path.splitext(os.path.basename(p))[0], + book, p) + except: + debug_print('FAILED to upload cover', p) else: debug_print('PRS505: NOT uploading covers in sync_booklists') @@ -222,6 +225,12 @@ class PRS505(USBMS): self.plugboards = plugboards self.plugboard_func = pb_func + def create_upload_path(self, path, mdata, fname, create_dirs=True): + maxlen = 250 - (max(len(CACHE_THUMBNAIL), len(MEDIA_THUMBNAIL)) + + len('main_thumbnail.jpg') + 1) + return self._create_upload_path(path, mdata, fname, + create_dirs=create_dirs, maxlen=maxlen) + def upload_cover(self, path, filename, metadata, filepath): opts = self.settings() if not opts.extra_customization[self.OPT_UPLOAD_COVERS]: diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index 4711a8eec4..ffe2484b38 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -874,8 +874,12 @@ class Device(DeviceConfig, DevicePlugin): return {} def create_upload_path(self, path, mdata, fname, create_dirs=True): + return self._create_upload_path(path, mdata, fname, + create_dirs=create_dirs, maxlen=250) + + def _create_upload_path(self, path, mdata, fname, create_dirs=True, + maxlen=None): path = os.path.abspath(path) - extra_components = [] special_tag = None if mdata.tags: @@ -902,7 +906,7 @@ class Device(DeviceConfig, DevicePlugin): app_id = str(getattr(mdata, 'application_id', '')) # The db id will be in the created filename extra_components = get_components(template, mdata, fname, - timefmt=opts.send_timefmt, length=250-len(app_id)-1) + timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1) if not extra_components: extra_components.append(sanitize(self.filename_callback(fname, mdata))) @@ -937,12 +941,11 @@ class Device(DeviceConfig, DevicePlugin): return ans extra_components = list(map(remove_trailing_periods, extra_components)) - components = shorten_components_to(250 - len(path), extra_components) + components = shorten_components_to(maxlen - len(path), extra_components) components = self.sanitize_path_components(components) filepath = os.path.join(path, *components) filedir = os.path.dirname(filepath) - if create_dirs and not os.path.exists(filedir): os.makedirs(filedir) diff --git a/src/calibre/utils/filenames.py b/src/calibre/utils/filenames.py index 47ccbe73c2..7225ab44c8 100644 --- a/src/calibre/utils/filenames.py +++ b/src/calibre/utils/filenames.py @@ -42,30 +42,44 @@ def supports_long_names(path): else: return True -def shorten_components_to(length, components): +def shorten_component(s, byWhat): + l = len(s) + if l < byWhat: + return s + l = int((l-byWhat)/2) + if l <= 0: + return s + return s[0:l] + s[-l:] + +def shorten_components_to(length, components, more_to_take = 0): filepath = os.sep.join(components) - extra = len(filepath) - length + extra = len(filepath) - (length - more_to_take) if extra < 1: return components - delta = int(ceil(extra/float(len(components)))) - ans = [] + deltas = [] for x in components: + pct = len(x)/float(len(filepath)) + deltas.append(int(ceil(pct*extra))) + ans = [] + + for i,x in enumerate(components): + delta = deltas[i] if delta > len(x): r = x[0] if x is components[-1] else '' else: if x is components[-1]: b, e = os.path.splitext(x) if e == '.': e = '' - r = b[:-delta]+e + r = shorten_component(b, delta)+e if r.startswith('.'): r = x[0]+r else: - r = x[:-delta] + r = shorten_component(x, delta) r = r.strip() if not r: r = x.strip()[0] if x.strip() else 'x' ans.append(r) if len(os.sep.join(ans)) > length: - return shorten_components_to(length, ans) + return shorten_components_to(length, components, more_to_take+2) return ans def find_executable_in_path(name, path=None):