Fix Procfile

master
Steven Loria 11 years ago
parent 3344480ffb
commit abda53a2f3
  1. 2
      .gitignore
  2. 9
      README.rst
  3. 2
      {{cookiecutter.repo_name}}/Procfile
  4. 15
      {{cookiecutter.repo_name}}/manage.py
  5. 16
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/app.py
  6. 8
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/database.py
  7. 15
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/main.py
  8. 1
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/__init__.py
  9. 14
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/modules/member.py
  10. 4
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/public/__init__.py
  11. 12
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/public/forms.py
  12. 8
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/public/views.py
  13. 2
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/_layouts/nav.html
  14. 0
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/templates/users/members.html
  15. 3
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/tests/test_models.py
  16. 3
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/user/__init__.py
  17. 13
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/user/models.py
  18. 12
      {{cookiecutter.repo_name}}/{{cookiecutter.repo_name}}/user/views.py

2
.gitignore vendored

@ -43,3 +43,5 @@ docs/_build
# Cookiecutter # Cookiecutter
output/ output/
myflaskapp/

@ -12,7 +12,7 @@ Features
- Flask-SQLAlchemy with basic User model - Flask-SQLAlchemy with basic User model
- Flask-WTForms with login and registration forms - Flask-WTForms with login and registration forms
- Procfile for deploying to a PaaS (e.g. Heroku) - Procfile for deploying to a PaaS (e.g. Heroku)
- nose for testing - Flask-Testing and nose for testing
- A simple ``manage.py`` script. - A simple ``manage.py`` script.
- CSS and JS minification using Flask-Assets - CSS and JS minification using Flask-Assets
- Easily switch between development and production environments through the MYFLASKAPP_ENV system variable. - Easily switch between development and production environments through the MYFLASKAPP_ENV system variable.
@ -61,6 +61,13 @@ BSD licensed.
Changelog Changelog
--------- ---------
0.3.0
*****
- More "divisional" organization: each blueprint contains its own view, models, and forms in a directory. There is still a single directory for templates and static assets.
- Use Flask-Bcrypt for password hashing.
- Flask-Testing support.
0.2.0 (09/21/2013) 0.2.0 (09/21/2013)
****************** ******************
- Add manage.py script - Add manage.py script

@ -1 +1 @@
web: gunicorn {{cookiecutter.repo_name}}.main:app -b 0.0.0.0:$PORT -w 3 web: gunicorn {{cookiecutter.repo_name}}.app:create_app\(\) -b 0.0.0.0:$PORT -w 3

@ -4,22 +4,21 @@ import os
import sys import sys
import subprocess import subprocess
from flask.ext.script import Manager, Shell, Server from flask.ext.script import Manager, Shell, Server
from {{cookiecutter.repo_name }} import models
from {{cookiecutter.repo_name }}.app import create_app from {{cookiecutter.repo_name }}.app import create_app
from {{cookiecutter.repo_name}}.models import db from {{cookiecutter.repo_name}}.settings import DevConfig
from {{cookiecutter.repo_name}}.database import db
env = os.environ.get("{{cookiecutter.repo_name | upper }}_ENV", 'prod')
app = create_app("{{cookiecutter.repo_name}}.settings.{0}Config" app = create_app(DevConfig)
.format(env.capitalize()))
manager = Manager(app) manager = Manager(app)
TEST_CMD = "nosetests" TEST_CMD = "nosetests"
def _make_context(): def _make_context():
'''Return context dict for a shell session so you can access '''Return context dict for a shell session so you can access
app, db, and models by default. app and db by default.
''' '''
return {'app': app, 'db': db, 'models': models} return {'app': app, 'db': db}
@manager.command @manager.command
def test(): def test():
@ -32,7 +31,7 @@ def createdb():
'''Create a database from the tables defined in models.py.''' '''Create a database from the tables defined in models.py.'''
db.create_all() db.create_all()
manager.add_command("runserver", Server()) manager.add_command("server", Server())
manager.add_command("shell", Shell(make_context=_make_context)) manager.add_command("shell", Shell(make_context=_make_context))
if __name__ == '__main__': if __name__ == '__main__':

