← flask-blog

modularity

b10cfa68833733e685a6e438a97b300f4f1519e6 · ovidiucs · May 19, 2015 20:36

+165 −120 · 23 files changed

  • app/__init__.py +31 −0
  • app/main/__init__.py +5 −0
  • app/main/routes.py +63 −0
  • app/models.py +47 −0
  • {templates => app/templates}/404.html +0 −0
  • {templates => app/templates}/base.html +0 −0
  • {templates => app/templates}/form.html +0 −0
  • {templates => app/templates}/form2.html +0 −0
  • {templates => app/templates}/index.html +0 −0
  • {templates => app/templates}/login.html +0 −0
  • {templates => app/templates}/logout.html +0 −0
  • {templates => app/templates}/macros.html +0 −0
  • {templates => app/templates}/other.html +0 −0
  • {templates => app/templates}/protected.html +0 −0
  • {templates => app/templates}/session.html +0 −0
  • {templates => app/templates}/sqla.html +0 −0
  • {templates => app/templates}/text.txt +0 −0
  • {templates => app/templates}/upload.html +0 −0
  • {templates => app/templates}/user.html +0 −0
  • {templates => app/templates}/weather-average.html +0 −0
  • config/config.py +7 −0
  • flask-blog.py +1 −120
  • run.py +11 −0
