def get_reservation(reservation): reservation = db_session.query(Reservation).filter_by( id=reservation).first() if reservation: return reservation_schema.jsonify(reservation) else: return abort(404)
def get_reservations(room, start=None, end=None): room = db_session.query(Room).filter_by(id=room).first() if room: reservations = room.reservations.filter( Reservation.cancelled.in_( [True, False] if g.user.admin else [False]) & (Reservation.start >= start) & (Reservation.end <= end)) return reservations_schema.jsonify(reservations) else: return error('Invalid room')
def reservations(): reservations = db_session.query(Reservation).options( joinedload(Reservation.room)) if not g.user.admin: reservations = reservations.filter_by(user=g.user) reservations = reservations.all() return render_template('reservations.html', reservations=reservations, now=datetime.datetime.now())
def sudo(): if request.method == 'POST': if request.form.get('password') == app.config['config']['DEFAULT'][ 'SUDO_ACCOUNT_PASSWORD']: sudo_user = db_session.query(User).filter_by( id=app.config['SUDO_USERID']).first() login_user(sudo_user) return redirect('/') flash('Incorrect password.') return render_template('sudo.html')
def ban_users(): users = set(request.form.getlist('banned-users')) for user in db_session.query(User).filter(( (User.banned == True) & ~User.id.in_(users)) | ( (User.banned == False) & User.id.in_(users))).all( ): # noqa: E712 (SQLAlchemy requires it) user.banned = user.id in users db_session.commit() flash('Updated list of banned users (%s users).' % len(users)) return redirect('/admin')
def cancel_reservation(reservation): reservation = db_session.query(Reservation).filter_by( id=reservation).first() if not reservation: return error('Invalid reservation') if reservation.start <= datetime.datetime.now(): return error('Cannot edit reservation starting in the past') if not g.user.admin and reservation.user != g.user: return error('Unauthorized to cancel that reservation') reservation.cancelled = True db_session.commit() return success()
def index(): authenticated = g.user and g.user.is_authenticated if request.args.get('logged_in', False) and authenticated: session['last_login'] = g.user.last_login g.user.last_login = datetime.datetime.now() db_session.commit() template = 'index.html' if authenticated: template = 'calendar.html' return render_template(template, rooms=db_session.query(Room).all(), config=app.config['config'])
def admin(): if request.method == 'GET': context = { 'rooms': db_session.query(Room).all(), 'users': db_session.query(User).all(), 'sudo': app.config['SUDO_USERID'], } return render_template('admin.html', **context) else: room_id = request.form.get('id', None) if not room_id: return abort(400) room = db_session.query(Room).filter_by(id=room_id).first() if not room: return abort(400) room.name = request.form.get('name', '') room.description = request.form.get('description', '') room.reservable = bool(request.form.get('reservable')) db_session.commit() return redirect('/admin')
def login_as(): user_id = request.form.get('id') if not user_id: return abort(400) user = db_session.query(User).filter_by(id=user_id).first() if not user: user = User(id=user_id) db_session.add(user) db_session.commit() logout_user() login_user(user) flash('Logged in as %s.' % user.id) return redirect('/')
def add_admin(): users = set(request.form.getlist('admins')) | set( [app.config['SUDO_USERID']]) if g.user.id not in users: flash('You may not remove your own administrative privileges.') return redirect('/admin') for user in db_session.query(User).filter(( (User.admin == True) & ~User.id.in_(users)) | ( (User.admin == False) & User.id.in_(users))).all( ): # noqa: E712 (SQLAlchemy requires it) user.admin = user.id in users db_session.commit() flash('Updated list of admins: %s.' % ', '.join(users)) return redirect('/admin')
def edit_reservation(reservation, start=None, end=None): reservation = db_session.query(Reservation).filter_by( id=reservation).first() if not reservation: return error('Invalid reservation') if not g.user.admin and reservation.user != g.user: return error('Unauthorized to edit that reservation') if reservation.start <= datetime.datetime.now(): return error('Cannot edit reservation starting in the past') try: reservation.start = start reservation.end = end db_session.commit() return success() except AssertionError as e: db_session.rollback() return error(str(e))
def add_reservation(start=None, end=None): room = request.form.get('room', None) if not room: return error('Missing room') room = db_session.query(Room).filter_by(id=int(room)).first() if not room: return error('Invalid room') try: db_session.add( Reservation(user_id=g.user.id, room_id=room.id, start=start, end=end)) db_session.commit() return success() except AssertionError as e: db_session.rollback() return error(str(e))
def validates_times(self, key, value): if key == 'end': start, end = self.start, value now = datetime.datetime.now() duration = end - start week_start = start.date() - datetime.timedelta( days=start.weekday()) week_end = week_start + datetime.timedelta(days=7) day_start = start.date() day_end = day_start + datetime.timedelta(days=1) admin = self.user_id in admins room = db_session.query(Room).filter_by( id=int(self.room_id)).first() config = functools.partial(app.config['config'].getint, 'SCHEDULING') user_reservations = room.reservations.filter( (Reservation.id != self.id) & (Reservation.cancelled == False) & # noqa: E712 (SQLAlchemy requires it) (Reservation.user_id == self.user_id)) contiguous_reservations = Reservation.contiguous_before( user_reservations, start) + Reservation.contiguous_after( user_reservations, end) contiguous_duration = sum( map(operator.methodcaller('duration'), contiguous_reservations), datetime.timedelta()) week_reservations = user_reservations.filter( (Reservation.start >= week_start) & (Reservation.start <= week_end)).all() week_reservation_duration = sum( map(operator.methodcaller('duration'), week_reservations), datetime.timedelta()) day_reservations = user_reservations.filter( (Reservation.start >= day_start) & (Reservation.start <= day_end)).all() day_reservation_duration = sum( map(operator.methodcaller('duration'), day_reservations), datetime.timedelta()) assert start > now, \ 'Reservation must start in the future' assert (start - now) <= datetime.timedelta(days=config('MAX_DAYS_IN_FUTURE')), \ 'Reservation must start in the next %d days' % config('MAX_DAYS_IN_FUTURE') assert end > start, \ 'Reservation must end after it starts' assert admin or datetime.timedelta(minutes=config('MINIMUM_DURATION_MINUTES')) <= duration, \ 'Reservation must be at least %d minutes' % config('MINIMUM_DURATION_MINUTES') assert admin or duration <= datetime.timedelta(hours=config('MAX_CONTIGUOUS_DURATION_HOURS')), \ 'Reservation must not be longer than %d hours' % config('MAX_CONTIGUOUS_DURATION_HOURS') assert admin or duration + contiguous_duration <= datetime.timedelta(hours=config('MAX_CONTIGUOUS_DURATION_HOURS')), \ 'Reservations must not be longer than %d contiguous hours' % config('MAX_CONTIGUOUS_DURATION_HOURS') assert room.reservations.filter(Reservation.cancelled == False, Reservation.id != self.id).filter( # noqa: E712 (SQLAlchemy requires it) ((Reservation.start <= start) & (Reservation.end > start)) | ((Reservation.start >= start) & (Reservation.end <= end)) | ((Reservation.start < end) & (Reservation.end >= end)) ).count() == 0, \ 'Reservation must not overlap with another' assert admin or duration + week_reservation_duration <= datetime.timedelta(hours=config('MAX_WEEK_HOURS')), \ 'Reservations must not exceed %d hours per week' % config('MAX_WEEK_HOURS') assert admin or duration + day_reservation_duration <= datetime.timedelta(hours=config('MAX_DAY_HOURS')), \ 'Reservations must not exceed %d hours per day' % config('MAX_DAY_HOURS') assert len(day_reservations) + 1 <= config('MAX_DAY_RESERVATIONS'), \ 'Reservations per day may not exceed %d reservations' % config('MAX_DAY_RESERVATIONS') return value
def load_user(id): try: return db_session.query(User).get(id) except (TypeError, ValueError): pass