class AddressServer(Application): """ This class is the gunicorn wrapper to serve up bottle. Strongly borrowed from: http://damianzaremba.co.uk/2012/08/running-a-wsgi- app-via-gunicorn-from-python/ """ def __init__(self, options={}): self.usage = None self.callable = None self.prog = None self.options = options self.do_load_config() self.setup_cork() super(AddressServer, self).__init__() self.app = Bottle() self.add_routes() self.add_middleware() def setup_cork(self): """Set up cork using environment variables.""" EMAIL = os.environ.get('EMAIL_SENDER') EMAIL_PASS = os.environ.get('EMAIL_PASSWORD') self.MONGO_DB = os.environ.get('MONGOHQ_DB') self.MONGO_URL = os.environ.get('MONGOHQ_URL') mb = MongoDBBackend(self.MONGO_DB, self.MONGO_URL) self.loginPlugin = Cork(backend=mb, email_sender=EMAIL, smtp_url='starttls://' + EMAIL + ':' + EMAIL_PASS + '@smtp.gmail.com:587') def add_middleware(self): """Set up the session middleware.""" ENCRYPT_KEY = os.environ.get('ENCRYPT_KEY') session_opts = { 'session.cookie_expires': True, 'session.encrypt_key': ENCRYPT_KEY, 'session.httponly': True, 'session.timeout': 3600 * 24, # 1 day 'session.type': 'cookie', 'session.validate_key': True, } self.app = SessionMiddleware(self.app, session_opts) def add_routes(self): """Add all the application routes.""" self.app.route(LOGIN_PATH, 'GET', callback=get_login) self.app.route(LOGIN_PATH, 'POST', callback=post_login, apply=self.add_login_plugin) self.app.route('/logout', 'GET', callback=logout, apply=self.add_login_plugin) self.app.route('/register', 'GET', callback=get_register, apply=self.add_login_plugin) self.app.route('/register', 'POST', callback=post_register, apply=self.add_login_plugin) self.app.route(VALIDATE_REGISTRATION_PATH + '/<registration_code>', 'GET', callback=validate_registration, apply=self.add_login_plugin) self.app.route(CHANGE_PASSWORD_PATH + '/<reset_code>', 'GET', callback=get_change_password) self.app.route(CHANGE_PASSWORD_PATH, 'POST', callback=post_change_password, apply=self.add_login_plugin) self.app.route('/reset_password', 'GET', callback=get_reset_password) self.app.route('/reset_password', 'POST', callback=post_reset_password, apply=self.add_login_plugin) self.app.route('/', 'GET', callback=index, apply=self.check_login) self.app.route('/addresses', 'GET', callback=get_addresses, apply=self.check_login) self.app.route('/addresses', 'POST', callback=post_addresses, apply=self.check_login) self.app.route('/addresses', 'PUT', callback=put_addresses, apply=self.check_login) self.app.route('/addresses/<deleteId>', 'DELETE', callback=delete_addresses, apply=self.check_login) self.app.route('/csv', 'GET', callback=csv_export, apply=self.check_login) self.app.route('/christmas_card', 'GET', callback=christmas_card_csv_export, apply=self.check_login) # self.app.route('/import_csv', 'GET', callback=csv_import, # apply=self.check_login) self.app.route('/js/<filename>', 'GET', callback=js_static) self.app.route('/css/<filename>', 'GET', callback=css_static) def init(self, *args): """Add any options passed in to the config. :param *args: the arguments of the application :returns: config object :rtype: dict """ cfg = {} for k, v in self.options.items(): if k.lower() in self.cfg.settings and v is not None: cfg[k.lower()] = v return cfg def load(self): """Load and return the bottle app.""" return self.app @hook('before_request') def check_login(self, fn): """Hook for checking the login before doing logic. :param fn: the function to call if the user is logged in :returns: the wrapped function :rtype: def """ def check_uid(**kwargs): self.loginPlugin.require(fail_redirect=LOGIN_PATH) kwargs["helper"] = AddressModel(self.MONGO_URL, self.MONGO_DB) kwargs["userName"] = self.loginPlugin.current_user.username return fn(**kwargs) return check_uid @hook('before_request') def add_login_plugin(self, fn): """Hook for adding the plugin information. :param fn: the function to pass the plugin :returns: the wrapped function :rtype: def """ def add_plugin(**kwargs): kwargs["loginPlugin"] = self.loginPlugin return fn(**kwargs) return add_plugin