@ -5,12 +5,14 @@ from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.assets import Environment from flask.ext.assets import Environment
from webassets.loaders import PythonLoader from webassets.loaders import PythonLoader
from {{ cookiecutter.repo_name }}.settings import ProdConfig
from {{cookiecutter.repo_name}} import assets from {{cookiecutter.repo_name}} import assets
from {{cookiecutter.repo_name}}.models import db from {{cookiecutter.repo_name}}.database import db
from {{cookiecutter.repo_name}} import public, user
assets_env = Environment() assets_env = Environment()
def create_app(config_object): def create_app(config_object=ProdConfig):
'''An application factory, as explained here: '''An application factory, as explained here:
http://flask.pocoo.org/docs/patterns/appfactories/ http://flask.pocoo.org/docs/patterns/appfactories/
@ -25,8 +27,12 @@ def create_app(config_object):
assets_loader = PythonLoader(assets) assets_loader = PythonLoader(assets)
for name, bundle in assets_loader.load_bundles().iteritems(): for name, bundle in assets_loader.load_bundles().iteritems():
assets_env.register(name, bundle) assets_env.register(name, bundle)
register_blueprints(app)
return app
def register_blueprints(app):
# Register blueprints # Register blueprints
from {{cookiecutter.repo_name}}.modules import public, member app.register_blueprint(public.views.blueprint)
app.register_blueprint(public.blueprint) app.register_blueprint(user.views.blueprint)
app.register_blueprint(member.blueprint)
return app return app

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
'''Database module, including the SQLAlchemy database object and DB-related
mixins.
'''
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()

