Fix problem generating file names in send-to-device and possibly save-to-disk. The original code assumed that the last component always had an extension, which isn't true when evaluating templates to generate a file name. If the resulting string was too long and if last segment of the string contained a period then the remainder of the string after the period was assumed to be an extension. If that remainder was longer than permitted, shorten_components_to generated a path consisting of a single letter.

Example: if the template generated this string:
"Some of the Best From Tor.com, 2013 Edition_ A Tor.Com Original - A. B. C. Personn & Aa Angstrom & Anne McCaffrey & Banks, Iain M & Bruce Sterling & Cajkovskij, Petr Ilic & Chacko, David & Charlie Huston & Collins, Wilkie & D'Ansey, Leigh & Dahl, Roland & Edward Elmer _Doc_ Smith & Eric Flint & George Charon & Jules Verne (1422)"
then the "extension" was everything after the A. B. C., with a length that can easily exceed the max path len.
This commit is contained in:
Charles Haley 2014-12-23 11:31:17 +01:00
parent 010dcde552
commit 4a7f3f5717
4 changed files with 9 additions and 7 deletions

View File

@ -453,7 +453,8 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
app_id = str(getattr(mdata, 'application_id', '')) app_id = str(getattr(mdata, 'application_id', ''))
id_ = mdata.get('id', fname) id_ = mdata.get('id', fname)
extra_components = get_components(template, mdata, id_, extra_components = get_components(template, mdata, id_,
timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1) timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1,
last_has_extension=False)
if not extra_components: if not extra_components:
extra_components.append(sanitize(fname)) extra_components.append(sanitize(fname))
else: else:

View File

@ -100,7 +100,7 @@ def create_upload_path(mdata, fname, template, sanitize,
id_ = mdata.get('id', fname) id_ = mdata.get('id', fname)
extra_components = get_components(template, mdata, id_, extra_components = get_components(template, mdata, id_,
timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1, timefmt=opts.send_timefmt, length=maxlen-len(app_id)-1,
sanitize_func=sanitize) sanitize_func=sanitize, last_has_extension=False)
if not extra_components: if not extra_components:
extra_components.append(sanitize(filename_callback(fname, extra_components.append(sanitize(filename_callback(fname,
mdata))) mdata)))

View File

@ -169,7 +169,7 @@ class Formatter(TemplateFormatter):
def get_components(template, mi, id, timefmt='%b %Y', length=250, def get_components(template, mi, id, timefmt='%b %Y', length=250,
sanitize_func=ascii_filename, replace_whitespace=False, sanitize_func=ascii_filename, replace_whitespace=False,
to_lowercase=False, safe_format=True): to_lowercase=False, safe_format=True, last_has_extension=True):
tsorder = tweaks['save_template_title_series_sorting'] tsorder = tweaks['save_template_title_series_sorting']
format_args = FORMAT_ARGS.copy() format_args = FORMAT_ARGS.copy()
@ -248,7 +248,7 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
if replace_whitespace: if replace_whitespace:
components = [re.sub(r'\s', '_', x) for x in components] components = [re.sub(r'\s', '_', x) for x in components]
return shorten_components_to(length, components) return shorten_components_to(length, components, last_has_extension=last_has_extension)
def save_book_to_disk(id_, db, root, opts, length): def save_book_to_disk(id_, db, root, opts, length):
@ -286,7 +286,8 @@ def get_path_components(opts, mi, book_id, path_length):
components = get_components(opts.template, mi, book_id, opts.timefmt, path_length, components = get_components(opts.template, mi, book_id, opts.timefmt, path_length,
ascii_filename if opts.asciiize else sanitize_file_name_unicode, ascii_filename if opts.asciiize else sanitize_file_name_unicode,
to_lowercase=opts.to_lowercase, to_lowercase=opts.to_lowercase,
replace_whitespace=opts.replace_whitespace, safe_format=False) replace_whitespace=opts.replace_whitespace, safe_format=False,
last_has_extension=False)
except Exception, e: except Exception, e:
raise ValueError(_('Failed to calculate path for ' raise ValueError(_('Failed to calculate path for '
'save to disk. Template: %(templ)s\n' 'save to disk. Template: %(templ)s\n'

View File

@ -52,7 +52,7 @@ def shorten_component(s, by_what):
return s return s
return s[:l] + s[-l:] return s[:l] + s[-l:]
def shorten_components_to(length, components, more_to_take=0): def shorten_components_to(length, components, more_to_take=0, last_has_extension=True):
filepath = os.sep.join(components) filepath = os.sep.join(components)
extra = len(filepath) - (length - more_to_take) extra = len(filepath) - (length - more_to_take)
if extra < 1: if extra < 1:
@ -68,7 +68,7 @@ def shorten_components_to(length, components, more_to_take=0):
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 last_has_extension and x is components[-1]:
b, e = os.path.splitext(x) b, e = os.path.splitext(x)
if e == '.': if e == '.':
e = '' e = ''