From d48e982a3f2464873d95302afdf7042cc81bf1f4 Mon Sep 17 00:00:00 2001 From: Norm Rasmussen Date: Wed, 22 Feb 2023 17:11:14 -0500 Subject: [PATCH] Bulk groups & people changes --- app/2 | 189 ++++++++++++++++++ app/__pycache__/routes.cpython-311.pyc | Bin 7695 -> 11947 bytes app/routes.py | 171 +++++++++++----- app/static/css/styles.css | 9 +- app/templates/bulk_add_groups.html | 27 +++ .../{bulk_add.html => bulk_add_ppl.html} | 15 +- app/templates/options.html | 25 ++- app/templates/table.html | 5 - 8 files changed, 370 insertions(+), 71 deletions(-) create mode 100644 app/2 create mode 100644 app/templates/bulk_add_groups.html rename app/templates/{bulk_add.html => bulk_add_ppl.html} (69%) diff --git a/app/2 b/app/2 new file mode 100644 index 0000000..7a7d52d --- /dev/null +++ b/app/2 @@ -0,0 +1,189 @@ +from app import app +from flask import request, Flask, flash, render_template, session, make_response +import requests +import json +import pandas as pd +import re + + +@app.route("/", methods=["GET", "POST"]) +def ask_key(): + 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: + return render_template("options.html", title="Options") + else: + error = "Hm. That doesn't seem right" + return render_template("index.html", title="Home", error=error) + + else: + return render_template("index.html", title="Home") + + +@app.route("/", methods=["GET", "POST"]) +def render_home(): + return render_template("index.html", title="Home") + + +@app.route("/get_courses", methods=["GET", "POST"]) +def get_courses(): + array = [] + df = pd.DataFrame() + tempdf = pd.DataFrame() + pd.set_option("display.max_colwidth", 100) + x = 0 + + if request.method == "POST": + while True: + x += 1 + url = f"https://api.northpass.com/v2/courses?page={x}" + headers = {"accept": "application/json", "X-Api-Key": session["key"]} + response = requests.get(url, headers=headers) + jsonresponse = response.json() + dt = jsonresponse["data"] + next = jsonresponse["links"] + + for course in dt: + df = df.append(course["attributes"], ignore_index=True) + # df = df.drop("list_image_url", axis=1) + + if "next" not in next: + break + + dfhtml = df.to_html(col_space=5) + session["dfcsv"] = df.to_csv() + return render_template("table.html", tables=dfhtml, titles="Course List") + + else: + return "This isn't working. Let's go our own way." + + +@app.route("/table") +def table(): + return render_template("table.html", tables=[session["dfhtml"]], titles=["Table"]) + + +@app.route("/downloadcsv", methods=["GET", "POST"]) +def download_csv(): + if request.method == "GET": + download = make_response(session["dfcsv"]) + download.headers["Content-Disposition"] = "attachment; filename=export.csv" + download.headers["Content-Type"] = "text/csv" + return download + + +@app.route("/get_people", methods=["GET", "POST"]) +def get_people(): + array = [] + ppl_dict = {} + df = pd.DataFrame() + x = 0 + + if request.method == "POST": + while True: + x += 1 + url = f"https://api.northpass.com/v2/people?page={x}" + headers = {"accept": "application/json", "X-Api-Key": session["key"]} + response = requests.get(url, headers=headers) + data = response.json() + + for response in data["data"]: + print(response) + uuid = response["id"] + ppl_dict = {"id": uuid} + for keys, values in response["attributes"].items(): + ppl_dict[keys] = values + array.append(ppl_dict) + + print(array) + + next = data["links"] + if "next" not in next: + break + + Table = [] + for key, value in array.items(): # or .items() in Python 3 + temp = [] + temp.extend([key,value]) #Note that this will change depending on the structure of your dictionary + Table.append(temp) + return render_template("table.html", tables=Table, titles="People List") + + +""" + for person in dt: + print(person) + df = df.append(person["attributes"], ignore_index=True) + + + dfppl = df.to_html(col_space=5) + session["dfcsv"] = df.to_csv() + + else: + return "what what" + """ + + +@app.route("/add_options", methods=["POST"]) +def add_options(): + array = [] + dict_response = {} + df = pd.DataFrame() + x = 0 + if request.method == "POST": + while True: + x += 1 + url = f"https://api.northpass.com/v2/groups?page={x}" + headers = {"accept": "application/json", "X-Api-Key": session["key"]} + response = requests.get(url, headers=headers) + data = response.json() + # data = json.loads(data) + print(data) + + # print(type(response)) + # print(response) + # jsonresponse = response.json() + # dt = jsonresponse["data"] + # next = jsonresponse["links"] + + # for group in dt: + # df = df.from_dict(group["attributes"], orient="index") + # df = df.append(group["id"], ignore_index=True) + # df = df.append(group["attributes"], ignore_index=True) + + # if "next" not in next: + # break + + session["dfcsv"] = df.to_csv() + dfgroups = df.to_html(col_space=5) + return render_template( + "bulk_add.html", tables=dfgroups, titles="Bulk Add Learners" + ) + + +@app.route("/bulk_add", methods=["GET", "POST"]) +def bulk_add(): + if request.method == "POST": + emails = request.form.get("emails") + groups = request.form.get("groups") + url = "https://api.northpass.com/v2/bulk/people" + + payload = { + "data": {"attributes": {"people": [{"email": emails, "groups": groups}]}} + } + + headers = { + "accept": "application/json", + "content-type": "application/json", + "X-Api-Key": session["key"], + } + + +app.secret_key = "@&I\x1a?\xce\x94\xbb0w\x17\xbf&Y\xa2\xc2(A\xf5\xf2\x97\xba\xeb\xfa" + + +if __name__ == "__main__": + ask_key() diff --git a/app/__pycache__/routes.cpython-311.pyc b/app/__pycache__/routes.cpython-311.pyc index c110b0b4e6d5c6cb624f9e9e66cfc150a772a4d9..6eefdbf4ac82fc4f54bc31e099740413298eabc4 100644 GIT binary patch literal 11947 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 +{% extends 'head.html' %} +{% block content %} +

