diff --git a/Assignment/HW7 - Mega Lab Travel App/__pycache__/config.cpython-35.pyc b/Assignment/HW7 - Mega Lab Travel App/__pycache__/config.cpython-35.pyc new file mode 100644 index 0000000..5e14061 Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/__pycache__/config.cpython-35.pyc differ diff --git a/Assignment/HW7 - Mega Lab Travel App/app.db b/Assignment/HW7 - Mega Lab Travel App/app.db new file mode 100644 index 0000000..420e013 Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/app.db differ diff --git a/Assignment/HW7 - Mega Lab Travel App/app/__init__.py b/Assignment/HW7 - Mega Lab Travel App/app/__init__.py new file mode 100755 index 0000000..353d3af --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/__init__.py @@ -0,0 +1,8 @@ +from flask import Flask +from flask.ext.sqlalchemy import SQLAlchemy + +app = Flask(__name__) +app.config.from_object('config') +db = SQLAlchemy(app) + +from app import views, models diff --git a/Assignment/HW7 - Mega Lab Travel App/app/__init__.pyc b/Assignment/HW7 - Mega Lab Travel App/app/__init__.pyc new file mode 100644 index 0000000..8ecfcf5 Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/app/__init__.pyc differ diff --git a/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/__init__.cpython-35.pyc b/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/__init__.cpython-35.pyc new file mode 100644 index 0000000..e3d44e8 Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/__init__.cpython-35.pyc differ diff --git a/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/forms.cpython-35.pyc b/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/forms.cpython-35.pyc new file mode 100644 index 0000000..deb5d4e Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/forms.cpython-35.pyc differ diff --git a/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/models.cpython-35.pyc b/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/models.cpython-35.pyc new file mode 100644 index 0000000..8b188f2 Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/models.cpython-35.pyc differ diff --git a/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/views.cpython-35.pyc b/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/views.cpython-35.pyc new file mode 100644 index 0000000..f5df49d Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/app/__pycache__/views.cpython-35.pyc differ diff --git a/Assignment/HW7 - Mega Lab Travel App/app/forms.py b/Assignment/HW7 - Mega Lab Travel App/app/forms.py new file mode 100755 index 0000000..d2f5be6 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/forms.py @@ -0,0 +1,21 @@ +from flask.ext.wtf import Form +from wtforms import StringField, IntegerField, SelectField, PasswordField +# from flask_wtf.html5 import EmailField +from wtforms.validators import DataRequired, EqualTo + +class TripsForm(Form): + trip_name = StringField('trip_name', validators=[DataRequired()]) + destination = StringField('destination', validators=[DataRequired()]) + friends = SelectField('friends', choices=[], coerce=int, validators=[DataRequired()]) + + +class LoginForm(Form): + username = StringField('username', validators=[DataRequired()]) + password = StringField('password', validators=[DataRequired()]) + + +class RegisterForm(Form): + name = StringField('name', validators=[DataRequired()]) + username = StringField('username', validators=[DataRequired()]) + password = PasswordField('password', validators=[DataRequired()]) + confirm = PasswordField('Confirm password', validators=[DataRequired(), EqualTo('password', message='Passwords not match.')]) diff --git a/Assignment/HW7 - Mega Lab Travel App/app/models.py b/Assignment/HW7 - Mega Lab Travel App/app/models.py new file mode 100755 index 0000000..4bd6f07 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/models.py @@ -0,0 +1,44 @@ +import sqlite3 as sql + +def login_user(username, password): + with sql.connect("app.db") as con: + con.row_factory = sql.Row + cur = con.cursor() + travellers = cur.execute('SELECT * FROM travellers WHERE username=? and password=?', (username, password)).fetchall() + return travellers + +def get_friends(my_id): + with sql.connect("app.db") as con: + con.row_factory = sql.Row + cur = con.cursor() + travellers = cur.execute('SELECT * FROM travellers WHERE traveller_id != ?', (my_id,)).fetchall() + return travellers + +def insert_user(user, username, password): + with sql.connect('app.db') as con: + cur = con.cursor() + cur.execute('INSERT INTO travellers (traveller_name, username, password) VALUES(?,?,?)', (user, username, password)) + con.commit() + user_id = cur.execute('SELECT last_insert_rowid()').fetchall()[0][0] + return user_id + + +def insert_trip(trip_name, destination, creator_id, friend_id): + with sql.connect("app.db") as con: + cur = con.cursor() + cur.execute('INSERT INTO trips (trip_name, destination, creator_id, friend_id) VALUES (?,?,?,?)', (trip_name, destination, creator_id, friend_id)) + con.commit() + +def retrieve_trips(my_id): + with sql.connect("app.db") as con: + con.row_factory = sql.Row + cur = con.cursor() + trips = cur.execute('SELECT * FROM trips WHERE creator_id = ? or friend_id = ?', (my_id, my_id,)).fetchall() + return trips + + +def delete_trip(trip_name, destination): + with sql.connect("app.db") as con: + cur = con.cursor() + cur.execute('DELETE FROM trips WHERE trip_name = ? and destination = ?', (trip_name, destination,)) + con.commit() diff --git a/Assignment/HW7 - Mega Lab Travel App/app/static/interactions.js b/Assignment/HW7 - Mega Lab Travel App/app/static/interactions.js new file mode 100755 index 0000000..3952220 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/static/interactions.js @@ -0,0 +1,22 @@ +// $(document).ready(function () { + $(document).on('click', '#delete-trip', function () { + // $(this.parentNode.parentNode).remove(); + trip_name = $(this).parent().prev().prev().text(); + destination = $(this).parent().prev().text(); + // alert(destination); + $(this).parent().parent().remove(); + $.post("http://0.0.0.0:8081/delete_trip", + { + trip_name: trip_name, + destination: destination + }, + function(data) { + if (data == "ok") { + alert("Trip deleted.") + } else { + alert("Error.") + } + } + ); + }); +// }); \ No newline at end of file diff --git a/Assignment/HW7 - Mega Lab Travel App/app/static/logo.png b/Assignment/HW7 - Mega Lab Travel App/app/static/logo.png new file mode 100644 index 0000000..870f321 Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/app/static/logo.png differ diff --git a/Assignment/HW7 - Mega Lab Travel App/app/static/main.css b/Assignment/HW7 - Mega Lab Travel App/app/static/main.css new file mode 100755 index 0000000..188616f --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/static/main.css @@ -0,0 +1,296 @@ +/*----------------- CSS RESET ------------------*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; + margin-top: 5%; + margin-left: 30%; +} + +/*----------------- CSS RESET ------------------*/ + +html, body { + background-color: #f9f9f9; + font-family: 'Open Sans', sans-serif; + font-size: 16px; +} + +header { + background-color: #1a9dbc; + box-shadow: 0 2px 6px 1px #a7a7a7; + color: #ecf0f1; + height: 5rem; +} + +footer { + float: left; + background-color: #1a9dbc; + bottom: 0; + color: #ecf0f1; + height: 7rem; + margin-top: 2em; + text-align: center; + width: 100%; +} + +footer p { + height: 7rem; + line-height: 7rem; +} + +h1, h3 { + padding: 4px; + margin-left: 10% +} + +h1 { + font-size: 2rem; + font-weight: bold; +} + +h3 { + font-size: 1.4rem; +} + +a { + text-decoration: none; +} + +input[type="text"], input[type="range"] { + border: 1px solid #bdc3c7; + border-radius: 2px; + margin-left: 1rem; + vertical-align: middle; +} + +input[type=range]{ + -webkit-appearance: none; +} + +input[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + border: none; + height: 1.2rem; + width: 1.2rem; + border-radius: 50%; + background: #1a9dbc; + margin-top: -.5rem; +} + +input[type=range]::-webkit-slider-runnable-track { + background: #ccc; + height: .2rem; +} + +.action-button { + margin-top: 10%; + margin-left:30%; + background-color: #1a9dbc; + border: none; + border-bottom: 3px solid #1670a03; + border-radius: 2px; + color: #ecf0f1; + display: inline-block; + font-size: 1rem; + font-weight: bold; + height: 3rem; + padding: 4px; + width: 6rem; +} + +.action-button:hover { + background-color: #1a9dbc; +} + +#site-title-wrapper { + display: inline-block; + height: 5rem; + width: 15%; +} + +#site-icon-wrapper { + display: inline-block; + margin-left: 1rem; + margin-top: -.5rem; + vertical-align: middle; + width: 2.5rem; +} + +#site-icon-wrapper img { + display: inline-block; + max-height: 100%; + max-width: 100% +} + +#site-title { + display: inline-block; + font-weight: bold; + height: 5rem; + line-height: 5rem; + margin-left: .1rem; +} + +#username { + margin-right: .7rem; +} + +#logout { + float: right; + height: inherit; + line-height: 5rem; + margin-right: 1rem; +} + +#logout-button { + background-color: #ecf0f1; + border-bottom-color: #bdc3c7; + color: #222222; + height: 2.5rem; + width: 5rem; +} + +#logout-button:hover { + background-color: #bdc3c7; +} + +#content { + margin-top: 2rem; + text-align: center; + width: 100%; +} + +.main-container { + background: #ecf0f1; + border-radius: 4px; + box-shadow: 0px 2px 10px 2px #95a5a6; + display: block; + min-height: 50vh; + margin: 2rem 0 0 25%; + padding: 1rem; + text-align: left; + width: 50%; +} + +.survey-item, .result-item, #results-email-container { + box-sizing: border-box; + display: block; + margin: 1.5rem 0; + padding: 4px; +} + +.survey-item span { + font-size: 1rem; + margin-left: 1rem; +} + +#email-results-button, #goHome { + height: 2rem; + line-height: 2rem; + margin-left: 1rem; + text-align: center; +} +#site-icon-wrapper { + margin-top: 10%; +} + +.section { + float: left; + width: 40%; + margin-top: 5%; + margin-left: 5%; + +} +.section a { + display: block; + width: 5em; + background: #1a9dbc; + color: white; + border: 1px solid #1a9dbc; + border-radius: 1em; + margin: 2% 40% 2% 40%; + padding: 1em 1em; +} + +td, th { + margin: 1em; + border: 1px solid black; +} + +form p { + margin: 1em; +} + +#logout-button { + margin-right: 2em; +} +.map { + width: 40%; + float: left; + margin-top: 5%; + margin-left: 5%; +} + + +#delete-trip { + margin-top: 1%; + margin-left:0; + background-color: #1a9dbc; + border: none; + border-radius: 2px; + color: #ecf0f1; + display: inline-block; + font-size: 1rem; + font-weight: bold; + height: 2.5rem; + padding: 4px; + width: 6rem; +} + +/* striped table. */ +.striped tr:first-child { + height: 30px; +} + +.striped th { + vertical-align: middle; + padding: 0 0.3em; +} diff --git a/Assignment/HW7 - Mega Lab Travel App/app/templates/base.html b/Assignment/HW7 - Mega Lab Travel App/app/templates/base.html new file mode 100755 index 0000000..27d5925 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/templates/base.html @@ -0,0 +1,33 @@ + + + + + + {% block title %}{% endblock %} - Monkey Travel + + + + {% block styles %}{% endblock %} + + + + +
+
+
+ +
+ +
+ {% block header %} + {% endblock %} +
+
{% block content %}{% endblock %}
+ + + + + + \ No newline at end of file diff --git a/Assignment/HW7 - Mega Lab Travel App/app/templates/create_trip.html b/Assignment/HW7 - Mega Lab Travel App/app/templates/create_trip.html new file mode 100755 index 0000000..27f61b8 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/templates/create_trip.html @@ -0,0 +1,31 @@ +{% extends "base.html" %} + +{% block title %} + Create Trip +{% endblock %} + + +{% block header %} +
+ +
+{% endblock %} + +{% block content %} +

