Пример #1
0
def add_resource():
    """
    POST endpoint that adds a new resource link to the club profile.
    """

    user = get_current_user()
    club = user.club

    json = g.clean_json

    res_name = json['name']
    res_link = json['link']

    new_resource_id = random_slugify(res_name, max_length=100)
    for resource in club.resources:
        if resource.id == new_resource_id:
            raise JsonError(status='error', reason='Resource already exists under that name')

    resource = Resource(
        id=new_resource_id,
        name=res_name,
        link=res_link
    )

    club.resources += [resource]

    user.club.last_updated = pst_right_now()
    user.save()

    return _fetch_resources_list(user)
Пример #2
0
def add_question():
    """
    POST endpoint that adds a new frequently asked question.
    """
    user = get_current_user()
    club = user.club

    json = g.clean_json
    question_statement = json['question']

    new_question_id = random_slugify(question_statement, max_length=100)
    for question in club.faq: 
        if question.id == new_question_id:
            raise JsonError(status='error', reason='Question already exists')

    new_question = Question(
            id = new_question_id,
            question = question_statement,
            answer = json['answer']
        )

    club.faq += [new_question]

    user.club.last_updated = pst_right_now()
    user.save()

    return _fetch_question_list(user)
Пример #3
0
def modify_gallery_pic(pic_id):
    """
    PUT endpoint that either replaces an existing gallery picture, changes the image's
    caption or does both at the same time.
    """

    user = get_current_user()
    json = g.clean_json

    gallery_pic = user.club.gallery_media.filter(id=pic_id).first()
    if gallery_pic is None:
        raise JsonError(status='error', reason='Specified gallery picture does not exist.')

    new_caption = json.get('caption', None)
    if new_caption is not None:
        gallery_pic.caption = new_caption

    gallery_pic_file = request.files.get('photo', None)

    if gallery_pic_file is not None:
        gallery_pic_url, new_pic_id = flask_exts.img_manager.upload_img_asset_s3(
            user.club.link_name, gallery_pic_file, 'gallery',
            file_size_limit = 2 * 1024 * 1024
        )
        
        gallery_pic.id = new_pic_id
        gallery_pic.url = gallery_pic_url
    
    user.club.last_updated = pst_right_now()

    user.save()
    return _fetch_gallery_media_list(user)
Пример #4
0
def add_gallery_media_pic():
    """
    POST endpoint that adds a new gallery picture to the club with an image upload and a caption.
    """

    user = get_current_user()
    json = g.clean_json

    gallery_pic_file = request.files.get('photo', None)

    if gallery_pic_file is not None:
        gallery_pic_url, pic_id = flask_exts.img_manager.upload_img_asset_s3(
            user.club.link_name, gallery_pic_file, 'gallery',
            file_size_limit = 2 * 1024 * 1024
        )

        gallery_pic = GalleryPic(
            id      = pic_id,
            url     = gallery_pic_url,
            caption = json['caption']
        )

        user.club.gallery_media += [gallery_pic]
        user.club.last_updated = pst_right_now()

        user.save()
        return _fetch_gallery_media_list(user)
    else:
        raise JsonError(status='error', reason='A gallery picture was not provided for uploading.')
Пример #5
0
def edit_profile():
    """
    POST endpoint that edits the club profile.
    """

    user = get_current_user()
    json = g.clean_json

    for key in json.keys():
        if key == 'is_reactivating':
            continue
        if key == 'tags':
            user.club['tags'] = Tag.objects.filter(id__in=json['tags'])
        elif key == 'num_users':
            user.club['num_users'] = NumUsersTag.objects.filter(id=json['num_users']).first()
        elif key == 'social_media_links':
            user.update(club__social_media_links=json['social_media_links'])
        else:
            user.club[key] = json[key]

    user.club.last_updated = pst_right_now()

    if json['is_reactivating'] and not user.club.reactivated:
        user.club.reactivated = True
        user.club.reactivated_last = user.club.last_updated
        
    user.save()

    return {'status': 'success'}
