Esempio n. 1
0
    def reservation_data(self):
        """ Prepares data to be shown in the my reservation's table """
        reservations = []

        for reservation in self.reservations():
            resource = utils.get_resource_by_uuid(reservation.resource)

            if resource is None:
                log.warn('Invalid UUID %s' % str(reservation.resource))
                continue

            resource = resource.getObject()

            data = {}

            data['title'] = utils.get_resource_title(resource)

            timespans = []
            for start, end in reservation.timespans():
                timespans.append(u'◆ ' + utils.display_date(start, end))

            data['time'] = '<br />'.join(timespans)
            data['quota'] = utils.get_reservation_quota_statement(
                reservation.quota
            ) if reservation.quota > 1 else u''

            data['url'] = resource.absolute_url()
            data['remove-url'] = ''.join((
                resource.absolute_url(),
                '/your-reservations?remove=',
                reservation.token.hex
            ))
            reservations.append(data)

        return reservations
Esempio n. 2
0
def load_resources(reservations):
    resources = dict()

    for resource in (r.resource for r in reservations):
        if resource in resources:
            continue

        resources[resource] = utils.get_resource_by_uuid(resource).getObject()

    return resources
Esempio n. 3
0
    def resources(self):
        objs = dict()

        for uuid in self.uuids:
            try:
                objs[uuid] = utils.get_resource_by_uuid(uuid).getObject()
            except AttributeError:
                continue

        return objs
Esempio n. 4
0
def load_resources(reservations):
    resources = dict()

    for resource in (r.resource for r in reservations):
        if resource in resources:
            continue

        resources[resource] = utils.get_resource_by_uuid(resource).getObject()

    return resources
Esempio n. 5
0
def send_reservations_confirmed(reservations, language):
    sender = utils.get_site_email_sender()

    if not sender:
        log.warn('Cannot send email as no sender is configured')
        return

    # load resources
    resources = dict()
    for reservation in reservations:

        if not reservation.resource in resources:
            resources[reservation.resource] = utils.get_resource_by_uuid(
                reservation.resource
            ).getObject()

            if not resources[reservation.resource]:
                log.warn('Cannot send email as the resource does not exist')
                return

    # send reservations grouped by reservee email
    groupkey = lambda r: r.email
    by_recipient = groupby(sorted(reservations, key=groupkey), key=groupkey)

    for recipient, grouped_reservations in by_recipient:

        lines = []

        for reservation in grouped_reservations:

            resource = resources[reservation.resource]

            prefix = '' if reservation.autoapprovable else '* '
            lines.append(prefix + utils.get_resource_title(resource))

            for start, end in reservation.timespans():
                lines.append(utils.display_date(start, end))

            lines.append('')

        # differs between resources
        subject, body = get_email_content(
            resource, 'reservation_received', language
        )

        mail = ReservationMail(
            resource, reservation,
            sender=sender,
            recipient=recipient,
            subject=subject,
            body=body,
            reservations=lines[:-1]
        )

        send_mail(resource, mail)
Esempio n. 6
0
    def resources(self):
        objs = dict()

        for uuid in self.uuids:
            try:
                objs[uuid] = utils.get_resource_by_uuid(uuid) \
                    .getObject()
            except AttributeError:
                continue

        return objs
Esempio n. 7
0
def send_reservation_mail(reservations,
                          email_type,
                          language,
                          to_managers=False,
                          reason=u'',
                          old_time=None,
                          new_time=None):

    if isinstance(reservations, CombinedReservations):
        reservation = reservations
    else:
        reservation = tuple(combine_reservations(reservations))[0]

    resource = utils.get_resource_by_uuid(reservation.resource)

    # the resource doesn't currently exist in testing so we quietly
    # exit. This should be changed => #TODO
    if not resource:
        log.warn('Cannot send email as the resource does not exist')
        return

    sender = utils.get_site_email_sender()

    if not sender:
        log.warn('Cannot send email as no sender is configured')
        return

    resource = resource.getObject()

    if to_managers:
        recipients = get_manager_emails(resource)
        if not recipients:
            log.warn("Couldn't find a manager to send an email to")
            return
    else:
        recipients = [reservation.email]

    subject, body = get_email_content(resource, email_type, language)

    for recipient in recipients:
        mail = ReservationMail(resource,
                               reservation,
                               sender=sender,
                               recipient=recipient,
                               subject=subject,
                               body=body,
                               reason=reason,
                               old_time=old_time,
                               new_time=new_time)

        if may_send_mail(resource, mail, intended_for_admin=to_managers):
            send_mail(resource, mail)
