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
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
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
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)
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
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)
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)
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
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
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)
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
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
def get_object(obj): if is_uuid(obj): return UUID(obj), get_resource_by_uuid(obj) else: return UUID(obj.uuid()), obj
def get_resource_brain(self): return get_resource_by_uuid(self.resource)
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