-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ciana Lim
authored and
Ciana Lim
committed
Nov 9, 2015
0 parents
commit fd39e64
Showing
27 changed files
with
654 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
Copyright (c) 2015 by Armin Ronacher and contributors. See AUTHORS | ||
for more details. | ||
|
||
Some rights reserved. | ||
|
||
Redistribution and use in source and binary forms of the software as well | ||
as documentation, with or without modification, are permitted provided | ||
that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright | ||
notice, this list of conditions and the following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above | ||
copyright notice, this list of conditions and the following | ||
disclaimer in the documentation and/or other materials provided | ||
with the distribution. | ||
|
||
* The names of the contributors may not be used to endorse or | ||
promote products derived from this software without specific | ||
prior written permission. | ||
|
||
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND | ||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT | ||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: gunicorn csitwit:app --log-file=- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export MINITWIT_SETTINGS env var or edit minitwit.py | ||
|
||
python3 -m flask -a csitwit initdb | ||
python3 csitwit.py | ||
|
||
This is a modification of the MiniTwit example from Flask. |
Empty file.
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from helpers import functions | ||
from flask import Flask, request, session, url_for, redirect, \ | ||
render_template, abort, g, flash, _app_ctx_stack | ||
|
||
def follow_user(username): | ||
"""Adds the current user as follower of the given user.""" | ||
if not g.user: | ||
abort(401) | ||
whom_id = functions.get_user_id(username) | ||
if whom_id is None: | ||
abort(404) | ||
db = functions.get_db() | ||
db.execute('insert into follower (who_id, whom_id) values (?, ?)', | ||
[session['user_id'], whom_id]) | ||
db.commit() | ||
flash('You are now following "%s"' % username) | ||
return redirect(functions.url_for('/%(username)s', {'username':username})) | ||
|
||
def unfollow_user(username): | ||
"""Removes the current user as follower of the given user.""" | ||
if not g.user: | ||
abort(401) | ||
whom_id = functions.get_user_id(username) | ||
if whom_id is None: | ||
abort(404) | ||
db = functions.get_db() | ||
db.execute('delete from follower where who_id=? and whom_id=?', | ||
[session['user_id'], whom_id]) | ||
db.commit() | ||
flash('You are no longer following "%s"' % username) | ||
return redirect(functions.url_for('/%(username)s', {'username':username})) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from helpers import functions | ||
from flask import Flask, request, session, url_for, redirect, \ | ||
render_template, abort, g, flash, _app_ctx_stack | ||
|
||
PER_PAGE = 30 | ||
|
||
def index(): | ||
"""Shows a users timeline or if no user is logged in it will | ||
redirect to the public timeline. This timeline shows the user's | ||
messages as well as all the messages of followed users. | ||
""" | ||
if not g.user: | ||
return redirect(functions.url_for('/public')) | ||
query_messages = functions.query_db(''' | ||
select message.*, user.* from message, user | ||
where message.author_id = user.user_id and ( | ||
user.user_id = ? or | ||
user.user_id in (select whom_id from follower | ||
where who_id = ?)) | ||
order by message.pub_date desc limit ?''', | ||
[session['user_id'], session['user_id'], PER_PAGE]) | ||
return render_template('timeline.html', messages=query_messages) | ||
|
||
def public(): | ||
"""Displays the latest messages of all users.""" | ||
return render_template('timeline.html', messages=functions.query_db(''' | ||
select message.*, user.* from message, user | ||
where message.author_id = user.user_id | ||
order by message.pub_date desc limit ?''', [PER_PAGE])) | ||
|
||
def user(username): | ||
"""Display's a users tweets.""" | ||
profile_user = functions.query_db('select * from user where username = ?', | ||
[username], one=True) | ||
if profile_user is None: | ||
abort(404) | ||
followed = False | ||
if g.user: | ||
followed = functions.query_db('''select 1 from follower where | ||
follower.who_id = ? and follower.whom_id = ?''', | ||
[session['user_id'], profile_user['user_id']], | ||
one=True) is not None | ||
return render_template('timeline.html', messages=functions.query_db(''' | ||
select message.*, user.* from message, user where | ||
user.user_id = message.author_id and user.user_id = ? | ||
order by message.pub_date desc limit ?''', | ||
[profile_user['user_id'], PER_PAGE]), followed=followed, | ||
profile_user=profile_user) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from helpers import functions | ||
from flask import Flask, request, session, url_for, redirect, \ | ||
render_template, abort, g, flash, _app_ctx_stack | ||
import time | ||
|
||
def add_message(): | ||
"""Registers a new message for the user.""" | ||
if 'user_id' not in session: | ||
abort(401) | ||
if request.form['text']: | ||
db = functions.get_db() | ||
db.execute('''insert into message (author_id, text, pub_date) | ||
values (?, ?, ?)''', (session['user_id'], request.form['text'], | ||
int(time.time()))) | ||
db.commit() | ||
flash('Your message was recorded') | ||
return redirect(functions.url_for('/')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
from helpers import functions | ||
from flask import Flask, request, session, url_for, redirect, \ | ||
render_template, abort, g, flash, _app_ctx_stack | ||
from werkzeug import check_password_hash, generate_password_hash | ||
|
||
def login(): | ||
"""Logs the user in.""" | ||
if g.user: | ||
return redirect(functions.url_for('/')) | ||
error = None | ||
if request.method == 'POST': | ||
user = functions.query_db('''select * from user where | ||
username = ?''', [request.form['username']], one=True) | ||
if user is None: | ||
error = 'Invalid username' | ||
elif not check_password_hash(user['pw_hash'], | ||
request.form['password']): | ||
error = 'Invalid password' | ||
else: | ||
flash('You were logged in') | ||
session['user_id'] = user['user_id'] | ||
return redirect(functions.url_for('/')) | ||
return render_template('login.html', error=error) | ||
|
||
def register(): | ||
"""Registers the user.""" | ||
if g.user: | ||
return redirect(functions.url_for('/')) | ||
error = None | ||
if request.method == 'POST': | ||
if not request.form['username']: | ||
error = 'You have to enter a username' | ||
elif not request.form['email'] or \ | ||
'@' not in request.form['email']: | ||
error = 'You have to enter a valid email address' | ||
elif not request.form['password']: | ||
error = 'You have to enter a password' | ||
elif request.form['password'] != request.form['password1']: | ||
error = 'The two passwords do not match' | ||
#request.form['password'] is not request.form['password1'] | ||
elif functions.get_user_id(request.form['username']) is not None: | ||
error = 'The username is already taken' | ||
else: | ||
db = functions.get_db() | ||
db.execute('''insert into user (username, email, pw_hash) values (?, ?, ?)''', | ||
[request.form['username'], request.form['email'], | ||
generate_password_hash(request.form['password'])]) | ||
db.commit() | ||
flash('You were successfully registered and can login now') | ||
return redirect(functions.url_for('login')) | ||
return render_template('register.html', error=error) | ||
|
||
def logout(): | ||
"""Logs the user out.""" | ||
flash('You were logged out') | ||
session.pop('user_id', None) | ||
return redirect(functions.url_for('/public')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from flask import Flask | ||
from helpers import functions, init | ||
import router | ||
|
||
# create our application | ||
app = Flask(__name__) | ||
|
||
# configuration | ||
app.config.update( | ||
DEBUG = True, | ||
DATABASE = 'minitwit.db', | ||
SECRET_KEY = 'a unique key' | ||
) | ||
|
||
# some initialization functions | ||
init.start(app) | ||
|
||
# set our router | ||
router.set_router(app) | ||
|
||
if __name__ == "__main__": | ||
app.run(port=5001) |
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
from flask import _app_ctx_stack | ||
from flask import current_app as app | ||
from flask import Flask, request, session, url_for, redirect, \ | ||
render_template, abort, g, flash, _app_ctx_stack | ||
from sqlite3 import dbapi2 as sqlite3 | ||
from hashlib import md5 | ||
from datetime import datetime | ||
|
||
def get_db(): | ||
"""Opens a new database connection if there is none yet for the | ||
current application context. | ||
""" | ||
top = _app_ctx_stack.top | ||
if not hasattr(top, 'sqlite_db'): | ||
top.sqlite_db = sqlite3.connect(app.config['DATABASE']) | ||
top.sqlite_db.row_factory = sqlite3.Row | ||
return top.sqlite_db | ||
|
||
def close_database(exception): | ||
"""Closes the database again at the end of the request.""" | ||
top = _app_ctx_stack.top | ||
if hasattr(top, 'sqlite_db'): | ||
top.sqlite_db.close() | ||
|
||
def init_db(): | ||
"""Initializes the database.""" | ||
db = get_db() | ||
with app.open_resource('schema.sql', mode='r') as f: | ||
db.cursor().executescript(f.read()) | ||
db.commit() | ||
|
||
def initdb_command(): | ||
"""Creates the database tables.""" | ||
init_db() | ||
print('Initialized the database.') | ||
|
||
def query_db(query, args=(), one=False): | ||
"""Queries the database and returns a list of dictionaries.""" | ||
cur = get_db().execute(query, args) | ||
rv = cur.fetchall() | ||
return (rv[0] if rv else None) if one else rv | ||
|
||
def get_user_id(username): | ||
"""Convenience method to look up the id for a username.""" | ||
rv = query_db('select user_id from user where username = ?', | ||
[username], one=True) | ||
return rv[0] if rv else None | ||
|
||
|
||
def format_datetime(timestamp): | ||
"""Format a timestamp for display.""" | ||
return datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%d @ %H:%M') | ||
|
||
|
||
def gravatar_url(email, size=80): | ||
"""Return the gravatar image for the given email address.""" | ||
return 'http://www.gravatar.com/avatar/%s?d=identicon&s=%d' % \ | ||
(md5(email.strip().lower().encode('utf-8')).hexdigest(), size) | ||
|
||
def url_for(string, data=None): | ||
if data is not None: | ||
return (string) % data | ||
else: | ||
return string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from helpers import functions | ||
|
||
def start(app): | ||
# add some filters to jinja, to enable us to use it on our template files | ||
app.jinja_env.filters['datetimeformat'] = functions.format_datetime | ||
app.jinja_env.filters['gravatar'] = functions.gravatar_url | ||
app.jinja_env.filters['url_for'] = functions.url_for | ||
|
||
# teardown_appcontext closes the database | ||
app.teardown_appcontext(functions.close_database) | ||
|
||
# we're adding the cli command to initialize the database | ||
app.cli.command('initdb')(functions.initdb_command) | ||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
click==5.1 | ||
-e git://github.com/mitsuhiko/flask.git#egg=Flask | ||
gunicorn==19.3.0 | ||
itsdangerous==0.24 | ||
Jinja2==2.8 | ||
MarkupSafe==0.23 | ||
Werkzeug==0.10.4 | ||
wheel==0.24.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from flask import g, session | ||
from helpers import functions, init | ||
from controllers import follow, timeline, tweet, user | ||
|
||
def set_router(app): | ||
# we're setting g.user as the user in the current session | ||
@app.before_request | ||
def before_request(): | ||
g.user = None | ||
if 'user_id' in session: | ||
# if there is a user_id in session | ||
# select it and set g.user to it | ||
g.user = functions.query_db('select * from user where user_id = ?', | ||
[session['user_id']], one=True) | ||
|
||
### Our Routes ### | ||
|
||
# timeline routes | ||
app.route('/')(timeline.index) | ||
app.route('/public')(timeline.public) | ||
app.route('/<username>')(timeline.user) | ||
|
||
# follow routes | ||
app.route('/<username>/follow')(follow.follow_user) | ||
app.route('/<username>/unfollow')(follow.unfollow_user) | ||
|
||
# tweet routes | ||
app.route('/add_message', methods=['POST'])(tweet.add_message) | ||
|
||
# user routes | ||
app.route('/login', methods=['GET', 'POST'])(user.login) | ||
app.route('/register', methods=['GET', 'POST'])(user.register) | ||
app.route('/logout')(user.logout) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
drop table if exists user; | ||
create table user ( | ||
user_id integer primary key autoincrement, | ||
username text not null, | ||
email text not null, | ||
pw_hash text not null | ||
); | ||
|
||
drop table if exists follower; | ||
create table follower ( | ||
who_id integer, | ||
whom_id integer | ||
); | ||
|
||
drop table if exists message; | ||
create table message ( | ||
message_id integer primary key autoincrement, | ||
author_id integer not null, | ||
text text not null, | ||
pub_date integer | ||
); | ||
|
||
INSERT INTO user (username, email, pw_hash) VALUES ('person', '[email protected]', 'pbkdf2:sha1:1000$L1UfsRgW$d780bf74e8432301bbdd361ee5ade12e842820e3') |
Oops, something went wrong.