forked from apozharski/gradescope-api
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
577c0d1
commit ca88c95
Showing
5 changed files
with
132 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,64 @@ | ||
from main import do_the_thing | ||
from flask import Flask, request, send_file | ||
from flask import Flask, request, send_file, render_template, make_response | ||
import json | ||
import base64 | ||
from typing import Callable, Dict, Any | ||
from typing import Dict, Any | ||
from io import BytesIO | ||
|
||
app = Flask(__name__) | ||
|
||
@app.route('/gradescope.ics') | ||
|
||
@app.route("/") | ||
def index(): | ||
response = make_response(render_template("index.html")) | ||
response.headers["Cache-Control"] = "public, max-age=3600" | ||
|
||
return response | ||
|
||
|
||
@app.route("/gradescope.ics") | ||
def gradescope_calendar(): | ||
try: | ||
# Get the base64 encoded query parameter | ||
encoded_data = request.args.get('data') | ||
encoded_data = request.args.get("data") | ||
if not encoded_data: | ||
return 'Missing data parameter', 400 | ||
return "Missing data parameter", 400 | ||
|
||
# Decode base64 to JSON string | ||
try: | ||
json_str = base64.b64decode(encoded_data).decode('utf-8') | ||
json_str = base64.b64decode(encoded_data).decode("utf-8") | ||
except Exception as e: | ||
return f'Invalid base64 encoding: {str(e)}', 400 | ||
return f"Invalid base64 encoding: {str(e)}", 400 | ||
|
||
# Parse JSON | ||
try: | ||
data: Dict[str, Any] = json.loads(json_str) | ||
except json.JSONDecodeError as e: | ||
return f'Invalid JSON: {str(e)}', 400 | ||
return f"Invalid JSON: {str(e)}", 400 | ||
|
||
# Validate required fields | ||
required_fields = ['email', 'pwd', 'sem'] | ||
required_fields = ["email", "pwd", "sem"] | ||
for field in required_fields: | ||
if field not in data: | ||
return f'Missing required field: {field}', 400 | ||
return f"Missing required field: {field}", 400 | ||
|
||
# Call do_the_thing with the parameters | ||
file_data = do_the_thing( | ||
email=data['email'], | ||
pwd=data['pwd'], | ||
sem=data['sem'] | ||
) | ||
file_data = do_the_thing(email=data["email"], pwd=data["pwd"], sem=data["sem"]) | ||
|
||
file_str = "".join(file_data) | ||
file_io = BytesIO(file_str.encode('utf-8')) | ||
file_io = BytesIO(file_str.encode("utf-8")) | ||
|
||
# Send the file | ||
return send_file( | ||
file_io, | ||
mimetype='text/calendar', | ||
mimetype="text/calendar", | ||
as_attachment=True, | ||
download_name='gradescope.ics' | ||
download_name="gradescope.ics", | ||
) | ||
|
||
except Exception as e: | ||
return f'Server error: {str(e)}', 500 | ||
return f"Server error: {str(e)}", 500 | ||
|
||
|
||
if __name__ == '__main__': | ||
app.run(debug=True) | ||
if __name__ == "__main__": | ||
app.run(debug=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Gradescope iCalendar</title> | ||
<style> | ||
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); | ||
|
||
body { | ||
font-family: 'Inter', sans-serif; | ||
} | ||
|
||
.container { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
/* justify-content: center; */ | ||
height: 100vh; | ||
} | ||
|
||
input { | ||
margin: 0.5rem; | ||
padding: 0.5rem; | ||
width: 300px; | ||
} | ||
|
||
h1 { | ||
margin-bottom: 20px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<h1>Gradescope iCalendar</h1> | ||
<input type="text" id="email" placeholder="Gradescope Email" /> | ||
<input type="password" id="pwd" placeholder="Gradescope Password" /> | ||
<input type="text" id="sem" placeholder="Semester (e.g. Spring 2025)" /> | ||
|
||
<div style="height: 1rem"></div> | ||
|
||
<input type="text" id="url" placeholder="URL" readonly /> | ||
</div> | ||
|
||
<script> | ||
function updateURL() { | ||
var email = document.getElementById("email").value; | ||
var pwd = document.getElementById("pwd").value; | ||
var sem = document.getElementById("sem").value; | ||
|
||
if (email === "" || pwd === "" || sem === "") { | ||
document.getElementById("url").value = ""; | ||
return; | ||
} | ||
|
||
const data = { | ||
email: email, | ||
pwd: pwd, | ||
sem: sem, | ||
}; | ||
|
||
const data_b64 = btoa(JSON.stringify(data)); | ||
|
||
let url = window.location.href; | ||
url = url.substring(0, url.lastIndexOf("/")); | ||
url += "/gradescope.ics?data=" + data_b64; | ||
document.getElementById("url").value = url; | ||
} | ||
|
||
document.getElementById("email").oninput = updateURL; | ||
document.getElementById("pwd").oninput = updateURL; | ||
document.getElementById("sem").oninput = updateURL; | ||
|
||
updateURL(); | ||
|
||
document.getElementById("url").onclick = function () { | ||
this.select(); | ||
document.execCommand("copy"); | ||
}; | ||
</script> | ||
</body> | ||
</html> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.