Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Brad Traversy committed Apr 25, 2017
0 parents commit 872871e
Show file tree
Hide file tree
Showing 17 changed files with 539 additions and 0 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# FlaskApp

Simple application with authentication and CRUD functionality using the Python Flask micro-framework

## Installation

To use this template, your computer needs:

- [Python 2 or 3](https://python.org)
- [Pip Package Manager](https://pypi.python.org/pypi)

### Running the app

Install the Foundation CLI with this command:

```bash
python app.py
```

279 changes: 279 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
from flask import Flask, render_template, flash, redirect, url_for, session, request, logging
#from data import Articles
from flask_mysqldb import MySQL
from wtforms import Form, StringField, TextAreaField, PasswordField, validators
from passlib.hash import sha256_crypt
from functools import wraps

app = Flask(__name__)

# Config MySQL
app.config['MYSQL_HOST'] = 'localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = '123456'
app.config['MYSQL_DB'] = 'myflaskapp'
app.config['MYSQL_CURSORCLASS'] = 'DictCursor'
# init MYSQL
mysql = MySQL(app)

#Articles = Articles()

# Index
@app.route('/')
def index():
return render_template('home.html')


# About
@app.route('/about')
def about():
return render_template('about.html')


# Articles
@app.route('/articles')
def articles():
# Create cursor
cur = mysql.connection.cursor()

# Get articles
result = cur.execute("SELECT * FROM articles")

articles = cur.fetchall()

if result > 0:
return render_template('articles.html', articles=articles)
else:
msg = 'No Articles Found'
return render_template('articles.html', msg=msg)
# Close connection
cur.close()


#Single Article
@app.route('/article/<string:id>/')
def article(id):
# Create cursor
cur = mysql.connection.cursor()

# Get article
result = cur.execute("SELECT * FROM articles WHERE id = %s", [id])

article = cur.fetchone()

return render_template('article.html', article=article)


# Register Form Class
class RegisterForm(Form):
name = StringField('Name', [validators.Length(min=1, max=50)])
username = StringField('Username', [validators.Length(min=4, max=25)])
email = StringField('Email', [validators.Length(min=6, max=50)])
password = PasswordField('Password', [
validators.DataRequired(),
validators.EqualTo('confirm', message='Passwords do not match')
])
confirm = PasswordField('Confirm Password')


# User Register
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegisterForm(request.form)
if request.method == 'POST' and form.validate():
name = form.name.data
email = form.email.data
username = form.username.data
password = sha256_crypt.encrypt(str(form.password.data))

# Create cursor
cur = mysql.connection.cursor()

# Execute query
cur.execute("INSERT INTO users(name, email, username, password) VALUES(%s, %s, %s, %s)", (name, email, username, password))

# Commit to DB
mysql.connection.commit()

# Close connection
cur.close()

flash('You are now registered and can log in', 'success')

return redirect(url_for('login'))
return render_template('register.html', form=form)


# User login
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# Get Form Fields
username = request.form['username']
password_candidate = request.form['password']

# Create cursor
cur = mysql.connection.cursor()

# Get user by username
result = cur.execute("SELECT * FROM users WHERE username = %s", [username])

if result > 0:
# Get stored hash
data = cur.fetchone()
password = data['password']

# Compare Passwords
if sha256_crypt.verify(password_candidate, password):
# Passed
session['logged_in'] = True
session['username'] = username

flash('You are now logged in', 'success')
return redirect(url_for('dashboard'))
else:
error = 'Invalid login'
return render_template('login.html', error=error)
# Close connection
cur.close()
else:
error = 'Username not found'
return render_template('login.html', error=error)

return render_template('login.html')

# Check if user logged in
def is_logged_in(f):
@wraps(f)
def wrap(*args, **kwargs):
if 'logged_in' in session:
return f(*args, **kwargs)
else:
flash('Unauthorized, Please login', 'danger')
return redirect(url_for('login'))
return wrap

# Logout
@app.route('/logout')
@is_logged_in
def logout():
session.clear()
flash('You are now logged out', 'success')
return redirect(url_for('login'))

# Dashboard
@app.route('/dashboard')
@is_logged_in
def dashboard():
# Create cursor
cur = mysql.connection.cursor()

# Get articles
result = cur.execute("SELECT * FROM articles")

articles = cur.fetchall()

if result > 0:
return render_template('dashboard.html', articles=articles)
else:
msg = 'No Articles Found'
return render_template('dashboard.html', msg=msg)
# Close connection
cur.close()

# Article Form Class
class ArticleForm(Form):
title = StringField('Title', [validators.Length(min=1, max=200)])
body = TextAreaField('Body', [validators.Length(min=30)])

# Add Article
@app.route('/add_article', methods=['GET', 'POST'])
@is_logged_in
def add_article():
form = ArticleForm(request.form)
if request.method == 'POST' and form.validate():
title = form.title.data
body = form.body.data

# Create Cursor
cur = mysql.connection.cursor()

# Execute
cur.execute("INSERT INTO articles(title, body, author) VALUES(%s, %s, %s)",(title, body, session['username']))

# Commit to DB
mysql.connection.commit()

#Close connection
cur.close()

flash('Article Created', 'success')

return redirect(url_for('dashboard'))

return render_template('add_article.html', form=form)


# Edit Article
@app.route('/edit_article/<string:id>', methods=['GET', 'POST'])
@is_logged_in
def edit_article(id):
# Create cursor
cur = mysql.connection.cursor()

# Get article by id
result = cur.execute("SELECT * FROM articles WHERE id = %s", [id])

article = cur.fetchone()
cur.close()
# Get form
form = ArticleForm(request.form)

# Populate article form fields
form.title.data = article['title']
form.body.data = article['body']

if request.method == 'POST' and form.validate():
title = request.form['title']
body = request.form['body']

# Create Cursor
cur = mysql.connection.cursor()
app.logger.info(title)
# Execute
cur.execute ("UPDATE articles SET title=%s, body=%s WHERE id=%s",(title, body, id))
# Commit to DB
mysql.connection.commit()

#Close connection
cur.close()

flash('Article Updated', 'success')

return redirect(url_for('dashboard'))

return render_template('edit_article.html', form=form)

# Delete Article
@app.route('/delete_article/<string:id>', methods=['POST'])
@is_logged_in
def delete_article(id):
# Create cursor
cur = mysql.connection.cursor()

# Execute
cur.execute("DELETE FROM articles WHERE id = %s", [id])

# Commit to DB
mysql.connection.commit()

#Close connection
cur.close()

flash('Article Deleted', 'success')

return redirect(url_for('dashboard'))

if __name__ == '__main__':
app.secret_key='secret123'
app.run(debug=True)
25 changes: 25 additions & 0 deletions data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
def Articles():
articles = [
{
'id': 1,
'title':'Article One',
'body':'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
'author':'Brad Traversy',
'create_date':'04-25-2017'
},
{
'id': 2,
'title':'Article Two',
'body':'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
'author':'John Doe',
'create_date':'04-25-2017'
},
{
'id': 3,
'title':'Article Three',
'body':'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
'author':'Brad Traversy',
'create_date':'04-25-2017'
}
]
return articles
Binary file added data.pyc
Binary file not shown.
6 changes: 6 additions & 0 deletions templates/about.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% extends 'layout.html' %}

{% block body %}
<h1>About Us</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
{% endblock %}
15 changes: 15 additions & 0 deletions templates/add_article.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% extends 'layout.html' %}

{% block body %}
<h1>Add Article</h1>
{% from "includes/_formhelpers.html" import render_field %}
<form method="POST" action="">
<div class="form-group">
{{ render_field(form.title, class_="form-control") }}
</div>
<div class="form-group">
{{ render_field(form.body, class_="form-control", id="editor") }}
</div>
<p><input class="btn btn-primary" type="submit" value="Submit">
</form>
{% endblock %}
10 changes: 10 additions & 0 deletions templates/article.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% extends 'layout.html' %}

{% block body %}
<h1>{{article.title}}</h1>
<small>Written by {{article.author}} on {{article.create_date}}</small>
<hr>
<div>
{{article.body | safe}}
</div>
{% endblock %}
10 changes: 10 additions & 0 deletions templates/articles.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% extends 'layout.html' %}

{% block body %}
<h1>Articles</h1>
<ul class="list-group">
{% for article in articles %}
<li class="list-group-item"><a href="article/{{article.id}}">{{article.title}}</a></li>
{% endfor %}
</ul>
{% endblock %}
Loading

0 comments on commit 872871e

Please sign in to comment.