Create an Awesome Trip

+
+
+ {{ form.csrf_token }} +

+ Trip Name: {{ form.trip_name(placeholder="Trip Name") }} +

+

+ Destination: {{ form.destination(placeholder="Destination") }} +

+

+ Fellow Traveller: {{ form.friends(placeholder="Fellow Traveller") }} +

+ +
+
+{% endblock %} \ No newline at end of file diff --git a/Assignment/HW7 - Mega Lab Travel App/app/templates/login.html b/Assignment/HW7 - Mega Lab Travel App/app/templates/login.html new file mode 100755 index 0000000..1b88c1d --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/templates/login.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block title %} + Login +{% endblock %} + +{% block content %} +

Hi There! Welcome to Monkey Travel!

+
+

Let's get you logged in

+
+
+
+ SignUp + +
+
+{% endblock %} diff --git a/Assignment/HW7 - Mega Lab Travel App/app/templates/not_authorized.html b/Assignment/HW7 - Mega Lab Travel App/app/templates/not_authorized.html new file mode 100755 index 0000000..99a0c25 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/templates/not_authorized.html @@ -0,0 +1,13 @@ + + + + + Oops! + + +

Uh Oh! You're not authorized

+ +
+ Take me back home, already! + + \ No newline at end of file diff --git a/Assignment/HW7 - Mega Lab Travel App/app/templates/page_not_found.html b/Assignment/HW7 - Mega Lab Travel App/app/templates/page_not_found.html new file mode 100755 index 0000000..dadcc99 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/templates/page_not_found.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} + +{% block title %} + Oops! +{% endblock %} + +{% block content %} +

