mirror of https://github.com/mahmoud/boltons.git
move osutils stuff into fileutils
This commit is contained in:
parent
f56aa8bf2b
commit
91e6f2e313
|
@ -1,9 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import re
|
||||
import stat
|
||||
import errno
|
||||
import fnmatch
|
||||
import tempfile
|
||||
from shutil import copy2, copystat, Error
|
||||
|
||||
|
||||
VALID_PERM_CHARS = 'rwx'
|
||||
|
||||
|
@ -157,13 +160,122 @@ class AtomicSaver(object):
|
|||
return
|
||||
|
||||
|
||||
#with atomic_save('/home/mahmoud/tmp/final.txt') as f:
|
||||
# f.write('rofl')
|
||||
# raise ValueError('nope')
|
||||
# f.write('\n')
|
||||
_CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def iter_find_files(directory, patterns, ignored=None):
|
||||
"""\
|
||||
Finds files under a `directory`, matching `patterns` using "glob"
|
||||
syntax (e.g., "*.txt"). It's also possible to ignore patterns with
|
||||
the `ignored` argument, which uses the same format as `patterns.
|
||||
|
||||
>>> filenames = sorted(iter_find_files(_CUR_DIR, '*.py'))
|
||||
>>> filenames[-1].split('/')[-1]
|
||||
'tzutils.py'
|
||||
>>> filenames = iter_find_files(_CUR_DIR, '*.py', ignored='.#*')
|
||||
|
||||
That last example ignores emacs lockfiles.
|
||||
"""
|
||||
if isinstance(patterns, basestring):
|
||||
patterns = [patterns]
|
||||
pats_re = re.compile('|'.join([fnmatch.translate(p) for p in patterns]))
|
||||
|
||||
if not ignored:
|
||||
ignored = []
|
||||
elif isinstance(ignored, basestring):
|
||||
ignored = [ignored]
|
||||
ign_re = re.compile('|'.join([fnmatch.translate(p) for p in ignored]))
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for basename in files:
|
||||
if pats_re.match(basename):
|
||||
if ignored and ign_re.match(basename):
|
||||
continue
|
||||
filename = os.path.join(root, basename)
|
||||
yield filename
|
||||
return
|
||||
|
||||
|
||||
def mkdir_p(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc:
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
return
|
||||
raise
|
||||
return
|
||||
|
||||
|
||||
def copytree(src, dst, symlinks=False, ignore=None):
|
||||
"""Recursively copy a directory tree using copy2().
|
||||
|
||||
The destination directory is allowed to already exist.
|
||||
If exception(s) occur, an Error is raised with a list of reasons.
|
||||
|
||||
If the optional symlinks flag is true, symbolic links in the
|
||||
source tree result in symbolic links in the destination tree; if
|
||||
it is false, the contents of the files pointed to by symbolic
|
||||
links are copied.
|
||||
|
||||
The optional ignore argument is a callable. If given, it
|
||||
is called with the `src` parameter, which is the directory
|
||||
being visited by copytree(), and `names` which is the list of
|
||||
`src` contents, as returned by os.listdir():
|
||||
|
||||
callable(src, names) -> ignored_names
|
||||
|
||||
Since copytree() is called recursively, the callable will be
|
||||
called once for each directory that is copied. It returns a
|
||||
list of names relative to the `src` directory that should
|
||||
not be copied.
|
||||
|
||||
XXX Consider this example code rather than the ultimate tool.
|
||||
|
||||
"""
|
||||
names = os.listdir(src)
|
||||
if ignore is not None:
|
||||
ignored_names = ignore(src, names)
|
||||
else:
|
||||
ignored_names = set()
|
||||
|
||||
mkdir_p(dst)
|
||||
errors = []
|
||||
for name in names:
|
||||
if name in ignored_names:
|
||||
continue
|
||||
srcname = os.path.join(src, name)
|
||||
dstname = os.path.join(dst, name)
|
||||
try:
|
||||
if symlinks and os.path.islink(srcname):
|
||||
linkto = os.readlink(srcname)
|
||||
os.symlink(linkto, dstname)
|
||||
elif os.path.isdir(srcname):
|
||||
copytree(srcname, dstname, symlinks, ignore)
|
||||
else:
|
||||
# Will raise a SpecialFileError for unsupported file types
|
||||
copy2(srcname, dstname)
|
||||
# catch the Error from the recursive copytree so that we can
|
||||
# continue with other files
|
||||
except Error as e:
|
||||
errors.extend(e.args[0])
|
||||
except EnvironmentError, why:
|
||||
errors.append((srcname, dstname, str(why)))
|
||||
try:
|
||||
copystat(src, dst)
|
||||
except OSError, why:
|
||||
if WindowsError is not None and isinstance(why, WindowsError):
|
||||
# Copying file access times may fail on Windows
|
||||
pass
|
||||
else:
|
||||
errors.append((src, dst, str(why)))
|
||||
if errors:
|
||||
raise Error(errors)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
#with atomic_save('/tmp/final.txt') as f:
|
||||
# f.write('rofl')
|
||||
# raise ValueError('nope')
|
||||
# f.write('\n')
|
||||
|
||||
def _main():
|
||||
up = FilePerms()
|
||||
|
|
|
@ -1,117 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import re
|
||||
import errno
|
||||
import fnmatch
|
||||
from shutil import copy2, copystat, Error
|
||||
|
||||
_CUR_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def iter_find_files(directory, patterns, ignored=None):
|
||||
"""\
|
||||
Finds files under a `directory`, matching `patterns` using "glob"
|
||||
syntax (e.g., "*.txt"). It's also possible to ignore patterns with
|
||||
the `ignored` argument, which uses the same format as `patterns.
|
||||
|
||||
>>> filenames = sorted(iter_find_files(_CUR_DIR, '*.py'))
|
||||
>>> filenames[-1].split('/')[-1]
|
||||
'tzutils.py'
|
||||
>>> filenames = iter_find_files(_CUR_DIR, '*.py', ignored='.#*')
|
||||
|
||||
That last example ignores emacs lockfiles.
|
||||
"""
|
||||
if isinstance(patterns, basestring):
|
||||
patterns = [patterns]
|
||||
pats_re = re.compile('|'.join([fnmatch.translate(p) for p in patterns]))
|
||||
|
||||
if not ignored:
|
||||
ignored = []
|
||||
elif isinstance(ignored, basestring):
|
||||
ignored = [ignored]
|
||||
ign_re = re.compile('|'.join([fnmatch.translate(p) for p in ignored]))
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for basename in files:
|
||||
if pats_re.match(basename):
|
||||
if ignored and ign_re.match(basename):
|
||||
continue
|
||||
filename = os.path.join(root, basename)
|
||||
yield filename
|
||||
return
|
||||
|
||||
|
||||
def mkdir_p(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc:
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
return
|
||||
raise
|
||||
return
|
||||
|
||||
|
||||
def copytree(src, dst, symlinks=False, ignore=None):
|
||||
"""Recursively copy a directory tree using copy2().
|
||||
|
||||
The destination directory is allowed to already exist.
|
||||
If exception(s) occur, an Error is raised with a list of reasons.
|
||||
|
||||
If the optional symlinks flag is true, symbolic links in the
|
||||
source tree result in symbolic links in the destination tree; if
|
||||
it is false, the contents of the files pointed to by symbolic
|
||||
links are copied.
|
||||
|
||||
The optional ignore argument is a callable. If given, it
|
||||
is called with the `src` parameter, which is the directory
|
||||
being visited by copytree(), and `names` which is the list of
|
||||
`src` contents, as returned by os.listdir():
|
||||
|
||||
callable(src, names) -> ignored_names
|
||||
|
||||
Since copytree() is called recursively, the callable will be
|
||||
called once for each directory that is copied. It returns a
|
||||
list of names relative to the `src` directory that should
|
||||
not be copied.
|
||||
|
||||
XXX Consider this example code rather than the ultimate tool.
|
||||
|
||||
"""
|
||||
names = os.listdir(src)
|
||||
if ignore is not None:
|
||||
ignored_names = ignore(src, names)
|
||||
else:
|
||||
ignored_names = set()
|
||||
|
||||
mkdir_p(dst)
|
||||
errors = []
|
||||
for name in names:
|
||||
if name in ignored_names:
|
||||
continue
|
||||
srcname = os.path.join(src, name)
|
||||
dstname = os.path.join(dst, name)
|
||||
try:
|
||||
if symlinks and os.path.islink(srcname):
|
||||
linkto = os.readlink(srcname)
|
||||
os.symlink(linkto, dstname)
|
||||
elif os.path.isdir(srcname):
|
||||
copytree(srcname, dstname, symlinks, ignore)
|
||||
else:
|
||||
# Will raise a SpecialFileError for unsupported file types
|
||||
copy2(srcname, dstname)
|
||||
# catch the Error from the recursive copytree so that we can
|
||||
# continue with other files
|
||||
except Error as e:
|
||||
errors.extend(e.args[0])
|
||||
except EnvironmentError, why:
|
||||
errors.append((srcname, dstname, str(why)))
|
||||
try:
|
||||
copystat(src, dst)
|
||||
except OSError, why:
|
||||
if WindowsError is not None and isinstance(why, WindowsError):
|
||||
# Copying file access times may fail on Windows
|
||||
pass
|
||||
else:
|
||||
errors.append((src, dst, str(why)))
|
||||
if errors:
|
||||
raise Error(errors)
|
||||
print 'Deprecation warning: the contents of osutils have moved to fileutils'
|
||||
from fileutils import *
|
||||
|
|
Loading…
Reference in New Issue