1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/moinformat/utils/directory.py Mon Jul 30 17:18:52 2018 +0200
1.3 @@ -0,0 +1,102 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +Directory context functionality.
1.8 +
1.9 +Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
1.10 +
1.11 +This program is free software; you can redistribute it and/or modify it under
1.12 +the terms of the GNU General Public License as published by the Free Software
1.13 +Foundation; either version 3 of the License, or (at your option) any later
1.14 +version.
1.15 +
1.16 +This program is distributed in the hope that it will be useful, but WITHOUT
1.17 +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.18 +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.19 +details.
1.20 +
1.21 +You should have received a copy of the GNU General Public License along with
1.22 +this program. If not, see <http://www.gnu.org/licenses/>.
1.23 +"""
1.24 +
1.25 +from glob import glob
1.26 +from os.path import abspath, commonprefix, exists, join
1.27 +
1.28 +# Get the directory with trailing path separator when assessing path prefixes
1.29 +# in order to prevent sibling directory confusion.
1.30 +
1.31 +def inside(filename, dirname):
1.32 +
1.33 + "Return whether 'filename' is inside 'dirname'."
1.34 +
1.35 + dirname = join(dirname, "")
1.36 + return commonprefix((filename, dirname)) == dirname
1.37 +
1.38 +def within(filename, dirname):
1.39 +
1.40 + "Return the part of 'filename' found within 'dirname'."
1.41 +
1.42 + dirname = join(dirname, "")
1.43 + prefix = commonprefix((filename, dirname))
1.44 +
1.45 + if prefix == dirname:
1.46 + return filename[len(prefix):]
1.47 + else:
1.48 + return None
1.49 +
1.50 +
1.51 +
1.52 +class Directory:
1.53 +
1.54 + "A directory abstraction."
1.55 +
1.56 + def __init__(self, filename):
1.57 +
1.58 + "Initialise the abstraction with the given 'filename'."
1.59 +
1.60 + self.filename = abspath(filename)
1.61 +
1.62 + def exists(self, filename):
1.63 +
1.64 + """
1.65 + Return whether 'filename' exists within the directory. This filename
1.66 + is relative to the directory.
1.67 + """
1.68 +
1.69 + return exists(self.get_filename(filename))
1.70 +
1.71 + def get_filename(self, filename):
1.72 +
1.73 + """
1.74 + Return the full path of a file with the given 'filename' found within
1.75 + the directory. The full path is an absolute path.
1.76 + """
1.77 +
1.78 + # Get the absolute path for the combination of directory and filename.
1.79 +
1.80 + pathname = abspath(join(self.filename, filename))
1.81 +
1.82 + if inside(pathname, self.filename):
1.83 + return pathname
1.84 + else:
1.85 + raise ValueError, filename
1.86 +
1.87 + def select_files(self, pattern):
1.88 +
1.89 + """
1.90 + Return a list of filenames found within the directory matching
1.91 + 'pattern'. These filenames are relative to the directory.
1.92 + """
1.93 +
1.94 + full_pattern = self.get_filename(pattern)
1.95 +
1.96 + filenames = []
1.97 +
1.98 + for filename in glob(full_pattern):
1.99 + filename = within(filename, self.filename)
1.100 + if filename:
1.101 + filenames.append(filename)
1.102 +
1.103 + return filenames
1.104 +
1.105 +# vim: tabstop=4 expandtab shiftwidth=4