commit 1bcbef6220cd124e5914f91569a5483a7ce938b5 Author: Norm Rasmussen Date: Fri Feb 17 16:59:42 2023 -0500 Lots of good progress getting it setup. Need to figure out templating, easier calling of functions, and cleaner routing. diff --git a/.flaskenv b/.flaskenv new file mode 100644 index 0000000..5630929 --- /dev/null +++ b/.flaskenv @@ -0,0 +1 @@ +FLASK_APP=apicalls.py diff --git a/__pycache__/apicalls.cpython-311.pyc b/__pycache__/apicalls.cpython-311.pyc new file mode 100644 index 0000000..b60cefa Binary files /dev/null and b/__pycache__/apicalls.cpython-311.pyc differ diff --git a/__pycache__/config.cpython-311.pyc b/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000..6bb9169 Binary files /dev/null and b/__pycache__/config.cpython-311.pyc differ diff --git a/apicalls.py b/apicalls.py new file mode 100644 index 0000000..d099b92 --- /dev/null +++ b/apicalls.py @@ -0,0 +1 @@ +from app import app diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..f5b34f4 --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,7 @@ +from flask import Flask +from config import Config + +app = Flask(__name__) +app.config.from_object(Config) + +from app import routes diff --git a/app/__pycache__/__init__.cpython-311.pyc b/app/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..fbf19c7 Binary files /dev/null and b/app/__pycache__/__init__.cpython-311.pyc differ diff --git a/app/__pycache__/routes.cpython-311.pyc b/app/__pycache__/routes.cpython-311.pyc new file mode 100644 index 0000000..f8c5d2a Binary files /dev/null and b/app/__pycache__/routes.cpython-311.pyc differ diff --git a/app/forms.py b/app/forms.py new file mode 100644 index 0000000..47edf23 --- /dev/null +++ b/app/forms.py @@ -0,0 +1,8 @@ +from flask_wtf import FlaskForm +from wtforms import StringField, PasswordField, BooleanField, SubmitField +from wtforms.validators import DataRequired + + +class RequestForm(FlaskForm): + apikey = StringField("Academy API Key", validators=[DataRequired()]) + submit = SubmitField("Submit") diff --git a/app/getpage.html b/app/getpage.html new file mode 100644 index 0000000..4402923 --- /dev/null +++ b/app/getpage.html @@ -0,0 +1,39 @@ +{% extends 'head.html' %} +{% block content %} + +
+
+
+

Hello there, CUSTOMER SUCCESS MANAGER.

+ Northpass Full Color Logo +

Today is Monday 1, January 2000.

+
+

{{ request.form.apikey }}

+
+

Hello! Please select what you'd like to do.

+
+
+ + +

Get Fucked

+
+
+
+
+ + +

Get Fucked

