Пример #1
0
    def __init__(self,
                 occurrences,
                 start_dt,
                 end_dt,
                 candidates=None,
                 rooms=None,
                 specific_room=None,
                 repeat_frequency=None,
                 repeat_interval=None,
                 flexible_days=0,
                 show_blockings=True):
        self.occurrences = occurrences
        self.start_dt = start_dt
        self.end_dt = end_dt
        self.candidates = candidates
        self.rooms = rooms
        self.specific_room = specific_room
        self.repeat_frequency = repeat_frequency
        self.repeat_interval = repeat_interval
        self.flexible_days = flexible_days
        self.show_blockings = show_blockings

        self.conflicts = 0
        self.bars = []

        if self.specific_room and self.rooms:
            raise ValueError('specific_room and rooms are mutually exclusive')

        if self.specific_room:
            self.rooms = [self.specific_room]
        elif self.rooms is None:
            self.rooms = Room.find_all(is_active=True)
        self.rooms = sorted(self.rooms,
                            key=lambda x: natural_sort_key(x.full_name))

        if self.show_blockings:
            # avoid loading user data we don't care about
            user_strategy = defaultload('blocking').defaultload(
                'created_by_user')
            user_strategy.noload('*')
            user_strategy.load_only('first_name', 'last_name')
            room_ids = [r.id for r in self.rooms]
            filters = {
                'room_ids': room_ids,
                'state': BlockedRoom.State.accepted,
                'start_date': self.start_dt.date(),
                'end_date': self.end_dt.date()
            }
            self.blocked_rooms = BlockedRoom.find_with_filters(
                filters).options(user_strategy)
            self.nonbookable_periods = NonBookablePeriod.find(
                NonBookablePeriod.room_id.in_(room_ids),
                NonBookablePeriod.overlaps(self.start_dt, self.end_dt)).all()
        else:
            self.blocked_rooms = []

        self._produce_bars()
Пример #2
0
 def _process_args(self):
     blocking_id = self._params.get('blocking_id')
     self._room = Room.get(self._params['room_id'])
     self._blocking = Blocking.get(blocking_id) if blocking_id else None
     if 'start_dt' in self._params and 'end_dt' in self._params:
         start_dt = datetime.strptime(self._params['start_dt'], '%H:%M %Y-%m-%d')
         end_dt = datetime.strptime(self._params['end_dt'], '%H:%M %Y-%m-%d')
         self._nonbookable = bool(NonBookablePeriod.find_first(NonBookablePeriod.room_id == self._room.id,
                                                               NonBookablePeriod.overlaps(start_dt, end_dt)))
     else:
         self._nonbookable = False
Пример #3
0
def group_nonbookable_periods(periods, dates):
    if not periods:
        return {}
    occurrences = defaultdict(list)
    for period in periods:
        for d in dates:
            if period.start_dt.date() <= d <= period.end_dt.date():
                period_occurrence = NonBookablePeriod()
                period_occurrence.start_dt = ((datetime.combine(d, time(0)))
                                              if period.start_dt.date() != d else period.start_dt)
                period_occurrence.end_dt = ((datetime.combine(d, time(23, 59)))
                                            if period.end_dt.date() != d else period.end_dt)
                occurrences[d].append(period_occurrence)
    return occurrences
Пример #4
0
def group_nonbookable_periods(periods, dates):
    if not periods:
        return {}
    occurrences = defaultdict(list)
    for period in periods:
        for date in dates:
            if period.start_dt.date() <= date <= period.end_dt.date():
                period_occurrence = NonBookablePeriod()
                period_occurrence.start_dt = ((datetime.combine(date, time(0)))
                                              if period.start_dt.date() != date else period.start_dt)
                period_occurrence.end_dt = ((datetime.combine(date, time(23, 59)))
                                            if period.end_dt.date() != date else period.end_dt)
                occurrences[date].append(period_occurrence)
    return occurrences
Пример #5
0
 def _process_args(self):
     blocking_id = self._params.get('blocking_id')
     self._room = Room.get(self._params['room_id'])
     self._blocking = Blocking.get(blocking_id) if blocking_id else None
     if 'start_dt' in self._params and 'end_dt' in self._params:
         start_dt = datetime.strptime(self._params['start_dt'],
                                      '%H:%M %Y-%m-%d')
         end_dt = datetime.strptime(self._params['end_dt'],
                                    '%H:%M %Y-%m-%d')
         self._nonbookable = bool(
             NonBookablePeriod.find_first(
                 NonBookablePeriod.room_id == self._room.id,
                 NonBookablePeriod.overlaps(start_dt, end_dt)))
     else:
         self._nonbookable = False
