diff --git a/README.rst b/README.rst index f8110cd4..d808b85b 100644 --- a/README.rst +++ b/README.rst @@ -25,16 +25,6 @@ you just have to run the following command:: This will run a Flask app available at `http://localhost:5000`. -It is also better to actually turn the debugging mode on when you're -developing. You can create a `settings.py` file in the `budget` directory, with -the following content:: - - DEBUG = True - SQLACHEMY_ECHO = DEBUG - -You can also set the `TESTING` flag to `True` so no mails are sent -(and no exception is raised) while you're on development mode. - Deploy it ========= @@ -62,13 +52,43 @@ With Nginx, Gunicorn and Supervisord Don't forget to set the right permission for your files ! -Also, create a `settings.py` file with the appropriate values if you need to -use a different database for instance. You can also set `APPLICATION_ROOT` if -you want to prefix your URLs to serve ihatemonney in the *folder* of a domain, -e.g: +Configure it +============ + +In a production environment +--------------------------- + +Make a copy of ``budget/default_settings.py`` and name it ``ihatemoney.cfg``. +Then adjust the settings to your needs and move this file to +``/etc/ihatemoney/ihatemoney.cfg``. +This is the default path of the settings but you can also place it +elsewhere and pass the configuration file path to the application using +the IHATEMONEY_SETTINGS_FILE_PATH environment variable. +e.g.:: + + $ export IHATEMONEY_SETTINGS_FILE_PATH="/path/to/your/conf/file.cfg" + +Note that you can also pass additional flask parameters with this file. +e.g. If you want to prefix your URLs to serve ihatemonney in the *folder* +of a domain, use the following: :: APPLICATION_ROOT='/budget' +In a dev environment +-------------------- + +It is better to actually turn the debugging mode on when you're developing. +You can create a ``settings.cfg`` file, with the following content:: + + DEBUG = True + SQLACHEMY_ECHO = DEBUG + +You can also set the `TESTING` flag to `True` so no mails are sent +(and no exception is raised) while you're on development mode. +Then before running the application, declare its path with :: + + $ export IHATEMONEY_SETTINGS_FILE_PATH="$(pwd)/settings.cfg" + The REST API? ============= diff --git a/budget/merged_settings.py b/budget/merged_settings.py deleted file mode 100644 index f6b1f811..00000000 --- a/budget/merged_settings.py +++ /dev/null @@ -1,10 +0,0 @@ -""" -Merges default settings with user-defined settings -""" - -from default_settings import * - -try: - from settings import * -except ImportError: - pass diff --git a/budget/run.py b/budget/run.py index 3ab036b2..00d43264 100644 --- a/budget/run.py +++ b/budget/run.py @@ -12,7 +12,7 @@ from api import api from utils import PrefixedWSGI from utils import minimal_round -app = Flask(__name__) +app = Flask(__name__, instance_path='/etc/ihatemoney', instance_relative_config=True) def pre_alembic_db(): @@ -27,8 +27,18 @@ def pre_alembic_db(): def configure(): """ A way to (re)configure the app, specially reset the settings """ - config_obj = os.environ.get('FLASK_SETTINGS_MODULE', 'merged_settings') - app.config.from_object(config_obj) + default_config_file = os.path.join(app.root_path, 'default_settings.py') + config_file = os.environ.get('IHATEMONEY_SETTINGS_FILE_PATH') + + # Load default settings first + # Then load the settings from the path set in IHATEMONEY_SETTINGS_FILE_PATH var + # If not set, default to /etc/ihatemoney/ihatemoney.cfg + # If the latter doesn't exist no error is raised and the default settings are used + app.config.from_pyfile(default_config_file) + if config_file: + app.config.from_pyfile(config_file) + else: + app.config.from_pyfile('ihatemoney.cfg', silent=True) app.wsgi_app = PrefixedWSGI(app) # Deprecations diff --git a/budget/tests/ihatemoney.cfg b/budget/tests/ihatemoney.cfg new file mode 100644 index 00000000..6345fcf4 --- /dev/null +++ b/budget/tests/ihatemoney.cfg @@ -0,0 +1,7 @@ +DEBUG = False +SQLALCHEMY_DATABASE_URI = 'sqlite:///budget.db' +SQLACHEMY_ECHO = DEBUG + +SECRET_KEY = "supersecret" + +MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") diff --git a/budget/tests/ihatemoney_envvar.cfg b/budget/tests/ihatemoney_envvar.cfg new file mode 100644 index 00000000..dbc078ee --- /dev/null +++ b/budget/tests/ihatemoney_envvar.cfg @@ -0,0 +1,7 @@ +DEBUG = False +SQLALCHEMY_DATABASE_URI = 'sqlite:///budget.db' +SQLACHEMY_ECHO = DEBUG + +SECRET_KEY = "lalatra" + +MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org") diff --git a/budget/tests/tests.py b/budget/tests/tests.py index 854c07b0..d979a299 100644 --- a/budget/tests/tests.py +++ b/budget/tests/tests.py @@ -10,14 +10,18 @@ import json from collections import defaultdict import six -os.environ['FLASK_SETTINGS_MODULE'] = 'default_settings' - from flask import session +# Unset configuration file env var if previously set +if 'IHATEMONEY_SETTINGS_FILE_PATH' in os.environ: + del os.environ['IHATEMONEY_SETTINGS_FILE_PATH'] + import run import models import utils +__HERE__ = os.path.dirname(os.path.abspath(__file__)) + class TestCase(unittest.TestCase): @@ -65,6 +69,40 @@ class TestCase(unittest.TestCase): class BudgetTestCase(TestCase): + def test_default_configuration(self): + """Test that default settings are loaded when no other configuration file is specified""" + run.configure() + self.assertFalse(run.app.config['DEBUG']) + self.assertEqual(run.app.config['SQLALCHEMY_DATABASE_URI'], 'sqlite:///budget.db') + self.assertFalse(run.app.config['SQLALCHEMY_TRACK_MODIFICATIONS']) + self.assertEqual(run.app.config['SECRET_KEY'], 'tralala') + self.assertEqual(run.app.config['MAIL_DEFAULT_SENDER'], + ("Budget manager", "budget@notmyidea.org")) + + def test_env_var_configuration_file(self): + """Test that settings are loaded from the specified configuration file""" + os.environ['IHATEMONEY_SETTINGS_FILE_PATH'] = os.path.join(__HERE__, + "ihatemoney_envvar.cfg") + run.configure() + self.assertEqual(run.app.config['SECRET_KEY'], 'lalatra') + + # Test that the specified configuration file is loaded + # even if the default configuration file ihatemoney.cfg exists + os.environ['IHATEMONEY_SETTINGS_FILE_PATH'] = os.path.join(__HERE__, + "ihatemoney_envvar.cfg") + run.app.config.root_path = __HERE__ + run.configure() + self.assertEqual(run.app.config['SECRET_KEY'], 'lalatra') + + if 'IHATEMONEY_SETTINGS_FILE_PATH' in os.environ: + del os.environ['IHATEMONEY_SETTINGS_FILE_PATH'] + + def test_default_configuration_file(self): + """Test that settings are loaded from the default configuration file""" + run.app.config.root_path = __HERE__ + run.configure() + self.assertEqual(run.app.config['SECRET_KEY'], 'supersecret') + def test_notifications(self): """Test that the notifications are sent, and that email adresses are checked properly.