def framesToFrameRange(frames, sort=True, zfill=0, compress=False): """ Converts an iterator of frames into a :class:`fileseq.framerange.FrameRange`. :type frames: iterable :param frames: sequence of frames to process :type sort: bool :param sort: sort the sequence before processing :type zfill: int :param zfill: width for zero padding :type compress: bool :param compress: remove any duplicates before processing :rtype: str """ if compress: frames = unique(set(), frames) frames = list(frames) if not frames: return '' if len(frames) == 1: return pad(frames[0], zfill) if sort: frames.sort() return ','.join(FrameSet.framesToFrameRanges(frames, zfill))
def framesToFrameRange(frames, sort=True, zfill=0, compress=False): """ Converts an iterator of frames into a frame range string. Args: frames (collections.Iterable): sequence of frames to process sort (bool): sort the sequence before processing zfill (int): width for zero padding compress (bool): remove any duplicates before processing Returns: str: """ if compress: frames = unique(set(), frames) frames = list(frames) if not frames: return '' if len(frames) == 1: return pad(frames[0], zfill) if sort: frames.sort() ret = ','.join(FrameSet.framesToFrameRanges(frames, zfill)) return futils.native_str(ret)
def framesToFrameRange(frames, sort=True, zfill=0, compress=False): """ Converts an iterator of frames into a FrameRange. :param frames: sequence of frames to process (iter) :param sort: sort the sequence before processing (bool) :param zfill: width for zero padding (int) :param compress: remove any duplicates before processing (bool) :return: str """ if compress: frames = unique(set(), frames) frames = list(frames) if not frames: return '' if len(frames) == 1: return pad(frames[0], zfill) if sort: frames.sort() return ','.join(FrameSet.framesToFrameRanges(frames, zfill))
def framesToFrameRange(frames, sort=True, zfill=0, compress=False): """ Converts an iterator of frames into a frame range string. Args: frames (collections.Iterable): sequence of frames to process sort (bool): sort the sequence before processing zfill (int): width for zero padding compress (bool): remove any duplicates before processing Returns: str: """ if compress: frames = unique(set(), frames) frames = list(frames) if not frames: return u'' if len(frames) == 1: return pad(frames[0], zfill) if sort: frames.sort() return u','.join(FrameSet.framesToFrameRanges(frames, zfill))
def __init__(self, frange): # if the user provides anything but a string, short-circuit the build if not isinstance(frange, basestring): # if it's apparently a FrameSet already, short-circuit the build if set(dir(frange)).issuperset(self.__slots__): for attr in self.__slots__: setattr(self, attr, getattr(frange, attr)) return # if it's inherently disordered, sort and build elif isinstance(frange, Set): self._maxSizeCheck(frange) self._items = frozenset(map(int, frange)) self._order = tuple(sorted(self._items)) self._frange = FrameSet.framesToFrameRange(self._order, sort=False, compress=False) return # if it's ordered, find unique and build elif isinstance(frange, Sequence): self._maxSizeCheck(frange) items = set() order = unique(items, map(int, frange)) self._order = tuple(order) self._items = frozenset(items) self._frange = FrameSet.framesToFrameRange(self._order, sort=False, compress=False) return # in all other cases, cast to a string else: try: frange = str(frange) except Exception as err: msg = 'Could not parse "{0}": cast to string raised: {1}' raise ParseException(msg.format(frange, err)) # we're willing to trim padding characters from consideration # this translation is orders of magnitude faster than prior method self._frange = str(frange).translate(None, ''.join(PAD_MAP.keys())) # because we're acting like a set, we need to support the empty set if not self._frange: self._items = frozenset() self._order = tuple() return # build the mutable stores, then cast to immutable for storage items = set() order = [] maxSize = constants.MAX_FRAME_SIZE for part in self._frange.split(","): # this is to deal with leading / trailing commas if not part: continue # parse the partial range start, end, modifier, chunk = FrameSet._parse_frange_part(part) # handle batched frames (1-100x5) if modifier == 'x': frames = xfrange(start, end, chunk, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle staggered frames (1-100:5) elif modifier == ':': for stagger in xrange(chunk, 0, -1): frames = xfrange(start, end, stagger, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle filled frames (1-100y5) elif modifier == 'y': not_good = frozenset( xfrange(start, end, chunk, maxSize=maxSize)) frames = xfrange(start, end, 1, maxSize=maxSize) frames = (f for f in frames if f not in not_good) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle full ranges and single frames else: frames = xfrange(start, end, 1 if start < end else -1, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # lock the results into immutable internals # this allows for hashing and fast equality checking self._items = frozenset(items) self._order = tuple(order)
def __init__(self, frange): """Initialize the :class:`FrameSet` object. """ # if the user provides anything but a string, short-circuit the build if not isinstance(frange, futils.string_types): # if it's apparently a FrameSet already, short-circuit the build if set(dir(frange)).issuperset(self.__slots__): for attr in self.__slots__: setattr(self, attr, getattr(frange, attr)) return # if it's inherently disordered, sort and build elif isinstance(frange, Set): self._maxSizeCheck(frange) self._items = frozenset(normalizeFrames(frange)) self._order = tuple(sorted(self._items)) self._frange = self.framesToFrameRange( self._order, sort=False, compress=False) return # if it's ordered, find unique and build elif isinstance(frange, Sequence): self._maxSizeCheck(frange) items = set() order = unique(items, normalizeFrames(frange)) self._order = tuple(order) self._items = frozenset(items) self._frange = self.framesToFrameRange( self._order, sort=False, compress=False) return # if it's an individual number build directly elif isinstance(frange, futils.integer_types + (float, decimal.Decimal)): frame = normalizeFrame(frange) self._order = (frame, ) self._items = frozenset([frame]) self._frange = self.framesToFrameRange( self._order, sort=False, compress=False) # in all other cases, cast to a string else: try: frange = asString(frange) except Exception as err: msg = 'Could not parse "{0}": cast to string raised: {1}' raise ParseException(msg.format(frange, err)) # we're willing to trim padding characters from consideration # this translation is orders of magnitude faster than prior method if futils.PY2: frange = bytes(frange).translate(None, ''.join(self.PAD_MAP.keys())) self._frange = asString(frange) else: frange = str(frange) for key in self.PAD_MAP: frange = frange.replace(key, '') self._frange = asString(frange) # because we're acting like a set, we need to support the empty set if not self._frange: self._items = frozenset() self._order = tuple() return # build the mutable stores, then cast to immutable for storage items = set() order = [] maxSize = constants.MAX_FRAME_SIZE frange_parts = [] frange_types = [] for part in self._frange.split(","): # this is to deal with leading / trailing commas if not part: continue # parse the partial range start, end, modifier, chunk = self._parse_frange_part(part) frange_parts.append((start, end, modifier, chunk)) frange_types.extend(map(type, (start, end, chunk))) # Determine best type for numbers in range. Note that # _parse_frange_part will always return decimal.Decimal for subframes FrameType = int if decimal.Decimal in frange_types: FrameType = decimal.Decimal for start, end, modifier, chunk in frange_parts: # handle batched frames (1-100x5) if modifier == 'x': frames = xfrange(start, end, chunk, maxSize=maxSize) frames = [FrameType(f) for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle staggered frames (1-100:5) elif modifier == ':': if '.' in futils.native_str(chunk): raise ValueError("Unable to stagger subframes") for stagger in range(chunk, 0, -1): frames = xfrange(start, end, stagger, maxSize=maxSize) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle filled frames (1-100y5) elif modifier == 'y': if '.' in futils.native_str(chunk): raise ValueError("Unable to fill subframes") not_good = frozenset(xfrange(start, end, chunk, maxSize=maxSize)) frames = xfrange(start, end, 1, maxSize=maxSize) frames = (f for f in frames if f not in not_good) frames = [f for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # handle full ranges and single frames else: frames = xfrange(start, end, 1 if start < end else -1, maxSize=maxSize) frames = [FrameType(f) for f in frames if f not in items] self._maxSizeCheck(len(frames) + len(items)) order.extend(frames) items.update(frames) # lock the results into immutable internals # this allows for hashing and fast equality checking self._items = frozenset(items) self._order = tuple(order)
def __init__(self, frange): # if the user provides anything but a string, short-circuit the build if not isinstance(frange, basestring): # if it's apparently a FrameSet already, short-circuit the build if set(dir(frange)).issuperset(self.__slots__): for attr in self.__slots__: setattr(self, attr, getattr(frange, attr)) return # if it's inherently disordered, sort and build elif isinstance(frange, Set): self._items = frozenset(map(int, frange)) self._order = tuple(sorted(self._items)) self._frange = FrameSet.framesToFrameRange( self._order, sort=False, compress=False) return # if it's ordered, find unique and build elif isinstance(frange, Sequence): items = set() order = unique(items, map(int, frange)) self._order = tuple(order) self._items = frozenset(items) self._frange = FrameSet.framesToFrameRange( self._order, sort=False, compress=False) return # in all other cases, cast to a string else: try: frange = str(frange) except Exception as err: msg = 'Could not parse "{0}": cast to string raised: {1}' raise ParseException(msg.format(frange, err)) # we're willing to trim padding characters from consideration # this translation is orders of magnitude faster than prior method self._frange = str(frange).translate(None, ''.join(PAD_MAP.keys())) # because we're acting like a set, we need to support the empty set if not self._frange: self._items = frozenset() self._order = tuple() return # build the mutable stores, then cast to immutable for storage items = set() order = [] for part in self._frange.split(","): # this is to deal with leading / trailing commas if not part: continue # parse the partial range start, end, modifier, chunk = FrameSet._parse_frange_part(part) # handle batched frames (1-100x5) if modifier == 'x': frames = xfrange(start, end, chunk) frames = [f for f in frames if f not in items] order.extend(frames) items.update(frames) # handle staggered frames (1-100:5) elif modifier == ':': for stagger in xrange(chunk, 0, -1): frames = xfrange(start, end, stagger) frames = [f for f in frames if f not in items] order.extend(frames) items.update(frames) # handle filled frames (1-100y5) elif modifier == 'y': not_good = frozenset(xfrange(start, end, chunk)) frames = xfrange(start, end, 1) frames = (f for f in frames if f not in not_good) frames = [f for f in frames if f not in items] order.extend(frames) items.update(frames) # handle full ranges and single frames else: frames = xfrange(start, end, 1 if start < end else -1) frames = [f for f in frames if f not in items] order.extend(frames) items.update(frames) # lock the results into immutable internals # this allows for hashing and fast equality checking self._items = frozenset(items) self._order = tuple(order)