def findSequencesOnDisk(cls, dirpath, include_hidden=False): """ Yield the sequences found in the given directory. :param dirpath: directory to scan :type include_hidden: bool :param include_hidden: if true, show .hidden files as well :rtype: list """ # reserve some functions we're going to need quick access to _not_hidden = lambda f: not f.startswith('.') _join = os.path.join # Get just the immediate files under the dir. # Avoids testing the os.listdir() for files as # a second step. ret = next(os.walk(dirpath), None) files = ret[-1] if ret else [] # collapse some generators to get us the files that match our regex if not include_hidden: files = ifilter(_not_hidden, files) # Ensure our dirpath ends with a path separator, so # that we can control which sep is used during the # os.path.join sep = utils._getPathSep(dirpath) if not dirpath.endswith(sep): dirpath += sep files = (_join(dirpath, f) for f in files) files = list(files) return list(FileSequence.yield_sequences_in_list(files))
def setDirname(self, dirname): """ Set a new directory name for the sequence. Args: dirname (str): the new directory name """ # Make sure the dirname always ends in # a path separator character sep = utils._getPathSep(dirname) if not dirname.endswith(sep): dirname += sep self._dir = utils.asString(dirname)
def setDirname(self, dirname): """ Set a new directory name for the sequence. :type dirname: str :param dirname: the new directory name :rtype: None """ # Make sure the dirname always ends in # a path separator character sep = utils._getPathSep(dirname) if not dirname.endswith(sep): dirname += sep self._dir = utils.asString(dirname)
def setDirname(self, dirname): """ Set a new directory name for the sequence. Args: dirname (str): the new directory name """ # Make sure the dirname always ends in # a path separator character dirname = utils.asString(dirname) sep = utils._getPathSep(dirname) if not dirname.endswith(sep): dirname += sep self._dir = dirname
def __init__(self, sequence): if not hasattr(self, '_frameSet'): self._frameSet = None try: # the main case, padding characters in the path.1-100#.exr path, frames, self._pad, self._ext = SPLIT_RE.split( sequence, 1) self._dir, self._base = os.path.split(path) self._frameSet = FrameSet(frames) except ValueError: # edge case 1; we've got an invalid pad for placeholder in PAD_MAP.keys(): if placeholder in sequence: msg = "Failed to parse FileSequence: {0}" raise ParseException(msg.format(sequence)) # edge case 2; we've got a single frame of a sequence a_frame = DISK_RE.match(sequence) if a_frame: self._dir, self._base, frames, self._ext = a_frame.groups() # edge case 3: we've got a single versioned file, not a sequence if frames and not self._base.endswith('.'): self._base = self._base + frames self._pad = '' elif not frames: self._pad = '' self._frameSet = None else: self._frameSet = FrameSet(frames) if self._frameSet: self._pad = FileSequence.getPaddingChars( len(frames)) else: self._pad = '' self._frameSet = None # edge case 4; we've got a solitary file, not a sequence else: path, self._ext = os.path.splitext(sequence) self._dir, self._base = os.path.split(path) self._pad = '' if self._dir: sep = utils._getPathSep(sequence) if not self._dir.endswith(sep): self._dir += sep self._zfill = self.__class__.getPaddingNum(self._pad)
def findSequencesOnDisk(cls, pattern, include_hidden=False, strictPadding=False): """ Yield the sequences found in the given directory. Example:: findSequencesOnDisk('/path/to/files') The pattern can also specify glob-like shell wildcards including the following: ? - 1 wildcard character * - 1 or more wildcard character {foo,bar} - either 'foo' or 'bar' Exact frame ranges are not considered, and padding characters are converted to wildcards (# or @) Example:: findSequencesOnDisk('/path/to/files/image_stereo_{left,right}.#.jpg') findSequencesOnDisk('/path/to/files/imag?_*_{left,right}.@@@.jpg', strictPadding=True) :param pattern: directory to scan, or pattern to filter in directory :type include_hidden: bool :param include_hidden: if true, show .hidden files as well :type strictPadding: bool :param strictPadding: if True, ignore files with padding length different from pattern :rtype: list """ # reserve some functions we're going to need quick access to _not_hidden = lambda f: not f.startswith('.') _match_pattern = None _filter_padding = None _join = os.path.join dirpath, filepat = pattern, None # Support the pattern defining a filter for the files # in the existing directory if not os.path.isdir(pattern): dirpath, filepat = os.path.split(pattern) if not os.path.isdir(dirpath): return [] # Start building a regex for filtering files seq = cls(filepat) patt = seq.basename().replace('.', r'\.') if seq.padding(): patt += '\d+' if seq.extension(): patt += seq.extension() # Convert braces groups into regex capture groups view = bytearray(patt) matches = re.finditer(r'{(.*?)(?:,(.*?))*}', patt) for match in reversed(list(matches)): i, j = match.span() view[i:j] = '(%s)' % '|'.join([m.strip() for m in match.groups()]) view = view.replace('*', '.*') view = view.replace('?', '.') view += '$' try: _match_pattern = re.compile(str(view)).match except re.error: msg = 'Invalid file pattern: {}'.format(filepat) raise FileSeqException(msg) if seq.padding() and strictPadding: _filter_padding = functools.partial(cls._filterByPaddingNum, num=seq.zfill()) # Get just the immediate files under the dir. # Avoids testing the os.listdir() for files as # a second step. ret = next(os.walk(dirpath), None) files = ret[-1] if ret else [] # collapse some generators to get us the files that match our regex if not include_hidden: files = ifilter(_not_hidden, files) # Filter by files that match the provided file pattern if _match_pattern: files = ifilter(_match_pattern, files) # Filter by files that match the frame padding in the file pattern if _filter_padding: # returns a generator files = _filter_padding(files) # Ensure our dirpath ends with a path separator, so # that we can control which sep is used during the # os.path.join sep = utils._getPathSep(dirpath) if not dirpath.endswith(sep): dirpath += sep files = (_join(dirpath, f) for f in files) files = list(files) return list(FileSequence.yield_sequences_in_list(files))
def findSequencesOnDisk(cls, pattern, include_hidden=False, strictPadding=False, pad_style=PAD_STYLE_DEFAULT, allow_subframes=False): """ Yield the sequences found in the given directory. Examples:: FileSequence.findSequencesOnDisk('/path/to/files') The `pattern` can also specify glob-like shell wildcards including the following: * ``?`` - 1 wildcard character * ``*`` - 1 or more wildcard character * ``{foo,bar}`` - either 'foo' or 'bar' Exact frame ranges are not considered, and padding characters are converted to wildcards (``#`` or ``@``) Examples:: FileSequence.findSequencesOnDisk('/path/to/files/image_stereo_{left,right}.#.jpg') FileSequence.findSequencesOnDisk('/path/to/files/imag?_*_{left,right}.@@@.jpg', strictPadding=True) Args: pattern (str): directory to scan, or pattern to filter in directory include_hidden (bool): if true, show .hidden files as well strictPadding (bool): if True, ignore files with padding length different from pattern pad_style (`.PAD_STYLE_DEFAULT` or `.PAD_STYLE_HASH1` or `.PAD_STYLE_HASH4`): padding style allow_subframes (bool): if True, handle subframe filenames Returns: list: """ # reserve some functions we're going to need quick access to _not_hidden = lambda f: not f.startswith('.') _match_pattern = None _filter_padding = None _join = os.path.join seq = None dirpath = pattern # Support the pattern defining a filter for the files # in the existing directory if not os.path.isdir(pattern): dirpath, filepat = os.path.split(pattern) if not os.path.isdir(dirpath): return [] # Start building a regex for filtering files seq = cls(filepat, pad_style=pad_style, allow_subframes=allow_subframes) patt = r'\A' patt += cls._globCharsToRegex(seq.basename()) if seq.padding(): patt += '(' if seq.framePadding(): patt += r'\d+' if seq.subframePadding(): patt += r'\.\d+' patt += ')' if seq.extension(): patt += cls._globCharsToRegex(seq.extension()) # Convert braces groups into regex capture groups matches = re.finditer(r'{(.*?)(?:,(.*?))*}', patt) for match in reversed(list(matches)): i, j = match.span() regex = '(?:%s)' % '|'.join( [m.strip() for m in match.groups()]) patt = "".join((patt[0:i], regex, patt[j:])) patt += r'\Z' try: _match_pattern = re.compile(patt).match except re.error: msg = 'Invalid file pattern: {!r}'.format(filepat) raise FileSeqException(msg) if seq.padding() and strictPadding: get_frame = lambda f: _match_pattern(f).group(1) _filter_padding = functools.partial( cls._filterByPaddingNum, zfill=seq.zfill(), decimal_places=seq.decimalPlaces(), get_frame=get_frame) # Get just the immediate files under the dir. # Avoids testing the os.listdir() for files as # a second step. ret = next(os.walk(dirpath), None) files = ret[-1] if ret else [] # collapse some generators to get us the files that match our regex if not include_hidden: files = filter(_not_hidden, files) # Filter by files that match the provided file pattern if _match_pattern: files = filter(_match_pattern, files) # Filter by files that match the frame padding in the file pattern if _filter_padding: # returns a generator files = _filter_padding(files) # Ensure our dirpath ends with a path separator, so # that we can control which sep is used during the # os.path.join sep = utils._getPathSep(dirpath) if not dirpath.endswith(sep): dirpath += sep files = [_join(dirpath, f) for f in files] seqs = list( cls.yield_sequences_in_list(files, pad_style=pad_style, allow_subframes=allow_subframes)) if _filter_padding and seq: frame_pad = cls.conformPadding(seq.framePadding(), pad_style=pad_style) subframe_pad = cls.conformPadding(seq.subframePadding(), pad_style=pad_style) # strict padding should preserve the original padding # characters in the found sequences. for s in seqs: s.setFramePadding(frame_pad) s.setSubframePadding(subframe_pad) return seqs
def findSequencesOnDisk(cls, pattern, include_hidden=False, strictPadding=False): """ Yield the sequences found in the given directory. Example:: findSequencesOnDisk('/path/to/files') The pattern can also specify glob-like shell wildcards including the following: ? - 1 wildcard character * - 1 or more wildcard character {foo,bar} - either 'foo' or 'bar' Exact frame ranges are not considered, and padding characters are converted to wildcards (# or @) Example:: findSequencesOnDisk('/path/to/files/image_stereo_{left,right}.#.jpg') findSequencesOnDisk('/path/to/files/imag?_*_{left,right}.@@@.jpg', strictPadding=True) :param pattern: directory to scan, or pattern to filter in directory :type include_hidden: bool :param include_hidden: if true, show .hidden files as well :type strictPadding: bool :param strictPadding: if True, ignore files with padding length different from pattern :rtype: list """ # reserve some functions we're going to need quick access to _not_hidden = lambda f: not f.startswith('.') _match_pattern = None _filter_padding = None _join = os.path.join dirpath, filepat = pattern, None # Support the pattern defining a filter for the files # in the existing directory if not os.path.isdir(pattern): dirpath, filepat = os.path.split(pattern) if not os.path.isdir(dirpath): return [] # Start building a regex for filtering files seq = cls(filepat) patt = seq.basename().replace('.', r'\.') if seq.padding(): patt += '\d+' if seq.extension(): patt += seq.extension() # Convert braces groups into regex capture groups view = bytearray(patt) matches = re.finditer(r'{(.*?)(?:,(.*?))*}', patt) for match in reversed(list(matches)): i, j = match.span() view[i:j] = '(%s)' % '|'.join( [m.strip() for m in match.groups()]) view = view.replace('*', '.*') view = view.replace('?', '.') view += '$' print(view) try: _match_pattern = re.compile(str(view)).match except re.error: msg = 'Invalid file pattern: {}'.format(filepat) raise FileSeqException(msg) if seq.padding() and strictPadding: _filter_padding = functools.partial(cls._filterByPaddingNum, num=seq.zfill()) # Get just the immediate files under the dir. # Avoids testing the os.listdir() for files as # a second step. ret = next(os.walk(dirpath), None) files = ret[-1] if ret else [] # collapse some generators to get us the files that match our regex if not include_hidden: files = filter(_not_hidden, files) # Filter by files that match the provided file pattern if _match_pattern: files = filter(_match_pattern, files) # Filter by files that match the frame padding in the file pattern if _filter_padding: # returns a generator files = _filter_padding(files) # Ensure our dirpath ends with a path separator, so # that we can control which sep is used during the # os.path.join sep = utils._getPathSep(dirpath) if not dirpath.endswith(sep): dirpath += sep files = (_join(dirpath, f) for f in files) files = list(files) return list(FileSequence.yield_sequences_in_list(files))