Hello! Please enter Group Names below.

+ {% if error %} +

{{ error }}

+ {% endif %} + +

+
+

Please enter a comma separated list of Groups you'd like to add

+ +

+ +
+ +

Here is a list of your client's Groups.

+ Click here to download as CSV. + +
+ {{ table | safe }} +
+ + + {% endblock %} + + diff --git a/app/templates/bulk_add.html b/app/templates/bulk_add_ppl.html similarity index 69% rename from app/templates/bulk_add.html rename to app/templates/bulk_add_ppl.html index c411780..ee75889 100644 --- a/app/templates/bulk_add.html +++ b/app/templates/bulk_add_ppl.html @@ -6,24 +6,23 @@

{{ error }}

{% endif %} -

-
+

+

Please Copy and Paste Emails of learners you'd like to add

Please paste in the Group UUIDs which these learners should be added to.

- - +

+
+

Here is a list of your client's Groups.

Click here to download as CSV.
- -

{{ titles }}

- {{ table }} + {{ table | safe }} +
- {% endblock %} diff --git a/app/templates/options.html b/app/templates/options.html index ed084f3..148eeb7 100644 --- a/app/templates/options.html +++ b/app/templates/options.html @@ -12,8 +12,7 @@ style="cursor:pointer;">

Get People

- - +

Get Courses

- -
+

Bulk Add People

-
+
+ +
+ + +

Bulk Add Groups

+
diff --git a/app/templates/table.html b/app/templates/table.html index c4b148e..259b0a2 100644 --- a/app/templates/table.html +++ b/app/templates/table.html @@ -1,4 +1,3 @@ - {% extends 'head.html' %} {% block content %} @@ -6,11 +5,7 @@ Click here to download as CSV.
- - {% for table in tables %} -

{{ titles }}

{{ table | safe }} - {% endfor %}