Skip to content

Commit

Permalink
Truncate on character boundaries
Browse files Browse the repository at this point in the history
  • Loading branch information
untitaker committed Jun 3, 2015
1 parent 419a12a commit 625ec59
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions beets/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,16 +535,37 @@ def truncate_path(path, length=MAX_FILENAME_LENGTH):
"""
comps = components(path)

out = [c[:length] for c in comps]
out = [truncate_string(s, length, _fsencoding()) for c in comps]
base, ext = os.path.splitext(comps[-1])
if ext:
# Last component has an extension.
base = base[:length - len(ext)]
base = truncate_string(s, length - len(ext), _fsencoding())
out[-1] = base + ext

return os.path.join(*out)


def truncate_string(s, length, encoding=None):
'''Truncate strings safely, i.e. on character boundaries.
Bytestrings are truncated to `length` bytes or less and are assumed to be
encoded in `encoding`. Unicode strings are truncated at `length` characters
or less.
'''
if isinstance(s, unicode):
return s[:length]

rv = b''
for char in s.decode(encoding):
new_rv = rv + char.encode(encoding)
if len(new_rv) <= length:
rv = new_rv
else:
break

return rv


def str2bool(value):
"""Returns a boolean reflecting a human-entered string."""
return value.lower() in ('yes', '1', 'true', 't', 'y')
Expand Down

0 comments on commit 625ec59

Please sign in to comment.