Example #1
0
    def invertedFrameRange(self, zfill=0, decimal_places=None):
        """
        Return the inverse of the :class:`FrameSet` 's frame range, padded if
        desired.
        The inverse is every frame within the full extent of the range.

        Examples:
            >>> FrameSet('1-100x2').invertedFrameRange()
            '2-98x2'
            >>> FrameSet('1-100x2').invertedFrameRange(5)
            '00002-00098x2'

        If the inverted frame size exceeds ``fileseq.constants.MAX_FRAME_SIZE``,
        a ``MaxSizeException`` will be raised.

        Args:
            zfill (int): the width to use to zero-pad the frame range string
            decimal_places (int or None): the number of decimal places to use in
                frame range string

        Returns:
            str:

        Raises:
            :class:`fileseq.exceptions.MaxSizeException`:
        """
        # No inverted frame range when range includes subframes
        for frame in self.items:
            if not isinstance(frame, futils.integer_types):
                return ''

        result = []
        frames = sorted(self.items)
        for idx, frame in enumerate(frames[:-1]):
            next_frame = frames[idx + 1]
            if next_frame - frame != 1:
                r = range(frame + 1, next_frame)
                # Check if the next update to the result set
                # will exceed out max frame size.
                # Prevent memory overflows.
                self._maxSizeCheck(len(r) + len(result))
                result += r

        if not result:
            return ''

        return self.framesToFrameRange(
            result, zfill=zfill, sort=False, compress=False)
Example #2
0
    def invertedFrameRange(self, zfill=0):
        """
        Return the inverse of the :class:`FrameSet` 's frame range, padded if
        desired.
        The inverse is every frame within the full extent of the range.

        Examples:
            >>> FrameSet('1-100x2').invertedFrameRange()
            '2-98x2'
            >>> FrameSet('1-100x2').invertedFrameRange(5)
            '00002-00098x2'

        If the inverted frame size exceeds `fileseq.constants.MAX_FRAME_SIZE`,
        a ``MaxSizeException`` will be raised.

        Args:
            zfill (int): the width to use to zero-pad the frame range string

        Returns:
            str:

        Raises:
            :class:`fileseq.exceptions.MaxSizeException`:
        """
        result = []
        frames = sorted(self.items)
        for idx, frame in enumerate(frames[:-1]):
            next_frame = frames[idx + 1]
            if next_frame - frame != 1:
                r = range(frame + 1, next_frame)
                # Check if the next update to the result set
                # will exceed out max frame size.
                # Prevent memory overflows.
                self._maxSizeCheck(len(r) + len(result))
                result += r

        if not result:
            return u''

        return FrameSet.framesToFrameRange(
            result, zfill=zfill, sort=False, compress=False)
Example #3
0
    def invertedFrameRange(self, zfill=0):
        """
        Return the inverse of the :class:`FrameSet` 's frame range, padded if
        desired.
        The inverse is every frame within the full extent of the range.

        :Example:
            >>> FrameSet('1-100x2').invertedFrameRange()
            '2-98x2'
            >>> FrameSet('1-100x2').invertedFrameRange(5)
            '00002-00098x2'

        If the inverted frame size exceeds `fileseq.constants.MAX_FRAME_SIZE`,
        a ``MaxSizeException`` will be raised.

        :type zfill: int
        :param zfill: the width to use to zero-pad the frame range string
        :rtype: str
        :raises: :class:`fileseq.exceptions.MaxSizeException`
        """
        result = []
        frames = sorted(self.items)
        for idx, frame in enumerate(frames[:-1]):
            next_frame = frames[idx + 1]
            if next_frame - frame != 1:
                r = range(frame + 1, next_frame)
                # Check if the next update to the result set
                # will exceed out max frame size.
                # Prevent memory overflows.
                self._maxSizeCheck(len(r) + len(result))
                result += r

        if not result:
            return ''

        return FrameSet.framesToFrameRange(result,
                                           zfill=zfill,
                                           sort=False,
                                           compress=False)
Example #4
0
    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)
Example #5
0
    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, future.utils.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(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 = utils.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 future.utils.PY2:
            frange = bytes(frange).translate(None, ''.join(PAD_MAP.keys()))
            self._frange = utils.asString(frange)
        else:
            frange = str(frange)
            for key in PAD_MAP:
                frange = frange.replace(key, u'')
            self._frange = utils.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

        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 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':
                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)
Example #6
0
    def __init__(self, frange):
        # if the user provides anything but a string, short-circuit the build
        if not isinstance(frange, str):
            # 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(
            str.maketrans('', '', ''.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 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':
                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)