def admin():
    '''
    * Displays the admin user control page that lists
      all non-admin users.

    \n Args: None

    \n Returns:
    * Displays the admin page.
    '''
    all_users = list(mongo.db.users.find())
    if session:
        if 'user' in session:
            if session["user"] == "admin":

                pagination, users_paginated = paginated_and_pagination_args(
                    all_users, 30, "page", "per_page")
                return render_template('admin.html',
                                       all_users=users_paginated,
                                       pagination=pagination)

            else:
                flash("You do not have permission to access this page!")
                abort(403)
        else:
            flash("You do not have permission to access this page!")
            abort(403)
    else:
        flash("You must be logged in to access this page!")
        abort(403)
def search():
    '''
    * Takes the user inputed search query and filters back images that
      match the criterion.

    \n Args:
    1. query (str): User input from the search form.

    \n Returns:
    * Renders an array of paginated and filtered photo objects that match
      the search criterion on the browse template.
    '''
    source_url = request.referrer

    category = request.args.get("category")
    query = request.args.get("query")
    awards = [int(n) for n in request.args.getlist("award")]

    filtered_photos = filter_user_search(category, query, awards, mongo)

    pagination, photos_paginated = paginated_and_pagination_args(
        filtered_photos, 10, "page", "per_page")

    if not filtered_photos:
        flash("I'm sorry, but your search did not return any images.")

    return render_template("browse_images.html",
                           photos=photos_paginated,
                           pagination=pagination,
                           source_url=source_url,
                           category=category,
                           query=query,
                           awards=awards)
def admin_search():
    '''
    * Takes the admin's inputed search query and filters back users that
      match the keyword criterion.

    \n Args:
    1. query (str): Admin input from the admin search form.

    \n Returns:
    * Renders an array of paginated and filtered photo objects that match
      the search criterion on the browse template.
    '''
    if session:
        if 'user' in session:
            if session["user"] == 'admin':
                source_url = request.referrer

                query = request.args.get("query")

                filtered_users = filter_admin_search(query, mongo)

                pagination, users_paginated = \
                    paginated_and_pagination_args(
                                    filtered_users, 10, "page", "per_page")

                if not filtered_users:
                    flash("I'm sorry, but your\
                         search did not return any images.")

                return render_template("admin.html",
                                       all_users=users_paginated,
                                       pagination=pagination,
                                       source_url=source_url,
                                       query=query)
            else:
                flash("You do not have permission to access this page!")
                abort(403)
        else:
            flash("You do not have permission to access this page!")
            abort(403)
    else:
        flash("You must be logged in to access this page!")
        abort(403)
def browse():
    '''
    * Fetches all the photos entered into the competition from all time
      and paginates them for quicker loading times.

    \n Args: None

    \n Returns:
    * Template displaying all the images to the user, paginated.
    '''

    all_photos = list(mongo.db.photos.find({"type": "entry"}))

    pagination, photos_paginated = paginated_and_pagination_args(
        all_photos, 10, "page", "per_page")

    return render_template("browse_images.html",
                           photos=photos_paginated,
                           pagination=pagination)
def compete():
    '''
    * If method is GET this renders the compete template which
      outlines the competition rules, upload guidelines and entry form.
      If the method is POST this uploads the new entry and its data
      to the db and confirms the upload with a flash message. If the POST
      is unsuccessful a flash message is displayed detailing the issue.

    \n Args:
    1. user input from form(str & file): title, story, camera, lens, aperture,
       shutter, iso & photo file.

    \n Return:
    * Saves the data to the db & reloads the compete page whether successful
      or not, uses flash messages to inform the user of which.
    '''
    date_time = datetime.now()

    photo_user_voted_for = None

    if session:
        if 'user' in session:

            current_user = mongo.db.users.find_one(
                {"username": session["user"]})

            this_weeks_entries = list(
                mongo.db.photos.find(
                    {"week_and_year": date_time.strftime("%V%G")}))

            # If the user has voted
            if current_user["votes_to_use"] == 0:
                for img in current_user["photos_voted_for"]:
                    for entry in this_weeks_entries:
                        if img == entry["_id"]:
                            photo_user_voted_for = img
            else:
                photo_user_voted_for = None

            current_week_number = int(datetime.now().strftime("%V"))
            this_weeks_comp_category = get_competition(
                current_week_number)["category"]
            this_weeks_comp_instructions = get_competition(
                current_week_number)["instructions"]

            if request.method == 'POST':

                if current_user["can_enter"] is True:

                    upload_comp_entry(request, mongo, app,
                                      this_weeks_comp_category, current_user)

                    flash("Entry Received!")
                    return redirect(url_for('compete'))

                else:
                    flash("I'm sorry, but you've already entered \
                        an image in this week's competition!")

            this_weeks_entries = list(
                mongo.db.photos.find(
                    {"week_and_year": date_time.strftime("%V%G")}))

            pagination, photos_paginated = \
                paginated_and_pagination_args(
                                this_weeks_entries, 50, "page", "per_page")

            photos_paginated_copy = photos_paginated.copy()

            photos_paginated_shuffled = shuffle_array(photos_paginated_copy)

            return render_template(
                "compete.html",
                this_weeks_entries=photos_paginated_shuffled,
                datetime=date_time,
                category=this_weeks_comp_category,
                instructions=this_weeks_comp_instructions,
                pagination=pagination,
                user=current_user,
                photo_user_voted_for=photo_user_voted_for)

        else:
            flash("You must be logged in to view the competition page.")
            return redirect(url_for("login"))
    else:
        flash("You must be logged in to view the competition page.")
        return redirect(url_for("login"))