@ -1,15 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Entry point for all things, to avoid circular imports.
"""
import os
from .app import create_app
from .models import User, db
import {{cookiecutter.repo_name}}.modules as modules
if __name__ == '__main__':
# Get the environment setting from the system environment variable
env = os.environ.get("{{cookiecutter.repo_name | upper}}_ENV", "prod")
app = create_app("{{cookiecutter.repo_name}}.settings.{env}Config"
.format(env=env.capitalize()))

@ -1 +0,0 @@
'''Blueprint modules for {{cookiecutter.repo_name}}.'''

@ -1,14 +0,0 @@
# -*- coding: utf-8 -*-
'''Members-only module, typically including the app itself.
'''
from flask import Blueprint, render_template
from {{cookiecutter.repo_name}}.utils import login_required
blueprint = Blueprint('member', __name__,
static_folder="../static",
template_folder="../templates")
@blueprint.route("/members/")
@login_required
def members():
return render_template("members.html")

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
'''The public module, including the homepage and user auth.'''
import views

@ -1,17 +1,19 @@
# -*- coding: utf-8 -*-
from flask_wtf import Form from flask_wtf import Form
from wtforms import TextField, PasswordField from wtforms import TextField, PasswordField
from wtforms.validators import DataRequired, Email, EqualTo, Length from wtforms.validators import DataRequired, Email, EqualTo, Length
class RegisterForm(Form): class RegisterForm(Form):
username = TextField('Username', validators=[DataRequired(), Length(min=3, max=25)]) username = TextField('Username',
email = TextField('Email', validators=[DataRequired(), Email(), Length(min=6, max=40)]) validators=[DataRequired(), Length(min=3, max=25)])
email = TextField('Email',
validators=[DataRequired(), Email(), Length(min=6, max=40)])
password = PasswordField('Password', password = PasswordField('Password',
validators=[DataRequired(), Length(min=6, max=40)]) validators=[DataRequired(), Length(min=6, max=40)])
confirm = PasswordField( confirm = PasswordField('Verify password',
'Verify password',
[DataRequired(), EqualTo('password', message='Passwords must match')]) [DataRequired(), EqualTo('password', message='Passwords must match')])
class LoginForm(Form): class LoginForm(Form):
username = TextField('Username', validators=[DataRequired()]) username = TextField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()])

@ -4,10 +4,10 @@ from flask import (Blueprint, request, render_template, flash, url_for,
redirect, session) redirect, session)
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from {{cookiecutter.repo_name}}.models import User from {{cookiecutter.repo_name}}.user.models import User
from {{cookiecutter.repo_name}}.forms import RegisterForm, LoginForm from {{cookiecutter.repo_name}}.public.forms import RegisterForm, LoginForm
from {{cookiecutter.repo_name}}.utils import flash_errors from {{cookiecutter.repo_name}}.utils import flash_errors
from {{cookiecutter.repo_name}}.models import db from {{cookiecutter.repo_name}}.database import db
blueprint = Blueprint('public', __name__, blueprint = Blueprint('public', __name__,
static_folder="../static", static_folder="../static",
@ -26,7 +26,7 @@ def home():
session['logged_in'] = True session['logged_in'] = True
session['username'] = u.username session['username'] = u.username
flash("You are logged in.", 'success') flash("You are logged in.", 'success')
return redirect(url_for("member.members")) return redirect(url_for("user.members"))
return render_template("home.html", form=form) return render_template("home.html", form=form)
@blueprint.route('/logout/') @blueprint.route('/logout/')

@ -23,7 +23,7 @@
{% if session.logged_in %} {% if session.logged_in %}
<a class="btn btn-default btn-sm navbar-btn navbar-right" href="{{ url_for('public.logout') }}">Log out</a> <a class="btn btn-default btn-sm navbar-btn navbar-right" href="{{ url_for('public.logout') }}">Log out</a>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li><a href="{{ url_for('member.members') }}">Logged in as {{ session.username }}</a></li> <li><a href="{{ url_for('user.members') }}">Logged in as {{ session.username }}</a></li>
</ul> </ul>
{% elif form %} {% elif form %}
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">

@ -4,7 +4,8 @@ from nose.tools import * # PEP8 asserts
from flask.ext.testing import TestCase from flask.ext.testing import TestCase
from {{ cookiecutter.repo_name }}.app import create_app from {{ cookiecutter.repo_name }}.app import create_app
from {{ cookiecutter.repo_name }}.models import User, db from {{ cookiecutter.repo_name }}.database import db
from {{ cookiecutter.repo_name }}.user.models import User
class TestUser(TestCase): class TestUser(TestCase):

@ -1,12 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""
{{cookiecutter.project_name}} models.
"""
from flask.ext.sqlalchemy import SQLAlchemy
from passlib.apps import custom_app_context as pwd_context from passlib.apps import custom_app_context as pwd_context
from {{cookiecutter.repo_name}}.database import db
db = SQLAlchemy()
class User(db.Model): class User(db.Model):
@ -14,7 +9,7 @@ class User(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False) username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(80), unique=True, nullable=False)
password = db.Column(db.String, nullable=False) # The hashed password password_hash = db.Column(db.String, nullable=False)
def __init__(self, username=None, email=None, password=None): def __init__(self, username=None, email=None, password=None):
self.username = username self.username = username
@ -23,10 +18,10 @@ class User(db.Model):
self.set_password(password) self.set_password(password)
def set_password(self, password): def set_password(self, password):
self.password = pwd_context.encrypt(password) self.password_hash = pwd_context.encrypt(password)
def check_password(self, password): def check_password(self, password):
return pwd_context.verify(password, self.password) return pwd_context.verify(password, self.password_hash)
def __repr__(self): def __repr__(self):
return '<User "{username}">'.format(username=self.username) return '<User "{username}">'.format(username=self.username)

@ -0,0 +1,12 @@
from flask import Blueprint, render_template
from {{cookiecutter.repo_name}}.utils import login_required
blueprint = Blueprint("user", __name__, url_prefix='/users')
@blueprint.route("/")
@login_required
def members():
return render_template("users/members.html")
Loading…
Cancel
Save