Пример #6
0
    def __init__(self, occurrences, start_dt, end_dt, candidates=None, rooms=None, specific_room=None,
                 repeat_frequency=None, repeat_interval=None, flexible_days=0, show_blockings=True):
        self.occurrences = occurrences
        self.start_dt = start_dt
        self.end_dt = end_dt
        self.candidates = candidates
        self.rooms = rooms
        self.specific_room = specific_room
        self.repeat_frequency = repeat_frequency
        self.repeat_interval = repeat_interval
        self.flexible_days = flexible_days
        self.show_blockings = show_blockings

        self.conflicts = 0
        self.bars = []

        if self.specific_room and self.rooms:
            raise ValueError('specific_room and rooms are mutually exclusive')

        if self.specific_room:
            self.rooms = [self.specific_room]
        elif self.rooms is None:
            self.rooms = Room.find_all(is_active=True)
        self.rooms = sorted(self.rooms, key=lambda x: natural_sort_key(x.full_name))

        if self.show_blockings:
            # avoid loading user data we don't care about
            user_strategy = defaultload('blocking').defaultload('created_by_user')
            user_strategy.noload('*')
            user_strategy.load_only('first_name', 'last_name')
            room_ids = [r.id for r in self.rooms]
            filters = {
                'room_ids': room_ids,
                'state': BlockedRoom.State.accepted,
                'start_date': self.start_dt.date(),
                'end_date': self.end_dt.date()
            }
            self.blocked_rooms = BlockedRoom.find_with_filters(filters).options(user_strategy)
            self.nonbookable_periods = NonBookablePeriod.find(
                NonBookablePeriod.room_id.in_(room_ids),
                NonBookablePeriod.overlaps(self.start_dt, self.end_dt)
            ).all()
        else:
            self.blocked_rooms = []

        self._produce_bars()
Пример #7
0
def update_room_availability(room, availability):
    if 'bookable_hours' in availability:
        room.bookable_hours.order_by(False).delete()
        unique_bh = set((hours['start_time'], hours['end_time']) for hours in availability['bookable_hours'])
        db.session.add_all(
            [BookableHours(room=room, start_time=hours[0], end_time=hours[1]) for hours in unique_bh])
    if 'nonbookable_periods' in availability:
        room.nonbookable_periods.order_by(False).delete()
        unique_nbp = set((period['start_dt'], period['end_dt']) for period in availability['nonbookable_periods'])
        db.session.add_all(
            [NonBookablePeriod(room=room, start_dt=datetime.combine(period[0], time(0, 0)),
                               end_dt=datetime.combine(period[1], time(23, 59))) for period in unique_nbp])
Пример #8
0
    def _save(self):
        room = self._room
        form = self._form
        # Simple fields
        form.populate_obj(room,
                          skip=('bookable_hours', 'nonbookable_periods'),
                          existing_only=True)
        room.update_name()
        # Photos
        if form.small_photo.data and form.large_photo.data:
            _cache.delete_multi('photo-{}-{}'.format(room.id, size)
                                for size in {'small', 'large'})
            room.photo = Photo(thumbnail=form.small_photo.data.read(),
                               data=form.large_photo.data.read())
        elif form.delete_photos.data:
            _cache.delete_multi('photo-{}-{}'.format(room.id, size)
                                for size in {'small', 'large'})
            room.photo = None
        # Custom attributes
        room.attributes = [
            RoomAttributeAssociation(value=form['attribute_{}'.format(
                attr.id)].data,
                                     attribute_id=attr.id)
            for attr in self._location.attributes.all()
            if form['attribute_{}'.format(attr.id)].data
        ]
        # Bookable times
        room.bookable_hours = [
            BookableHours(start_time=bt['start'], end_time=bt['end'])
            for bt in form.bookable_hours.data
            if all(x is not None for x in bt.viewvalues())
        ]

        # Nonbookable dates
        room.nonbookable_periods = [
            NonBookablePeriod(start_dt=nbd.start_dt, end_dt=nbd.end_dt)
            for nbd in form.nonbookable_periods
            if (nbd.start_dt and nbd.end_dt)
        ]