diff --git a/app/__init__.py b/app/__init__.py
new file mode 100644
index 0000000..3f9ec31
--- /dev/null
+++ b/app/__init__.py
@@ -0,0 +1,31 @@
+import os
+from flask import Flask
+from flask.ext.bootsrap import Bootstrap
+from flask.ext.sqlalchemy import SQLAlchemy
+from flask.ext.login import LoginManager
+
+bootstrap = Bootstrap()
+db = SQLAlchemy()
+lm = LoginManager()
+lm.login_view = 'main.login'
+
+
+def create_app(config_name):
+    """Create an application instance"""
+    app = Flask(__name__)
+
+    # import configuration
+    cfg = os.path.join(os.getcwd(), 'config', config_name + '.py')
+    app.config.from_pyfile(cfg)
+
+    # initialize extensions
+    bootstrap.init_app(app)
+    db.init_app(app)
+    lm.init_app(app)
+
+    # import blueprints
+    from .main import main as main_blueprint
+
+    app.register_blueprint(main_blueprint)
+
+    return app
diff --git a/app/main/__init__.py b/app/main/__init__.py
new file mode 100644
index 0000000..c0c9c3c
--- /dev/null
+++ b/app/main/__init__.py
@@ -0,0 +1,5 @@
+from flask import Blueprint
+
+main = Blueprint('main', __name__)
+
+from . import routes
diff --git a/app/main/routes.py b/app/main/routes.py
new file mode 100644
index 0000000..86d8683
--- /dev/null
+++ b/app/main/routes.py
@@ -0,0 +1,63 @@
+from flask import render_template, request, url_for, redirect
+from flask.ext.login import login_required, login_user, logout_user
+from ..models import User
+from . import main
+from .forms import LoginForm
+
+"""
+POST request > wtf run all the validators and if
+they validate they get in the if body
+ser.query.filter_by(username=form.username.data)
+--if user is None
+1 or None (user is valid, user invalid return None
+Never get more than one. Username is unique
+
+--user.verify_password(form.password.data):
+    we need to let the user try again, redirect to login page
+    a redirect to itself
+--login_user(user, form.remember_me.data)
+    function that comes with flask.login,
+    login the user pass the user object and tell it if
+    we want it that it should be a user to be remembered
+--return redirect(request.args.get('next') or url_for('index'))
+    redirect to home page or protected page while being logged out
+    intercepted and sent to the login
+--request.args
+    python dictionary will have all the elements
+    next is used in arguments if user tried to access restricted page
+    if user will login ok then it will use the next parameter, which in
+    turn it will go to protected page
+--args.get('next'
+    none > redirect to index page or protected page
+--
+"""
+
+
+@main.route('/login', methods=['GET', 'POST'])
+def login():
+    form = LoginForm()
+    if form.validate_on_submit():
+        user = User.query.filter_by(username=form.username.data).first
+        if user is None or not user.verify_password(form.password.data):
+            return redirect(url_for('main.login', **request.args))
+        login_user(user, form.remember_me.data)
+        return redirect(request.args.get('next') or url_for('main.index'))
+    return render_template('login.html', form=form)
+
+
+@main.route('/logout')
+@login_required
+def logout():
+    logout_user()
+    return redirect(url_for('main.index'))
+
+
+@main.route('/protected')
+@login_required
+def protected():
+    return render_template('protected.html')
+
+
+@app.route('/')
+def hello_world():
+    return render_template('index.html')
diff --git a/app/models.py b/app/models.py
new file mode 100644
index 0000000..e1f59e2
--- /dev/null
+++ b/app/models.py
@@ -0,0 +1,47 @@
+from flask.ext.login import UserMixin
+from werkzeug.security import generate_password_hash, check_password_hash
+from . import db, lm
+
+
+
+
+# Define a class that represents our users in the database
+# This class inherits from  a base model classes
+# Models > Classes > Associated with entities within a database.
+# The hardest part was finding the right SQLAlchemy data types and picking a
+# length for our String fields in the database. Using our models is also extremely
+# simple, thanks to the SQLAlchemy query syntax
+
+class User(UserMixin, db.Model):
+    """
+    Inherit from a user mixin class.
+    Methods > or implement your own methods
+    """
+    __tablename__ = 'users'
+    id = db.Column(db.Integer, primary_key=True)
+    name = db.Column(db.String(16), index=True, unique=True)
+
+    username = db.Column(db.String(16), index=True, unique=True)
+    password_hash = db.Column(db.String(64))
+
+    def set_password(self, password):
+        self.password_hash = generate_password_hash(password)
+
+    def verify_password(self, password):
+        return check_password_hash(self.password_hash, password)
+
+    @staticmethod
+    def register(username, password):
+        user = User(username=username)
+        user.set_password(password)
+        db.session.add(user)
+        db.session.commit()
+        return user
+
+    def __repr__(self):
+        return '<User {0}>'.format(self.username)
+
+
+@lm.user_loader
+def load_user(id):
+    return User.query.get(int(id))
diff --git a/templates/404.html b/app/templates/404.html
similarity index 100%
rename from templates/404.html
rename to app/templates/404.html
diff --git a/templates/base.html b/app/templates/base.html
similarity index 100%
rename from templates/base.html
rename to app/templates/base.html
diff --git a/templates/form.html b/app/templates/form.html
similarity index 100%
rename from templates/form.html
rename to app/templates/form.html
diff --git a/templates/form2.html b/app/templates/form2.html
similarity index 100%
rename from templates/form2.html
rename to app/templates/form2.html
diff --git a/templates/index.html b/app/templates/index.html
similarity index 100%
rename from templates/index.html
rename to app/templates/index.html
diff --git a/templates/login.html b/app/templates/login.html
similarity index 100%
rename from templates/login.html
rename to app/templates/login.html
diff --git a/templates/logout.html b/app/templates/logout.html
similarity index 100%
rename from templates/logout.html
rename to app/templates/logout.html
diff --git a/templates/macros.html b/app/templates/macros.html
similarity index 100%
rename from templates/macros.html
rename to app/templates/macros.html
diff --git a/templates/other.html b/app/templates/other.html
similarity index 100%
rename from templates/other.html
rename to app/templates/other.html
diff --git a/templates/protected.html b/app/templates/protected.html
similarity index 100%
rename from templates/protected.html
rename to app/templates/protected.html
diff --git a/templates/session.html b/app/templates/session.html
similarity index 100%
rename from templates/session.html
rename to app/templates/session.html
diff --git a/templates/sqla.html b/app/templates/sqla.html
similarity index 100%
rename from templates/sqla.html
rename to app/templates/sqla.html
diff --git a/templates/text.txt b/app/templates/text.txt
similarity index 100%
rename from templates/text.txt
rename to app/templates/text.txt
diff --git a/templates/upload.html b/app/templates/upload.html
similarity index 100%
rename from templates/upload.html
rename to app/templates/upload.html
diff --git a/templates/user.html b/app/templates/user.html
similarity index 100%
rename from templates/user.html
rename to app/templates/user.html
diff --git a/templates/weather-average.html b/app/templates/weather-average.html
similarity index 100%
rename from templates/weather-average.html
rename to app/templates/weather-average.html
diff --git a/config/config.py b/config/config.py
new file mode 100644
index 0000000..358246a
--- /dev/null
+++ b/config/config.py
@@ -0,0 +1,7 @@
+__author__ = 'ovidiucs'
+import os
+
+DEBUG = True
+SECRET_KEY = 'top secret'
+SQLALHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(
+    os.path.dirname(__file__), '../data-dev.sqlite3')
diff --git a/flask-blog.py b/flask-blog.py
index 1472cb6..6bf32fb 100644
--- a/flask-blog.py
+++ b/flask-blog.py
@@ -1,6 +1,5 @@
 import os
 import imghdr
-from werkzeug.security import generate_password_hash, check_password_hash
 from datetime import datetime
 from flask import Flask, render_template, request, session, g, \
     make_response, jsonify, url_for, redirect
@@ -10,9 +9,6 @@ from wtforms import PasswordField, StringField, SubmitField, FileField, \
     ValidationError, BooleanField
 from wtforms.validators import Required, Length
 from flask.ext.sqlalchemy import SQLAlchemy
-from flask.ext.login import LoginManager, UserMixin, login_user, logout_user, \
-    login_required
-
 
 app = Flask(__name__)
 
