imcflibs.pathtools

Helper functions to work with filenames, directories etc.

  1"""Helper functions to work with filenames, directories etc."""
  2
  3import os.path
  4import platform
  5from os import sep
  6
  7from . import strtools
  8from .log import LOG as log
  9
 10
 11def parse_path(path, prefix=""):
 12    r"""Parse a path into its components.
 13
 14    If the path doesn't end with the pathsep, it is assumed being a file!
 15    No tests based on existing files are done, as this is supposed to also work
 16    on path strings that don't exist on the system running this code.
 17
 18    The function accepts `java.io.File` objects (as retrieved by using ImageJ2's
 19    *Script Parameter* `#@ File`) for either of the parameters, so it is safe to
 20    use this in ImageJ Python scripts without additional measures.
 21
 22    Parameters
 23    ----------
 24    path : str or str-like
 25        The path to be parsed into components.
 26    prefix : str or str-like, optional
 27        An optional path component that will be prefixed to the given path using
 28        `os.path.join()`.
 29
 30    Returns
 31    -------
 32    dict
 33        The parsed (and possibly combined) path split into its components, with
 34        the following keys:
 35        - `orig` : The full string as passed into this function (possibly
 36          combined with the prefix in case one was specified).
 37        - `full` : The same as `orig` with separators adjusted to the current
 38          platform.
 39        - `path` : The same as `full`, up to (including) the last separator.
 40        - `dname` : The segment between the last two separators (directory).
 41        - `fname` : The segment after the last separator (filename).
 42        - `basename` : The filename without extension. Note that *OME-TIFF*
 43          files (having a suffix like `.ome.tif` or `.ome.tiff`) are treated as
 44          special case in the sense that the `.ome` part is also stripped from
 45          the basename and added to the `ext` key (see below).
 46        - `ext` : The filename extension, containing max 1 dot (included) with
 47          the special case of `.ome.tif` / `.ome.tiff` where 2 dots are
 48          contained to represent the full suffix.
 49
 50    Examples
 51    --------
 52
 53    POSIX-style path to a file with a suffix:
 54
 55    >>> parse_path('/tmp/foo/file.suffix')
 56    {'dname': 'foo',
 57     'ext': '',
 58     'fname': 'file',
 59     'full': '/tmp/foo/file',
 60     'basename': 'file',
 61     'orig': '/tmp/foo/file',
 62     'path': '/tmp/foo/'}
 63
 64    POSIX-style path to a directory:
 65
 66    >>> parse_path('/tmp/foo/')
 67    {'dname': 'foo',
 68     'ext': '',
 69     'fname': '',
 70     'full': '/tmp/foo/',
 71     'basename': '',
 72     'orig': '/tmp/foo/',
 73     'path': '/tmp/foo/'}
 74
 75    Windows-style path to a file:
 76
 77    >>> parse_path('C:\\Temp\\foo\\file.ext')
 78    {'dname': 'foo',
 79     'ext': '.ext',
 80     'fname': 'file.ext',
 81     'full': 'C:/Temp/foo/file.ext',
 82     'basename': 'file',
 83     'orig': 'C:\\Temp\\foo\\file.ext',
 84     'path': 'C:/Temp/foo/'}
 85
 86    Special treatment for *OME-TIFF* suffixes:
 87
 88    >>> parse_path("/path/to/some/nice.OME.tIf")
 89    {'basename': 'nice',
 90    'dname': 'some',
 91    'ext': '.OME.tIf',
 92    'fname': 'nice.OME.tIf',
 93    'full': '/path/to/some/nice.OME.tIf',
 94    'orig': '/path/to/some/nice.OME.tIf',
 95    'path': '/path/to/some/'}
 96    """
 97    path = str(path)
 98    if prefix:
 99        # remove leading slash, otherwise join() will discard the first path:
