diff --git a/app/__pycache__/routes.cpython-311.pyc b/app/__pycache__/routes.cpython-311.pyc
index f8c5d2a..6d68df8 100644
Binary files a/app/__pycache__/routes.cpython-311.pyc and b/app/__pycache__/routes.cpython-311.pyc differ
diff --git a/app/getpage.html b/app/getpage.html
deleted file mode 100644
index 4402923..0000000
--- a/app/getpage.html
+++ /dev/null
@@ -1,39 +0,0 @@
-{% extends 'head.html' %}
-{% block content %}
-
-
-
-
Hello! Please select what you'd like to do.
-
-
-
-
-
-
-
- {% endblock %}
diff --git a/app/routes.py b/app/routes.py
index 5a746ef..9b05885 100644
--- a/app/routes.py
+++ b/app/routes.py
@@ -8,61 +8,126 @@ import re
@app.route("/", methods=["GET", "POST"])
def ask_key():
+ session.clear()
if request.method == "POST":
- session['key'] = request.form.get('apikey')
- print(session['key'])
- flash(session['key'])
- if re.search(r'(\S+\w+)', session['key']) and len(session['key']) > 5:
- print("regex worked")
- print(len(session['key']))
- return render_template("get.html", title="Options")
+ 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":
- url = "https://api.northpass.com/v2/courses"
- headers = {"accept": "application/json", "X-Api-Key": session['key']}
- response = requests.get(url, headers=headers)
- jsonresponse = response.json()
- dt = jsonresponse["data"]
- for course in dt:
- df = df.append(course["attributes"], ignore_index=True)
+ 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."
- print(df)
- download = make_response(df.to_csv())
- download.headers["Content-Disposition"] = "attachment; filename=export.csv"
- download.headers["Content-Type"] = "text/csv"
- return download
+
+
+@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():
- print(session['key'])
+ array = []
+ df = pd.DataFrame()
+ x = 0
+
if request.method == "POST":
- url = "https://api.northpass.com/v2/people"
- headers = {"accept": "application/json", "X-Api-Key": session['key']}
- response = requests.get(url, headers=headers)
- jsonresponse = response.json()
- dt = jsonresponse
- person = dt
- print(person)
- return person
+ 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)
+ jsonresponse = response.json()
+ dt = jsonresponse["data"]
+ next = jsonresponse["links"]
+
+ for person in dt:
+ print(person)
+ df = df.append(person["attributes"], ignore_index=True)
+
+ if "next" not in next:
+ break
+
+ dfppl = df.to_html(col_space=5)
+ session["dfcsv"] = df.to_csv()
+ return render_template("table.html", tables=dfppl, titles="People List")
+
else:
return "what what"
-@app.route("/startpage", methods=["GET", "POST"])
-def startpage():
- return render_template("startpage.html", title="StartTest")
+@app.route("/add_options")
+def add_options():
+ return render_template("bulk_add.html", title="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"
diff --git a/app/static/app.js b/app/static/app.js
deleted file mode 100644
index 485180f..0000000
--- a/app/static/app.js
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*****************/
-/* EDITABLE INFO */
-/*****************/
-
-/* -------------------------------------------------------- */
-
-const NAME = "Norm";
-
-const CARDS = [
- {
- name: "Get all Users",
- icon: "ri-admin-line",
- link: "submit",
- },
- {
- name: "Get all Courses",
- icon: "ri-mail-line",
- link: "submit",
- },
- {
- name: "Get all Assignments",
- icon: "ri-calendar-line",
- link: "submit",
- },
- ];
-/* -------------------------------------------------------- */
-
-/******************/
-/* CLOCK FUNCTION */
-/******************/
-
-const DAYS = [
- "Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday",
-];
-
-const MONTHS = [
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December",
-];
-
-const updateDate = () => {
- // Create a new Date object and get the complete Date/Time information
- const completeDate = new Date();
-
- // Time Variables
- let currentHour = formatDigit(completeDate.getHours());
- let currentMinute = formatDigit(completeDate.getMinutes());
-
- // Date Variables
- let currentDay = completeDate.getDay();
- let currentNumber = completeDate.getDate();
- let currentMonth = completeDate.getMonth();
- let currentYear = completeDate.getFullYear();
-
- // Update the Time
- currentTime.innerHTML = `${
- currentHour % 12 == 0 ? "12" : currentHour % 12
- }:${currentMinute} ${currentHour > 11 ? "PM" : "AM"}`;
-
- // Update the Date
- currentDate.innerHTML = `${DAYS[currentDay]} ${currentNumber}, ${MONTHS[currentMonth]} ${currentYear}`;
-
- // Create a Loop
- setTimeout(() => {
- updateDate();
- }, 1000);
-};
-
-const formatDigit = (digit) => {
- return digit > 9 ? `${digit}` : `0${digit}`;
-};
-
-/******************/
-/* CARDS FUNCTION */
-/******************/
-
-const printCards = () => {
- for (const card of CARDS) {
- let currentCard = document.createElement("a");
- let currentCardText = document.createElement("p");
- currentCardText.appendChild(document.createTextNode(card.name));
- let currentCardIcon = document.createElement("i");
- currentCardIcon.classList.add(card.icon);
-
- // Style the Card Element
- currentCard.classList.add("card");
- currentCard.href = card.link;
-
- // Handle the click event
- currentCard.addEventListener("click", async (event) => {
- //document.forms["apiform"].submit();
- // Copy the href to the clipboard
- try {
- await navigator.clipboard.writeText(card.link);
- currentCard.blur();
- currentCardText.innerText = "Saved to clipboard!";
- setTimeout(() => {
- currentCardText.innerText = card.name;
- }, 1500);
- } catch {
- currentCardText.innerText = "Unable to copy";
- setTimeout(() => {
- currentCardText.innerText = card.name;
- }, 1500);
- }
- });
-
- // Style the Icon
- currentCardIcon.classList.add("card__icon");
-
- // Style the Text
- currentCardText.classList.add("card__name");
-
- currentCard.append(currentCardIcon);
- currentCard.append(currentCardText);
- cardContainer.appendChild(currentCard);
- }
-};
-
-/****************/
-/* STARTER CODE */
-/****************/
-
-userName.innerHTML = NAME;
-printCards();
-updateDate();
diff --git a/app/static/css/styles.css b/app/static/css/styles.css
index 2414e0b..e06c155 100644
--- a/app/static/css/styles.css
+++ b/app/static/css/styles.css
@@ -2,10 +2,12 @@
/* Custom Variables | Color Scheme */
:root {
- --primary: #fff;
- --text-light: #E5E9F0;
- --background: #3B4252;
- --background-light: #4C566A;
+ --primary: #66C92D;
+ --text-light: #FFFFFF;
+ --text-dark: #667E8A;
+ --background: #667E8A;
+ --background-light: #E5E9EB;
+ height: 100%;
}
*,
@@ -17,21 +19,17 @@
}
body {
- margin-bottom: 0;
- flex-grow: 1;
- background: linear-gradient(
+ /*background: linear-gradient(
145deg, #81A1C1, #88C0D0, #8FBCBB, #A3BE8C, #EBCB8B, #D08770
);
background-size: 700% 550%;
- animation: gradient 7s ease-in-out infinite;
- height: 125vh;
- margin-top: -100px;
- padding-top: 100px;
- color: var(--text-light);
+ animation: gradient 7s ease-in-out infinite;*/
+ color: var(--text-dark);
font-family: 'Space Grotesk', sans-serif;
- padding: 2rem 4rem;
- background-color: var(--background);
+ background-color: var(--background-light);
box-sizing: border-box;
+ text-align: center;
+ width: 100%;
}
@keyframes gradient {
@@ -46,6 +44,42 @@ body {
}
}
+html {
+ display: flex;
+ justify-content: center;
+}
+
+input,
+select {
+ width: 200px;
+ height: 25px;
+ margin: 2px;
+ --moz-box-sizing: border-box;
+ --webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.dataframe {
+ font-size: 11pt;
+ border-collapse: collapse;
+ border: 1px solid #66C92D;
+ width: 100%;
+ text-align: left !important;
+}
+
+.dataframe td, th {
+ padding: 5px;
+}
+
+.dataframe tr:nth-child(even) {
+ background: #193D4F;
+}
+
+.dataframe tr:hover {
+ background: #096F8E;
+ cursor: pointer;
+}
+
h1 {
font-size: 4rem;
font-weight: bold;
@@ -61,13 +95,11 @@ h4 {
}
img {
- height: 50px;
- width 500px;
- align-items: flex-start;
+ height: 80px;
}
+
main {
margin: 4px;
- display: flex;
flex-wrap: wrap;
justify-content: center;
}
@@ -75,9 +107,7 @@ main {
.header {
font-weight: 200;
margin-top: 80px;
- display: flex;
justify-content: space-between;
- align-items: center;
}
#currentDate {
@@ -91,7 +121,7 @@ main {
@media screen and (max-width: 1250px) {
h1 {
- display: none;
+ display: flex;
}
.header {
@@ -107,7 +137,26 @@ main {
text-align: center;
}
}
+ul {
+ display: flex;
+}
+.card-grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ grid-auto-rows: 100px;
+ grid-gap: 2rem;
+ padding: 20px;
+}
+
+.card {
+ background-color: #089FB7;
+ padding: 5px;
+ border-radius: 10px;
+ border: 1px solid #66C92D;
+ color: #FFFFFF;
+}
+/*
.card:link,
.card:visited {
color: white;
@@ -117,8 +166,6 @@ main {
padding: 4rem 8rem;
background-color: var(--background-light);
- border-radius: 15px;
- border: 1px solid #B48EAD;
display: flex;
justify-content: center;
@@ -130,13 +177,10 @@ main {
outline: none;
transition: 0.1s;
-}
+}*/
.card:hover,
.card:focus {
- border-color: var(--primary);
- color: var(--primary);
-
transform: scale(1.02);
}
@@ -151,17 +195,13 @@ main {
.card__icon {
font-size: 2rem;
padding: 1rem;
- background-color: #81A1C1;
- border-radius: 50%;
display: grid;
- place-items: center;
}
.card__name {
font-weight: 400;
transform: translate(-50%, -50%);
- position: absolute;
- bottom: -25%;
+ position: relative;
left: 50%;
transition: 0.1s;
}
diff --git a/app/static/getallgroups.js b/app/static/getallgroups.js
new file mode 100644
index 0000000..fecb43a
--- /dev/null
+++ b/app/static/getallgroups.js
@@ -0,0 +1,40 @@
+document.addEventListener("DOMContentLoaded", function() {
+ getAllGroups();
+});
+
+const apiKey = 'session["key"]';
+const groups= [];
+const getAllGroups = async (num) => {
+ if(num === 1){
+ }
+ let page = num;
+
+ await axios({
+ method: 'get',
+ url: `https://api.northpass.com/v2/groups?page=${page}`,
+ headers: {
+ 'accept': '*/*',
+ 'x-api-key': apiKey,
+ 'content-type': 'application/json'
+ }
+ })
+ .then(async (res) => {
+ if (res.data.links.next != null) {
+ page++;
+ for (let i = 0; i < res.data.data.length; i++) {
+ let groupName = res.data.data[i].attributes.name;
+ selectInput = '';
+ $('#groups').append(selectInput);
+ groups.push(res.data.data[i].attributes.name);
+ }
+ await getAllGroups(page);
+ } else {
+ for (let i = 0; i < res.data.data.length; i++) {
+ groups.push(res.data.data[i].attributes.name);
+ }
+ }
+ })
+ .catch(err => {
+ console.log(err);
+ })
+}
diff --git a/app/templates/bulk_add.html b/app/templates/bulk_add.html
new file mode 100644
index 0000000..7500594
--- /dev/null
+++ b/app/templates/bulk_add.html
@@ -0,0 +1,24 @@
+
+{% extends 'head.html' %}
+{% block content %}
+ Hello! Please enter the emails below.
+ {% if error %}
+ {{ error }}
+ {% endif %}
+
+
+
+
+
+
+
-
-
Hello! Please select what you'd like to do.
-
+
+
+