computer-science-club

computer-science-club
git clone https://git.prime8.dev/computer-science-club.git
Log | Files | Refs | README | LICENSE

commit e682f8ed3791160d4a9853d83c78bc932809d2a0
parent 590e18cd444f676dda633d3cecd4c1233f12f9e5
Author: Damian Myrda <damian@prime8.dev>
Date:   Thu, 25 Apr 2024 22:16:21 -0500

Update and format everything

Diffstat:
M.gitignore | 1+
MREADME.md | 10+++++++---
Mconfig.py | 1+
Mdatabase.json | 14+++++++++++++-
Mdatabase.py | 47++++++++++++++++++++++++-----------------------
Mmain.py | 102++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mmodels/discussion.py | 55++++++++++++++++++++++++++++++++-----------------------
Mmodels/event.py | 34++++++++++++++++++++--------------
Mmodels/group.py | 46+++++++++++++++++++++++-----------------------
Mmodels/member.py | 10+++++-----
Mmodels/project.py | 22+++++++++++-----------
Mmodels/update.py | 15++++++++-------
Mprojects.py | 28++++++++++++++--------------
Mschoology.py | 114++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mstatic/intro.css | 70+++++++++++++++++++++++++++++++++++-----------------------------------
Mstatic/style.css | 19++++++++++---------
Mtemplates/discussions.html | 34++++++++++++++++++----------------
Mtemplates/elements/authors.html | 7+++----
Mtemplates/elements/datetime.html | 10+++-------
Mtemplates/elements/discussions.html | 20+++++++-------------
Mtemplates/elements/events.html | 55+++++++++++++------------------------------------------
Mtemplates/elements/metadata.html | 10++++------
Mtemplates/elements/navigation.html | 20++++++++++++++------
Mtemplates/elements/projects.html | 77+++++++++++++++++++++++++++++++++--------------------------------------------
Mtemplates/elements/space.html | 38+++++++++++++++++++-------------------
Mtemplates/elements/updates.html | 30+++++++++++++-----------------
Mtemplates/home.html | 43+++++++++++++++++++++----------------------
Mtemplates/members.html | 74++++++++++++++++++++++++++++++++++++++------------------------------------
Mtemplates/projects.html | 43++++++++++++++++++++++---------------------
Mtemplates/updates.html | 34++++++++++++++++++----------------
30 files changed, 584 insertions(+), 499 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,3 +3,4 @@ lib64 bin/ __pycache__/ pyvenv.cfg +google_auth.json diff --git a/README.md b/README.md @@ -1,11 +1,15 @@ # computer_science_club + A website for Computer Science Club. It was made during a mini-hackathon. ## setup -To setup the server environment, run ```python -m venv .``` in the root of the project. Then, execute ```. ./bin/activate``` and you should be in the virtual environment. Next, run ```pip install flask schoolopy``` to install all the dependencies. Now, exit using by running ```exit```. + +To setup the server environment, run `python -m venv .` in the root of the project. Then, execute `. ./bin/activate` and you should be in the virtual environment. Next, run `pip install flask schoolopy` to install all the dependencies. Now, exit using by running `exit`. + +To setup Google OAuth2, goto [get google api clientid](https://developers.google.com/identity/oauth2/web/guides/get-google-api-clientid) and follow the instructions. Copy the json file into `google_auth.json` in the root of the project. In the `config.py` file in the directory of the project, change `REDIRECT_URL` to the url you used when you set up the google project. ## running -To run the server, you need an API key and its companioning secret. In your browser, go to ```schoology.(PUT DOMAIN HERE).org/api```. There, you can manage your API credentials. Get the key and secret and return. -Now, you can execute ```SCHOOLOGY_API_KEY="PUT KEY HERE" SCHOOLOGY_API_SECRET="PUT SECRET HERE" ./run.sh```. +To run the server, you need an API key and its companioning secret. In your browser, go to `schoology.(PUT DOMAIN HERE).org/api`. There, you can manage your API credentials. Get the key and secret and return. +Now, you can execute `SCHOOLOGY_API_KEY="PUT KEY HERE" SCHOOLOGY_API_SECRET="PUT SECRET HERE" ./run.sh`. diff --git a/config.py b/config.py @@ -1,2 +1,3 @@ DOMAIN = "https://schoology.d214.org" GROUP_ID = 6454678062 +REDIRECT_URL = "127.0.0.1:5000" diff --git a/database.json b/database.json @@ -1 +1,13 @@ -{"py/object": "database.Data", "projects": [{"py/object": "project.Project", "name": "Computer Science Club Website", "description": "Made for Computer Science Club's Mini-Hackathon.", "authors": ["Damian Myrda"], "source": "https://github.com/moncheeta/computer_science_club", "images": null}]} +{ + "py/object": "database.Data", + "projects": [ + { + "py/object": "project.Project", + "name": "Computer Science Club Website", + "description": "(this website)", + "authors": ["Damian Myrda"], + "source": "https://github.com/moncheeta/computer_science_club.git", + "images": null + } + ] +} diff --git a/database.py b/database.py @@ -1,31 +1,32 @@ import os from jsonpickle import decode, encode + class Data: - projects = [] - - def __init__(self, projects): - self.projects = projects + projects = [] + + def __init__(self, projects): + self.projects = projects + class Database: - def read(self): - if not os.path.isfile("database.json"): - data = Data([]) - self.write(data) - return data - with open("database.json", "r") as file: - return decode(file.read()) - - def write(self, data): - with open("database.json", "w") as file: - file.write(encode(data)) + def read(self): + if not os.path.isfile("database.json"): + return Data([]) + with open("database.json", "r") as file: + return decode(file.read()) + + def write(self, data): + with open("database.json", "w") as file: + file.write(encode(data)) + class ProjectDatabase: - def read(self): - projects = [] - for project in Database().read().projects: - projects.append(project) - return projects - - def write(self, projects): - Database().write(Data(projects)) + def read(self): + projects = [] + for project in Database().read().projects: + projects.append(project) + return projects + + def write(self, projects): + Database().write(Data(projects)) diff --git a/main.py b/main.py @@ -1,34 +1,120 @@ import os, sys, pathlib + PROJECT_DIR = os.path.join(pathlib.Path(__file__).parent) sys.path.append(os.path.join(PROJECT_DIR, "config.py")) sys.path.append(os.path.join(PROJECT_DIR, "models")) sys.path.append(os.path.join(PROJECT_DIR, "projects.py")) sys.path.append(os.path.join(PROJECT_DIR, "schoology.py")) +from config import REDIRECT_URL +from models import Project +from database import ProjectDatabase from schoology import group -from flask import Flask, render_template +from flask import Flask, request, redirect, abort, render_template, session +from cachecontrol import CacheControl app = Flask(__name__) app.secret_key = "https://computer-science-club.moncheeto.repl.co" + @app.route("/") def index(): - return render_template("home.html", group=group) + return render_template("home.html", group=group, account=session.get("name")) + @app.route("/updates") def updates(): - return render_template("updates.html", group=group) + return render_template("updates.html", group=group, account=session.get("name")) + @app.route("/discussions") def discussions(): - return render_template("discussions.html", group=group) + return render_template("discussions.html", group=group, account=session.get("name")) + -@app.route("/projects", methods = ["GET", "POST"]) +@app.route("/projects", methods=["GET", "POST"]) def projects(): - return render_template("projects.html", group=group) + return render_template( + "projects.html", group=group, create=False, account=session.get("name") + ) + + +@app.route("/projects/add", methods=["GET", "POST"]) +def add_project(): + if request.method == "POST": + if not session.get("name"): + return abort(401) + name = request.form["name"].rstrip() + description = request.form["description"].rstrip() + authors = request.form["authors"] + for author in authors: + author = author.rstrip() + source = request.form["source"].rstrip() + if source == "": + source = None + images = request.files.get("images") + group.projects.append(Project(name, description, [authors], source, images)) + ProjectDatabase().write(group.projects) + return redirect("/projects") + return render_template( + "projects.html", group=group, create=True, account=session.get("name") + ) + @app.route("/members") def members(): - return render_template("members.html", group=group) + return render_template("members.html", group=group, account=session.get("name")) + + +import requests +import google.auth.transport.requests +from google_auth_oauthlib.flow import Flow +from google.oauth2 import id_token + +GOOGLE_CLIENT_ID = ( + "861597772911-7k5ipk33tj84ubts3oulmqt6jp053hnr.apps.googleusercontent.com" +) +GOOGLE_CLIENT_SECRETS_FILE = os.path.join(PROJECT_DIR, "google_auth.json") +GOOGLE_AUTH_SCOPES = [ + "https://www.googleapis.com/auth/userinfo.profile", + "https://www.googleapis.com/auth/userinfo.email", + "openid", +] +os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1" +flow = Flow.from_client_secrets_file( + client_secrets_file=GOOGLE_CLIENT_SECRETS_FILE, + scopes=GOOGLE_AUTH_SCOPES, + redirect_uri="http://" + REDIRECT_URL + "/login/callback", +) + + +@app.route("/login") +def login(): + auth_url, state = flow.authorization_url() + session["state"] = state + return redirect(auth_url) + + +@app.route("/login/callback") +def login_callback(): + flow.fetch_token(authorization_response=request.url) + if not session["state"] == request.args["state"]: + abort(500) + credentials = flow.credentials + request_session = requests.session() + cached_session = CacheControl(request_session) + token_request = google.auth.transport.requests.Request(session=cached_session) + id_info = id_token.verify_oauth2_token( + id_token=credentials._id_token, request=token_request, audience=GOOGLE_CLIENT_ID + ) + session["name"] = id_info.get("name") + return redirect("/") + + +@app.route("/logout") +def logout(): + session.clear() + return redirect("/") + if __name__ == "__main__": - app.run(host='0.0.0.0', port=8000) + app.run(host="0.0.0.0") diff --git a/models/discussion.py b/models/discussion.py @@ -1,30 +1,39 @@ from config import DOMAIN + class Discussion: - name = "" - description = "" - link = f"{DOMAIN}/discussion/" - - def __init__(self, id, name, description): - self.link += str(id) - self.name = name - self.description = description + name = "" + description = "" + link = f"{DOMAIN}/discussion/" + + def __init__(self, id, name, description): + self.link += str(id) + self.name = name + self.description = description + + from datetime import datetime from config import DOMAIN + class Event: - name = "" - description = "" - start = datetime.now() - end = None - differentDay = False - link = f"{DOMAIN}/event/" - - def __init__(self, id, name, description, start, end): - self.link += str(id) - self.name = name - self.description = description - self.start = start - self.end = end - if end and self.end.year >= self.start.year and self.end.month >= self.start.month and self.end.day > start.day: - differentDay = True + name = "" + description = "" + start = datetime.now() + end = None + differentDay = False + link = f"{DOMAIN}/event/" + + def __init__(self, id, name, description, start, end): + self.link += str(id) + self.name = name + self.description = description + self.start = start + self.end = end + if ( + end + and self.end.year >= self.start.year + and self.end.month >= self.start.month + and self.end.day > start.day + ): + differentDay = True diff --git a/models/event.py b/models/event.py @@ -1,19 +1,25 @@ from datetime import datetime from config import DOMAIN + class Event: - name = "" - description = "" - start = datetime.now() - end = None - differentDay = False - link = f"{DOMAIN}/event/" + name = "" + description = "" + start = datetime.now() + end = None + differentDay = False + link = f"{DOMAIN}/event/" - def __init__(self, id, name, description, start, end): - self.link += str(id) - self.name = name - self.description = description - self.start = start - self.end = end - if end and self.end.year >= self.start.year and self.end.month >= self.start.month and self.end.day > start.day: - differentDay = True + def __init__(self, id, name, description, start, end): + self.link += str(id) + self.name = name + self.description = description + self.start = start + self.end = end + if ( + end + and self.end.year >= self.start.year + and self.end.month >= self.start.month + and self.end.day > start.day + ): + differentDay = True diff --git a/models/group.py b/models/group.py @@ -1,24 +1,25 @@ class Group: - name = "" - description = "" - picture = "https://www.shutterstock.com/image-vector/computer-science-icon-outline-thin-600nw-1613513884.jpg" - leaders = [] - members = [] - events = [] - updates = [] - discussions = [] - projects = [] + name = "" + description = "" + picture = "https://www.shutterstock.com/image-vector/computer-science-icon-outline-thin-600nw-1613513884.jpg" + leaders = [] + members = [] + events = [] + updates = [] + discussions = [] + projects = [] - def __init__(self, name, description, events, updates, discussions, projects, members): - self.name = name - self.description = description - self.events = events - self.updates = updates - self.discussions = discussions - self.projects = projects - for member in members: - if member.leader: - self.leaders.append(member) - continue - self.members.append(member) - -\ No newline at end of file + def __init__( + self, name, description, events, updates, discussions, projects, members + ): + self.name = name + self.description = description + self.events = events + self.updates = updates + self.discussions = discussions + self.projects = projects + for member in members: + if member.leader: + self.leaders.append(member) + continue + self.members.append(member) diff --git a/models/member.py b/models/member.py @@ -1,7 +1,7 @@ class Member: - name = "" - leader = False + name = "" + leader = False - def __init__(self, name = "", leader = False): - self.name = name - self.leader = leader + def __init__(self, name="", leader=False): + self.name = name + self.leader = leader diff --git a/models/project.py b/models/project.py @@ -1,13 +1,13 @@ class Project: - name = "" - description = "" - authors = [] - source = None - images = None + name = "" + description = "" + authors = [] + source = None + images = None - def __init__(self, name, description, authors, source = None, images = None): - self.name = name - self.description = description - self.authors = authors - self.source = source - self.images = images + def __init__(self, name, description, authors, source=None, images=None): + self.name = name + self.description = description + self.authors = authors + self.source = source + self.images = images diff --git a/models/update.py b/models/update.py @@ -1,12 +1,13 @@ from datetime import datetime from member import Member + class Update: - member = Member() - text = "" - time = datetime.now() + member = Member() + text = "" + time = datetime.now() - def __init__(self, member, text, time): - self.member = member - self.text = text - self.time = time + def __init__(self, member, text, time): + self.member = member + self.text = text + self.time = time diff --git a/projects.py b/projects.py @@ -1,19 +1,19 @@ from models import Project from database import Database, Data + class ProjectDatabase: - def read(self): - projects = [] - for project in Database().read()["projects"]: - name = project.get("name") - description = project.get("description") - authors = project.get("authors") - source = project.get("source") - images = project.get("images") - projects.append(Project(name, description, authors, source, images)) - return projects + def read(self): + projects = [] + for project in Database().read()["projects"]: + name = project.get("name") + description = project.get("description") + authors = project.get("authors") + source = project.get("source") + images = project.get("images") + projects.append(Project(name, description, authors, source, images)) + return projects - def write(self, projects): - with open("database.json", "w") as file: - file.write(encode(Data(projects))) - + def write(self, projects): + with open("database.json", "w") as file: + file.write(encode(Data(projects))) diff --git a/schoology.py b/schoology.py @@ -1,71 +1,77 @@ import os from datetime import datetime from config import DOMAIN, GROUP_ID -from models import Group, Event, Update, Discussion, Project, Member +from models import Group, Event, Update, Discussion, Member +from database import ProjectDatabase from schoolopy import Schoology, Auth + class SchoologyAPI: - api = None - auth = Auth(os.environ["SCHOOLOGY_API_KEY"], os.environ["SCHOOLOGY_API_SECRET"], domain = DOMAIN) + api = None + auth = Auth( + os.environ["SCHOOLOGY_API_KEY"], + os.environ["SCHOOLOGY_API_SECRET"], + domain=DOMAIN, + ) + + def __init__(self): + self.api = Schoology(self.auth) + self.api.limit = 64 - def __init__(self): - self.api = Schoology(self.auth) - self.api.limit = 64 + def name(self): + return self.api.get_group(GROUP_ID).title - def name(self): - return self.api.get_group(GROUP_ID).title + def description(self): + return self.api.get_group(GROUP_ID).description - def description(self): - return self.api.get_group(GROUP_ID).description + def events(self): + events = [] + for event in self.api.get_group_events(GROUP_ID): + start = datetime.strptime(event.start, "%Y-%m-%d %H:%M:%S") + end = None + if event.has_end: + end = datetime.strptime(event.end, "%Y-%m-%d %H:%M:%S") + event = Event(event.id, event.title, event.description, start, end) + events.append(event) + return events - def events(self): - events = [] - for event in self.api.get_group_events(GROUP_ID): - start = datetime.strptime(event.start, "%Y-%m-%d %H:%M:%S") - end = None - differentDay = False - if event.has_end: - end = datetime.strptime(event.end, "%Y-%m-%d %H:%M:%S") - event = Event(event.id, event.title, event.description, start, end) - events.append(event) - return events + def updates(self): + updates = [] + for update in self.api.get_group_updates(GROUP_ID): + user = self.api.get_user(update.uid) + member = Member(user.name_display) + # time = datetime.utcfromtimestamp(int(update.created)) + time = datetime.utcfromtimestamp(int(update.last_updated)) + updates.append(Update(member, update.body, time)) + return updates - def updates(self): - updates = [] - for update in self.api.get_group_updates(GROUP_ID): - user = self.api.get_user(update.uid) - member = Member(user.name_display) - #time = datetime.utcfromtimestamp(int(update.created)) - time = datetime.utcfromtimestamp(int(update.last_updated)) - updates.append(Update(member, update.body, time)) - return updates + def discussions(self): + discussions = [] + for discussion in self.api.get_group_discussions(GROUP_ID): + discussions.append( + Discussion(discussion.id, discussion.title, discussion.body) + ) + return discussions - def discussions(self): - discussions = [] - for discussion in self.api.get_group_discussions(GROUP_ID): - discussions.append(Discussion(discussion.id, discussion.title, discussion.body)) - return discussions + def members(self): + members = [] + for enrolled in self.api.get_group_enrollments(GROUP_ID): + member = Member(enrolled.name_display) + if enrolled.admin == 1: + member.leader = True + members.append(member) + return members - def members(self): - members = [] - for enrolled in self.api.get_group_enrollments(GROUP_ID): - member = Member(enrolled.name_display) - if enrolled.admin == 1: - member.leader = True - members.append(member) - return members + def group(self): + name = self.name() + description = self.description() + events = self.events() + updates = self.updates() + discussions = self.discussions() + projects = ProjectDatabase().read() + members = self.members() + return Group(name, description, events, updates, discussions, projects, members) - def group(self): - name = self.name() - description = self.description() - events = self.events() - updates = self.updates() - discussions = self.discussions() - projects = [ - Project("Computer Science Club Website", "(this website)", ["Damian Myrda"], "https://replit.com/@Moncheeto/Computer-Science-Club?v=1") - ] - members = self.members() - return Group(name, description, events, updates, discussions, projects, members) api = SchoologyAPI() group = api.group() diff --git a/static/intro.css b/static/intro.css @@ -1,58 +1,58 @@ * { - color: #FFFF82; - text-align: center; - background-color: black; + color: #ffff82; + text-align: center; + background-color: black; } #board { - font-family: sans-serif; - transform: perspective(300px) rotateX(25deg); - transform-origin: 50% 100%; - text-align: justify; - position: absolute; - margin-left: -9em; - font-weight: bold; - overflow: hidden; - font-size: 350%; - height: 50em; - width: 18em; - bottom: 0; - left: 50%; + font-family: sans-serif; + transform: perspective(300px) rotateX(25deg); + transform-origin: 50% 100%; + text-align: justify; + position: absolute; + margin-left: -9em; + font-weight: bold; + overflow: hidden; + font-size: 350%; + height: 50em; + width: 18em; + bottom: 0; + left: 50%; } #board:after { - position: absolute; - content: ' '; - bottom: 60%; - left: 0; - right: 0; - top: 0; + position: absolute; + content: " "; + bottom: 60%; + left: 0; + right: 0; + top: 0; } #content { - animation: scroll 128s; - position: absolute; - top: 100%; + animation: scroll 128s; + position: absolute; + top: 100%; } @keyframes scroll { - 0% { - top: 100%; - } - 100% { - top: -350%; - } + 0% { + top: 100%; + } + 100% { + top: -350%; + } } #back { - color: white; + color: white; } #back.hidden { - opacity: 0; + opacity: 0; } #back.shown { - opacity: 1; - transition: opacity 2000ms; + opacity: 1; + transition: opacity 2000ms; } diff --git a/static/style.css b/static/style.css @@ -1,19 +1,20 @@ * { - color: white; - font-family: monospace; + color: white; + font-family: monospace; } body { - background-color: black; + background-color: black; } -input, textarea { - color: black; +input, +textarea { + color: black; } center { - top: 50%; - left: 50%; - transform: translate(-50%,-50%); - position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + position: absolute; } diff --git a/templates/discussions.html b/templates/discussions.html @@ -1,21 +1,23 @@ <html> -<head> - {% import "elements/metadata.html" as metadata %} - {{ metadata.head(group, "Discussions") }} - <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> -</head> + <head> + {% import "elements/metadata.html" as metadata %} {{ metadata.head(group, + "Discussions") }} + <link + rel="stylesheet" + href="{{ url_for('static', filename='style.css') }}" + /> + </head> -<header> - {% import "elements/navigation.html" as navigation %} - {{ navigation.bar() }} -</header> + <header> + {% import "elements/navigation.html" as navigation %} {{ + navigation.bar(account) }} + </header> -<body> - {% import "elements/space.html" as space %} - {{ space.stars(500) }} + <body> + {% import "elements/space.html" as space %} {{ space.stars(500) }} - <h1>Discussions</h1> - {% import "elements/discussions.html" as discussions %} - {{ discussions.list(group.discussions) }} -</body> + <h1>Discussions</h1> + {% import "elements/discussions.html" as discussions %} {{ + discussions.list(group.discussions) }} + </body> </html> diff --git a/templates/elements/authors.html b/templates/elements/authors.html @@ -1,9 +1,8 @@ {% macro view(author) -%} <a>{{ author }}</a> -{%- endmacro %} - -{% macro list(authors) -%} +{%- endmacro %} {% macro list(authors) -%} <div> - By: {{ view(authors[0]) }}{% for author in authors[1:] %}, {{ author }}{% endfor %} + By: {{ view(authors[0]) }}{% for author in authors[1:] %}, {{ author }}{% + endfor %} </div> {%- endmacro %} diff --git a/templates/elements/datetime.html b/templates/elements/datetime.html @@ -1,7 +1,3 @@ -{% macro time(time) -%} - {{ time.hour }}:{{ time.minute }} -{%- endmacro %} - -{% macro date(date) -%} - {{ date.year }}.{{ date.month }}.{{ date.day }} -{%- endmacro %} +{% macro time(time) -%} {{ time.hour }}:{{ time.minute }} {%- endmacro %} {% +macro date(date) -%} {{ date.year }}.{{ date.month }}.{{ date.day }} {%- +endmacro %} diff --git a/templates/elements/discussions.html b/templates/elements/discussions.html @@ -1,14 +1,8 @@ {% macro view(discussion) -%} - <a target="_blank" href="{{ discussion.link }}"> - {{ discussion.name }} - {{ discussion.description }} - </a> -{%- endmacro %} - -{% macro list(discussions) -%} -{% for discussion in discussions %} -<div> - {{ view(discussion) }} -</div> -{% endfor %} -{%- endmacro %} +<a target="_blank" href="{{ discussion.link }}"> + {{ discussion.name }} {{ discussion.description }} +</a> +{%- endmacro %} {% macro list(discussions) -%} {% for discussion in discussions +%} +<div>{{ view(discussion) }}</div> +{% endfor %} {%- endmacro %} diff --git a/templates/elements/events.html b/templates/elements/events.html @@ -1,46 +1,17 @@ -{% import "elements/datetime.html" as datetime %} - -{% macro view(event) -%} +{% import "elements/datetime.html" as datetime %} {% macro view(event) -%} <a target="_blank" href="{{ event.link }}"> - {{ event.name }} - - at {{ datetime.time(event.start) }} - {% if event.end %} - to {{ datetime.time(event.end) }} - {% endif %} - - on {{ datetime.date(event.start) }} - {% if event.end %} - {% if event.differentDay %} - to {{ datetime.date(event.end) }} - {% endif %} - {% endif %} + {{ event.name }} at {{ datetime.time(event.start) }} {% if event.end %} to {{ + datetime.time(event.end) }} {% endif %} on {{ datetime.date(event.start) }} {% + if event.end %} {% if event.differentDay %} to {{ datetime.date(event.end) }} + {% endif %} {% endif %} </a> -{%- endmacro %} - -{% macro next(event) -%} +{%- endmacro %} {% macro next(event) -%} <a target="_blank" href="{{ event.link }}"> - Upcoming: - {{ event.name }} - - at {{ datetime.time(event.start) }} - {% if event.end %} - to {{ datetime.time(event.end) }} - {% endif %} - - on {{ datetime.date(event.start) }} - {% if event.end %} - {% if event.differentDay %} - to {{ datetime.date(event.end) }} - {% endif %} - {% endif %} + Upcoming: {{ event.name }} at {{ datetime.time(event.start) }} {% if event.end + %} to {{ datetime.time(event.end) }} {% endif %} on {{ + datetime.date(event.start) }} {% if event.end %} {% if event.differentDay %} + to {{ datetime.date(event.end) }} {% endif %} {% endif %} </a> -{%- endmacro %} - -{% macro upcoming(events) -%} -{% for event in events %} -<div> - view(event) -</div> -{% endfor %} -{%- endmacro %} +{%- endmacro %} {% macro upcoming(events) -%} {% for event in events %} +<div>view(event)</div> +{% endfor %} {%- endmacro %} diff --git a/templates/elements/metadata.html b/templates/elements/metadata.html @@ -1,8 +1,6 @@ {% macro head(group, subsection) -%} - <title>{{ group.name }} - {% if subsection %} - - {{ subsection }} - {% endif %} - </title> - <link rel="icon" type="image/x-icon" href="{{ group.picture }}"> +<title> + {{ group.name }} {% if subsection %} - {{ subsection }} {% endif %} +</title> +<link rel="icon" type="image/x-icon" href="{{ group.picture }}" /> {%- endmacro %} diff --git a/templates/elements/navigation.html b/templates/elements/navigation.html @@ -1,9 +1,17 @@ -{% macro bar() -%} +{% macro bar(account) -%} <nav> - <a href="/">Home</a> - <a href="/updates">Updates</a> - <a href="/discussions">Discussions</a> - <a href="/projects">Projects</a> - <a href="/members">Members</a> + <a href="/">Home</a> + <a href="/updates">Updates</a> + <a href="/discussions">Discussions</a> + <a href="/projects">Projects</a> + <a href="/members">Members</a> + <div style="float: right"> + {% if account %} + <a>{{ account }}</a> + <a href="/logout">Logout</a> + {% else %} + <a href="/login">Login</a> + {% endif %} + </div> </nav> {%- endmacro %} diff --git a/templates/elements/projects.html b/templates/elements/projects.html @@ -1,49 +1,38 @@ -{% import "elements/authors.html" as authors %} - -{% macro view(project) -%} - <h2>{{ project.name }}</h2> - <p>{{ project.description }}</p> - {% if project.source %} - <a target="_blank" href="{{ project.source }}">Source Code</a> - <br> - {% endif %} - {{ authors.list(project.authors) }} - {% if project.images %} - {% for image in project.images %} - <img src="{{ image }}"> - {% endfor %} - {% endif %} -{%- endmacro %} - -{% macro list(projects) -%} -{% for project in projects %} +{% import "elements/authors.html" as authors %} {% macro view(project) -%} +<h2>{{ project.name }}</h2> +<p>{{ project.description }}</p> +{% if project.source %} +<a target="_blank" href="{{ project.source }}">Source Code</a> +<br /> +{% endif %} {{ authors.list(project.authors) }} {% if project.images %} {% for +image in project.images %} +<img src="{{ image }}" /> +{% endfor %} {% endif %} {%- endmacro %} {% macro list(projects) -%} {% for +project in projects %} <div> - {{ view(project) }} - <br> + {{ view(project) }} + <br /> </div> -{% endfor %} -{%- endmacro %} - -{% macro new() -%} +{% endfor %} {%- endmacro %} {% macro new() -%} <center> - <h1>Add New Project</h1> - <form method="post" enctype="multipart/form-data"> - <label for="name">Name:</label> - <input name="name" id="name" required> - <br> - <label for="description">Description:</label> - <textarea name="description" id="description" required></textarea> - <br> - <label for="authors">Authors:</label> - <input name="authors" id="authors" required> - <br> - <label for="source">Source:</label> - <input name="source" id="source"> - <br> - <label for="images">Images:</label> - <input name="images" id="images" type="file" accept="image/*" multiple> - <br> - <input type="submit" value="Add"> - </form> + <h1>Add New Project</h1> + <form method="post" enctype="multipart/form-data"> + <label for="name">Name:</label> + <input name="name" id="name" required /> + <br /> + <label for="description">Description:</label> + <textarea name="description" id="description" required></textarea> + <br /> + <label for="authors">Authors:</label> + <input name="authors" id="authors" required /> + <br /> + <label for="source">Source:</label> + <input name="source" id="source" /> + <br /> + <label for="images">Images:</label> + <input name="images" id="images" type="file" accept="image/*" multiple /> + <br /> + <input type="submit" value="Add" /> + </form> </center> {%- endmacro %} diff --git a/templates/elements/space.html b/templates/elements/space.html @@ -1,26 +1,26 @@ {% macro stars(num) -%} <style> - #star { - position: absolute; - width: 1px; - height: 1px; - background-color: white; - } + #star { + position: absolute; + width: 1px; + height: 1px; + background-color: white; + } </style> <script> - for (let i = 0; i < {{ num }}; i++) { - let star = document.createElement("div"); - star.id = "star"; - var [w, h] = randomPosition(); - star.style.top = h + "px"; - star.style.left = w + "px"; - document.body.append(star); - } + for (let i = 0; i < {{ num }}; i++) { + let star = document.createElement("div"); + star.id = "star"; + var [w, h] = randomPosition(); + star.style.top = h + "px"; + star.style.left = w + "px"; + document.body.append(star); + } - function randomPosition() { - var rw = Math.floor(Math.random() * window.innerWidth); - var rh = Math.floor(Math.random() * window.innerHeight); - return [rw, rh]; - } + function randomPosition() { + var rw = Math.floor(Math.random() * window.innerWidth); + var rh = Math.floor(Math.random() * window.innerHeight); + return [rw, rh]; + } </script> {%- endmacro %} diff --git a/templates/elements/updates.html b/templates/elements/updates.html @@ -1,17 +1,13 @@ -{% import "elements/datetime.html" as datetime %} - -{% macro view(update) -%} - <p>{{ update.member.name }} on {{ datetime.date(update.time) }} at {{ datetime.time(update.time) }}: {{ update.text }}</p> -{%- endmacro %} - -{% macro recent(update) -%} - <p>Annocement from {{ update.member.name }} on {{ datetime.date(update.time) }} at {{ datetime.time(update.time) }}: {{ update.text }}</p> -{%- endmacro %} - -{% macro list(updates) -%} -{% for update in updates %} -<div> - {{ view(update) }} -</div> -{% endfor %} -{%- endmacro %} +{% import "elements/datetime.html" as datetime %} {% macro view(update) -%} +<p> + {{ update.member.name }} on {{ datetime.date(update.time) }} at {{ + datetime.time(update.time) }}: {{ update.text }} +</p> +{%- endmacro %} {% macro recent(update) -%} +<p> + Annocement from {{ update.member.name }} on {{ datetime.date(update.time) }} + at {{ datetime.time(update.time) }}: {{ update.text }} +</p> +{%- endmacro %} {% macro list(updates) -%} {% for update in updates %} +<div>{{ view(update) }}</div> +{% endfor %} {%- endmacro %} diff --git a/templates/home.html b/templates/home.html @@ -1,27 +1,26 @@ <html> -<head> - {% import "elements/metadata.html" as metadata %} - {{ metadata.head(group)}} - <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> -</head> + <head> + {% import "elements/metadata.html" as metadata %} {{ metadata.head(group)}} + <link + rel="stylesheet" + href="{{ url_for('static', filename='style.css') }}" + /> + </head> -<header> - {% import "elements/navigation.html" as navigation %} - {{ navigation.bar() }} -</header> + <header> + {% import "elements/navigation.html" as navigation %} {{ + navigation.bar(account) }} + </header> -<body> - {% import "elements/space.html" as space %} - {{ space.stars(500) }} - <center> - <h1>{{ group.name }}</h1> - <p>{{ group.description }}</p> + <body> + {% import "elements/space.html" as space %} {{ space.stars(500) }} + <center> + <h1>{{ group.name }}</h1> + <p>{{ group.description }}</p> - {% import "elements/events.html" as events %} - {{ events.next(group.events[0]) }} - - {% import "elements/updates.html" as updates %} - {{ updates.recent(group.updates[0]) }} - </center> -</body> + {% import "elements/events.html" as events %} {{ + events.next(group.events[0]) }} {% import "elements/updates.html" as + updates %} {{ updates.recent(group.updates[0]) }} + </center> + </body> </html> diff --git a/templates/members.html b/templates/members.html @@ -1,39 +1,41 @@ <html> -<head> - {% import "elements/metadata.html" as metadata %} - {{ metadata.head(group, "Members") }} - <link rel="stylesheet" href="{{ url_for('static', filename='intro.css') }}"> -</head> + <head> + {% import "elements/metadata.html" as metadata %} {{ metadata.head(group, + "Members") }} + <link + rel="stylesheet" + href="{{ url_for('static', filename='intro.css') }}" + /> + </head> -<body> - {% import "elements/space.html" as space %} - {{ space.stars(200) }} - <div id="board"> - <div id="content"> - <center> - <h1>COMPUTER</h1> - <h1>SCIENCE</h1> - <h1>CLUB</h1> - <h2>LEADERS</h2> - {% for leader in group.leaders %} - <p>{{ leader.name }}</p> - {% endfor %} - <br> - <h2>MEMBERS</h2> - {% for member in group.members %} - <p>{{ member.name }}</p> - {% endfor %} - <br> - <h2>CREATED BY</h2> - <p>Damian Myrda</p> - </center> - </div> - </div> - <a id="back" class="hidden" href="/">Back</a> - <script> - setTimeout(function() { - document.getElementById("back").className = "shown"; - }, 8000); - </script> -</body> + <body> + {% import "elements/space.html" as space %} {{ space.stars(200) }} + <div id="board"> + <div id="content"> + <center> + <h1>COMPUTER</h1> + <h1>SCIENCE</h1> + <h1>CLUB</h1> + <h2>LEADERS</h2> + {% for leader in group.leaders %} + <p>{{ leader.name }}</p> + {% endfor %} + <br /> + <h2>MEMBERS</h2> + {% for member in group.members %} + <p>{{ member.name }}</p> + {% endfor %} + <br /> + <h2>CREATED BY</h2> + <p>Damian Myrda</p> + </center> + </div> + </div> + <a id="back" class="hidden" href="/">Back</a> + <script> + setTimeout(function () { + document.getElementById("back").className = "shown"; + }, 8000); + </script> + </body> </html> diff --git a/templates/projects.html b/templates/projects.html @@ -1,25 +1,26 @@ <html> -<head> - {% import "elements/metadata.html" as metadata %} - {% if create %} - {{ metadata.head(group, "New Project") }} - {% else %} - {{ metadata.head(group, "Projects") }} - {% endif %} - <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> -</head> + <head> + {% import "elements/metadata.html" as metadata %} {% if create %} {{ + metadata.head(group, "New Project") }} {% else %} {{ metadata.head(group, + "Projects") }} {% endif %} + <link + rel="stylesheet" + href="{{ url_for('static', filename='style.css') }}" + /> + </head> -<header> - {% import "elements/navigation.html" as navigation %} - {{ navigation.bar() }} -</header> + <header> + {% import "elements/navigation.html" as navigation %} {{ + navigation.bar(account) }} + </header> -<body> - {% import "elements/space.html" as space %} - {{ space.stars(500) }} - - {% import "elements/projects.html" as projects %} - <h1>Projects</h1> - {{ projects.list(group.projects) }} -</body> + <body> + {% import "elements/space.html" as space %} {{ space.stars(500) }} {% import + "elements/projects.html" as projects %} {% if create %} {{ projects.new() }} + {% else %} + <h1>Projects</h1> + {{ projects.list(group.projects) }} {% if account %} + <a href="/projects/add">Add a Project</a> + {% endif %} {% endif %} + </body> </html> diff --git a/templates/updates.html b/templates/updates.html @@ -1,21 +1,23 @@ <html> -<head> - {% import "elements/metadata.html" as metadata %} - {{ metadata.head(group, "Updates") }} - <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> -</head> + <head> + {% import "elements/metadata.html" as metadata %} {{ metadata.head(group, + "Updates") }} + <link + rel="stylesheet" + href="{{ url_for('static', filename='style.css') }}" + /> + </head> -<header> - {% import "elements/navigation.html" as navigation %} - {{ navigation.bar() }} -</header> + <header> + {% import "elements/navigation.html" as navigation %} {{ + navigation.bar(account) }} + </header> -<body> - {% import "elements/space.html" as space %} - {{ space.stars(500) }} + <body> + {% import "elements/space.html" as space %} {{ space.stars(500) }} - <h1>Updates</h1> - {% import "elements/updates.html" as updates %} - {{ updates.list(group.updates) }} -</body> + <h1>Updates</h1> + {% import "elements/updates.html" as updates %} {{ + updates.list(group.updates) }} + </body> </html>