Пример #6
0
def add_recruiting_event():
    """
    POST endpoint that adds a new recruiting event.
    """

    user = get_current_user()
    club = user.club

    json = g.clean_json
    r_event_name = json['name']

    new_event_id = random_slugify(r_event_name, max_length=100)
    for r_event in club.recruiting_events:
        if r_event.id == new_event_id:
            raise JsonError(status='error', reason='Recruiting event already exists under that name')

    new_r_event = RecruitingEvent(
        id              = new_event_id,
        name            = r_event_name,
        link            = json['link'],
        virtual_link    = json['virtual_link'],
        event_start     = json['event_start'],
        event_end       = json['event_end'],
        description     = json['description'],
        invite_only     = json['invite_only'],
    )

    club.recruiting_events += [new_r_event]

    user.club.last_updated = pst_right_now()
    user.save()

    return _fetch_recruiting_events_list(user)
Пример #7
0
def remove_gallery_media(media_id):
    """
    DELETE endpoint that deletes an existing gallery picture.
    """

    user = get_current_user()

    user.club.gallery_media = [gallery_media for gallery_media in user.club.gallery_media if gallery_media.id != media_id]
    user.club.last_updated = pst_right_now()
    user.save()

    return _fetch_gallery_media_list(user)
Пример #8
0
    def update_apply_required_or_recruiting_statuses():
        """
        Update if a club is open for applying or recruiting.
        """
        right_now_dt = pst_right_now()

        for officer_user in NewOfficerUser.objects:
            if officer_user.club.app_required and officer_user.club.apply_deadline_start and officer_user.club.apply_deadline_end:
                apply_deadline_in_range = officer_user.club.apply_deadline_start < right_now_dt and officer_user.club.apply_deadline_end > right_now_dt
                officer_user.club.new_members = apply_deadline_in_range
                officer_user.save()
            elif not officer_user.club.app_required and officer_user.club.recruiting_start and officer_user.club.recruiting_end:
                recruiting_period_in_range = officer_user.club.recruiting_start < right_now_dt and officer_user.club.recruiting_end > right_now_dt
                officer_user.club.new_members = recruiting_period_in_range
                officer_user.save()
Пример #9
0
def add_event():
    """
    POST endpoint that adds a new event.
    """

    user = get_current_user()
    club = user.club

    json = g.clean_json

    event_name        = json['name']
    event_invite_only = json['invite_only']
    event_link        = json['link']
    event_links       = json['links']
    event_location    = json['location']
    event_start       = json['event_start']
    event_end         = json['event_end']
    event_description = json['description']
    event_tags        = json['tags']

    new_event_id = random_slugify(event_name, max_length=100)
    for event in club.events:
        if event.id == new_event_id:
            raise JsonError(status='error', reason='Event already exists under that name')

    event = Event(
        id=new_event_id,
        invite_only=event_invite_only,
        name=event_name,
        link=event_link,
        links=event_links,
        location=event_location,
        event_start=event_start,
        event_end=event_end,
        description=event_description,
        tags=event_tags
    )

    club.events += [event]

    user.club.last_updated = pst_right_now()
    user.save()

    return _fetch_event_list(user)
Пример #10
0
def delete_question(question_id):
    """
    DELETE endpoint that deletes an existing question.
    """
    user = get_current_user()
    club = user.club

    prev_len = len(club.faq)

    club.faq = [question for question in club.faq if question.id != question_id]

    user.club.last_updated = pst_right_now()
    user.save()
    
    new_len = len(club.faq)
    if new_len != prev_len:
        return _fetch_question_list(user)
    else:
        raise JsonError(status='error', reason='Requested question does not exist', status_=404)
Пример #11
0
def delete_recruiting_event(r_event_id):
    """
    DELETE endpoint that deletes an existing recruiting event.
    """

    user = get_current_user()
    club = user.club

    prev_len = len(club.recruiting_events)

    club.recruiting_events = [r_event for r_event in club.recruiting_events if r_event.id != r_event_id]

    user.club.last_updated = pst_right_now()
    user.save()

    new_len = len(club.recruiting_events)
    if new_len != prev_len:
        return _fetch_recruiting_events_list(user)
    else:
        raise JsonError(status='error', reason='Requested recruiting event does not exist', status_=404)