Esempio n. 8
0
def send_reservation_mail(
    reservations, email_type, language, to_managers=False,
        reason=u'', old_time=None, new_time=None
):

    if isinstance(reservations, CombinedReservations):
        reservation = reservations
    else:
        reservation = tuple(combine_reservations(reservations))[0]

    resource = utils.get_resource_by_uuid(reservation.resource)

    # the resource doesn't currently exist in testing so we quietly
    # exit. This should be changed => #TODO
    if not resource:
        log.warn('Cannot send email as the resource does not exist')
        return

    sender = utils.get_site_email_sender()

    if not sender:
        log.warn('Cannot send email as no sender is configured')
        return

    resource = resource.getObject()

    if to_managers:
        recipients = get_manager_emails(resource)
        if not recipients:
            log.warn("Couldn't find a manager to send an email to")
            return
    else:
        recipients = [reservation.email]

    subject, body = get_email_content(resource, email_type, language)

    for recipient in recipients:
        mail = ReservationMail(
            resource, reservation,
            sender=sender,
            recipient=recipient,
            subject=subject,
            body=body,
            reason=reason,
            old_time=old_time,
            new_time=new_time
        )

        if may_send_mail(resource, mail, intended_for_admin=to_managers):
            send_mail(resource, mail)
Esempio n. 9
0
    def resources(self):
        uids = self.request.get('compare_to', [])
        if not hasattr(uids, '__iter__'):
            uids = [uids]

        resources = [self.context]
        for uid in uids:
            resource = utils.get_resource_by_uuid(uid)
            resources.append(resource.getObject())

        template = 'seantis-reservation-calendar-%i'
        for ix, resource in enumerate(resources):
            setattr(resource, '_v_calendar_id', template % ix)

        return resources
Esempio n. 10
0
    def build_your_reservations(
        self, reservations
    ):
        """ Prepares the given reservations to be shown in the
        your-reservations macro.

        """
        result = []

        for reservation in reservations:
            resource = utils.get_resource_by_uuid(reservation.resource)

            if resource is None:
                log.warn('Invalid UUID %s' % str(reservation.resource))
                continue

            resource = resource.getObject()

            data = {}

            data['token'] = reservation.token
            data['title'] = utils.get_resource_title(resource)

            timespans = []
            for start, end in reservation.timespans():
                timespans.append(utils.display_date(start, end))

            data['time'] = '<ul class="dense"><li>{}</li></ul>'.format(
                '</li><li>'.join(timespans)
            )
            data['quota'] = utils.get_reservation_quota_statement(
                reservation.quota
            ) if reservation.quota > 1 else u''

            data['url'] = resource.absolute_url()
            data['remove-url'] = ''.join((
                resource.absolute_url(),
                '/your-reservations?remove=',
                reservation.token.hex
            ))
            result.append(data)

        return result
Esempio n. 11
0
def send_reservation_mail(reservation, email_type, language,
                          to_managers=False, revocation_reason=u'',
                          bcc=tuple(), mail_class=None):
    mail_class = mail_class or ReservationMail
    resource = utils.get_resource_by_uuid(reservation.resource)

    # the resource doesn't currently exist in testing so we quietly
    # exit. This should be changed => #TODO
    if not resource:
        log.warn('Cannot send email as the resource does not exist')
        return

    sender = utils.get_site_email_sender()

    if not sender:
        log.warn('Cannot send email as no sender is configured')
        return

    resource = resource.getObject()

    if to_managers:
        recipients = get_manager_emails_by_context(resource)
        if not recipients:
            log.warn("Couldn't find a manager to send an email to")
            return
    else:
        recipients = [reservation.email]

    subject, body = get_email_content(resource, email_type, language)

    for recipient in recipients:
        mail = mail_class(
            resource, reservation,
            sender=sender,
            recipient=recipient,
            bcc=bcc,
            subject=subject,
            body=body,
            revocation_reason=revocation_reason
        )

        send_mail(resource, mail)
Esempio n. 12
0
    def build_your_reservations(self, reservations):
        """ Prepares the given reservations to be shown in the
        your-reservations macro.

        """
        result = []

        for reservation in reservations:
            resource = utils.get_resource_by_uuid(reservation.resource)

            if resource is None:
                log.warn('Invalid UUID %s' % str(reservation.resource))
                continue

            resource = resource.getObject()

            data = {}

            data['token'] = reservation.token
            data['title'] = utils.get_resource_title(resource)

            timespans = []
            for start, end in reservation.timespans():
                timespans.append(utils.display_date(start, end))

            data['time'] = '<ul class="dense"><li>{}</li></ul>'.format(
                '</li><li>'.join(timespans))
            data['quota'] = utils.get_reservation_quota_statement(
                reservation.quota) if reservation.quota > 1 else u''

            data['url'] = resource.absolute_url()
            data['remove-url'] = ''.join(
                (resource.absolute_url(), '/your-reservations?remove=',
                 reservation.token.hex))
            result.append(data)

        return result
Esempio n. 13
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
Esempio n. 14
0
 def get_object(obj):
     if is_uuid(obj):
         return UUID(obj), get_resource_by_uuid(obj)
     else:
         return UUID(obj.uuid()), obj
Esempio n. 15
0
 def get_resource_brain(self):
     return get_resource_by_uuid(self.resource)
Esempio n. 16
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