mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
When shortening filepaths to conform to windows path length limitations, remove text from the middle of each component instead of the ends. Fix #8451 (Error Communicating with Device).
This commit is contained in:
commit
1ad9b6cbfd
@ -98,6 +98,9 @@ class PRS505(USBMS):
|
|||||||
|
|
||||||
THUMBNAIL_HEIGHT = 200
|
THUMBNAIL_HEIGHT = 200
|
||||||
|
|
||||||
|
MAX_PATH_LEN = 201 # 250 - (max(len(CACHE_THUMBNAIL), len(MEDIA_THUMBNAIL)) +
|
||||||
|
# len('main_thumbnail.jpg') + 1)
|
||||||
|
|
||||||
def windows_filter_pnp_id(self, pnp_id):
|
def windows_filter_pnp_id(self, pnp_id):
|
||||||
return '_LAUNCHER' in pnp_id
|
return '_LAUNCHER' in pnp_id
|
||||||
|
|
||||||
@ -201,10 +204,13 @@ class PRS505(USBMS):
|
|||||||
self._card_b_prefix if idx == 2 \
|
self._card_b_prefix if idx == 2 \
|
||||||
else self._main_prefix
|
else self._main_prefix
|
||||||
for book in bl:
|
for book in bl:
|
||||||
p = os.path.join(prefix, book.lpath)
|
try:
|
||||||
self._upload_cover(os.path.dirname(p),
|
p = os.path.join(prefix, book.lpath)
|
||||||
os.path.splitext(os.path.basename(p))[0],
|
self._upload_cover(os.path.dirname(p),
|
||||||
book, p)
|
os.path.splitext(os.path.basename(p))[0],
|
||||||
|
book, p)
|
||||||
|
except:
|
||||||
|
debug_print('FAILED to upload cover', p)
|
||||||
else:
|
else:
|
||||||
debug_print('PRS505: NOT uploading covers in sync_booklists')
|
debug_print('PRS505: NOT uploading covers in sync_booklists')
|
||||||
|
|
||||||
@ -232,8 +238,7 @@ class PRS505(USBMS):
|
|||||||
try:
|
try:
|
||||||
self._upload_cover(path, filename, metadata, filepath)
|
self._upload_cover(path, filename, metadata, filepath)
|
||||||
except:
|
except:
|
||||||
import traceback
|
debug_print('FAILED to upload cover', filepath)
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
def _upload_cover(self, path, filename, metadata, filepath):
|
def _upload_cover(self, path, filename, metadata, filepath):
|
||||||
if metadata.thumbnail and metadata.thumbnail[-1]:
|
if metadata.thumbnail and metadata.thumbnail[-1]:
|
||||||
|
@ -98,6 +98,9 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
# copy these back to the library
|
# copy these back to the library
|
||||||
BACKLOADING_ERROR_MESSAGE = None
|
BACKLOADING_ERROR_MESSAGE = None
|
||||||
|
|
||||||
|
#: The maximum length of paths created on the device
|
||||||
|
MAX_PATH_LEN = 250
|
||||||
|
|
||||||
def reset(self, key='-1', log_packets=False, report_progress=None,
|
def reset(self, key='-1', log_packets=False, report_progress=None,
|
||||||
detected_device=None):
|
detected_device=None):
|
||||||
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
|
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
|
||||||
@ -875,7 +878,7 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
|
|
||||||
def create_upload_path(self, path, mdata, fname, create_dirs=True):
|
def create_upload_path(self, path, mdata, fname, create_dirs=True):
|
||||||
path = os.path.abspath(path)
|
path = os.path.abspath(path)
|
||||||
extra_components = []
|
maxlen = self.MAX_PATH_LEN
|
||||||
|
|
||||||
special_tag = None
|
special_tag = None
|
||||||
if mdata.tags:
|
if mdata.tags:
|
||||||
@ -902,7 +905,7 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
app_id = str(getattr(mdata, 'application_id', ''))
|
app_id = str(getattr(mdata, 'application_id', ''))
|
||||||
# The db id will be in the created filename
|
# The db id will be in the created filename
|
||||||
extra_components = get_components(template, mdata, fname,
|
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:
|
if not extra_components:
|
||||||
extra_components.append(sanitize(self.filename_callback(fname,
|
extra_components.append(sanitize(self.filename_callback(fname,
|
||||||
mdata)))
|
mdata)))
|
||||||
@ -937,12 +940,11 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
return ans
|
return ans
|
||||||
|
|
||||||
extra_components = list(map(remove_trailing_periods, extra_components))
|
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)
|
components = self.sanitize_path_components(components)
|
||||||
filepath = os.path.join(path, *components)
|
filepath = os.path.join(path, *components)
|
||||||
filedir = os.path.dirname(filepath)
|
filedir = os.path.dirname(filepath)
|
||||||
|
|
||||||
|
|
||||||
if create_dirs and not os.path.exists(filedir):
|
if create_dirs and not os.path.exists(filedir):
|
||||||
os.makedirs(filedir)
|
os.makedirs(filedir)
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ class BulkEnumeration(BulkBase, Enumeration):
|
|||||||
value = None
|
value = None
|
||||||
ret_value = None
|
ret_value = None
|
||||||
dialog_shown = False
|
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)
|
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 val and val not in self.col_metadata['display']['enum_values']:
|
||||||
if not dialog_shown:
|
if not dialog_shown:
|
||||||
@ -610,7 +610,7 @@ class BulkEnumeration(BulkBase, Enumeration):
|
|||||||
show=True, show_copy_button=False)
|
show=True, show_copy_button=False)
|
||||||
dialog_shown = True
|
dialog_shown = True
|
||||||
ret_value = ' nochange '
|
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 '
|
ret_value = ' nochange '
|
||||||
value = val
|
value = val
|
||||||
if ret_value is None:
|
if ret_value is None:
|
||||||
|
@ -42,30 +42,44 @@ def supports_long_names(path):
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def shorten_components_to(length, components):
|
def shorten_component(s, by_what):
|
||||||
|
l = len(s)
|
||||||
|
if l < by_what:
|
||||||
|
return s
|
||||||
|
l = (l - by_what)//2
|
||||||
|
if l <= 0:
|
||||||
|
return s
|
||||||
|
return s[:l] + s[-l:]
|
||||||
|
|
||||||
|
def shorten_components_to(length, components, more_to_take=0):
|
||||||
filepath = os.sep.join(components)
|
filepath = os.sep.join(components)
|
||||||
extra = len(filepath) - length
|
extra = len(filepath) - (length - more_to_take)
|
||||||
if extra < 1:
|
if extra < 1:
|
||||||
return components
|
return components
|
||||||
delta = int(ceil(extra/float(len(components))))
|
deltas = []
|
||||||
ans = []
|
|
||||||
for x in components:
|
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):
|
if delta > len(x):
|
||||||
r = x[0] if x is components[-1] else ''
|
r = x[0] if x is components[-1] else ''
|
||||||
else:
|
else:
|
||||||
if x is components[-1]:
|
if x is components[-1]:
|
||||||
b, e = os.path.splitext(x)
|
b, e = os.path.splitext(x)
|
||||||
if e == '.': e = ''
|
if e == '.': e = ''
|
||||||
r = b[:-delta]+e
|
r = shorten_component(b, delta)+e
|
||||||
if r.startswith('.'): r = x[0]+r
|
if r.startswith('.'): r = x[0]+r
|
||||||
else:
|
else:
|
||||||
r = x[:-delta]
|
r = shorten_component(x, delta)
|
||||||
r = r.strip()
|
r = r.strip()
|
||||||
if not r:
|
if not r:
|
||||||
r = x.strip()[0] if x.strip() else 'x'
|
r = x.strip()[0] if x.strip() else 'x'
|
||||||
ans.append(r)
|
ans.append(r)
|
||||||
if len(os.sep.join(ans)) > length:
|
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
|
return ans
|
||||||
|
|
||||||
def find_executable_in_path(name, path=None):
|
def find_executable_in_path(name, path=None):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user