Пример #9
0
    def _save(self):
        room = self._room
        form = self._form
        # Simple fields
        form.populate_obj(room,
                          skip=('bookable_hours', 'nonbookable_periods'),
                          existing_only=True)
        room.update_name()
        # Photos
        if form.large_photo.data:
            _cache.delete('photo-{}'.format(room.id))
            room.photo = Photo(data=form.large_photo.data.read())
            build_rooms_spritesheet()
        elif form.delete_photos.data:
            _cache.delete('photo-{}'.format(room.id))
            room.photo = None
            build_rooms_spritesheet()
        # Custom attributes
        room.attributes = [
            RoomAttributeAssociation(
                value=form['attribute_{}'.format(attr.id)].data,
                attribute_id=attr.id) for attr in RoomAttribute.query.all()
            if form['attribute_{}'.format(attr.id)].data
        ]
        # Bookable times
        room.bookable_hours = [
            BookableHours(start_time=bt['start'], end_time=bt['end'])
            for bt in form.bookable_hours.data
            if all(x is not None for x in bt.viewvalues())
        ]

        # Nonbookable dates
        room.nonbookable_periods = [
            NonBookablePeriod(start_dt=nbd.start_dt, end_dt=nbd.end_dt)
            for nbd in form.nonbookable_periods
            if (nbd.start_dt and nbd.end_dt)
        ]
Пример #10
0
def test_overlaps(start_dt, end_dt, expected):
    start_dt = datetime.strptime(start_dt, "%Y-%m-%d %H:%M")
    end_dt = datetime.strptime(end_dt, "%Y-%m-%d %H:%M")
    nbp = NonBookablePeriod(start_dt=datetime(2014, 12, 5), end_dt=datetime(2014, 12, 6))
    assert nbp.overlaps(start_dt, end_dt) == expected
Пример #11
0
def test_overlaps(start_dt, end_dt, expected):
    start_dt = datetime.strptime(start_dt, '%Y-%m-%d %H:%M')
    end_dt = datetime.strptime(end_dt, '%Y-%m-%d %H:%M')
    nbp = NonBookablePeriod(start_dt=datetime(2014, 12, 5),
                            end_dt=datetime(2014, 12, 6))
    assert nbp.overlaps(start_dt, end_dt) == expected