100        if path.startswith("/"):
101            path = path[1:]
102        path = os.path.join(str(prefix), path)
103    parsed = {}
104    parsed["orig"] = path
105    path = path.replace("\\", sep)
106    parsed["full"] = path
107    parsed["path"] = os.path.dirname(path) + sep
108    parsed["fname"] = os.path.basename(path)
109    parsed["dname"] = os.path.basename(os.path.dirname(parsed["path"]))
110    base, ext = os.path.splitext(parsed["fname"])
111    parsed["ext"] = ext
112    parsed["basename"] = base
113    if base.lower().endswith(".ome") and ext.lower().startswith(".tif"):
114        parsed["basename"] = base[:-4]
115        parsed["ext"] = base[-4:] + ext
116
117    return parsed
118
119
120def join2(path1, path2):
121    """Join two paths into one, much like os.path.join().
122
123    The main difference is that `join2()` takes exactly two arguments, but they
124    can be non-str (as long as they're having a `__str__()` method), so this is
125    safe to be used with stuff like `java.io.File` objects as retrieved when
126    using ImageJ2's *Script Parameter* `#@ File`.
127
128    In addition some sanitizing is done, e.g. in case one of the components is
129    containing double backslashes (`\\`), they will be replaced by the current
130    OS's path separator.
131
132    Parameters
133    ----------
134    path1 : str or str-like
135        The first component of the path to be joined.
136    path2 : str or str-like
137        The second component of the path to be joined.
138
139    Returns
140    -------
141    str
142    """
143    return parse_path(path2, prefix=path1)["full"]
144
145
146def jython_fiji_exists(path):
147    """Wrapper to work around problems with Jython 2.7 in Fiji.
148
149    In current Fiji, the Jython implementation of os.path.exists(path) raises a
150    java.lang.AbstractMethodError iff 'path' doesn't exist. This function
151    catches the exception to allow normal usage of the exists() call.
152    """
153    try:
154        return os.path.exists(path)
155    except java.lang.AbstractMethodError:
156        return False
157
158
159def listdir_matching(path, suffix, fullpath=False, sort=False):
160    """Get a list of files in a directory matching a given suffix.
161
162    Parameters
163    ----------
164    path : str
165        The directory to scan for files.
166    suffix : str
167        The suffix to match filenames against.
168    fullpath : bool, optional
169        If set to True, the list returned by the function will contain the full
170        paths to the matching files (the default is False, which will result in
171        the file names only, without path).
172    sort : bool, optional
173        If set to True, the returned list will be sorted using
174        `imcflibs.strtools.sort_alphanumerically()`.
175
176    Returns
177    -------
178    list
179        All file names in the directory matching the suffix (without path!).
180    """
181    matching_files = list()
182    for candidate in os.listdir(path):
183        if candidate.lower().endswith(suffix.lower()):
184            # log.debug("Found file %s", candidate)
185            if fullpath:
186                matching_files.append(os.path.join(path, candidate))
187            else:
188                matching_files.append(candidate)
189
190    if sort:
191        matching_files = strtools.sort_alphanumerically(matching_files)
192
193    return matching_files
194
195
196def image_basename(orig_name):
197    """Return the file name component without suffix(es).
198
199    Strip away the path and suffix of a given file name, doing a special
200    treatment for the composite suffix ".ome.tif(f)" which will be fully
201    stripped as well.
202
203    Parameters
204    ----------
205    orig_name : str
206
207    Examples
208    --------
209    >>> image_basename('/path/to/some_funny_image_file_01.png')
210    'some_funny_image_file_01'
211
212    >>> image_basename('some-more-complex-stack.ome.tif')
213    'some-more-complex-stack'
214
215    >>> image_basename('/tmp/FoObAr.OMe.tIf')
216    'FoObAr'
217    """
218    return parse_path(orig_name)["basename"]
219
220
221def gen_name_from_orig(path, orig_name, tag, suffix):
222    """Derive a file name from a given input file, an optional tag and a suffix.
223
224    Parameters
225    ----------
226    path : str or object that can be cast to a str
227        The output path.
228    orig_name : str or object that can be cast to a str
229        The input file name, may contain arbitrary path components.
230    tag : str
231        An optional tag to be added at the end of the new file name, can be used
232        to denote information like "-avg" for an average projection image.
233    suffix : str
234        The new file name suffix, which also sets the file format for BF.
235
236    Returns
237    -------
238    out_file : str
239        The newly generated file name with its full path.
240    """
241    name = os.path.join(path, image_basename(orig_name) + tag + suffix)
242    return name
243
244
245def derive_out_dir(in_dir, out_dir):
246    """Derive `out_dir` from its own value and the value of `in_dir`.
247
248    In case the supplied value of `out_dir` is one of '-' or 'NONE', the
249    returned value will be set to `in_dir`. Otherwise the value of `out_dir`
250    will be returned unchanged.
251
252    Parameters
253    ----------
254    in_dir : str
255        The full path to the input directory.
256    out_dir : str
257        Either the full path to an output directory or one of '-' or 'NONE'.
258
259    Returns
260    -------
261    str
262        The full path to the directory to be used for output and temp files.
263    """
264    if out_dir.upper() in ["-", "NONE"]:
265        out_dir = in_dir
266        log.info("No output directory given, using input dir [%s].", out_dir)
267    else:
268        log.info("Using directory [%s] for results and temp files.", out_dir)
269
270    return out_dir
271
272
273def find_dirs_containing_filetype(source, filetype):
274    """Recursively list directories containing files with a given suffix.
275
276    Parameters
277    ----------
278    source : str
279        Path to base directory to start recursive search in.
280    filetype : str
281        Filetype (string pattern) that should be matched against filenames in
282        the directories.
283
284    Returns
285    -------
286    list(str)
287        List of all dirs that contain files with the given suffix / filetype.
288    """
289    dirs_containing_filetype = []
290
291    # walk recursively through all directories
292    # list their paths and all files inside (=os.walk)
293    for dirname, _, filenames in os.walk(source):
294        # stop when encountering a directory that contains "filetype"
295        # and store the directory path
296        for filename in filenames:
297            if filetype in filename:
298                dirs_containing_filetype.append(dirname + "/")
299                break
300
301    return dirs_containing_filetype
302
303
304def folder_size(source):
305    """Get the total size of a given directory and its subdirectories.
306
307    Parameters
308    ----------
309    source : str
310        Directory for which the size should be determined.
311
312    Returns
313    -------
314    int
315        The total size of all files in the source dir and subdirs in bytes.
316    """
317    total_size = 0
318    for dirpath, _, filenames in os.walk(source):
319        for fname in filenames:
320            fpath = os.path.join(dirpath, fname)
321            # skip if it is symbolic link
322            if not os.path.islink(fpath):
323                total_size += os.path.getsize(fpath)
324
325    return total_size
326
327
328# pylint: disable-msg=C0103
329#   we use the variable name 'exists' in its common spelling (lowercase), so
330#   removing this workaround will be straightforward at a later point
331if platform.python_implementation() == "Jython":
332    # pylint: disable-msg=F0401
333    #   java.lang is only importable within Jython, pylint would complain
334    import java.lang
335
336    exists = jython_fiji_exists
337else:
338    exists = os.path.exists
def parse_path(path, prefix=''):
 12def parse_path(path, prefix=""):
 13    r"""Parse a path into its components.
 14
 15    If the path doesn't end with the pathsep, it is assumed being a file!
 16    No tests based on existing files are done, as this is supposed to also work
 17    on path strings that don't exist on the system running this code.
 18
 19    The function accepts `java.io.File` objects (as retrieved by using ImageJ2's
 20    *Script Parameter* `#@ File`) for either of the parameters, so it is safe to
 21    use this in ImageJ Python scripts without additional measures.
 22
 23    Parameters
 24    ----------
 25    path : str or str-like
 26        The path to be parsed into components.
 27    prefix : str or str-like, optional
 28        An optional path component that will be prefixed to the given path using
 29        `os.path.join()`.
 30
 31    Returns
 32    -------
 33    dict
 34        The parsed (and possibly combined) path split into its components, with
 35        the following keys:
 36        - `orig` : The full string as passed into this function (possibly
 37          combined with the prefix in case one was specified).
 38        - `full` : The same as `orig` with separators adjusted to the current
 39          platform.
 40        - `path` : The same as `full`, up to (including) the last separator.
 41        - `dname` : The segment between the last two separators (directory).
 42        - `fname` : The segment after the last separator (filename).
 43        - `basename` : The filename without extension. Note that *OME-TIFF*
 44          files (having a suffix like `.ome.tif` or `.ome.tiff`) are treated as
 45          special case in the sense that the `.ome` part is also stripped from
 46          the basename and added to the `ext` key (see below).
 47        - `ext` : The filename extension, containing max 1 dot (included) with
 48          the special case of `.ome.tif` / `.ome.tiff` where 2 dots are
 49          contained to represent the full suffix.
 50
 51    Examples
 52    --------
 53
 54    POSIX-style path to a file with a suffix:
 55
 56    >>> parse_path('/tmp/foo/file.suffix')
 57    {'dname': 'foo',
 58     'ext': '',
 59     'fname': 'file',
 60     'full': '/tmp/foo/file',
 61     'basename': 'file',
 62     'orig': '/tmp/foo/file',
 63     'path': '/tmp/foo/'}
 64
 65    POSIX-style path to a directory:
 66
 67    >>> parse_path('/tmp/foo/')
 68    {'dname': 'foo',
 69     'ext': '',
 70     'fname': '',
 71     'full': '/tmp/foo/',
 72     'basename': '',
 73     'orig': '/tmp/foo/',
 74     'path': '/tmp/foo/'}
 75
 76    Windows-style path to a file:
 77
 78    >>> parse_path('C:\\Temp\\foo\\file.ext')
 79    {'dname': 'foo',
 80     'ext': '.ext',
 81     'fname': 'file.ext',
 82     'full': 'C:/Temp/foo/file.ext',
 83     'basename': 'file',
 84     'orig': 'C:\\Temp\\foo\\file.ext',
 85     'path': 'C:/Temp/foo/'}
 86
 87    Special treatment for *OME-TIFF* suffixes:
 88
 89    >>> parse_path("/path/to/some/nice.OME.tIf")
 90    {'basename': 'nice',
 91    'dname': 'some',
 92    'ext': '.OME.tIf',
 93    'fname': 'nice.OME.tIf',
 94    'full': '/path/to/some/nice.OME.tIf',
 95    'orig': '/path/to/some/nice.OME.tIf',
 96    'path': '/path/to/some/'}
 97    """
 98    path = str(path)
 99    if prefix:
