Get unique filename in dir with proper filename length, using given filename/dir. File/dir won't be created (thread nonsafe) :param dir_path: path to dir :param filename: original filename :return: unique filename
(dir_path, filename, cache=collections.defaultdict(set))
| 182 | |
| 183 | |
| 184 | def get_unique_file_path(dir_path, filename, cache=collections.defaultdict(set)): |
| 185 | """ |
| 186 | Get unique filename in dir with proper filename length, using given filename/dir. |
| 187 | File/dir won't be created (thread nonsafe) |
| 188 | :param dir_path: path to dir |
| 189 | :param filename: original filename |
| 190 | :return: unique filename |
| 191 | """ |
| 192 | max_suffix = 10000 |
| 193 | # + 1 symbol for dot before suffix |
| 194 | tail_length = int(round(math.log(max_suffix, 10))) + 1 |
| 195 | # truncate filename length in accordance with filesystem limitations |
| 196 | filename, extension = os.path.splitext(filename) |
| 197 | # XXX |
| 198 | if sys.platform.startswith("win"): |
| 199 | # Trying to fit into MAX_PATH if it's possible. |
| 200 | # Remove after DEVTOOLS-1646 |
| 201 | max_path = 260 |
| 202 | filename_len = len(dir_path) + len(extension) + tail_length + len(os.sep) |
| 203 | if filename_len < max_path: |
| 204 | filename = yatest_lib.tools.trim_string(filename, max_path - filename_len) |
| 205 | filename = ( |
| 206 | yatest_lib.tools.trim_string(filename, get_max_filename_length(dir_path) - tail_length - len(extension)) |
| 207 | + extension |
| 208 | ) |
| 209 | candidate = os.path.join(dir_path, filename) |
| 210 | |
| 211 | key = dir_path + filename |
| 212 | counter = sorted( |
| 213 | cache.get( |
| 214 | key, |
| 215 | { |
| 216 | 0, |
| 217 | }, |
| 218 | ) |
| 219 | )[-1] |
| 220 | while os.path.exists(candidate): |
| 221 | cache[key].add(counter) |
| 222 | counter += 1 |
| 223 | assert counter < max_suffix |
| 224 | candidate = os.path.join(dir_path, filename + ".{}".format(counter)) |
| 225 | return candidate |
| 226 | |
| 227 | |
| 228 | def escape_for_fnmatch(s): |
no test coverage detected