Пример #12
0
    def migrate_rooms(self):
        eq = defaultdict(set)
        vc = defaultdict(set)
        for old_room_id, old_room in self.rb_root['Rooms'].iteritems():
            eq[old_room._locationName].update(
                e for e in old_room._equipment.split('`') if e)
            vc[old_room._locationName].update(
                e for e in getattr(old_room, 'avaibleVC', []) if e)

        print cformat('%{white!}migrating equipment')
        for name, eqs in eq.iteritems():
            l = Location.find_first(name=name)

            if l is None:
                print cformat('%{yellow!}*** WARNING')
                print cformat(
                    "%{{yellow!}}***%{{reset}} Location '{}' does not exist. Skipped equipment: {}"
                    .format(name, eqs))
                continue

            l.equipment_types.extend(EquipmentType(name=x) for x in eqs)
            print cformat('- [%{cyan}{}%{reset}] {}').format(name, eqs)
            db.session.add(l)
        db.session.commit()
        print

        print cformat('%{white!}migrating vc equipment')
        for name, vcs in vc.iteritems():
            l = Location.find_first(name=name)

            if l is None:
                print cformat('%{yellow!}*** WARNING')
                print cformat(
                    "%{{yellow!}}***%{{reset}} Location '{}' does not exist. Skipped VC equipment: {}"
                    .format(name, vcs))
                continue

            pvc = l.get_equipment_by_name('Video conference')
            for vc_name in vcs:
                req = EquipmentType(name=vc_name)
                req.parent = pvc
                l.equipment_types.append(req)
                print cformat('- [%{cyan}{}%{reset}] {}').format(
                    name, req.name)
            db.session.add(l)
        db.session.commit()
        print

        print cformat('%{white!}migrating rooms')

        for old_room_id, old_room in self.rb_root['Rooms'].iteritems():
            l = Location.find_first(name=old_room._locationName)

            if l is None:
                print cformat('%{yellow!}*** WARNING')
                print cformat(
                    "%{{yellow!}}***%{{reset}} Location '{}' does not exist. Skipped room '{}'"
                    .format(old_room._locationName, old_room.id))
                continue

            r = Room(
                id=old_room_id,
                name=convert_to_unicode((old_room._name or '').strip()
                                        or generate_name(old_room)),
                site=convert_to_unicode(old_room.site),
                division=convert_to_unicode(old_room.division),
                building=convert_to_unicode(old_room.building),
                floor=convert_to_unicode(old_room.floor),
                number=convert_to_unicode(old_room.roomNr),
                notification_before_days=((
                    old_room.resvStartNotificationBefore or None) if getattr(
                        old_room, 'resvStartNotification', False) else None),
                notification_for_responsible=getattr(
                    old_room, 'resvNotificationToResponsible', False),
                notification_for_assistance=getattr(
                    old_room, 'resvNotificationAssistance', False),
                reservations_need_confirmation=old_room.resvsNeedConfirmation,
                telephone=convert_to_unicode(
                    getattr(old_room, 'telephone', None)),
                key_location=convert_to_unicode(
                    getattr(old_room, 'whereIsKey', None)),
                capacity=getattr(old_room, 'capacity', None),
                surface_area=getattr(old_room, 'surfaceArea', None),
                latitude=getattr(old_room, 'latitude', None),
                longitude=getattr(old_room, 'longitude', None),
                comments=convert_to_unicode(getattr(old_room, 'comments',
                                                    None)),
                owner_id=self.merged_avatars.get(old_room.responsibleId,
                                                 old_room.responsibleId),
                is_active=old_room.isActive,
                is_reservable=old_room.isReservable,
                max_advance_days=int(old_room.maxAdvanceDays) if getattr(
                    old_room, 'maxAdvanceDays', None) else None)

            print cformat(
                '- [%{cyan}{}%{reset}] %{grey!}{:4}%{reset}  %{green!}{}%{reset}'
            ).format(l.name, r.id, r.name)

            for old_bookable_time in getattr(old_room, '_dailyBookablePeriods',
                                             []):
                r.bookable_hours.append(
                    BookableHours(start_time=old_bookable_time._startTime,
                                  end_time=old_bookable_time._endTime))
                print cformat('  %{blue!}Bookable:%{reset} {}').format(
                    r.bookable_hours[-1])

            for old_nonbookable_date in getattr(old_room, '_nonBookableDates',
                                                []):
                r.nonbookable_periods.append(
                    NonBookablePeriod(start_dt=old_nonbookable_date._startDate,
                                      end_dt=old_nonbookable_date._endDate))
                print cformat('  %{blue!}Nonbookable:%{reset} {}').format(
                    r.nonbookable_periods[-1])

            if self.photo_path:
                try:
                    with open(
                            os.path.join(
                                self.photo_path, 'large_photos',
                                get_canonical_name_of(old_room) + '.jpg'),
                            'rb') as f:
                        large_photo = f.read()
                except Exception:
                    large_photo = None

                try:
                    with open(
                            os.path.join(
                                self.photo_path, 'small_photos',
                                get_canonical_name_of(old_room) + '.jpg'),
                            'rb') as f:
                        small_photo = f.read()
                except Exception:
                    small_photo = None

                if large_photo and small_photo:
                    r.photo = Photo(data=large_photo, thumbnail=small_photo)
                    print cformat('  %{blue!}Photos')

            new_eq = []
            for old_equipment in ifilter(
                    None,
                    old_room._equipment.split('`') + old_room.avaibleVC):
                room_eq = l.get_equipment_by_name(old_equipment)
                new_eq.append(room_eq)
                r.available_equipment.append(room_eq)
            if new_eq:
                print cformat('  %{blue!}Equipment:%{reset} {}').format(
                    ', '.join(sorted(x.name for x in new_eq)))

            for attr_name, value in getattr(old_room, 'customAtts',
                                            {}).iteritems():
                value = convert_to_unicode(value)
                if not value or ('Simba' in attr_name
                                 and value == u'Error: unknown mailing list'):
                    continue
                attr_name = attribute_map.get(attr_name,
                                              attr_name).replace(' ',
                                                                 '-').lower()
                ca = l.get_attribute_by_name(attr_name)
                if not ca:
                    print cformat(
                        '  %{blue!}Attribute:%{reset} {} %{red!}not found'
                    ).format(attr_name)
                    continue
                attr = RoomAttributeAssociation()
                attr.value = value
                attr.attribute = ca
                r.attributes.append(attr)
                print cformat('  %{blue!}Attribute:%{reset} {} = {}').format(
                    attr.attribute.title, attr.value)

            l.rooms.append(r)
            db.session.add(l)
            print
        db.session.commit()