Source code for dirops_mod
"""Module of one function: my_mkdir,which creates directories as needed."""
import os
import re
import errno
import constants_mod
import helpers
[docs]class ExistingDirs(object):
"""Keep track of directories seen recently, that we know (pre)exist."""
def __init__(self):
"""Initialize."""
self.dirs = []
self.count = 0
self.limit_list = 100
[docs] def add(self, path):
"""Add path to list of dirs, keeping only the last self.limit_list entries."""
if path in self.dirs:
self.dirs.remove(path)
self.dirs.append(path)
self.count = self.count + 1
if self.count >= self.limit_list:
self.dirs = self.dirs[-self.limit_list:]
[docs] def exists(self, path):
"""Test if a path is known to exist."""
result = path in self.dirs
return result
EXISTINGDIRS = ExistingDirs()
[docs]def my_mkdir(pathname):
"""
Create one or more directories specified by directory_list.
If pathname has [ 'a', 'b', 'c' ], then we create a/b/c.
If pathname has 'a/b/c' then we create a/b/c
"""
bytes_path_sep = helpers.string_to_binary(os.path.sep)
if isinstance(pathname, str):
complete_relative_path = helpers.string_to_binary(pathname)
directory_list = helpers.string_to_binary(pathname).split(bytes_path_sep)
elif isinstance(pathname, bytes):
# Sometimes this'll be str - handled above
complete_relative_path = pathname
directory_list = pathname.split(bytes_path_sep)
elif isinstance(pathname, list):
complete_relative_path = os.path.join(*pathname)
directory_list = pathname
else:
raise ValueError('pathname is not str, bytes or list')
if EXISTINGDIRS.exists(complete_relative_path):
return
if os.path.isdir(complete_relative_path):
EXISTINGDIRS.add(complete_relative_path)
return
for final_position in range(1, len(directory_list) + 1):
partial_relative_slice = directory_list[:final_position]
partial_relative_path = os.path.join(*partial_relative_slice)
if EXISTINGDIRS.exists(partial_relative_path):
continue
try:
os.mkdir(partial_relative_path, 7 * 64 + 5 * 8 + 5)
EXISTINGDIRS.add(partial_relative_path)
except OSError as mkdir_extra:
if mkdir_extra.errno == errno.EEXIST:
EXISTINGDIRS.add(partial_relative_path)
continue
else:
raise
[docs]def prepend_dirs(path):
"""Take a relative path and add dir- prefixes to all the directories."""
path_parts, filename = get_path_parts(path)
directories = path_parts[:]
# filename is a directory too in this case
directories.append(filename)
nonempty_directories = [directory for directory in directories if directory and directory != constants_mod.Constants.b_dot]
dired_directories = ['dir-%s' % helpers.binary_to_string(directory) for directory in nonempty_directories]
if not dired_directories:
dired_directories = ['.']
result = os.path.join(*dired_directories)
return result
[docs]def strip_dirs(pathname):
"""Strip off all the dir- prefixes."""
path1 = re.sub(constants_mod.Constants.b_slash_dir_dash, constants_mod.Constants.b_slash, helpers.string_to_binary(pathname))
path2 = re.sub(constants_mod.Constants.b_hat_dot_slash, helpers.empty_bytes, path1)
path3 = re.sub(constants_mod.Constants.b_hat_dir_dash, helpers.empty_bytes, path2)
return path3
[docs]def get_path_parts(relative_path):
"""Chop a (directory-containing) pathname into the directory leading up to it (dirname), and its final part (basename)."""
if isinstance(relative_path, list):
path_components = relative_path
else:
bin_rel_path = helpers.string_to_binary(relative_path)
bin_sep = helpers.string_to_binary(os.path.sep)
path_components = bin_rel_path.split(bin_sep)
nonempty_path_components = [component for component in path_components if component != helpers.empty_bytes]
relative_directories = nonempty_path_components[:-1]
if nonempty_path_components:
filename = nonempty_path_components[-1]
else:
filename = helpers.string_to_binary(os.path.sep)
return (relative_directories, filename)