예제 #1
0
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)
예제 #2
0
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')
예제 #3
0
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())
예제 #4
0
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')
예제 #5
0
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')
예제 #6
0
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()
예제 #7
0
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'])
예제 #8
0
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')
예제 #9
0
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('/')
예제 #10
0
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')
예제 #11
0
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))
예제 #12
0
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))
예제 #13
0
    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
예제 #14
0
def load_user(id):
    try:
        return db_session.query(User).get(id)
    except (TypeError, ValueError):
        pass