]> prime8.dev >> repos - csc.git/commitdiff
Update and format everything
authorDamian Myrda <monkey.damianek@gmail.com>
Fri, 26 Apr 2024 03:16:21 +0000 (22:16 -0500)
committerDamian Myrda <monkey.damianek@gmail.com>
Fri, 26 Apr 2024 03:16:21 +0000 (22:16 -0500)
30 files changed:
.gitignore
README.md
config.py
database.json
database.py
main.py
models/discussion.py
models/event.py
models/group.py
models/member.py
models/project.py
models/update.py
projects.py
schoology.py
static/intro.css
static/style.css
templates/discussions.html
templates/elements/authors.html
templates/elements/datetime.html
templates/elements/discussions.html
templates/elements/events.html
templates/elements/metadata.html
templates/elements/navigation.html
templates/elements/projects.html
templates/elements/space.html
templates/elements/updates.html
templates/home.html
templates/members.html
templates/projects.html
templates/updates.html

index 4f43ac16a702d1f290b77533ae2b224f9c5b18fd..6002496b9bc3ed4c227073778b95cfb516af98a8 100755 (executable)
@@ -3,3 +3,4 @@ lib64
 bin/
 __pycache__/
 pyvenv.cfg
+google_auth.json
index 3d561cd4813df2512358a5a264f8f70ef370612c..6f3815d2fa717de2805d18b65ad0c4164020b995 100644 (file)
--- 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`.
index 0dbfb30f5c628779afdc247c3c285292efdc19d8..eca7a57e3b047bc238e13402a933a647c5320a75 100644 (file)
--- 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"
index 3fa2896acdc82aea407fb72ca385bbbe9fa5b059..e5868d1131c14204b11670ce9f4670abe17c865f 100644 (file)
@@ -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
+    }
+  ]
+}
index 785a90ad8159756ea7bfdbb90ff9318f7bcd0109..08bd2e23557ad4e94b8002e9d97abdba07457978 100644 (file)
@@ -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
index cc0f10e8e3efc0af4fc6d3466dbb5a27903326b4..21718fd88d5aa7dd33d7404b381899127fd8d5dd 100644 (file)
--- a/main.py
+++ b/main.py
 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")
index 45275f2041ac6a3ff9964d5d491f861f79101b7f..dc973b44e896637f6ec6ff72ec9bf23dcc784740 100644 (file)
@@ -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
index e3179536a7fce90286747afbea56d30a645af89e..00df198aac04a284048a39501e8c1541f022bd29 100644 (file)
@@ -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
index 16e5e39f8b3ee6c8ec3ba35d12e90eef2bf3fa5c..b8301746bcd2c8baa37e5bf5e5badfc9c62c265e 100644 (file)
@@ -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)
index e00e70990e5a0ffec2b013c052e3eab59070621c..c53b566a5dc47cd4835e4f14fda0811ba42d7471 100644 (file)
@@ -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
index 11f0f170d42b849888f9b00dc835784a9188d88f..348496686948bb02c064e9eb80d32ca50a714d6f 100644 (file)
@@ -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
index 5507110c079a18da1e614c51796b3768c4275535..82b2f7792059532a5db66465b6e144956e0e35c5 100644 (file)
@@ -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
index fb558f638a8799bd66de2c3747136544b26b3a5b..6074ee9a72bbfc505de41f5b3a3daa594fbbc371 100644 (file)
@@ -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)))
index 7ea51d9cce81cb7cdc1f4138c01ef749438c741b..7715362e90495d926f3f0ec367a743caa7fb15de 100644 (file)
@@ -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()
index 3597bfc4c0cd3a5e717b0dd5e9a6b4f1259dfb2f..76273888d2c56bb70570581e7011558558424863 100644 (file)
@@ -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;
 }
index c0f081e3cc84f7cfe3b6111471297cfa1de8060b..752efab322915b3acf9848dffc2763da7eba8dad 100644 (file)
@@ -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;
 }
index ebfe387dfc1536be3702af8ca56857e27e2eada1..93721f8e6f9c51ef2d7cb622aa7c2612f9ca39fb 100644 (file)
@@ -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>
index 3a6f82cd117a448a5d7eeb91defc7bf07f4beca8..f7cb1a2e8879343a4feb8256313a0cb576cb4ab5 100644 (file)
@@ -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 %}
index 5218411ae058853a3467fca16626f5595fe2dfae..db2e889e552fa2c2bf270ac50ab2e8ba033a5b69 100644 (file)
@@ -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 %}
index b1c563dc1c18e9a81179c0026815af7441d98d16..d6d5848121d4068569717bdf5b576faae08ea927 100644 (file)
@@ -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 %}
index 344cb14ac550ca026882a49fd7c9c55e04eccf91..948418aa2f383cb62cd570e416d9dc05b7fe5d5b 100644 (file)
@@ -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 %}
index 70d9d7931d5d5833e81397184638d1bceda662c8..2b9d0a07dc25f1d7413af5982e883b96508ee108 100644 (file)
@@ -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 %}
index 61d3e720901c8c2eb45c466928151be65891d7e2..d38b1bfa7bde133fe6e952fab698a03ca0b90c0a 100644 (file)
@@ -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 %}
index b9e3f4ab228dda3462c9a0df8887aedb0a1b1de6..c86dca609843ac1a5ee3de67f6049d1afacd683d 100644 (file)
@@ -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 %}
index f725d8fd9cfd66fbd39939d6fd3ef388e2aef83e..0a3e7e014ece650ca594f12b26504f77f37c20e2 100644 (file)
@@ -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 %}
index f9df6f913c38cc853b7bf2d015a000ff9d4710da..deb347f486760ce113f8cee0ba2e624210acaf1a 100644 (file)
@@ -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 %}
index 6d478b4d1c779a0300ba2753444123f8e4ffcf8f..bfea052ca433082d66e670817eaad6e63c08f792 100644 (file)
@@ -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>
index 5fd07b9887b8f69b13e3022b27185cf3407858a8..903f15b378728dc16733a7e294d8eb5ed3f2498d 100644 (file)
@@ -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>
index dadbca5a7b3f5a9f11dc3a6ae0fcda193601b8c7..edd3d6b043a6596148edb0c5ea41a7e40f2a62c7 100644 (file)
@@ -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>
index dfc347777c331748a5d93527a64aea4605ee4039..970f71b43ca2539a0812199cf7fa3ca642ea505f 100644 (file)
@@ -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>