Exemplo n.º 1
0
    def test_iterator(self):
        start = datetime(2011, 1, 1, 0)
        end = datetime(2011, 1, 2, 0)

        for raster in VALID_RASTER_VALUES:
            results = list(iterate_span(start, end, raster))
            self.assertEqual(len(results), 24 * 60 / raster)
Exemplo n.º 2
0
    def test_iterator(self):
        start = datetime(2011, 1, 1, 0)
        end = datetime(2011, 1, 2, 0)

        for raster in VALID_RASTER_VALUES:
            results = list(iterate_span(start, end, raster))
            self.assertEqual(len(results), 24 * 60 / raster)
Exemplo n.º 3
0
    def all_slots(self, start=None, end=None):
        """ Returns the slots which exist with this timespan. Reserved or free.

        """
        start, end = self.align_dates(start, end)

        if self.partly_available:
            for start, end in iterate_span(start, end, self.raster):
                yield start, end
        else:
            yield self.start, self.end
Exemplo n.º 4
0
    def all_slots(self, start=None, end=None):
        """ Returns the slots which exist with this timespan. Reserved or free.

        """
        start, end = self.align_dates(start, end)

        if self.partly_available:
            for start, end in iterate_span(start, end, self.raster):
                yield start, end
        else:
            yield self.start, self.end
Exemplo n.º 5
0
    def availability(self):
        """Returns the availability in percent."""

        if self.partly_available:
            total = sum(1 for s in self.all_slots())
        else:
            total = 1

        count = len(self.reserved_slots)
        for blocked_period in self._query_blocked_periods():
            count += len(list(iterate_span(blocked_period.start, blocked_period.end, self.raster)))

        if total == count:
            return 0.0

        if count == 0:
            return 100.0

        return 100.0 - (float(count) / float(total) * 100.0)
Exemplo n.º 6
0
    def availability(self):
        """Returns the availability in percent."""

        if self.partly_available:
            total = sum(1 for s in self.all_slots())
        else:
            total = 1

        count = len(self.reserved_slots)
        for blocked_period in self._query_blocked_periods():
            count += len(list(iterate_span(blocked_period.start,
                                           blocked_period.end,
                                           self.raster)))

        if total == count:
            return 0.0

        if count == 0:
            return 100.0

        return 100.0 - (float(count) / float(total) * 100.0)
Exemplo n.º 7
0
    def availability_partitions(self, scheduler):
        """Partitions the space between start and end into blocks of either
        free, blocked or reserved time. Each block has a percentage
        representing the space the block occupies compared to the size of the
        whole allocation.

        The blocks are ordered from start to end. Each block is an item with
        two values. The first being the percentage, the second being the type.
        The type can be one of None, 'reserved' or 'blocked'.

        So given an allocation that goes from 8 to 9 and a reservation that
        goes from 8:15 until 8:30 and a block that goes from 8:30 to 9:00
        we get the following blocks:

        [
            (25%, None),
            (25%, 'reserved'),
            (50%, 'blocked')
        ]

        This is useful to divide an allocation block into different divs on the
        frontend, indicating to the user which parts of an allocation are
        available for reservation.

        Makes sure to only display slots that are within it's resources
        first_hour/last_hour timespan.

        """

        resource = get_resource_by_uuid(scheduler.uuid).getObject()
        min_start_resource = datetime.combine(self.start,
                                              time(resource.first_hour))
        max_end_resource = datetime.combine(self.end,
                                            time(resource.last_hour))

        display_start = max(min_start_resource, self.start)
        display_end = min(max_end_resource, self.end)

        reserved = dict((r.start, r) for r in self.reserved_slots if
                        r.start >= display_start and r.end <= display_end)
        blocked = set()
        for blocked_period in self._query_blocked_periods():
            blocked.update(start for start, end in
                           iterate_span(max(blocked_period.start,
                                            display_start),
                                        min(blocked_period.end,
                                            display_end),
                                        self.raster))

        if not (reserved or blocked):
            return [(100.0, None)]

        # Get the percentage one slot represents
        slots = list(self.all_slots(display_start, display_end))
        step = 100.0 / float(len(slots))

        # Create an entry for each slot with either True or False
        pieces = []
        for slot in slots:
            piece = None
            if slot[0] in reserved:
                reserved_slot = reserved[slot[0]]
                token = reserved_slot.reservation_token
                reservation = scheduler.reservation_by_token(token).one()
                piece = ('reserved', reservation.description, reservation.id)
            elif slot[0] in blocked:
                piece = ('blocked', None)
            pieces.append(piece)

        # Group by the None/'reserved'/'blocked' values in the pieces and sum
        # up the percentage
        partitions = []
        for flag, group in groupby(pieces, key=lambda p: p):
            percentage = len(list(group)) * step
            partitions.append([percentage, flag])

        # Make sure to get rid of floating point rounding errors
        total = sum([p[0] for p in partitions])
        diff = 100.0 - total
        partitions[-1:][0][0] -= diff

        return partitions
Exemplo n.º 8
0
    def availability_partitions(self, scheduler):
        """Partitions the space between start and end into blocks of either
        free, blocked or reserved time. Each block has a percentage
        representing the space the block occupies compared to the size of the
        whole allocation.

        The blocks are ordered from start to end. Each block is an item with
        two values. The first being the percentage, the second being the type.
        The type can be one of None, 'reserved' or 'blocked'.

        So given an allocation that goes from 8 to 9 and a reservation that
        goes from 8:15 until 8:30 and a block that goes from 8:30 to 9:00
        we get the following blocks:

        [
            (25%, None),
            (25%, 'reserved'),
            (50%, 'blocked')
        ]

        This is useful to divide an allocation block into different divs on the
        frontend, indicating to the user which parts of an allocation are
        available for reservation.

        Makes sure to only display slots that are within it's resources
        first_hour/last_hour timespan.

        """

        resource = get_resource_by_uuid(scheduler.uuid).getObject()
        min_start_resource = datetime.combine(self.start, time(resource.first_hour))
        max_end_resource = datetime.combine(self.end, time(resource.last_hour))

        display_start = max(min_start_resource, self.start)
        display_end = min(max_end_resource, self.end)

        reserved = dict((r.start, r) for r in self.reserved_slots if r.start >= display_start and r.end <= display_end)
        blocked = set()
        for blocked_period in self._query_blocked_periods():
            blocked.update(
                start
                for start, end in iterate_span(
                    max(blocked_period.start, display_start), min(blocked_period.end, display_end), self.raster
                )
            )

        if not (reserved or blocked):
            return [(100.0, None)]

        # Get the percentage one slot represents
        slots = list(self.all_slots(display_start, display_end))
        step = 100.0 / float(len(slots))

        # Create an entry for each slot with either True or False
        pieces = []
        for slot in slots:
            piece = None
            if slot[0] in reserved:
                reserved_slot = reserved[slot[0]]
                token = reserved_slot.reservation_token
                reservation = scheduler.reservation_by_token(token).one()
                piece = ("reserved", reservation.description, reservation.id)
            elif slot[0] in blocked:
                piece = ("blocked", None)
            pieces.append(piece)

        # Group by the None/'reserved'/'blocked' values in the pieces and sum
        # up the percentage
        partitions = []
        for flag, group in groupby(pieces, key=lambda p: p):
            percentage = len(list(group)) * step
            partitions.append([percentage, flag])

        # Make sure to get rid of floating point rounding errors
        total = sum([p[0] for p in partitions])
        diff = 100.0 - total
        partitions[-1:][0][0] -= diff

        return partitions