From ca5960365dc9b3878b28a2359fc9e5398218a3a8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Jul 2009 22:28:37 -0600 Subject: [PATCH] Fix path length restriction code in device drivers --- src/calibre/devices/prs505/driver.py | 2 + src/calibre/devices/usbms/device.py | 73 ++++++++++++++++++++++++++++ src/calibre/devices/usbms/driver.py | 62 ----------------------- 3 files changed, 75 insertions(+), 62 deletions(-) diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 9c9aaca97e..e736ba0864 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -43,6 +43,8 @@ class PRS505(CLI, Device): CARD_PATH_PREFIX = __appname__ + SUPPORTS_SUB_DIRS = True + def open(self): Device.open(self) diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index d34e8aa676..499352c483 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -9,11 +9,13 @@ device. This class handles device detection. import os, subprocess, time, re, sys, glob, shutil from itertools import repeat +from math import ceil from calibre.devices.interface import DevicePlugin from calibre.devices.errors import DeviceError from calibre.devices.usbms.deviceconfig import DeviceConfig from calibre import iswindows, islinux, isosx, __appname__ +from calibre import sanitize_file_name as sanitize class Device(DeviceConfig, DevicePlugin): ''' @@ -41,6 +43,8 @@ class Device(DeviceConfig, DevicePlugin): STORAGE_CARD_VOLUME_LABEL = '' STORAGE_CARD2_VOLUME_LABEL = None + SUPPORTS_SUB_DIRS = False + FDI_TEMPLATE = \ ''' @@ -605,3 +609,72 @@ class Device(DeviceConfig, DevicePlugin): pass self._main_prefix = self._card_a_prefix = self._card_b_prefix = None + def create_upload_path(self, path, mdata, fname): + resizable = [] + newpath = path + if self.SUPPORTS_SUB_DIRS: + + if 'tags' in mdata.keys(): + for tag in mdata['tags']: + if tag.startswith(_('News')): + newpath = os.path.join(newpath, 'news') + c = sanitize(mdata.get('title', '')) + if c: + newpath = os.path.join(newpath, c) + resizable.append(c) + c = sanitize(mdata.get('timestamp', '')) + if c: + newpath = os.path.join(newpath, c) + resizable.append(c) + break + elif tag.startswith('/'): + for c in tag.split('/'): + c = sanitize(c) + if not c: continue + newpath = os.path.join(newpath, c) + resizable.append(c) + break + + if newpath == path: + c = sanitize(mdata.get('authors', _('Unknown'))) + if c: + newpath = os.path.join(newpath, c) + resizable.append(c) + c = sanitize(mdata.get('title', _('Unknown'))) + if c: + newpath = os.path.join(newpath, c) + resizable.append(c) + + newpath = os.path.abspath(newpath) + fname = sanitize(fname) + resizable.append(fname) + + filepath = os.path.join(newpath, fname) + + if len(filepath) > 245: + extra = len(filepath) - 245 + delta = int(ceil(extra/float(len(resizable)))) + for x in resizable: + if delta > len(x): + r = x[0] if x is resizable[-1] else '' + else: + if x is resizable[-1]: + b, e = os.path.splitext(x) + r = b[:-delta]+e + if r.startswith('.'): r = x[0]+r + else: + r = x[:-delta] + if x is resizable[-1]: + filepath = filepath.replace(os.sep+x, os.sep+r) + else: + filepath = filepath.replace(os.sep+x+os.sep, os.sep+r+os.sep) + filepath = filepath.replace(os.sep+os.sep, os.sep) + newpath = os.path.dirname(filepath) + + + if not os.path.exists(newpath): + os.makedirs(newpath) + + return filepath + + diff --git a/src/calibre/devices/usbms/driver.py b/src/calibre/devices/usbms/driver.py index 065c144662..cdcf99546b 100644 --- a/src/calibre/devices/usbms/driver.py +++ b/src/calibre/devices/usbms/driver.py @@ -10,10 +10,8 @@ for a particular device. import os import fnmatch import shutil -from math import ceil from itertools import cycle -from calibre import sanitize_file_name as sanitize from calibre.ebooks.metadata import authors_to_string from calibre.devices.usbms.cli import CLI from calibre.devices.usbms.device import Device @@ -34,7 +32,6 @@ class USBMS(CLI, Device): EBOOK_DIR_MAIN = '' EBOOK_DIR_CARD_A = '' EBOOK_DIR_CARD_B = '' - SUPPORTS_SUB_DIRS = False CAN_SET_METADATA = False def reset(self, key='-1', log_packets=False, report_progress=None): @@ -149,65 +146,6 @@ class USBMS(CLI, Device): return zip(paths, cycle([on_card])) - def create_upload_path(self, path, mdata, fname): - resizable = [] - newpath = path - if self.SUPPORTS_SUB_DIRS: - - if 'tags' in mdata.keys(): - for tag in mdata['tags']: - if tag.startswith(_('News')): - newpath = os.path.join(newpath, 'news') - c = sanitize(mdata.get('title', '')) - if c: - newpath = os.path.join(newpath, c) - resizable.append(c) - c = sanitize(mdata.get('timestamp', '')) - if c: - newpath = os.path.join(newpath, c) - resizable.append(c) - break - elif tag.startswith('/'): - for c in tag.split('/'): - c = sanitize(c) - if not c: continue - newpath = os.path.join(newpath, c) - resizable.append(c) - break - - if newpath == path: - c = sanitize(mdata.get('authors', _('Unknown'))) - if c: - newpath = os.path.join(newpath, c) - resizable.append(c) - c = sanitize(mdata.get('title', _('Unknown'))) - if c: - newpath = os.path.join(newpath, c) - resizable.append(c) - - newpath = os.path.abspath(newpath) - fname = sanitize(fname) - resizable.append(fname) - filepath = os.path.join(newpath, fname) - - if len(filepath) > 250: - extra = len(filepath) - 250 - delta = int(ceil(extra/float(len(resizable)))) - for x in resizable: - if delta > len(x): - r = '' - else: - r = x[:-delta] - filepath = filepath.replace(os.sep+x+os.sep, os.sep+r+os.sep) - filepath = filepath.replace(os.sep+os.sep, os.sep) - newpath = os.path.dirname(filepath) - - - if not os.path.exists(newpath): - os.makedirs(newpath) - - return filepath - def add_books_to_metadata(self, locations, metadata, booklists): for i, location in enumerate(locations):