-
Notifications
You must be signed in to change notification settings - Fork 11
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
Showing
82 changed files
with
2,090 additions
and
37 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,35 +1,6 @@ | ||
*.py[cod] | ||
*.pyc | ||
*.project | ||
*.settings | ||
node_modules | ||
venv* | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Packages | ||
*.egg | ||
*.egg-info | ||
dist | ||
build | ||
eggs | ||
parts | ||
bin | ||
var | ||
sdist | ||
develop-eggs | ||
.installed.cfg | ||
lib | ||
lib64 | ||
|
||
# Installer logs | ||
pip-log.txt | ||
|
||
# Unit test / coverage reports | ||
.coverage | ||
.tox | ||
nosetests.xml | ||
|
||
# Translations | ||
*.mo | ||
|
||
# Mr Developer | ||
.mr.developer.cfg | ||
.project | ||
.pydevproject |
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 |
---|---|---|
@@ -1,4 +1,21 @@ | ||
pyMVC | ||
===== | ||
PyMVC Framework | ||
=== | ||
|
||
A python MVC web application framework written using Flask | ||
PyMVC is a MVC web application framework written in Python using Flask. | ||
|
||
Requires | ||
--- | ||
|
||
- PIP ([Install instructions](http://www.pip-installer.org/en/latest/installing.html)) | ||
- VirtualEnv ([Install instructions](http://pypi.python.org/pypi/virtualenv/)) | ||
|
||
|
||
Getting Started | ||
--- | ||
|
||
1. Install PIP | ||
2. Install VirtualEnv | ||
3. Create a virtual environment using virtualenv and activate it | ||
4. Copy the PyMVC source in your virtual env | ||
5. Install the requirements using <code>pip install -r requirements.pip</code> | ||
6. Run the application with <code>python manage.py runserver</code> |
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,53 @@ | ||
|
||
class BaseSettings(object): | ||
ENABLE_ASYNC = True | ||
|
||
LOGGING_CONFIG = { | ||
'handlers': { | ||
'console': { | ||
'class': 'logging.StreamHandler', | ||
'formatter': 'short', | ||
'level': 'DEBUG' | ||
} | ||
}, | ||
'formatters': { | ||
'short': { | ||
'format': '%(levelname)s: %(message)s' | ||
}, | ||
'full': { | ||
'format': '%(levelname)s|%(asctime)s|%(pathname)s:%(lineno)s|%(message)s' | ||
} | ||
}, | ||
'loggers': { | ||
'development': { | ||
'handlers': ['console'], | ||
'level': 'DEBUG' | ||
}, | ||
'staging': { | ||
'handlers': ['console'], | ||
'level': 'DEBUG' | ||
}, | ||
'production': { | ||
'handlers': ['console'], | ||
'level': 'DEBUG' | ||
}, | ||
}, | ||
'version': 1 | ||
} | ||
|
||
class DevelopmentSettings(BaseSettings): | ||
ENVIRONMENT = 'development' | ||
DEVELOPMENT = True | ||
ENABLE_ASYNC = True | ||
|
||
class StagingSettings(BaseSettings): | ||
ENVIRONMENT = 'staging' | ||
STAGING = True | ||
|
||
class ProductionSettings(BaseSettings): | ||
ENVIRONMENT = 'production' | ||
PRODUCTION = True | ||
|
||
settings = {'development': DevelopmentSettings(), | ||
'staging': StagingSettings(), | ||
'production': ProductionSettings()} |
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,7 @@ | ||
# desktop specific javascript | ||
js_login: | ||
filters: jsmin | ||
output: compiled/login.%(version)s.js | ||
contents: | ||
- scripts/libs/less-min.js | ||
- scripts/libs/require-min.js |
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,13 @@ | ||
# -*- mode: conf -*- | ||
|
||
APP_HOST = 'localhost:5000' | ||
|
||
# Storage setup | ||
SQLALCHEMY_DATABASE_URI = 'mysql://root:test@localhost/pyMVC' | ||
SQLALCHEMY_POOL_RECYCLE = 60 | ||
SQLALCHEMY_ECHO = False | ||
|
||
# StatsD | ||
STATSD_HOST = 'localhost' | ||
STATSD_PORT = 8125 | ||
STATSD_PREFIX = 'application' |
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,13 @@ | ||
# -*- mode: conf -*- | ||
|
||
APP_HOST = 'localhost:5000' | ||
|
||
# Storage setup | ||
SQLALCHEMY_DATABASE_URI = 'mysql://root:test@localhost/pyMVC' | ||
SQLALCHEMY_POOL_RECYCLE = 60 | ||
SQLALCHEMY_ECHO = False | ||
|
||
# StatsD | ||
STATSD_HOST = 'localhost' | ||
STATSD_PORT = 8125 | ||
STATSD_PREFIX = 'application' |
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,13 @@ | ||
# -*- mode: conf -*- | ||
|
||
APP_HOST = 'localhost:5000' | ||
|
||
# Storage setup | ||
SQLALCHEMY_DATABASE_URI = 'mysql://root:test@localhost/pyMVC' | ||
SQLALCHEMY_POOL_RECYCLE = 60 | ||
SQLALCHEMY_ECHO = False | ||
|
||
# StatsD | ||
STATSD_HOST = 'localhost' | ||
STATSD_PORT = 8125 | ||
STATSD_PREFIX = 'application' |
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,38 @@ | ||
from flask import request, flash, redirect, url_for, jsonify | ||
from core.Controller import Controller | ||
from models.account.RegisterModel import RegisterModel | ||
from services.UserService import UserService, DuplicateUserException | ||
from services.entities.User import User | ||
|
||
class AccountController(Controller): | ||
|
||
def __init__(self, action_name, user_service = None): | ||
super(AccountController, self).__init__(action_name) | ||
self.__user_service = user_service or UserService() | ||
|
||
def register(self): | ||
model = RegisterModel(request.form, csrf_context=self._session) | ||
return self._view(model=model) | ||
|
||
def register_post(self): | ||
model = RegisterModel(request.form, csrf_context=self._session) | ||
if model.validate(): | ||
user = User() | ||
user.username = model.username.data | ||
user.email = model.email.data | ||
user.ignite_id = 'blah' | ||
|
||
try: | ||
self.__user_service.create_user(user) | ||
self._session['username'] = model.username.data | ||
flash('You were successfully registered in') | ||
return redirect(url_for('index')) | ||
except DuplicateUserException: | ||
model.username.errors.append('user already exists') | ||
|
||
return self._view('register.html', model=model) | ||
|
||
def user_exists(self): | ||
username = request.args.get('username', '') | ||
exists = self.__user_service.get_user(username = username) is not None | ||
return jsonify(result = exists) |
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,16 @@ | ||
from flask.ext.admin import AdminIndexView, BaseView, expose | ||
from flask.ext.login import current_user | ||
|
||
class ProtectedView(object): | ||
def is_accessible(self): | ||
return current_user.is_authenticated() and current_user.is_admin | ||
|
||
class HomeView(ProtectedView, AdminIndexView): | ||
@expose() | ||
def index(self): | ||
return self.render('admin/index.html') | ||
|
||
class SampleView(ProtectedView, BaseView): | ||
@expose('/') | ||
def index(self): | ||
return self.render('admin/sample.html') |
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,35 @@ | ||
from flask import request, redirect, url_for, jsonify | ||
from core.Controller import Controller | ||
from models.account.LoginModel import LoginModel | ||
from services.UserService import UserService | ||
from flask.ext.login import login_user, logout_user | ||
|
||
class AuthController(Controller): | ||
def __init__(self, action_name, user_service = None): | ||
super(AuthController, self).__init__(action_name) | ||
self.__user_service = user_service or UserService() | ||
|
||
def login(self): | ||
model = LoginModel(request.form, csrf_context=self._session) | ||
next = request.args.get('next', url_for('index')) | ||
return self._view(model=model, next = next) | ||
|
||
def login_post(self): | ||
model = LoginModel(request.form, csrf_context=self._session) | ||
next = request.args.get('next', url_for('index')) | ||
if model.validate(): | ||
user = self.__user_service.get_user(username = model.username.data) | ||
if user is None: | ||
model.username.errors.append('invalid username') | ||
else: | ||
login_user(user, model.remember_me.data) | ||
return redirect(next) | ||
return self._view('login.html', model=model, next = next) | ||
|
||
def user(self): | ||
result = {'DisplayName': self._user.DisplayName if hasattr(self._user, 'DisplayName') else None} | ||
return jsonify(result) | ||
|
||
def logout(self): | ||
logout_user() | ||
return redirect (url_for('index'), 302) |
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,20 @@ | ||
from core.Controller import Controller | ||
from flask.ext.login import login_required | ||
|
||
class HomeController(Controller): | ||
|
||
def index(self): | ||
self._logger.debug('home page served') | ||
name = getattr(self._user, 'username', 'unknown') | ||
message = u'Welcome %(name)s' % {'name': name} | ||
self._app.stats.increment('index') | ||
|
||
return self._view(message = message) | ||
|
||
@login_required | ||
def client(self, **args): | ||
import datetime | ||
|
||
now = datetime.datetime.now() | ||
self._logger.debug('going to client page') | ||
return self._view(now=str(now)) |
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,11 @@ | ||
from flask import current_app | ||
|
||
class Cache(object): | ||
def __init__(self, app = None): | ||
self.__app = app or current_app | ||
|
||
def get(self, key): | ||
return self.__app.cache.get(key) | ||
|
||
def set(self, key, value, expire = None): | ||
self.__app.cache.set(key, value, expire) |
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,49 @@ | ||
from flask import current_app as app, session, request, render_template | ||
from flask.views import View | ||
from flask.ext.login import current_user | ||
|
||
from core.ViewLocator import ViewLocator | ||
from core.Cache import Cache | ||
|
||
import logging | ||
import inspect | ||
import re | ||
|
||
class Controller(View): | ||
__mobileAgentPattern = re.compile('iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm'); | ||
|
||
def __init__(self, action_name): | ||
super(Controller, self).__init__() | ||
|
||
self.__action_name = action_name | ||
self._app = app | ||
self._session = session | ||
self._logger = logging.getLogger(app.config['ENVIRONMENT']) | ||
self._cache = Cache() | ||
self._user = current_user | ||
|
||
def dispatch_request(self, *args, **kwargs): | ||
action = getattr(self, self.__action_name, None) | ||
if action is None: | ||
raise Exception('action_name', 'Action {0} not found'.format(self.__action_name)) | ||
return action(*args, **kwargs) | ||
|
||
def _is_mobile(self): | ||
is_mobile = Controller.__mobileAgentPattern.search(request.user_agent.string.lower()) is not None; | ||
return is_mobile; | ||
|
||
def resolve_device_name(self): | ||
if self._is_mobile(): | ||
return 'mobile' | ||
return ''; | ||
|
||
def _view(self, view_name = None, **kwargs): | ||
if view_name is None: | ||
view_name = inspect.stack()[1][3]; | ||
|
||
view_path = ViewLocator.resolve_view_name(self, view_name) | ||
|
||
if 'app' not in kwargs: | ||
kwargs['app'] = self._app | ||
|
||
return render_template(view_path, **kwargs) |
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,3 @@ | ||
|
||
def add_route(app, routeName, pattern, controller, action, **kwargs): | ||
app.add_url_rule(pattern, view_func=controller.as_view(routeName, action), **kwargs) |
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 @@ | ||
from wtforms.ext.csrf.session import SessionSecureForm | ||
from datetime import timedelta | ||
|
||
class SecureForm(SessionSecureForm): | ||
SECRET_KEY = 'Enj09jpkj8Gx1SjnyLxwBBSQfnQ9DJYe0Ym' | ||
TIME_LIMIT = timedelta(minutes=20) |
Oops, something went wrong.