100        # remove leading slash, otherwise join() will discard the first path:
101        if path.startswith("/"):
102            path = path[1:]
103        path = os.path.join(str(prefix), path)
104    parsed = {}
105    parsed["orig"] = path
106    path = path.replace("\\", sep)
107    parsed["full"] = path
108    parsed["path"] = os.path.dirname(path) + sep
109    parsed["fname"] = os.path.basename(path)
110    parsed["dname"] = os.path.basename(os.path.dirname(parsed["path"]))
111    base, ext = os.path.splitext(parsed["fname"])
112    parsed["ext"] = ext
113    parsed["basename"] = base
114    if base.lower().endswith(".ome") and ext.lower().startswith(".tif"):
115        parsed["basename"] = base[:-4]
116        parsed["ext"] = base[-4:] + ext
117
118    return parsed

Parse a path into its components.

If the path doesn't end with the pathsep, it is assumed being a file! No tests based on existing files are done, as this is supposed to also work on path strings that don't exist on the system running this code.

The function accepts java.io.File objects (as retrieved by using ImageJ2's Script Parameter #@ File) for either of the parameters, so it is safe to use this in ImageJ Python scripts without additional measures.

Parameters
  • path (str or str-like): The path to be parsed into components.
  • prefix (str or str-like, optional): An optional path component that will be prefixed to the given path using os.path.join().
Returns
  • dict: The parsed (and possibly combined) path split into its components, with the following keys:
    • orig : The full string as passed into this function (possibly combined with the prefix in case one was specified).
    • full : The same as orig with separators adjusted to the current platform.
    • path : The same as full, up to (including) the last separator.
    • dname : The segment between the last two separators (directory).
    • fname : The segment after the last separator (filename).
    • basename : The filename without extension. Note that OME-TIFF files (having a suffix like .ome.tif or .ome.tiff) are treated as special case in the sense that the .ome part is also stripped from the basename and added to the ext key (see below).
    • ext : The filename extension, containing max 1 dot (included) with the special case of .ome.tif / .ome.tiff where 2 dots are contained to represent the full suffix.
Examples

POSIX-style path to a file with a suffix:

>>> parse_path('/tmp/foo/file.suffix')
{'dname': 'foo',
 'ext': '',
 'fname': 'file',
 'full': '/tmp/foo/file',
 'basename': 'file',
 'orig': '/tmp/foo/file',
 'path': '/tmp/foo/'}

POSIX-style path to a directory:

>>> parse_path('/tmp/foo/')
{'dname': 'foo',
 'ext': '',
 'fname': '',
 'full': '/tmp/foo/',
 'basename': '',
 'orig': '/tmp/foo/',
 'path': '/tmp/foo/'}

Windows-style path to a file:

>>> parse_path('C:\\Temp\\foo\\file.ext')
{'dname': 'foo',
 'ext': '.ext',
 'fname': 'file.ext',
 'full': 'C:/Temp/foo/file.ext',
 'basename': 'file',
 'orig': 'C:\\Temp\\foo\\file.ext',
 'path': 'C:/Temp/foo/'}

Special treatment for OME-TIFF suffixes:

>>> parse_path("/path/to/some/nice.OME.tIf")
{'basename': 'nice',
'dname': 'some',
'ext': '.OME.tIf',
'fname': 'nice.OME.tIf',
'full': '/path/to/some/nice.OME.tIf',
'orig': '/path/to/some/nice.OME.tIf',
'path': '/path/to/some/'}
def join2(path1, path2):
121def join2(path1, path2):
122    """Join two paths into one, much like os.path.join().
123
124    The main difference is that `join2()` takes exactly two arguments, but they
125    can be non-str (as long as they're having a `__str__()` method), so this is
126    safe to be used with stuff like `java.io.File` objects as retrieved when
127    using ImageJ2's *Script Parameter* `#@ File`.
128
129    In addition some sanitizing is done, e.g. in case one of the components is
130    containing double backslashes (`\\`), they will be replaced by the current
131    OS's path separator.
132
133    Parameters
134    ----------
135    path1 : str or str-like
136        The first component of the path to be joined.
137    path2 : str or str-like
138        The second component of the path to be joined.
139
140    Returns
141    -------
142    str
143    """
144    return parse_path(path2, prefix=path1)["full"]

Join two paths into one, much like os.path.join().

The main difference is that join2() takes exactly two arguments, but they can be non-str (as long as they're having a __str__() method), so this is safe to be used with stuff like java.io.File objects as retrieved when using ImageJ2's Script Parameter #@ File.

In addition some sanitizing is done, e.g. in case one of the components is containing double backslashes (\), they will be replaced by the current OS's path separator.

Parameters
  • path1 (str or str-like): The first component of the path to be joined.
  • path2 (str or str-like): The second component of the path to be joined.
Returns
  • str
def jython_fiji_exists(path):
147def jython_fiji_exists(path):
148    """Wrapper to work around problems with Jython 2.7 in Fiji.
149
150    In current Fiji, the Jython implementation of os.path.exists(path) raises a
151    java.lang.AbstractMethodError iff 'path' doesn't exist. This function
152    catches the exception to allow normal usage of the exists() call.
153    """
154    try:
155        return os.path.exists(path)
156    except java.lang.AbstractMethodError:
157        return False

Wrapper to work around problems with Jython 2.7 in Fiji.

In current Fiji, the Jython implementation of os.path.exists(path) raises a java.lang.AbstractMethodError iff 'path' doesn't exist. This function catches the exception to allow normal usage of the exists() call.

def listdir_matching(path, suffix, fullpath=False, sort=False):
160def listdir_matching(path, suffix, fullpath=False, sort=False):
161    """Get a list of files in a directory matching a given suffix.
162
163    Parameters
164    ----------
165    path : str
166        The directory to scan for files.
167    suffix : str
168        The suffix to match filenames against.
169    fullpath : bool, optional
170        If set to True, the list returned by the function will contain the full
171        paths to the matching files (the default is False, which will result in
172        the file names only, without path).
173    sort : bool, optional
174        If set to True, the returned list will be sorted using
175        `imcflibs.strtools.sort_alphanumerically()`.
176
177    Returns
178    -------
179    list
180        All file names in the directory matching the suffix (without path!).
181    """
182    matching_files = list()
183    for candidate in os.listdir(path):
184        if candidate.lower().endswith(suffix.lower()):
185            # log.debug("Found file %s", candidate)
186            if fullpath:
187                matching_files.append(os.path.join(path, candidate))
188            else:
189                matching_files.append(candidate)
190
191    if sort:
192        matching_files = strtools.sort_alphanumerically(matching_files)
193
194    return matching_files

Get a list of files in a directory matching a given suffix.

Parameters
  • path (str): The directory to scan for files.
  • suffix (str): The suffix to match filenames against.
  • fullpath (bool, optional): If set to True, the list returned by the function will contain the full paths to the matching files (the default is False, which will result in the file names only, without path).
  • sort (bool, optional): If set to True, the returned list will be sorted using imcflibs.strtools.sort_alphanumerically().
Returns
  • list: All file names in the directory matching the suffix (without path!).
def image_basename(orig_name):
197def image_basename(orig_name):
198    """Return the file name component without suffix(es).
199
200    Strip away the path and suffix of a given file name, doing a special
201    treatment for the composite suffix ".ome.tif(f)" which will be fully
202    stripped as well.
203
204    Parameters
205    ----------
206    orig_name : str
207
208    Examples
209    --------
210    >>> image_basename('/path/to/some_funny_image_file_01.png')
211    'some_funny_image_file_01'
212
213    >>> image_basename('some-more-complex-stack.ome.tif')
214    'some-more-complex-stack'
215
216    >>> image_basename('/tmp/FoObAr.OMe.tIf')
217    'FoObAr'
218    """
219    return parse_path(orig_name)["basename"]

Return the file name component without suffix(es).

Strip away the path and suffix of a given file name, doing a special treatment for the composite suffix ".ome.tif(f)" which will be fully stripped as well.

Parameters
  • orig_name (str):
Examples
>>> image_basename('/path/to/some_funny_image_file_01.png')
'some_funny_image_file_01'
>>> image_basename('some-more-complex-stack.ome.tif')
'some-more-complex-stack'
>>> image_basename('/tmp/FoObAr.OMe.tIf')
'FoObAr'
def gen_name_from_orig(path, orig_name, tag, suffix):
222def gen_name_from_orig(path, orig_name, tag, suffix):
223    """Derive a file name from a given input file, an optional tag and a suffix.
224
225    Parameters
226    ----------
227    path : str or object that can be cast to a str
228        The output path.
229    orig_name : str or object that can be cast to a str
230        The input file name, may contain arbitrary path components.
231    tag : str
232        An optional tag to be added at the end of the new file name, can be used
233        to denote information like "-avg" for an average projection image.
234    suffix : str
235        The new file name suffix, which also sets the file format for BF.
236
237    Returns
238    -------
239    out_file : str
240        The newly generated file name with its full path.
241    """
242    name = os.path.join(path, image_basename(orig_name) + tag + suffix)
243    return name

Derive a file name from a given input file, an optional tag and a suffix.

Parameters
  • path (str or object that can be cast to a str): The output path.
  • orig_name (str or object that can be cast to a str): The input file name, may contain arbitrary path components.
  • tag (str): An optional tag to be added at the end of the new file name, can be used to denote information like "-avg" for an average projection image.
  • suffix (str): The new file name suffix, which also sets the file format for BF.
Returns
  • out_file (str): The newly generated file name with its full path.
def derive_out_dir(in_dir, out_dir):
246def derive_out_dir(in_dir, out_dir):
247    """Derive `out_dir` from its own value and the value of `in_dir`.
248
249    In case the supplied value of `out_dir` is one of '-' or 'NONE', the
250    returned value will be set to `in_dir`. Otherwise the value of `out_dir`
251    will be returned unchanged.
252
253    Parameters
254    ----------
255    in_dir : str
256        The full path to the input directory.
257    out_dir : str
258        Either the full path to an output directory or one of '-' or 'NONE'.
259
260    Returns
261    -------
262    str
263        The full path to the directory to be used for output and temp files.
264    """
265    if out_dir.upper() in ["-", "NONE"]:
266        out_dir = in_dir
267        log.info("No output directory given, using input dir [%s].", out_dir)
268    else:
269        log.info("Using directory [%s] for results and temp files.", out_dir)
270
271    return out_dir

Derive out_dir from its own value and the value of in_dir.

In case the supplied value of out_dir is one of '-' or 'NONE', the returned value will be set to in_dir. Otherwise the value of out_dir will be returned unchanged.

Parameters
  • in_dir (str): The full path to the input directory.
  • out_dir (str): Either the full path to an output directory or one of '-' or 'NONE'.
Returns
  • str: The full path to the directory to be used for output and temp files.
def find_dirs_containing_filetype(source, filetype):
274def find_dirs_containing_filetype(source, filetype):
275    """Recursively list directories containing files with a given suffix.
276
277    Parameters
278    ----------
279    source : str
280        Path to base directory to start recursive search in.
281    filetype : str
282        Filetype (string pattern) that should be matched against filenames in
283        the directories.
284
285    Returns
286    -------
287    list(str)
288        List of all dirs that contain files with the given suffix / filetype.
289    """
290    dirs_containing_filetype = []
291
292    # walk recursively through all directories
293    # list their paths and all files inside (=os.walk)
294    for dirname, _, filenames in os.walk(source):
295        # stop when encountering a directory that contains "filetype"
296        # and store the directory path
297        for filename in filenames:
298            if filetype in filename:
299                dirs_containing_filetype.append(dirname + "/")
300                break
301
302    return dirs_containing_filetype

Recursively list directories containing files with a given suffix.

Parameters
  • source (str): Path to base directory to start recursive search in.
  • filetype (str): Filetype (string pattern) that should be matched against filenames in the directories.
Returns
  • list(str): List of all dirs that contain files with the given suffix / filetype.
def folder_size(source):
305def folder_size(source):
306    """Get the total size of a given directory and its subdirectories.
307
308    Parameters
309    ----------
310    source : str
311        Directory for which the size should be determined.
312
313    Returns
314    -------
315    int
316        The total size of all files in the source dir and subdirs in bytes.
317    """
318    total_size = 0
319    for dirpath, _, filenames in os.walk(source):
320        for fname in filenames:
321            fpath = os.path.join(dirpath, fname)
322            # skip if it is symbolic link
323            if not os.path.islink(fpath):
324                total_size += os.path.getsize(fpath)
325
326    return total_size

Get the total size of a given directory and its subdirectories.

Parameters
  • source (str): Directory for which the size should be determined.
Returns
  • int: The total size of all files in the source dir and subdirs in bytes.