Skip to content

Commit

Permalink
Release v 0.1.12.25 and Merry X'mas!
Browse files Browse the repository at this point in the history
  • Loading branch information
imwilsonxu committed Dec 24, 2012
1 parent 41b9f1b commit 7df0de4
Show file tree
Hide file tree
Showing 66 changed files with 646 additions and 1,043 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ production.py
dist
build
logs

uploads
6 changes: 6 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Here you can see the full list of changes between each release.

## Version 0.1.12.25 (Merry X'mas!)

Re-organize blueprints, models and Templates.
Remove Flask-admin, implement a simple admin interface.
Clean codes according to pep8.

## Version 0.1

First public preview release.
2 changes: 1 addition & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ You can use it for
- Integrate with [jQuery](http://jquery.com/) and [bootstrap](https://github.com/twitter/bootstrap).
- Implement **user session management (signin/signout/rememberme)** with [Flask-Login](https://github.com/maxcountryman/flask-login).
- Implement **reset password via email** with [Flask-Mail](http://packages.python.org/Flask-Mail/).
- Implement **admin interface** with [Flask-Admin](https://flask-admin.readthedocs.org/en/latest/quickstart/).
- Implement **unit testing** with [Flask-Testing](http://packages.python.org/Flask-Testing/).
- Implement **external script (initdb/testing/etc)** with [Flask-Script](http://flask-script.readthedocs.org/en/latest/).
- Implement **admin interface**.
- Implement **Logger**.
- Handle **i18n** with [Flask-Babel](http://packages.python.org/Flask-Babel/).
- Handle **web forms** with [WTForms](http://wtforms.simplecodes.com/).
Expand Down
4 changes: 2 additions & 2 deletions app.wsgi
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ BASE_DIR = os.path.join(os.path.dirname(__file__))
activate_this = os.path.join(BASE_DIR, "env/bin/activate_this.py")
execfile(activate_this, dict(__file__=activate_this))

#if BASE_DIR not in sys.path:
#sys.path.append(BASE_DIR)
if BASE_DIR not in sys.path:
sys.path.append(BASE_DIR)

# give wsgi the "application"
from fbone import create_app
Expand Down
56 changes: 25 additions & 31 deletions fabfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,40 @@
# the servers where the commands are executed
env.hosts = ['127.0.0.1']

#def pack():
#local('rm -rf %s-%s/' % (project, version))
#local('python setup.py sdist --formats=gztar', capture=False)

# Deploy method form Flask docs.
# If you don't wanna mess up source codes with deployed codes, pls use this method.
#def deploy():
#pack()
## figure out the release name and version
#dist = local('python setup.py --fullname', capture=True).strip()

## upload the source tarball to the temporary folder on the server
#put('dist/%s.tar.gz' % dist, '/tmp/%s.tar.gz' % project)

## create a place where we can unzip the tarball, then enter
## that directory and unzip it
#run('mkdir /tmp/%s' % project)
#with cd('/tmp/%s' % project):
#run('tar xzf /tmp/%s.tar.gz' % project)
#with cd('/tmp/%s/%s' % (project, dist)):
## now setup the package with our virtual environment's
## python interpreter
#run('/var/www/%s/env/bin/python setup.py install' % project)
## now that all is set up, delete the folder again
#run('rm -rf /tmp/%s /tmp/%s.tar.gz' % (project, project))
## and finally touch the .wsgi file so that mod_wsgi triggers
## a reload of the application
#run('touch /var/www/%s.wsgi' % project)

def run():
local("python manage.py run")



# alias of run()
def r():
run()


def initdb():
local("sudo rm -f /tmp/fbone.sqlite")
local("rm -f /tmp/fbone.sqlite")
local("python manage.py initdb")


def babel():
local("python setup.py compile_catalog --directory `find -name translations` --locale zh -f")


def debug():
initdb()
run()


# alias of debug()
def d():
debug()


def init(project="myapp"):
project_dir = os.getcwd()
vhost_name = project + ".vhost"
with cd(project_dir):
local("sudo chown $USER -R "+project_dir)
local("sudo chown $USER -R " + project_dir)
# logs folder
local("mkdir logs")
# setup.py and config.py
Expand All @@ -85,11 +71,19 @@ def init(project="myapp"):
local("virtualenv env")
activate_this = os.path.join(project_dir, "env/bin/activate_this.py")
execfile(activate_this, dict(__file__=activate_this))

# Save downloading time, test only.
#local("cp -r ~/.virtualenvs/fbone/lib/python2.7/site-packages/ /srv/www/myapp/env/lib/python2.7/")

# You should move uploads folder to somewhere else
local("mkdir /tmp/uploads")

local("python setup.py install")
local("python manage.py initdb")
# make db readable
local("sudo chmod o+w /tmp/%s.sqlite" % project)


def deploy():
local("virtualenv env")
activate_this = os.path.join(project_dir, "env/bin/activate_this.py")
Expand Down
3 changes: 3 additions & 0 deletions fbone/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from .views import admin
18 changes: 18 additions & 0 deletions fbone/admin/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-

from flask.ext.wtf import Form
from flask.ext.wtf import HiddenField, SubmitField, RadioField, DateField
from flask.ext.wtf import AnyOf

from ..user import USER_ROLE, USER_STATUS


class UserForm(Form):
next = HiddenField()
role_id = RadioField(u"Role", [AnyOf([str(val) for val in USER_ROLE.keys()])],
choices=[(str(val), label) for val, label in USER_ROLE.items()])
status_id = RadioField(u"Status", [AnyOf([str(val) for val in USER_STATUS.keys()])],
choices=[(str(val), label) for val, label in USER_STATUS.items()])
# A demo of datepicker.
created_time = DateField(u'Created time')
submit = SubmitField(u'Save')
47 changes: 47 additions & 0 deletions fbone/admin/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-

from flask import Blueprint, render_template, request, flash
from flask.ext.login import login_required

from ..extensions import db
from ..decorators import admin_required

from ..user import User
from .forms import UserForm


admin = Blueprint('admin', __name__, url_prefix='/admin')


@admin.route('/')
@login_required
@admin_required
def index():
users = User.query.all()
return render_template('admin/index.html', users=users, active='index')


@admin.route('/users')
@login_required
@admin_required
def users():
users = User.query.all()
return render_template('admin/users.html', users=users, active='users')


@admin.route('/user/<user_id>', methods=['GET', 'POST'])
@login_required
@admin_required
def user(user_id):
user = User.query.filter_by(id=user_id).first_or_404()
form = UserForm(obj=user, next=request.args.get('next'))

if form.validate_on_submit():
form.populate_obj(user)

db.session.add(user)
db.session.commit()

flash('User updated.', 'success')

return render_template('admin/user.html', user=user, form=form)
1 change: 0 additions & 1 deletion fbone/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from flask import Blueprint, current_app, request, jsonify
from flask.ext.login import login_user, current_user, logout_user

from ..extensions import db
from ..user import User


Expand Down
49 changes: 13 additions & 36 deletions fbone/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@

from flask import Flask, request, render_template
from flaskext.babel import Babel
from flask.ext.admin import Admin
from flask.ext.admin.contrib.sqlamodel import ModelView
from flask.ext.admin.contrib.fileadmin import FileAdmin

from .utils import pretty_date
from .configs import DevConfig
from .user import User, UserDetail, UserRole, user
from .user import User, user
from .settings import settings
from .frontend import frontend
from .api import api
from .admin import admin
from .extensions import db, mail, cache, login_manager


Expand All @@ -25,6 +22,7 @@
user,
settings,
api,
admin,
)


Expand Down Expand Up @@ -70,43 +68,21 @@ def configure_extensions(app):

# flask-babel
babel = Babel(app)

@babel.localeselector
def get_locale():
override = request.args.get('lang')
if override:
session['lang'] = override
return session.get('lang', 'en')
else:
accept_languages = app.config.get('ACCEPT_LANGUAGES')
return request.accept_languages.best_match(accept_languages)
accept_languages = app.config.get('ACCEPT_LANGUAGES')
return request.accept_languages.best_match(accept_languages)

# flask-login
login_manager.login_view = 'frontend.login'
login_manager.refresh_view = 'frontend.reauth'

@login_manager.user_loader
def load_user(id):
return User.query.get(id)
login_manager.setup_app(app)

# flask-admin
admin = Admin()
# Setup locale
admin.locale_selector(get_locale)
# Views
# Model admin
admin.add_view(ModelView(User, db.session, endpoint='usermodel', category='Model'))
admin.add_view(ModelView(UserDetail, db.session, endpoint='userdetailmodel', category='Model'))
admin.add_view(ModelView(UserRole, db.session, endpoint='rolemodel', category='Model'))
# File admin
path = os.path.join(os.path.dirname(__file__), 'static/img/users')
# Create directory if existed.
try:
os.mkdir(path)
except OSError:
pass
admin.add_view(FileAdmin(path, '/static/img/users', endpoint='useravatar', name='User Avatars', category='Image'))
admin.init_app(app)


def configure_blueprints(app, blueprints):
"""Configure blueprints in views."""
Expand All @@ -116,10 +92,15 @@ def configure_blueprints(app, blueprints):


def configure_template_filters(app):

@app.template_filter()
def pretty_date(value):
return pretty_date(value)

@app.template_filter()
def format_date(value, format='%Y-%m-%d'):
return value.strftime(format)


def configure_logging(app):
"""Configure file(info) and email(error) logging."""
Expand All @@ -130,7 +111,7 @@ def configure_logging(app):
return

import logging
from logging.handlers import RotatingFileHandler, SMTPHandler
from logging.handlers import SMTPHandler

# Set info level on logger, which might be overwritten by handers.
# Suppress DEBUG messages.
Expand Down Expand Up @@ -181,10 +162,6 @@ def forbidden_page(error):
def page_not_found(error):
return render_template("errors/page_not_found.html"), 404

@app.errorhandler(405)
def method_not_allowed_page(error):
return render_template("errors/method_not_allowed.html"), 405

@app.errorhandler(500)
def server_error_page(error):
return render_template("errors/server_error.html"), 500
22 changes: 13 additions & 9 deletions fbone/configs/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import os


class BaseConfig(object):

# Get app root path
_basedir = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
# ../../configs/config.py
_basedir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))

PROJECT = "fbone"
DEBUG = False
Expand All @@ -23,28 +25,28 @@ class DevConfig(BaseConfig):

# ===========================================
# Flask-Sqlalchemy
#
#
# http://packages.python.org/Flask-SQLAlchemy/config.html
SQLALCHEMY_ECHO = True
# Database connection URI, change to suit yourself.
SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/' + BaseConfig.PROJECT + ".sqlite" # sqlite for testing/debug.
SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/' + BaseConfig.PROJECT + ".sqlite" # sqlite for testing/debug.
#SQLALCHEMY_DATABASE_URI = 'mysql://username:password@server/db' # mysql

# ===========================================
# Flask-babel
#
#
ACCEPT_LANGUAGES = ['zh']
BABEL_DEFAULT_LOCALE = 'en'

# ===========================================
# Flask-cache
#
#
CACHE_TYPE = 'simple'
CACHE_DEFAULT_TIMEOUT = 60

# ===========================================
# Flask-mail
#
#
# Should be imported from env var.
# https://bitbucket.org/danjac/flask-mail/issue/3/problem-with-gmails-smtp-server
MAIL_DEBUG = DEBUG
Expand All @@ -55,9 +57,11 @@ class DevConfig(BaseConfig):
MAIL_PASSWORD = 'gmail_password'
DEFAULT_MAIL_SENDER = '%s@gmail.com' % MAIL_USERNAME

# Should be imported from env var.
# export FBONE_APP_CONFIG=/home/wilson/.fbone.cfg
USER_IMG_UPLOAD_PATH = "/path/to/fbone/static/img/users"
# You should overwrite in production.py
# Limited the maximum allowed payload to 16 megabytes.
MAX_CONTENT_LENGTH = 16 * 1024 * 1024
USER_AVATAR_UPLOAD_FOLDER = "/tmp/uploads"
#USER_AVATAR_UPLOAD_FOLDER = os.path.join(BaseConfig._basedir, 'uploads')


class TestConfig(BaseConfig):
Expand Down
Loading

0 comments on commit 7df0de4

Please sign in to comment.