# Computer Science Club Website
+
A website for Computer Science Club made during a mini-hackathon.
![home page](./assets/home.png)
## setup
+
### environment
+
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 jsonpickle cachecontrol google-auth google_auth_oauthlib` to install all the dependencies. Now, `exit`.
### schoology
-In ```config.py```, change ```DOMAIN``` to the URL of the Schoology instance. In addition, change ```GROUP_ID``` to the ID of the Schoology group. This can be found by visiting the Schoology website and by navigating to the Schoology group. The group's ID should be right after the ```/group/...``` subdirectory of the domain. To get a Schoolopy API key and secret, goto `schoology.(PUT DOMAIN HERE).org/api`. There, you can manage your API credentials. You will need the key and secret to run the server.
+
+In `config.py`, change `DOMAIN` to the URL of the Schoology instance. In addition, change `GROUP_ID` to the ID of the Schoology group. This can be found by visiting the Schoology website and by navigating to the Schoology group. The group's ID should be right after the `/group/...` subdirectory of the domain. To get a Schoolopy API key and secret, goto `schoology.(PUT DOMAIN HERE).org/api`. There, you can manage your API credentials. You will need the key and secret to run the server.
### google
+
To setup Google OAuth2, go [here](https://developers.google.com/identity/oauth2/web/guides/get-google-api-clientid) and follow the instructions. Copy the json into a file called `google_auth.json` in the root of the project. In `config.py`, change `REDIRECT_URL` to the URL you used when you set up the Google project. Make sure that the redirect URL is added as one of the "Authorized redirect URIs."
## running
-Now, you can execute `SCHOOLOGY_API_KEY="PUT KEY HERE" SCHOOLOGY_API_SECRET="PUT SECRET HERE" ./run.sh`.
+Now, you can execute `SCHOOLOGY_API_KEY="PUT KEY HERE" SCHOOLOGY_API_SECRET="PUT SECRET HERE" ./run.sh`.
"name": "Computer Science Club Website",
"description": "(this website)",
"authors": ["Damian Myrda"],
- "source": "https://github.com/moncheeta/computer_science_club.git",
- "images": null
+ "source": "https://github.com/moncheeta/computer_science_club.git"
}
]
}
-import os
-from jsonpickle import decode, encode
+from models import Project
+import jsonpickle as json
+import sqlite3
+import pickle
class Data:
projects = []
- def __init__(self, projects):
+ def __init__(self, projects=[]):
self.projects = projects
-class Database:
+class JSONDatabase:
+ def __init__(self):
+ self.projects = []
+ self.read()
+
def read(self):
- if not os.path.isfile("database.json"):
- return Data([])
with open("database.json", "r") as file:
- return decode(file.read())
+ self.projects = json.decode(file.read()).projects
+ return self.projects
- def write(self, data):
+ def write(self):
with open("database.json", "w") as file:
- file.write(encode(data))
+ file.write(json.encode(Data(self.projects)))
+
+ def add(self, project):
+ self.projects.append(project)
+ self.write()
+
+
+class SQLDatabase:
+ def __init__(self):
+ self.connection = sqlite3.connect("database.db", check_same_thread=False)
+ self.cursor = self.connection.cursor()
+ self.cursor.execute(
+ """CREATE TABLE IF NOT EXISTS projects (
+ name text NOT NULL,
+ description text,
+ authors text NOT NULL,
+ source text
+ )"""
+ )
+ self.write()
+ self.read()
+
+ def __del__(self):
+ self.connection.close()
+
+ def read(self):
+ self.projects = []
+ self.cursor.execute("SELECT * FROM projects")
+ for data in self.cursor.fetchall():
+ name = data[0]
+ description = data[1]
+ authors = pickle.loads(data[2])
+ source = data[3]
+ project = Project(name, description, authors, source)
+ self.projects.append(project)
+ return self.projects
+
+ def write(self):
+ self.connection.commit()
+
+ def add(self, project):
+ self.projects.append(project)
+ data = (
+ project.name,
+ project.description,
+ pickle.dumps(project.authors),
+ project.source,
+ )
+ self.cursor.execute("INSERT INTO projects VALUES (?, ?, ?, ?)", data)
+ self.write()
class ProjectDatabase:
+ def __init__(self):
+ self.database = SQLDatabase()
+
def read(self):
- projects = []
- for project in Database().read().projects:
- projects.append(project)
- return projects
+ return self.database.read()
+
+ def write(self):
+ self.database.write()
+
+ def add(self, project):
+ self.database.add(project)
+
- def write(self, projects):
- Database().write(Data(projects))
+database = ProjectDatabase()
sys.path.append(os.path.join(PROJECT_DIR, "schoology.py"))
from config import REDIRECT_URL
from models import Project
-from database import ProjectDatabase
+from database import database
from schoology import group
from flask import Flask, request, redirect, abort, render_template, session
from cachecontrol import CacheControl
return abort(401)
name = request.form["name"].rstrip()
description = request.form["description"].rstrip()
+ if description == "":
+ description = None
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)
+ project = Project(name, description, [authors], source)
+ database.add(project)
return redirect("/projects")
return render_template(
"projects.html", group=group, create=True, account=session.get("name")
description = ""
authors = []
source = None
- images = None
- def __init__(self, name, description, authors, source=None, images=None):
+ def __init__(self, name, description, authors, source=None):
self.name = name
self.description = description
self.authors = authors
self.source = source
- self.images = images
+++ /dev/null
-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 write(self, projects):
- with open("database.json", "w") as file:
- file.write(encode(Data(projects)))
from datetime import datetime
from config import DOMAIN, GROUP_ID
from models import Group, Event, Update, Discussion, Member
-from database import ProjectDatabase
+from database import database
from schoolopy import Schoology, Auth
events = self.events()
updates = self.updates()
discussions = self.discussions()
- projects = ProjectDatabase().read()
+ projects = database.read()
members = self.members()
return Group(name, description, events, updates, discussions, projects, members)
{% import "elements/authors.html" as authors %} {% macro view(project) -%}
<h2>{{ project.name }}</h2>
+{% if project.description %}
<p>{{ project.description }}</p>
-{% if project.source %}
+{% endif %} {% if project.source %}
<a target="_blank" href="{{ project.source }}">Source Code</a>
<br />
{% endif %} {{ authors.list(project.authors) }} {% if project.images %} {% for
<input name="name" id="name" required />
<br />
<label for="description">Description:</label>
- <textarea name="description" id="description" required></textarea>
+ <textarea name="description" id="description"></textarea>
<br />
<label for="authors">Authors:</label>
<input name="authors" id="authors" required />
<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>