From 074819ce8f49ee43a35913f6afabcf2e1caf30d3 Mon Sep 17 00:00:00 2001 From: Norm Rasmussen Date: Thu, 2 Mar 2023 17:56:31 -0500 Subject: [PATCH] Started the CSV Upload functionality --- app/__pycache__/routes.cpython-311.pyc | Bin 15835 -> 16926 bytes app/routes.py | 128 +++++++++++++++---------- app/templates/csv.html | 14 +++ app/templates/options.html | 3 +- 4 files changed, 91 insertions(+), 54 deletions(-) create mode 100644 app/templates/csv.html diff --git a/app/__pycache__/routes.cpython-311.pyc b/app/__pycache__/routes.cpython-311.pyc index 155c7fe1ddf5318ece18441dffca175acaa70f82..dec5ff3e6f94a68a51c755610504e7cef2cf3700 100644 GIT binary patch delta 6914 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 a50KNKiWF7%6k&EE=Z&+z{jZu4`2PzZoN;CV delta 5743 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 diff --git a/app/routes.py b/app/routes.py index a00e0f3..ec06a0c 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,25 +1,31 @@ -from app import app -from flask import request, Flask, flash, render_template, session, make_response import requests -import json import itertools import pandas as pd -from itables import show import re +import os +import glob +from app import app +from flask import request, render_template, session, make_response + +# Upload folder +UPLOAD_FOLDER = 'static/files' +app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER +ALLOWED_EXTENSIONS = {'csv'} def key_response(response): if "402" in str(response): error = response.text return render_template("index.html", title="Error Home", error=error) - elif "401" in str(response): + if "401" in str(response): error = [ - "Unauthorized access error. This can mean a lot of things, such as the key being changed.", + "Unauthorized access error.", + "This can mean a lot of things,", + "such as the key being changed.", "Remember, they are paired to each educator!", ] return render_template("index.html", title="Error Home", error=error) - else: - return correct_key(response) + return correct_key(response) def correct_key(response): @@ -29,31 +35,45 @@ def correct_key(response): return render_template("options.html", title="Options") + @app.route("/", methods=["GET", "POST"]) def ask_key(): + """This is the main function that asks for the API Key. + Without this key, no other functions will work. + It also assigns the api key to the session and clears the session upon each reload. + """ session.clear() if request.method == "POST": session["key"] = request.form.get("apikey") - if re.search("\s", session["key"]): - error = "Hm. That doesn't seem right" - return render_template("index.html", title="Home", error=error) - elif session["key"] is not None and len(session["key"]) > 10: + #if re.search(r"\s", session["key"]): + # error = "Hm. That doesn't seem right" + # return render_template("index.html", title="Home", error=error) + if session["key"] is not None and len(session["key"]) > 10: url = "https://api.northpass.com/v2/properties/school" headers = {"accept": "application/json", "X-Api-Key": session["key"]} response = requests.get(url, headers=headers) return key_response(response) - else: - error = "Hm. That doesn't seem right" - return render_template("index.html", title="Home", error=error) + error = "Hm. That doesn't seem right" + return render_template("index.html", title="Home", error=error) - else: - return render_template("index.html", title="Home") + return render_template("index.html", title="Home") -# @app.route("/", method="POST") -# def upload_csv(): -# pass +@app.route("/csv", methods=["GET", "POST"]) +def parse_csv(): + csvData = pd.DataFrame() + if request.method == 'POST': + uploaded_file = request.files['file'] + file_path = os.path.join(app.config['UPLOAD_FOLDER'], uploaded_file.filename) + uploaded_file.save(file_path) + col_names = ['Learner Full Name', 'Email','Course Name'] + csvData = pd.read_csv(file_path,names=col_names, header=None) + return "SUBMITTED!" + for i,row in csvData.iterrows(): + print(i, row['Email']) + return("File uploaded!") + return render_template("csv.html", title="Upload") @app.route("/", methods=["GET", "POST"]) def render_home(): @@ -78,18 +98,16 @@ def download_csv(): def get_courses(): array = [] course_dict = {} - df = pd.DataFrame() - tempdf = pd.DataFrame() pd.set_option("display.max_colwidth", 100) - x = 0 + count = 0 + dataframe = pd.DataFrame() if request.method == "POST": while True: - x += 1 - url = f"https://api.northpass.com/v2/courses?page={x}" + count += 1 + url = f"https://api.northpass.com/v2/courses?page={count}" headers = {"accept": "application/json", "X-Api-Key": session["key"]} response = requests.get(url, headers=headers) - jsonresponse = response.json() data = response.json() nextlink = data["links"] @@ -105,7 +123,7 @@ def get_courses(): dataframe["full_description"] = dataframe[ "full_description" ].str.replace(r"<[^<>]*>", "", regex=True) - print(dataframe) + print(dataframe) if "next" not in nextlink: break @@ -121,13 +139,13 @@ def get_courses(): def get_people(): array = [] ppl_dict = {} - df = pd.DataFrame() - x = 0 + count = 0 + dataframe = pd.DataFrame() if request.method == "POST": while True: - x += 1 - url = f"https://api.northpass.com/v2/people?page={x}" + count += 1 + url = f"https://api.northpass.com/v2/people?page={count}" headers = {"accept": "application/json", "X-Api-Key": session["key"]} response = requests.get(url, headers=headers) data = response.json() @@ -140,7 +158,7 @@ def get_people(): ppl_dict[keys] = values array.append(ppl_dict) dataframe = pd.DataFrame(array).drop("custom_avatar_url", axis=1) - print(dataframe) + print(dataframe) if "next" not in nextlink: break @@ -156,12 +174,13 @@ def get_people(): def add_ppl_opts(): array = [] dict_response = {} - df = pd.DataFrame() - x = 0 + dataframe = pd.DataFrame() + count = 0 + if request.method == "POST": while True: - x += 1 - url = f"https://api.northpass.com/v2/groups?page={x}" + count += 1 + url = f"https://api.northpass.com/v2/groups?page={count}" headers = {"accept": "application/json", "X-Api-Key": session["key"]} response = requests.get(url, headers=headers) data = response.json() @@ -190,13 +209,12 @@ def add_ppl_opts(): @app.route("/bulk_add_ppl", methods=["GET", "POST"]) def bulk_add_ppl(): - emailarr = [] - grouparr = [] if request.method == "POST": emails = request.form.get("emails") groups = request.form.get("groups") - emails = emails.split(",") - groups = groups.split(",") + emails.split(",") + groups.split(",") + url = "https://api.northpass.com/v2/bulk/people" combinations = list(itertools.product(emails, groups)) print(combinations) @@ -219,9 +237,9 @@ def bulk_add_ppl(): error=error, ) elif "403" in response: - error = "Uh oh. Looks like you're not the admin or don't have appropriate privileges. Please talk to your academy admin." + error = "Uh oh. Looks like you don't have appropriate privileges." elif "422" in response: - error = "Hm. Looks like something was wrong with the names. Reach out to the manager of this app." + error = "Hm. Looks like something was wrong with the names." return render_template( "bulk_add_people.html", table=session["dfgroups"], @@ -237,12 +255,13 @@ def bulk_add_ppl(): def add_groups_opts(): array = [] dict_response = {} - df = pd.DataFrame() - x = 0 + count = 0 + dataframe = pd.DataFrame() + if request.method == "POST": while True: - x += 1 - url = f"https://api.northpass.com/v2/groups?page={x}" + count += 1 + url = f"https://api.northpass.com/v2/groups?page={count}" headers = {"accept": "application/json", "X-Api-Key": session["key"]} response = requests.get(url, headers=headers) data = response.json() @@ -272,14 +291,14 @@ def add_groups_opts(): @app.route("/bulk_add_groups", methods=["GET", "POST"]) def bulk_add_groups(): grouparr = [] - i = 0 + count = 0 if request.method == "POST": groups = request.form.get("groups") - if "\n" in groups: - groups = groups.split("\n") + if '\n' in groups: + groups.split('\n') groups = [group.strip() for group in groups] - elif "," in groups: - groups = groups.split(",") + elif ',' in groups: + groups.split(",") groups = [group.strip() for group in groups] for group in groups: groupdict = {} @@ -305,9 +324,12 @@ def bulk_add_groups(): error=error, ) elif "403" in response: - error = "Uh oh. Looks like you're not the admin or don't have appropriate privileges. Please talk to your academy admin." + error = [ "Uh oh. Looks like you're not the", + "admin or don't have appropriate privileges.", + "Please talk to your academy admin." ] elif "422" in response: - error = "Hm. Looks like something was wrong with the group names. Reach out to the manager of this app." + error = ["Hm. Looks like something was wrong with the group names.", + "Reach out to the manager of this app."] return render_template( "bulk_add_groups.html", table=session["dfgroups"], diff --git a/app/templates/csv.html b/app/templates/csv.html new file mode 100644 index 0000000..8989f8e --- /dev/null +++ b/app/templates/csv.html @@ -0,0 +1,14 @@ + +{% include 'logo.html' %} +{% extends 'head.html' %} +{% block content %} + +

If you'd like to upload a CSV. Please do so here:

+

+
+

+

+
+ +{% endblock %} + diff --git a/app/templates/options.html b/app/templates/options.html index a5715be..776e1db 100644 --- a/app/templates/options.html +++ b/app/templates/options.html @@ -2,7 +2,8 @@ {% extends 'head.html' %} {% include 'logo.html' %} {% block content %} -

Hello! Please find the options for {{ session.school }}.

+

Hello! Please find the options for {{ session.school }}.

+