Пример #12
0
def delete_resource(resource_id):
    """
    DELETE endpoint that deletes an existing resource link.
    """

    user = get_current_user()
    club = user.club

    prev_len = len(club.resources)

    club.resources = [resource for resource in club.resources if resource.id != resource_id]

    user.club.last_updated = pst_right_now()
    user.save()

    new_len = len(club.resources)
    if new_len != prev_len:
        return _fetch_resources_list(user)
    else:
        raise JsonError(status='error', reason='Requested resource does not exist', status_=404)
Пример #13
0
def update_recruiting_event(r_event_id):
    """
    PUT endpoint that updates an existing recruiting event.
    """

    user = get_current_user()
    club = user.club

    json = g.clean_json

    for (i, r_event) in enumerate(club.recruiting_events):
        if r_event.id == r_event_id:
            for key in json.keys():
                club.recruiting_events[i][key] = json[key]

            user.club.last_updated = pst_right_now()
            user.save()

            return _fetch_recruiting_events_list(user)

    raise JsonError(status='error', reason='Requested recruiting event does not exist', status_=404)
Пример #14
0
def update_resource(resource_id):
    """
    PUT endpoint that updates an existing resource link.
    """

    user = get_current_user()
    club = user.club

    json = g.clean_json

    for (i, resource) in enumerate(club.resources):
        if resource.id == resource_id:
            for key in json.keys():
                if json.get(key) is not None:
                    club.resources[i][key] = json[key]

            user.club.last_updated = pst_right_now()
            user.save()

            return _fetch_resources_list(user)

    raise JsonError(status='error', reason='Requested resource does not exist', status_=404)
Пример #15
0
def confirm_email(token):
    """
    GET endpoint that confirms the new officer user. This endpoint link is normally within
    the confirmation email.
    """

    club_email = flask_exts.email_verifier.confirm_token(
        token, 'confirm-email')
    if club_email is None:
        raise JsonError(status='error',
                        reason='The confirmation link is invalid.',
                        status_=404)

    potential_user = NewOfficerUser.objects(email=club_email).first()
    if potential_user is None:
        raise JsonError(status='error',
                        reason='The user matching the email does not exist.',
                        status_=404)

    # First, revoke the given email token
    flask_exts.email_verifier.revoke_token(token, 'confirm-email')

    if potential_user.confirmed:
        return redirect(LOGIN_URL + LOGIN_CONFIRMED_EXT)

    confirmed_on = pst_right_now()
    if confirmed_on - potential_user.registered_on > CurrentConfig.CONFIRM_EMAIL_EXPIRY:
        raise JsonError(
            status='error',
            reason=
            'The account associated with the email has expired. Please request for a new confirmation email by logging in.'
        )

    # Then, set the user and club to 'confirmed' if it's not done already
    potential_user.confirmed = True
    potential_user.confirmed_on = confirmed_on
    potential_user.save()

    return redirect(LOGIN_URL + LOGIN_CONFIRMED_EXT)
Пример #16
0
def upload_logo():
    """
    POST endpoint that replaces the current club's logo with a new one. Logos must respect
    a 1:1 aspect ratio (with a default 5% deviation allowed). A 2 MB limit is imposed as well.
    """

    user = get_current_user()

    logo_file = request.files.get('logo', None)

    if logo_file is not None:
        logo_url, _ = flask_exts.img_manager.upload_img_asset_s3(
            user.club.link_name, logo_file, 'logo',
            req_aspect_ratio = 1.0,
            file_size_limit = 2 * 1024 * 1024
        )

        user.club.last_updated = pst_right_now()
        user.club.logo_url = logo_url

        user.save()
        return {'status': 'success', 'logo-url': user.club.logo_url}
    else:
        raise JsonError(status='error', reason='A logo was not provided for uploading.')