Oh, Pooh Bear! You're stuck because we don't have that page for you.

+ +
+ Go back! +{% endblock %} \ No newline at end of file diff --git a/Assignment/HW7 - Mega Lab Travel App/app/templates/signup.html b/Assignment/HW7 - Mega Lab Travel App/app/templates/signup.html new file mode 100755 index 0000000..c3d715c --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/templates/signup.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} + +{% block title %} + Create Account +{% endblock %} + +{% block content %} +

Create an Account

+
+
+ {{ form.csrf_token }} +

+ Name: {{ form.name(placeholder="Name") }} +

+

+ Username: {{ form.username(placeholder="username") }} +

+

+ Password: {{ form.password(placeholder="password") }} +

+

+ Confirm Password: {{ form.confirm(placeholder="Confirm password") }} +

+ Login + +
+
+{% endblock %} diff --git a/Assignment/HW7 - Mega Lab Travel App/app/templates/trips.html b/Assignment/HW7 - Mega Lab Travel App/app/templates/trips.html new file mode 100755 index 0000000..9a885bb --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/templates/trips.html @@ -0,0 +1,49 @@ +{% extends "base.html" %} + +{% block header %} +
+ +
+{% endblock %} + +{% block content %} +
+
+

Hi There! Welcome to Monkey Travel!

