Skip to content

Commit ab4da2c

Browse files
committed
first commit
0 parents  commit ab4da2c

31 files changed

+3862
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
__pycache__/
2+
sched_venv/
3+
app.db
4+
*junk*
5+
sched.sublime-project
6+
sched.sublime-workspace
7+
urtext_log.txt

app/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from flask import Flask
2+
from config import Config
3+
from flask_sqlalchemy import SQLAlchemy
4+
from flask_migrate import Migrate
5+
6+
7+
app = Flask(__name__)
8+
app.config.from_object(Config)
9+
db = SQLAlchemy(app)
10+
migrate = Migrate(app, db)
11+
12+
from app import routes, models

app/forms.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from flask_wtf import FlaskForm
2+
from wtforms import StringField, PasswordField, BooleanField, SubmitField
3+
from wtforms.validators import DataRequired
4+
5+
6+
class LoginForm(FlaskForm):
7+
username = StringField('Username', validators=[DataRequired()])
8+
password = PasswordField('Password', validators=[DataRequired()])
9+
remember_me = BooleanField('Remember Me')
10+
submit = SubmitField('Sign In')
11+
12+
13+
class ChangePassword(FlaskForm):
14+
username = StringField('Username', validators=[DataRequired()])
15+
password = PasswordField('Password', validators=[DataRequired()])
16+
new_password = PasswordField('New Password', validators=[DataRequired()])
17+
submit = SubmitField('Change Password')

app/models.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from app import db
2+
from datetime import datetime
3+
4+
5+
class User(db.Model):
6+
id = db.Column(db.Integer, primary_key=True)
7+
username = db.Column(db.String(64), index=True, unique=True)
8+
email = db.Column(db.String(120), index=True, unique=True)
9+
password_hash = db.Column(db.String(128))
10+
posts = db.relationship('Post', backref='author', lazy='dynamic')
11+
r1_bids = db.relationship('UserBids', backref='bidder', lazy='dynamic')
12+
13+
def __repr__(self):
14+
return '<User {}>'.format(self.username)
15+
16+
17+
class Post(db.Model):
18+
id = db.Column(db.Integer, primary_key=True)
19+
body = db.Column(db.String(140))
20+
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
21+
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
22+
23+
def __repr__(self):
24+
return '<Post {}>'.format(self.body)
25+
26+
27+
class Section(db.Model):
28+
id = db.Column(db.Integer, primary_key=True)
29+
bids = db.relationship('SectionBid', backref='sect', lazy='dynamic')
30+
choice_num = db.Column(db.Integer, unique=True) # 1-127 or so, to match spreadsheet
31+
start_time = db.Column(db.Time) # use with datetime.time()
32+
end_time = db.Column(db.Time)
33+
mon_wed = db.Column(db.Boolean) # class meets Monday Wednesday
34+
tue_thu = db.Column(db.Boolean) # class meets Tuesday Thursday
35+
mtwth = db.Column(db.Boolean) # class meets 4 days: MTWTh
36+
course = db.Column(db.String(4)) # eg '228A'
37+
room = db.Column(db.String(6)) # eg '1003B'
38+
units = db.Column(db.Integer) # eg, 3 or 5
39+
semester = db.Column(db.String(6)) # eg, 'Sp2020' or 'Fa2020'
40+
taken_by = db.Column(db.String(25)) # eg 'Tchertchian E'
41+
42+
def __repr__(self):
43+
return '<Section choice {}, math {}, id {}>'.format(self.choice_num, self.course, self.id)
44+
45+
46+
class SectionBid(db.Model):
47+
# each row represents one teacher's bid on one class
48+
id = db.Column(db.Integer, primary_key=True)
49+
bid = db.Column(db.Integer)
50+
section_id = db.Column(db.Integer, db.ForeignKey('section.id'))
51+
user_bids_id = db.Column(db.Integer, db.ForeignKey('user_bids.id'))
52+
53+
def __repr__(self):
54+
return '<SectionBid id {}, bid {}, section_id {}, user_bids_id {}>'.format(self.id,
55+
self.bid, self.section_id, self.user_bids_id)
56+
57+
58+
59+
class UserBids(db.Model):
60+
# collection of one teacher's round 1 bids
61+
id = db.Column(db.Integer, primary_key=True)
62+
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
63+
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
64+
primary = db.Column(db.Boolean) # only 1 UserBids w/ this true per user
65+
bid_1_prep = db.Column(db.Integer)
66+
bid_2_prep = db.Column(db.Integer)
67+
bid_3_prep = db.Column(db.Integer)
68+
bid_4_prep = db.Column(db.Integer)
69+
bid_5_prep = db.Column(db.Integer)
70+
min_acc_units = db.Column(db.Integer) # minimum acceptable unit total, eg, 13
71+
max_acc_units = db.Column(db.Integer) # maximum acceptable unit total, eg, 17
72+
min_des_units = db.Column(db.Integer) # minimum desired unit total, eg 14
73+
max_des_units = db.Column(db.Integer) # maximum desired unit total, eg 16
74+
section_bids = db.relationship('SectionBid', backref='from_userbids', lazy='dynamic')
75+
76+
def __repr__(self):
77+
return '<UserBids id {}, user_id {}, primary {}>'.format(self.id,
78+
self.user_id, self.primary)
79+
80+
# TODO: SchedOpt, SchedOptSection, SchedOptProj (joining table?)
81+