Пример #17
0
def upload_banner():
    """
    POST endpoint that replaces the current club's banner with a new one. Banners must respect
    a 10:3 aspect ratio (with a default 5% deviation allowed). A 2 MB limit is imposed as well.
    """

    user = get_current_user()

    banner_file = request.files.get('banner', None)

    if banner_file is not None:
        banner_url, _ = flask_exts.img_manager.upload_img_asset_s3(
            user.club.link_name, banner_file, 'banner',
            req_aspect_ratio = 10 / 3,
            file_size_limit = 10 * 1024 * 1024
        )

        user.club.last_updated = pst_right_now()
        user.club.banner_url = banner_url

        user.save()
        return {'status': 'success', 'banner-url': user.club.banner_url}
    else:
        raise JsonError(status='error', reason='A banner was not provided for uploading.')
Пример #18
0
def fetch_sign_up_stats():
    """
    GET endpoint that fetches the sign up statistics for all user account types.
    """

    time_delta = pst_right_now() - datetime.timedelta(weeks=1)
    history_deltas = [
        pst_right_now() - datetime.timedelta(weeks=delay)
        for delay in range(11)
    ]

    # Officer stats
    num_registered_clubs = NewOfficerUser.objects.count()
    recent_num_registered_clubs = NewOfficerUser.objects.filter(
        registered_on__gte=time_delta).count()
    num_registered_clubs_history = reversed(
        array_diff([
            NewOfficerUser.objects.filter(
                registered_on__gte=hist_delta).count()
            for hist_delta in history_deltas
        ]))

    num_confirmed_clubs = NewOfficerUser.objects.filter(confirmed=True).count()
    recent_num_confirmed_clubs = NewOfficerUser.objects.filter(
        confirmed=True, registered_on__gte=time_delta).count()
    num_confirmed_clubs_history = reversed(
        array_diff([
            NewOfficerUser.objects.filter(
                confirmed=True, registered_on__gte=hist_delta).count()
            for hist_delta in history_deltas
        ]))

    num_reactivated_clubs = NewOfficerUser.objects.filter(
        confirmed=True, club__reactivated=True).count()
    recent_num_reactivated_clubs = NewOfficerUser.objects.filter(
        confirmed=True,
        club__reactivated=True,
        club__reactivated_last__gte=time_delta).count()
    num_reactivated_clubs_history = reversed(
        array_diff([
            NewOfficerUser.objects.filter(
                confirmed=True,
                club__reactivated=True,
                club__reactivated_last__gte=hist_delta).count()
            for hist_delta in history_deltas
        ]))

    num_clubs_rso_list = PreVerifiedEmail.objects.count()

    # Student stats
    num_students_signed_up = NewStudentUser.objects.count()
    recent_num_students_signed_up = NewStudentUser.objects.filter(
        registered_on__gte=time_delta).count()

    num_confirmed_students = NewStudentUser.objects.filter(
        confirmed=True).count()
    recent_num_confirmed_students = NewStudentUser.objects.filter(
        confirmed=True, registered_on__gte=time_delta).count()

    return {
        'club_admin': {
            'main': {
                'clubs_registered': num_registered_clubs,
                'clubs_confirmed': num_confirmed_clubs,
                'clubs_reactivated': num_reactivated_clubs,
                'clubs_rso_list': num_clubs_rso_list,
            },
            'changed': {
                'clubs_registered': recent_num_registered_clubs,
                'clubs_confirmed': recent_num_confirmed_clubs,
                'clubs_reactivated': recent_num_reactivated_clubs,
            },
            'history': {
                'clubs_registered': num_registered_clubs_history,
                'clubs_confirmed': num_confirmed_clubs_history,
                'clubs_reactivated': num_reactivated_clubs_history,
            }
        },
        'student': {
            'main': {
                'students_signed_up': num_students_signed_up,
                'students_confirmed': num_confirmed_students,
            },
            'changed': {
                'students_signed_up': recent_num_students_signed_up,
                'students_confirmed': recent_num_confirmed_students
            }
        }
    }