+
+
+
+
+ + {% endblock %} diff --git a/app/routes.py b/app/routes.py new file mode 100644 index 0000000..5a746ef --- /dev/null +++ b/app/routes.py @@ -0,0 +1,72 @@ +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(): + 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") + 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("/get_courses", methods=["GET", "POST"]) +def get_courses(): + array = [] + df = pd.DataFrame() + 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) + 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("/get_people", methods=["GET", "POST"]) +def get_people(): + print(session['key']) + 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 + else: + return "what what" + + +@app.route("/startpage", methods=["GET", "POST"]) +def startpage(): + return render_template("startpage.html", title="StartTest") + + +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/static/NP-Logo-Primary-FC.png b/app/static/NP-Logo-Primary-FC.png new file mode 100644 index 0000000..4b14add Binary files /dev/null and b/app/static/NP-Logo-Primary-FC.png differ diff --git a/app/static/NP-Logo-Primary-White.png b/app/static/NP-Logo-Primary-White.png new file mode 100644 index 0000000..7c4cfcc Binary files /dev/null and b/app/static/NP-Logo-Primary-White.png differ diff --git a/app/static/app.js b/app/static/app.js new file mode 100644 index 0000000..485180f --- /dev/null +++ b/app/static/app.js @@ -0,0 +1,143 @@ + +/*****************/ +/* 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 new file mode 100644 index 0000000..2414e0b --- /dev/null +++ b/app/static/css/styles.css @@ -0,0 +1,167 @@ + +/* Custom Variables | Color Scheme */ + +:root { + --primary: #fff; + --text-light: #E5E9F0; + --background: #3B4252; + --background-light: #4C566A; +} + +*, +*::before, +*::after { + margin: 0; + padding: 0; + box-sizing: inherit; +} + +body { + margin-bottom: 0; + flex-grow: 1; + 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); + font-family: 'Space Grotesk', sans-serif; + padding: 2rem 4rem; + background-color: var(--background); + box-sizing: border-box; +} + +@keyframes gradient { + 0% { + background-position: 0% 79%; + } + 50% { + background-position: 100% 22%; + } + 100% { + background-position: 0% 79%; + } +} + +h1 { + font-size: 4rem; + font-weight: bold; +} + +h1 > span { + color: var(--primary); +} + +h4 { + align-items: center; + text-align: center; +} + +img { + height: 50px; + width 500px; + align-items: flex-start; +} +main { + margin: 4px; + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.header { + font-weight: 200; + margin-top: 80px; + display: flex; + justify-content: space-between; + align-items: center; +} + +#currentDate { + color: var(--primary); +} + +#currentTime { + font-size: 4rem; + font-weight: 600; +} + +@media screen and (max-width: 1250px) { + h1 { + display: none; + } + + .header { + flex-direction: column-reverse; + } + + #currentTime { + font-size: 3rem; + margin-bottom: 1rem; + } + + #fullDate { + text-align: center; + } +} + +.card:link, +.card:visited { + color: white; + text-decoration: none; + + margin: 1.2rem; + padding: 4rem 8rem; + + background-color: var(--background-light); + border-radius: 15px; + border: 1px solid #B48EAD; + + display: flex; + justify-content: center; + align-items: center; + + overflow: hidden; + cursor: pointer; + position: relative; + + outline: none; + transition: 0.1s; +} + +.card:hover, +.card:focus { + border-color: var(--primary); + color: var(--primary); + + transform: scale(1.02); +} + +.card:focus > .card__name { + bottom: 0; +} + +.card:hover > .card__name { + bottom: 0; +} + +.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%; + left: 50%; + transition: 0.1s; +} diff --git a/app/templates/get.html b/app/templates/get.html new file mode 100644 index 0000000..10cd20c --- /dev/null +++ b/app/templates/get.html @@ -0,0 +1,41 @@ +{% extends 'head.html' %} +{% block content %} + +
+
+
+

Hello there, CUSTOMER SUCCESS MANAGER.

+ Northpass Full Color Logo +

Today is Monday 1, January 2000.

+
+

{{ request.form.apikey }}

+
+

Hello! Please select what you'd like to do.

+
+
+ + +

Get People

+
+
+ +
+
+ + +

Get Courses

+
+
+
+
+ + {% endblock %} diff --git a/app/templates/get_courses.html b/app/templates/get_courses.html new file mode 100644 index 0000000..8e53cc4 --- /dev/null +++ b/app/templates/get_courses.html @@ -0,0 +1,21 @@ + + + + Northpass CSM Bulk Actions + + +
+
+ Northpass Full Color Logo +
+
+

Hello! Please select what you'd like to do.

+
+ + + +
+ + + + diff --git a/app/templates/head.html b/app/templates/head.html new file mode 100644 index 0000000..8e98b7a --- /dev/null +++ b/app/templates/head.html @@ -0,0 +1,20 @@ + + + + + + + + + CSM Bulk Actions + + + + + +{% block content %} {% endblock %} + diff --git a/app/templates/index.html b/app/templates/index.html new file mode 100644 index 0000000..f4fd752 --- /dev/null +++ b/app/templates/index.html @@ -0,0 +1,20 @@ +{% extends 'head.html' %} +{% block content %} + +
+
+
+

Hello there, CUSTOMER SUCCESS MANAGER.

+ Northpass Full Color Logo +
+

Hello! Please click below to enter your key.

+ {% if error %} +

Error! {{ error }} + {% endif %} +

+ + +
+
+ + {% endblock %} diff --git a/config.py b/config.py new file mode 100644 index 0000000..b10288f --- /dev/null +++ b/config.py @@ -0,0 +1,5 @@ +import os + + +class Config(object): + SECRET_KEY = os.environ.get("NORTHPASS") or "north-pass"