app/routes.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from flask import render_template, flash, redirect, url_for
2+
from app import app
3+
from app.forms import LoginForm, ChangePassword
4+
5+
6+
@app.route('/')
7+
@app.route('/index')
8+
def index():
9+
user = {'username': 'bensm'}
10+
posts = [
11+
{
12+
'author': {'username': 'John'},
13+
'body': 'Beautiful day in Portland!'
14+
},
15+
{
16+
'author': {'username': 'Susan'},
17+
'body': 'The Avengers movie was so cool!'
18+
}
19+
]
20+
return render_template('index.html', title='Home', user=user, posts=posts)
21+
22+
23+
@app.route('/login', methods=['GET', 'POST'])
24+
def login():
25+
user = {'username': 'bensm'}
26+
form = LoginForm()
27+
if form.validate_on_submit():
28+
flash('Login requested for user {}, remember_me={}'.format(
29+
form.username.data, form.remember_me.data))
30+
return redirect('/index')
31+
return render_template('login.html', title='Sign In', user=user, form=form)
32+
33+
34+
@app.route('/history')
35+
def history():
36+
user = {'username': 'bensm'}
37+
return render_template('history.html', title='History', user=user)
38+
39+
40+
@app.route('/password', methods=['GET', 'POST'])
41+
def password():
42+
user = {'username': 'bensm'}
43+
form = ChangePassword()
44+
if form.validate_on_submit():
45+
flash('Password changed successfully')
46+
return redirect('/index')
47+
return render_template(
48+
'password.html', user=user,
49+
title='Change Password', form=form)

app/templates/base.html

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<html>
2+
<head>
3+
{% if title %}
4+
<title>{{ title }} - Scheduleer</title>
5+
{% else %}
6+
<title>Welcome to Scheduleer!</title>
7+
{% endif %}
8+
</head>
9+
<body>
10+
<div>
11+
Hi {{ user.username }}, you currently have xx credits.
12+
<a href="{{ url_for('index') }}">Home</a>
13+
<a href="{{ url_for('login') }}">Login</a>
14+
<a href="{{ url_for('history') }}">History</a>
15+
<a href="{{ url_for('password') }}">Change Password</a>
16+
</div>
17+
<hr>
18+
{% with messages = get_flashed_messages() %}
19+
{% if messages %}
20+
<ul>
21+
{% for message in messages %}
22+
<li>{{ message }}</li>
23+
{% endfor %}
24+
</ul>
25+
{% endif %}
26+
{% endwith %}
27+
{% block content %}{% endblock %}
28+
</body>
29+
</html>

app/templates/history.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
<h1>{{ user.username }}'s history: </h1>
5+
<div><p>For Spring 2020, Spent xx schedule dollars, with yy remaining, for schedule:</p>
6+
<p> Insert Schedule here. </p>
7+
</div>
8+
<div><p>Semester: Fall 2020, Spent xx schedule dollars, with yy remaining, for schedule:</p>
9+
<p> Insert Schedule here. </p>
10+
</div>
11+
{% endblock %}

app/templates/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
<h1>Hello, {{ user.username }}!</h1>
5+
{% for post in posts %}
6+
<div><p>{{ post.author.username }} says: <b>{{ post.body }}</b></p></div>
7+
{% endfor %}
8+
{% endblock %}

app/templates/login.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
<h1>Sign In</h1>
5+
<form action="" method="post" novalidate>
6+
{{ form.hidden_tag() }}
7+
<p>
8+
{{ form.username.label }}<br>
9+
{{ form.username(size=32) }}<br>
10+
{% for error in form.username.errors %}
11+
<span style="color: red;">[{{ error }}]</span>
12+
{% endfor %}
13+
</p>
14+
<p> {{ form.password.label }}<br>
15+
{{ form.password(size=40) }}<br>
16+
{% for error in form.password.errors %}
17+
<span style="color: blue;">[{{ error }}]</span>
18+
{% endfor %}
19+
</p>
20+
<p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
21+
<p>{{ form.submit() }}</p>
22+
</form>
23+
{% endblock %}

app/templates/password.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{% extends "base.html" %}
2+
3+
{% block content %}
4+
Change your password here bro!
5+
{% endblock %}

0 commit comments

Comments
 (0)