diff --git a/beets/library.py b/beets/library.py index b777e4ad6..ced3361c0 100644 --- a/beets/library.py +++ b/beets/library.py @@ -1152,6 +1152,7 @@ class Library(BaseLibrary): """ pathmod = pathmod or os.path platform = platform or sys.platform + basedir = basedir or self.directory # Use a path format based on a query, falling back on the # default. @@ -1197,15 +1198,15 @@ class Library(BaseLibrary): subpath += extension.lower() # Truncate too-long components. - subpath = util.truncate_path( - subpath, pathmod, - beets.config['max_filename_length'].get(int), - ) + maxlen = beets.config['max_filename_length'].get(int) + if not maxlen: + # When zero, try to determine from filesystem. + maxlen = util.max_filename_length(self.directory) + subpath = util.truncate_path(subpath, pathmod, maxlen) if fragment: return subpath else: - basedir = basedir or self.directory return normpath(os.path.join(basedir, subpath)) diff --git a/beets/util/__init__.py b/beets/util/__init__.py index 48e0c5d25..b0a85f74d 100644 --- a/beets/util/__init__.py +++ b/beets/util/__init__.py @@ -601,3 +601,17 @@ def command_output(cmd): if proc.returncode: raise subprocess.CalledProcessError(proc.returncode, cmd) return stdout + +def max_filename_length(path, fallback=MAX_FILENAME_LENGTH): + """Attempt to determine the maximum filename length for the + filesystem containing `path`. If it cannot be determined, return a + predetermined fallback value. + """ + if hasattr(os, 'statvfs'): + try: + res = os.statvfs(path) + except OSError: + return fallback + return res[9] + else: + return fallback