+
+

Trip Map.

+ +
+ + + +
+
+

Here are all your trips:

+ + + + + + + + + {% for trip in trips %} + + + + + + {% endfor %} +
Trip NameDestinationAction
{{ trip['trip_name'] }}{{ trip['destination'] }}
+
+
+
+{% endblock %} diff --git a/Assignment/HW7 - Mega Lab Travel App/app/views.py b/Assignment/HW7 - Mega Lab Travel App/app/views.py new file mode 100755 index 0000000..9a287a4 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/app/views.py @@ -0,0 +1,96 @@ +from flask import request, render_template, session, redirect, url_for, escape, flash +from app import app, models, db +from .forms import TripsForm, RegisterForm +from .models import * +# import json + +@app.route('/') +@app.route('/index') +def index(): + username = '' + if 'username' in session: + username = escape(session['username']) + return redirect(url_for('display_trips')) + else: + return render_template('login.html') + +@app.route('/login', methods=['GET', 'POST']) +def login(): + if request.method == 'POST': + # validate if user exists otherwise say access denied... + travellers = login_user(request.form.get("username"), request.form.get("password")) #get username and password from post + # return json.dumps([dict(ix) for ix in travellers]) + if not travellers: + return render_template('not_authorized.html') + else: + for traveller in travellers: + session['name'] = traveller['traveller_name'] + session['id'] = traveller['traveller_id'] + session['username'] = traveller['username'] + session['password'] = traveller['password'] + return redirect(url_for('index')) + +@app.route('/signup', methods=['GET', 'POST']) +def signup(): + form = RegisterForm(request.form) + if form.validate_on_submit(): + user = form.name.data + username = form.username.data + password = form.password.data + travellers = login_user(request.form.get("username"), request.form.get("password")) + if travellers: + flash("Username has already taken.", 'danger') + return render_template('signup.html', form=form) + else: + user_id = insert_user(user, username, password) + session['name'] = user + session['username'] = username + session['password'] = password + session['id'] = user_id + return redirect(url_for('index')) + return render_template('signup.html', form=form) + + +@app.route('/logout') +def logout(): + session.pop('username', None) + session.pop('password', None) + session.pop('name', None) + session.pop('id', None) + return redirect(url_for('index')) + +@app.route('/create_trip', methods=['GET', 'POST']) +def create_trip(): + if 'username' in session: + form = TripsForm(request.form) + friends = get_friends(session['id']) + form.friends.choices = [(friend['traveller_id'], friend['traveller_name']) for friend in friends] + if form.validate_on_submit(): + trip_name = form.trip_name.data + destination = form.destination.data + fellow_traveller = form.friends.data + # return "done" + insert_trip(trip_name, destination, session['id'], fellow_traveller) + return redirect('/trips') + return render_template('create_trip.html', form=form) + return render_template('login.html') + # friends = get_friends(session['id']) + + +@app.route('/trips') +def display_trips(): + print("hello") + print ("my session id: ", session['id']) + trips = retrieve_trips(session['id']) + return render_template('trips.html', + trips=trips) + +@app.route('/delete_trip', methods=['GET', 'POST']) +def delete(): + if 'username' in session: + trip_name = request.form['trip_name'] + destination = request.form['destination'] + delete_trip(trip_name, destination) + return "ok" + else: + return "error" diff --git a/Assignment/HW7 - Mega Lab Travel App/config.py b/Assignment/HW7 - Mega Lab Travel App/config.py new file mode 100755 index 0000000..a995426 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/config.py @@ -0,0 +1,8 @@ +import os +basedir = os.path.abspath(os.path.dirname(__file__)) + +SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db') +SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository') + +WTF_CSRF_ENABLED = True +SECRET_KEY = 'you-will-never-guess' diff --git a/Assignment/HW7 - Mega Lab Travel App/requirements.txt b/Assignment/HW7 - Mega Lab Travel App/requirements.txt new file mode 100755 index 0000000..bfbaf81 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/requirements.txt @@ -0,0 +1,10 @@ +Flask==0.10.1 +Flask-SQLAlchemy==2.1 +Flask-WTF==0.12 +itsdangerous==0.24 +Jinja2==2.8 +MarkupSafe==0.23 +SQLAlchemy==1.0.12 +Werkzeug==0.11.4 +wheel==0.29.0 +WTForms==2.1 diff --git a/Assignment/HW7 - Mega Lab Travel App/run.py b/Assignment/HW7 - Mega Lab Travel App/run.py new file mode 100755 index 0000000..5d2f714 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/run.py @@ -0,0 +1,2 @@ +from app import app +app.run(debug=True, host="0.0.0.0", port=8081) diff --git a/Assignment/HW7 - Mega Lab Travel App/schema.sql b/Assignment/HW7 - Mega Lab Travel App/schema.sql new file mode 100644 index 0000000..d17a223 --- /dev/null +++ b/Assignment/HW7 - Mega Lab Travel App/schema.sql @@ -0,0 +1,18 @@ +drop table if exists customers; +create table trips ( + trip_id integer primary key autoincrement, + trip_name text not null, + destination text not null, + creator_id integer not null, + friend_id integer not null, + FOREIGN KEY (creator_id) REFERENCES travellers(traveller_id), + FOREIGN KEY (friend_id) REFERENCES travellers(traveller_id) +); + +drop table if exists travellers; +create table travellers ( + traveller_id integer primary key autoincrement, + traveller_name text not null, + username text not null unique, + password text not null +); diff --git a/Assignment/HW7 - Mega Lab Travel App/~app.db b/Assignment/HW7 - Mega Lab Travel App/~app.db new file mode 100644 index 0000000..a79b42e Binary files /dev/null and b/Assignment/HW7 - Mega Lab Travel App/~app.db differ