@@ -22,13 +18,10 @@ app = Flask(__name__)
 app.config['SECRET_KEY'] = 'top secret!'
 # where the db is
 app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.sqlite3'
+
 db = SQLAlchemy(app)
 # initialize extension
 bootstrap = Bootstrap(app)
-# login manager
-lm = LoginManager(app)
-lm.login_view = 'login'
-
 
 class NameForm(Form):
     name = StringField('What is your name?', validators=[Required(),
@@ -47,60 +40,12 @@ class UploadForm(Form):
             raise ValidationError('Invalid image format')
 
 
-# Define a class that represents our users in the database
-# This class inherits from  a base model classes
-# Models > Classes > Associated with entities within a database.
-# The hardest part was finding the right SQLAlchemy data types and picking a
-# length for our String fields in the database. Using our models is also extremely
-# simple, thanks to the SQLAlchemy query syntax
-
-class User(UserMixin, db.Model):
-    """
-    Inherit from a user mixin class.
-    Methods > or implement your own methods
-    """
-    __tablename__ = 'users'
-    id = db.Column(db.Integer, primary_key=True)
-    name = db.Column(db.String(16), index=True, unique=True)
-
-    username = db.Column(db.String(16), index=True, unique=True)
-    password_hash = db.Column(db.String(64))
-
-    def set_password(self, password):
-        self.password_hash = generate_password_hash(password)
-
-    def verify_password(self, password):
-        return check_password_hash(self.password_hash, password)
-
-    @staticmethod
-    def register(username, password):
-        user = User(username=username)
-        user.set_password(password)
-        db.session.add(user)
-        db.session.commit()
-        return user
-
-    def __repr__(self):
-        return '<User {0}>'.format(self.username)
-
-
-@lm.user_loader
-def load_user(id):
-    return User.query.get(int(id))
-
-
 class LoginForm(Form):
     username = StringField('Username', validators=[Required(), Length(1, 16)])
     password = PasswordField('Password', validators=[Required()])
     remember_me = BooleanField('Remember Me')
     submit = SubmitField('Submit')
 
-
-@app.route('/')
-def hello_world():
-    return render_template('index.html')
-
-
 @app.route('/text')
 def text():
     return render_template('text.txt'), 200, {'Content-Type': 'text/plain'}
@@ -235,68 +180,6 @@ def sqla():
     return render_template('sqla.html', form=form, name=name, new=new)
 
 
-@lm.user_loader
-def load_user(id):
-    return User.query.get(int(id))
-
-
-@app.route('/login', methods=['GET', 'POST'])
-def login():
-    form = LoginForm()
-    """
-    POST request > wtf run all the validators and if
-    they validate they get in the if body
-    ser.query.filter_by(username=form.username.data)
-    --if user is None
-    1 or None (user is valid, user invalid return None
-    Never get more than one. Username is unique
-
-    --user.verify_password(form.password.data):
-        we need to let the user try again, redirect to login page
-        a redirect to itself
-    --login_user(user, form.remember_me.data)
-        function that comes with flask.login,
-        login the user pass the user object and tell it if
-        we want it that it should be a user to be remembered
-    --return redirect(request.args.get('next') or url_for('index'))
-        redirect to home page or protected page while being logged out
-        intercepted and sent to the login
-    --request.args
-        python dictionary will have all the elements
-        next is used in arguments if user tried to access restricted page
-        if user will login ok then it will use the next parameter, which in
-        turn it will go to protected page
-    --args.get('next'
-        none > redirect to index page or protected page
-    --
-    """
-    if form.validate_on_submit():
-        user = User.query.filter_by(username=form.username.data).first()
-        if user is None or not user.verify_password(form.password.data):
-            return redirect(url_for('login'), **request.args)
-        login_user(user, form.remember_me.data)
-        return redirect(request.args.get('next') or url_for('login'))
-    return render_template('login.html', form=form)
-
-
-"""
-This route needs to be protected
-"""
-
-
-@app.route('/logout')
-@login_required
-def logout():
-    logout_user()
-    return redirect(url_for('index'))
-
-
-@app.route('/protected')
-@login_required
-def protected():
-    return render_template('protected.html')
-
-
 @app.errorhandler(404)
 def not_found(e):
     return render_template('404.html')
@@ -304,6 +187,4 @@ def not_found(e):
 
 if __name__ == '__main__':
     db.create_all()
-    if User.query.filter_by(username='john').first() is None:
-        User.register('john', 'cat')
     app.run(debug=True)
diff --git a/run.py b/run.py
new file mode 100644
index 0000000..c7a903a
--- /dev/null
+++ b/run.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+from app import create_app, db
+from app.models import User
+
+if __name__ == '__main__':
+    app = create_app('development')
+    with app.app_context():
+        db.create_all()
+        if User.query.filter_by(username='john').first() is None:
+            User.register('john', 'cat')
+    app.run()