Skip to content

Commit

Permalink
environment variables
Browse files Browse the repository at this point in the history
  • Loading branch information
charlestang06 committed Mar 8, 2024
1 parent 10386b9 commit 5a4dda3
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 96 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[label .gitignore]
db.sqlite3
*.pyc
.venv/*
.env
32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@

[Iridium Tutoring](https://www.iridiumtutoring.org) is a nationwide 501(c)(3) nonprofit tutoring organization serving K-12 students with free, personalized educational support in all subjects. Our mission is to provide high-quality, accessible, and equitable tutoring to students in need, regardless of their background or financial status. We are committed to helping students reach their full potential and achieve academic success.

This dashboard streamlines the tutoring session registration process and tutor sign-up process to a non-Google-Sheets/Forms-hosted platform. Developed by the 2024 Iridium Tutoring director team (Charles Tang). Utilizes Model-View-Template (MVT) architecture for `Tutors`, `Students`, and `Tutoring-Sessions`.

This dashboard streamlines the tutoring session registration process and tutor sign-up process to a non-Google-Sheets/Forms-hosted platform. Developed by the 2024 Iridium Tutoring's founder, Charles Tang. Utilizes Model-View-Template (MVT) architecture for models Tutors`, `Students`, and `Tutoring-Sessions`; views `studentView`, `tutorView`, `index`, `etc`; and Bootstrapped templates for each view.

## Tech Stack
- **Frontend**: Django, HTML, CSS, JavaScript
- **Backend**: Django, SQLite
- **Frontend**: HTML, CSS (Bootstrap 5.0), JavaScript
- **Backend**: Django, SQLite, Web Mail (SMTP)
- **Deployment**: DigitalOcean

## Features
[x] Admin dashboard (manage tutor, student, session registrations)
[x] Student session registration (sign up for tutoring sessions, email confirmation, automatic account generation)
[x] Student dashboard (login/logout, see past/upcoming sessions, register session, see session details, see tutor details)
[x] Tutor session dashboard (login/logout, see available sessions, see historical sessions, sign up for sessions, past taken sessions, add session)
[] Tutor profile dashboard (volunteering hours)
[] Admin dashboard (sort by model, create new tutor form, create new session form)
[] Deployed onto DigitalOcean (thanks to nonprofit credits), subdomain of iridiumtutoring.org
Italicized features are in the implementation stages.
- [x] (MVP #1) Admin dashboard (manage tutor, student, and session registrations)
- [x] (MVP #2) Student session registration (sign up for tutoring sessions, email confirmation, automatic account generation)
- [x] (MVP #3) Student dashboard (login/logout, see past/upcoming sessions, register session, see session details, see tutor details)
- [x] (MVP #4) Tutor session dashboard (login/logout, see available sessions, *see historical sessions*, sign up for sessions, past taken sessions, *add session*)
- [ ] Tutor profile dashboard (volunteering hours)
- [ ] Admin dashboard (sort by model, create new tutor form, create new session form)
- [ ] Deployed onto DigitalOcean (thanks to nonprofit credits), configured DNS for a subdomain (portal.iridiumtutoring.org)

## Notes

Since we are deploying with a SQLite single-file database, we will need to download the database from the server every time we deploy. This is not ideal, but it is the best we can do with our current resources.
Since we are deploying with a SQLite single-file database, we will need to download the database from the server every time we deploy. This is not ideal, but it is the best we can do with our current resources. We will eventually migrate to either PostgreSQL or MySQL, depending on what is more readily available and can fit our needs.

## How To Run
We assume you have the latest version of Python installed.
Expand All @@ -36,7 +36,13 @@ We assume you have the latest version of Python installed.
pip install django
```

3. Run the server.
3. Make migrations
```bash
python manage.py makemigrations
python manage.py migrate
```

4. Run the server.
```bash
python manage.py runserver
```
Binary file modified db.sqlite3
Binary file not shown.
55 changes: 26 additions & 29 deletions iridisite/settings.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,26 @@
"""
Django settings for iridisite project.
Generated by 'django-admin startproject' using Django 5.0.2.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""

from pathlib import Path
from django.core.management.utils import get_random_secret_key
import os
import sys
import dj_database_url

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-4mv49k@ao+x=c37soeh@+r5&^v0*ue_e&kzc(&!gt&g@+u$n++'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []
SECRET_KEY = SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", get_random_secret_key())
ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "127.0.0.1,localhost").split(",")
DEBUG = os.getenv("DEBUG", "False") == "True"

EMAIL_HOST = "mail.iridiumtutoring.org"
EMAIL_HOST_USER = "[email protected]"
EMAIL_HOST_PASSWORD = "123456"
EMAIL_PORT = 587
EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
EMAIL_PORT = os.getenv("EMAIL_PORT")

# Application definition

Expand Down Expand Up @@ -77,14 +67,21 @@


# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
DEVELOPMENT_MODE = os.getenv("DEVELOPMENT_MODE", "False") == "True"

if DEVELOPMENT_MODE is True:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
}
}
elif len(sys.argv) > 0 and sys.argv[1] != 'collectstatic':
if os.getenv("DATABASE_URL", None) is None:
raise Exception("DATABASE_URL environment variable not defined")
DATABASES = {
"default": dj_database_url.parse(os.environ.get("DATABASE_URL")),
}
}


# Password validation
Expand Down Expand Up @@ -128,9 +125,9 @@


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/

STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")

# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
Expand Down
40 changes: 4 additions & 36 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,41 +1,9 @@
absl-py==2.1.0
asgiref==3.7.2
astunparse==1.6.3
certifi==2024.2.2
charset-normalizer==3.3.2
Django==5.0.2
dm-tree==0.1.8
flatbuffers==23.5.26
gast==0.5.4
google-pasta==0.2.0
grpcio==1.62.0
h5py==3.10.0
idna==3.6
joblib==1.3.2
libclang==16.0.6
Markdown==3.5.2
markdown-it-py==3.0.0
MarkupSafe==2.1.5
mdurl==0.1.2
ml-dtypes==0.3.2
namex==0.0.7
numpy==1.26.4
opt-einsum==3.3.0
dj-database-url==2.1.0
Django==5.0.3
gunicorn==21.2.0
packaging==23.2
protobuf==4.25.3
Pygments==2.17.2
requests==2.31.0
rich==13.7.1
scipy==1.12.0
setuptools==69.1.1
six==1.16.0
psycopg2-binary==2.9.9
sqlparse==0.4.4
termcolor==2.4.0
threadpoolctl==3.3.0
typing_extensions==4.10.0
tzdata==2024.1
urllib3==2.2.1
Werkzeug==3.0.1
wheel==0.42.0
wrapt==1.16.0
pre-commit
Binary file modified tutoring_student/__pycache__/views.cpython-312.pyc
Binary file not shown.
14 changes: 7 additions & 7 deletions tutoring_student/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ def __str__(self):
studentName = models.CharField(max_length=100)
email = models.EmailField("Email Address")
password = models.CharField(max_length=100, default="123456")
phone = models.CharField(max_length=15, null=True)
location = models.CharField(max_length=100, null=True)
phone = models.CharField(max_length=15, null=True, blank=True)
location = models.CharField(max_length=100, null=True, blank=True)

# Additional Information
howDidYouHear = models.CharField(max_length=100, null=True)
additionalComments = models.TextField(null=True)
howDidYouHear = models.CharField(max_length=100, null=True, blank=True)
additionalComments = models.TextField(null=True, blank=True)

class Tutor(models.Model):
"""
Expand All @@ -36,8 +36,8 @@ def __str__(self):
email = models.EmailField("Email Address")
password = models.CharField(max_length=100, default="123456")
phone = models.CharField(max_length=15, null=True)
onBoardingDate = models.DateField("Date Onboarded", null=True)
description = models.CharField(max_length=100, null=True)
onBoardingDate = models.DateField("Date Onboarded", null=True, blank=True)
description = models.CharField(max_length=100, null=True, blank=True)

class TutoringSession(models.Model):
"""
Expand All @@ -56,7 +56,7 @@ def __str__(self):

# Personal Information
student = models.ForeignKey(Student, on_delete=models.CASCADE)
tutor = models.ForeignKey(Tutor, on_delete=models.CASCADE, null=True)
tutor = models.ForeignKey(Tutor, on_delete=models.CASCADE, null=True, blank=True)

# Useful Functions
def was_in_the_past(self):
Expand Down
5 changes: 3 additions & 2 deletions tutoring_student/templates/tutoring_student/tutorView.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,12 @@ <h5 class="mb-1">{{session.student.studentName}} - {{session.subject}} (Grade {{
</a> <!-- <span class="badge bg-secondary">New</span> -->
{% endif %} {% endfor %}
</div>
{% endif %} {% if not tutoringSessionList %}
<p>No tutoring sessions available.</p>
{% endif %}
<div class="col d-none d-md-block"> </div>
</div>

<!-- TODO: Historical sessions + pagination -->
<!-- https://www.geeksforgeeks.org/how-to-add-pagination-in-django-project/-->
</div>
{% else %}
<!-- Password form -->
Expand Down
19 changes: 19 additions & 0 deletions tutoring_student/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import threading
from django.core.mail import EmailMessage


class EmailThread(threading.Thread):
def __init__(self, subject, html_content, recipient_list, sender):
self.subject = subject
self.recipient_list = recipient_list
self.html_content = html_content
self.sender = sender
threading.Thread.__init__(self)

def run(self):
msg = EmailMessage(self.subject, self.html_content, self.sender, self.recipient_list)
msg.content_subtype = 'html'
msg.send()

def send_html_mail(subject, html_content, recipient_list, sender):
EmailThread(subject, html_content, recipient_list, sender).start()
12 changes: 3 additions & 9 deletions tutoring_student/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.contrib.auth.models import User
from django.contrib.auth import login, logout
from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.mail import send_mail
from .utils import send_html_mail
from .backends import TutorBackend, StudentBackend
from .models import *

Expand Down Expand Up @@ -218,17 +218,11 @@ def sessionConfirmation(request):
html = loader.render_to_string(
"tutoring_student/sessionConfirmation.html", context
)
# send_mail(
# "Iridium Tutoring | Tutoring Session Confirmation",
# "",
# "[email protected]",
# [email],
# html_message=html,
# )
send_html_mail("Iridium Tutoring | Tutoring Session Confirmation", html, [email], "[email protected]")
t.save()
except:
context["error_message"] = (
"There was an error confirming the session. Try again or contact us for support."
"There was an error confirming the session or sending the email. Try again or contact us for support."
)
context["button"] = True
return render(request, "tutoring_student/sessionConfirmation.html", context)

0 comments on commit 5a4dda3

Please sign in to comment.