aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst6
-rw-r--r--LICENSE2
-rw-r--r--Makefile5
-rw-r--r--README.rst158
-rwxr-xr-xbudget/manage.py13
-rw-r--r--budget/run.py21
-rw-r--r--budget/templates/layout.html1
-rw-r--r--budget/tests/tests.py3
-rw-r--r--budget/web.py14
-rw-r--r--docs/_themes/pelican/layout.html22
-rw-r--r--docs/_themes/pelican/static/pelican.css_t254
-rw-r--r--docs/_themes/pelican/theme.conf10
-rw-r--r--docs/conf.py5
-rw-r--r--docs/contributing.rst76
-rw-r--r--[l---------]docs/index.rst25
-rw-r--r--docs/installation.rst114
-rw-r--r--setup.py2
17 files changed, 281 insertions, 450 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index fa0724d..7e5514c 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -3,10 +3,12 @@ Changelog
This document describes changes between each past release.
-1.1 (unreleased)
+2.0 (unreleased)
----------------
-- Nothing changed yet.
+### Changed
+
+- **BREAKING CHANGE** Use a hashed ``ADMIN_PASSWORD`` instead of a clear text one, ``./budget/manage.py generate_password_hash`` can be used to generate a proper password HASH (#236)
1.0 (2017-06-20)
diff --git a/LICENSE b/LICENSE
index ecc7977..cc2b19c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -21,7 +21,7 @@ that the following conditions are met:
* If you meet the authors of this software in person and you want to
pay them a beer, you're encouraged to do so. Please, do. If you have
- homebrewed beer, this works as well (may even be better).
+ homebrewed or a craft beer, it might be even better.
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
diff --git a/Makefile b/Makefile
index eefb19f..ba4ec36 100644
--- a/Makefile
+++ b/Makefile
@@ -23,6 +23,11 @@ $(DEV_STAMP): $(PYTHON) dev-requirements.txt
$(VENV)/bin/pip install -Ur dev-requirements.txt
touch $(DEV_STAMP)
+remove-install-stamp:
+ rm $(INSTALL_STAMP)
+
+update: remove-install-stamp install
+
serve: install
cd budget; $(PYTHON) run.py
diff --git a/README.rst b/README.rst
index 1aa29ed..77337ae 100644
--- a/README.rst
+++ b/README.rst
@@ -1,155 +1,23 @@
-Budget-manager
-##############
+I hate money
+############
.. image:: https://travis-ci.org/spiral-project/ihatemoney.svg?branch=master
:target: https://travis-ci.org/spiral-project/ihatemoney
:alt: Travis CI Build Status
-This is a really tiny app to ease the shared houses budget management. Keep
-track of who bought what, when, and for who to then compute the balance of each
-person.
+«I hate money» is a web application made to ease shared budget management.
+It keeps track of who bought what, when, and for whom; and helps to settle the
+bills.
-The code is distributed under a BSD beerware derivative: if you meet the people
-in person and you want to pay them a beer, you are encouraged to do so (see
-LICENSE for more details).
+* `Online documentation <https://ihatemoney.readthedocs.org>`_
+* `Hosted version <https://ihatemoney.org>`_
-Make it run!
-============
-
-With a `Python 3 <https://www.python.org/>`_ environment,
-`pip <https://pypi.python.org/pypi/pip/>`_ and
-`virtualenv <https://pypi.python.org/pypi/virtualenv>`_ installed,
-you just have to run the following command::
-
- $ make serve
-
-This will run a Flask app available at `http://localhost:5000`.
-
-Deploy it
-=========
-
-You have multiple options to deploy ihatemoney. Two of them are documented at the moment:
-
-With Apache and mod_wsgi
-------------------------
-
-1. Install Apache and mod_wsgi - libapache2-mod-wsgi(-py3) for Debian based and mod_wsgi for RedHat based distributions -
-
-2. Create an Apache virtual host based on the sample configuration file in conf/apache-vhost.conf
-
-3. Adapt it to your paths and specify your virtualenv path if you use one
-
-4. Activate the virtual host if needed and restart Apache
-
-With Nginx, Gunicorn and Supervisord
-------------------------------------
+The code is distributed under a BSD *beerware* derivative: if you meet the people
+in person and you want to pay them a craft beer, you are highly encouraged to do
+so.
-1. Add the lines in conf/supervisord.conf to your supervisord.conf file.
- **adapt them to your paths!**
-2. Copy and paste the content of conf/nginx.conf in your nginx conf file.
- **adapt them to your paths!**
-3. reload both nginx and supervisord. It should be working ;)
-
-Don't forget to set the right permission for your files !
-
-Configure it
+Requirements
============
-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?
-=============
-
-Yep, you're right, there is a REST API with this. Head to the `api
-documentation <https://ihatemoney.readthedocs.io/en/latest/api.html>`_ to know more.
-
-How to contribute
-=================
-
-You would like to contribute? First, thanks a bunch! This project is a small
-project with just a few people behind it, so any help is appreciated!
-
-There are different ways to help us, regarding if you are a designer,
-a developer or an user.
-
-As a developer
---------------
-
-If you want to contribute code, you can write it and then issue a pull request on
-github. Please, think about updating and running the tests before asking for
-a pull request as it will help us to maintain the code clean and running.
-
-To do so::
-
- $ make test
-
-As a designer / Front-end developer
------------------------------------
-
-Feel free to provide us mockups or to involve yourself into the discussions
-hapenning on the github issue tracker. All ideas are welcome. Of course, if you
-know how to implement them, feel free to fork and make a pull request.
-
-End-user
---------
-
-You are using the application and found a bug? You have some ideas about how to
-improve the project? Please tell us [by filling a new issue](https://github.com/spiral-project/ihatemoney/issues).
-Or, if you prefer, you can send me an email to `alexis@notmyidea.org` and I will
-update the issue tracker with your feedback.
-
-Thanks again!
-
-How to release?
-===============
-
-In order to prepare a new release, we are following the following steps:
-
-- Merge remaining pull requests;
-- Update :file:`CHANGELOG.rst` with the last changes;
-- Update :file:`CONTRIBUTORS`;
-- Update known good versions of dependencies in ``requirements.txt`` with this command (from inside the venv):
-
-.. code-block:: bash
-
- $ pip freeze | grep -v -- '-e' > requirements.txt
-
-Once this is done, use the "release" instruction:
-
-.. code-block:: bash
-
- $ make release
-
-And the new version should be published on PyPI.
+* **Python**: 2.7, 3.4, 3.5.
+* **Backends**: MySQL, PostgreSQL, SQLite, Memory.
diff --git a/budget/manage.py b/budget/manage.py
index 94a21a2..f717fed 100755
--- a/budget/manage.py
+++ b/budget/manage.py
@@ -1,15 +1,26 @@
#!/usr/bin/env python
-from flask_script import Manager
+from flask_script import Manager, Command
from flask_migrate import Migrate, MigrateCommand
+from werkzeug.security import generate_password_hash
from run import app
from models import db
+from getpass import getpass
+
+
+class GeneratePasswordHash(Command):
+ "Get password from user and hash it without printing it in clear text"
+
+ def run(self):
+ password = getpass(prompt='Password: ')
+ print(generate_password_hash(password))
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
+manager.add_command('generate_password_hash', GeneratePasswordHash)
if __name__ == '__main__':
diff --git a/budget/run.py b/budget/run.py
index 00d4326..7fe4e24 100644
--- a/budget/run.py
+++ b/budget/run.py
@@ -12,6 +12,8 @@ from api import api
from utils import PrefixedWSGI
from utils import minimal_round
+import default_settings
+
app = Flask(__name__, instance_path='/etc/ihatemoney', instance_relative_config=True)
@@ -41,17 +43,34 @@ def configure():
app.config.from_pyfile('ihatemoney.cfg', silent=True)
app.wsgi_app = PrefixedWSGI(app)
+ if app.config['SECRET_KEY'] == default_settings.SECRET_KEY:
+ warnings.warn(
+ "Running a server without changing the SECRET_KEY can lead to"
+ + " user impersonation. Please update your configuration file.",
+ UserWarning
+ )
# Deprecations
if 'DEFAULT_MAIL_SENDER' in app.config:
# Since flask-mail 0.8
warnings.warn(
"DEFAULT_MAIL_SENDER is deprecated in favor of MAIL_DEFAULT_SENDER"
- +" and will be removed in further version",
+ + " and will be removed in further version",
UserWarning
)
if not 'MAIL_DEFAULT_SENDER' in app.config:
app.config['MAIL_DEFAULT_SENDER'] = DEFAULT_MAIL_SENDER
+ if "pbkdf2:sha256:" not in app.config['ADMIN_PASSWORD'] and app.config['ADMIN_PASSWORD']:
+ # Since 2.0
+ warnings.warn(
+ "The way Ihatemoney stores your ADMIN_PASSWORD has changed. You are using an unhashed"
+ +" ADMIN_PASSWORD, which is not supported anymore and won't let you access your admin"
+ +" endpoints. Please use the command './budget/manage.py generate_password_hash'"
+ +" to generate a proper password HASH and copy the output to the value of"
+ +" ADMIN_PASSWORD in your settings file.",
+ UserWarning
+ )
+
configure()
diff --git a/budget/templates/layout.html b/budget/templates/layout.html
index 3f2c35d..6ecff41 100644
--- a/budget/templates/layout.html
+++ b/budget/templates/layout.html
@@ -4,6 +4,7 @@
<head>
<title>{{ _("Account manager") }}{% block title %}{% endblock %}</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel=stylesheet type=text/css href="{{ url_for("static", filename='css/main.css') }}">
<script src="{{ url_for("static", filename="js/jquery-3.1.1.min.js") }}"></script>
<script src="{{ url_for("static", filename="js/ihatemoney.js") }}"></script>
diff --git a/budget/tests/tests.py b/budget/tests/tests.py
index a1cedfa..16aaae9 100644
--- a/budget/tests/tests.py
+++ b/budget/tests/tests.py
@@ -10,6 +10,7 @@ import json
from collections import defaultdict
import six
+from werkzeug.security import generate_password_hash
from flask import session
# Unset configuration file env var if previously set
@@ -376,7 +377,7 @@ class BudgetTestCase(TestCase):
self.assertNotIn('raclette', session)
def test_admin_authentication(self):
- run.app.config['ADMIN_PASSWORD'] = "pass"
+ run.app.config['ADMIN_PASSWORD'] = generate_password_hash("pass")
# test the redirection to the authentication page when trying to access admin endpoints
resp = self.app.get("/create")
diff --git a/budget/web.py b/budget/web.py
index 47ff371..f4961cb 100644
--- a/budget/web.py
+++ b/budget/web.py
@@ -13,6 +13,8 @@ from flask import Blueprint, current_app, flash, g, redirect, \
render_template, request, session, url_for, send_file
from flask_mail import Mail, Message
from flask_babel import get_locale, gettext as _
+from werkzeug.security import generate_password_hash, \
+ check_password_hash
from smtplib import SMTPRecipientsRefused
import werkzeug
from sqlalchemy import orm
@@ -35,10 +37,10 @@ def requires_admin(f):
"""
@wraps(f)
def admin_auth(*args, **kws):
- admin_password = session.get('admin_password', '')
- if not admin_password == current_app.config['ADMIN_PASSWORD']:
- raise Redirect303(url_for('.admin', goto=request.path))
- return f(*args, **kws)
+ is_admin = session.get('is_admin')
+ if is_admin or not current_app.config['ADMIN_PASSWORD']:
+ return f(*args, **kws)
+ raise Redirect303(url_for('.admin', goto=request.path))
return admin_auth
@@ -87,8 +89,8 @@ def admin():
goto = request.args.get('goto', url_for('.home'))
if request.method == "POST":
if form.validate():
- if form.admin_password.data == current_app.config['ADMIN_PASSWORD']:
- session['admin_password'] = form.admin_password.data
+ if check_password_hash(current_app.config['ADMIN_PASSWORD'], form.admin_password.data):
+ session['is_admin'] = True
session.update()
return redirect(goto)
else:
diff --git a/docs/_themes/pelican/layout.html b/docs/_themes/pelican/layout.html
deleted file mode 100644
index aa1716a..0000000
--- a/docs/_themes/pelican/layout.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "basic/layout.html" %}
-{% block header %}
- {{ super() }}
- {% if pagename == 'index' %}
- <div class=indexwrapper>
- {% endif %}
-{% endblock %}
-{% block footer %}
- {% if pagename == 'index' %}
- </div>
- {% endif %}
-{% endblock %}
-{# do not display relbars #}
-{% block relbar1 %}{% endblock %}
-{% block relbar2 %}
- {% if theme_github_fork %}
- <a href="http://github.com/{{ theme_github_fork }}"><img style="position: fixed; top: 0; right: 0; border: 0;"
- src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
- {% endif %}
-{% endblock %}
-{% block sidebar1 %}{% endblock %}
-{% block sidebar2 %}{% endblock %}
diff --git a/docs/_themes/pelican/static/pelican.css_t b/docs/_themes/pelican/static/pelican.css_t
deleted file mode 100644
index 8d8a9b2..0000000
--- a/docs/_themes/pelican/static/pelican.css_t
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * pelican.css_t
- * ~~~~~~~~~~~~
- *
- * Sphinx stylesheet -- pelican theme, based on the nature theme
- *
- * :copyright: Copyright 2011 by Alexis Metaireau.
- */
-
-@import url("basic.css");
-
-/* -- page layout ----------------------------------------------------------- */
-
-body {
- font-family: Arial, sans-serif;
- font-size: 100%;
- background-color: white;
- color: #555;
- margin: 0;
- padding: 0;
-}
-
-div.documentwrapper {
- width: 70%;
- margin: auto;
-}
-
-div.bodywrapper {
- margin: 0 0 0 230px;
-}
-
-hr {
- border: 1px solid #B1B4B6;
-}
-
-div.document {
-}
-
-div.body {
- background-color: #ffffff;
- color: #3E4349;
- padding: 0 30px 30px 30px;
- font-size: 0.9em;
-}
-
-div.footer {
- color: #555;
- width: 100%;
- padding: 13px 0;
- text-align: center;
- font-size: 75%;
-}
-
-div.footer a {
- color: #444;
- text-decoration: underline;
-}
-
-div.related {
- background-color: #6BA81E;
- line-height: 32px;
- color: #fff;
- text-shadow: 0px 1px 0 #444;
- font-size: 0.9em;
-}
-
-div.related a {
- color: #E2F3CC;
-}
-
-div.sphinxsidebar {
- font-size: 0.75em;
- line-height: 1.5em;
-}
-
-div.sphinxsidebarwrapper{
- padding: 20px 0;
-}
-
-div.sphinxsidebar h3,
-div.sphinxsidebar h4 {
- font-family: Arial, sans-serif;
- color: #222;
- font-size: 1.2em;
- font-weight: normal;
- margin: 0;
- padding: 5px 10px;
- background-color: #ddd;
- text-shadow: 1px 1px 0 white
-}
-
-div.sphinxsidebar h4{
- font-size: 1.1em;
-}
-
-div.sphinxsidebar h3 a {
- color: #444;
-}
-
-
-div.sphinxsidebar p {
- color: #888;
- padding: 5px 20px;
-}
-
-div.sphinxsidebar p.topless {
-}
-
-div.sphinxsidebar ul {
- margin: 10px 20px;
- padding: 0;
- color: #000;
-}
-
-div.sphinxsidebar a {
- color: #444;
-}
-
-div.sphinxsidebar input {
- border: 1px solid #ccc;
- font-family: sans-serif;
- font-size: 1em;
-}
-
-div.sphinxsidebar input[type=text]{
- margin-left: 20px;
-}
-
-/* -- body styles ----------------------------------------------------------- */
-
-a {
- color: #005B81;
- text-decoration: none;
-}
-
-a:hover {
- color: #E32E00;
- text-decoration: underline;
-}
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
- font-family: Arial, sans-serif;
- font-weight: normal;
- color: #212224;
- margin: 30px 0px 10px 0px;
- padding: 5px 0 5px 10px;
- text-shadow: 0px 1px 0 white
-}
-
-{% if theme_index_logo %}
-div.indexwrapper h1 {
- text-indent: -999999px;
- background: url({{ theme_index_logo }}) no-repeat center center;
- height: {{ theme_index_logo_height }};
-}
-{% endif %}
-div.body h1 {
- border-top: 20px solid white;
- margin-top: 0;
- font-size: 250%;
- text-align: center;
-}
-
-div.body h2 { font-size: 150%; background-color: #C8D5E3; }
-div.body h3 { font-size: 120%; background-color: #D8DEE3; }
-div.body h4 { font-size: 110%; background-color: #D8DEE3; }
-div.body h5 { font-size: 100%; background-color: #D8DEE3; }
-div.body h6 { font-size: 100%; background-color: #D8DEE3; }
-
-a.headerlink {
- color: #c60f0f;
- font-size: 0.8em;
- padding: 0 4px 0 4px;
- text-decoration: none;
-}
-
-a.headerlink:hover {
- background-color: #c60f0f;
- color: white;
-}
-
-div.body p, div.body dd, div.body li {
- line-height: 1.5em;
-}
-
-div.admonition p.admonition-title + p {
- display: inline;
-}
-
-div.highlight{
- background-color: #111;
-}
-
-div.note {
- background-color: #eee;
- border: 1px solid #ccc;
-}
-
-div.seealso {
- background-color: #ffc;
- border: 1px solid #ff6;
-}
-
-div.topic {
- background-color: #eee;
-}
-
-div.warning {
- background-color: #ffe4e4;
- border: 1px solid #f66;
-}
-
-p.admonition-title {
- display: inline;
-}
-
-p.admonition-title:after {
- content: ":";
-}
-
-pre {
- padding: 10px;
- background-color: #111;
- color: #fff;
- line-height: 1.2em;
- border: 1px solid #C6C9CB;
- font-size: 1.1em;
- margin: 1.5em 0 1.5em 0;
- -webkit-box-shadow: 1px 1px 1px #d8d8d8;
- -moz-box-shadow: 1px 1px 1px #d8d8d8;
-}
-
-tt {
- background-color: #ecf0f3;
- color: #222;
- /* padding: 1px 2px; */
- font-size: 1.1em;
- font-family: monospace;
-}
-
-.viewcode-back {
- font-family: Arial, sans-serif;
-}
-
-div.viewcode-block:target {
- background-color: #f4debf;
- border-top: 1px solid #ac9;
- border-bottom: 1px solid #ac9;
-}
diff --git a/docs/_themes/pelican/theme.conf b/docs/_themes/pelican/theme.conf
deleted file mode 100644
index ffbb794..0000000
--- a/docs/_themes/pelican/theme.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-[theme]
-inherit = basic
-stylesheet = pelican.css
-nosidebar = true
-pygments_style = fruity
-
-[options]
-index_logo_height = 120px
-index_logo =
-github_fork =
diff --git a/docs/conf.py b/docs/conf.py
index 332c3de..176f694 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -12,8 +12,3 @@ release = '1.0'
exclude_patterns = ['_build']
pygments_style = 'sphinx'
-
-sys.path.append(os.path.abspath('_themes'))
-html_theme_path = ['_themes']
-html_theme = 'pelican'
-html_theme_options = { 'nosidebar': True }
diff --git a/docs/contributing.rst b/docs/contributing.rst
new file mode 100644
index 0000000..b0a829f
--- /dev/null
+++ b/docs/contributing.rst
@@ -0,0 +1,76 @@
+Contributing
+############
+
+Setup 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"
+
+How to contribute
+=================
+
+You would like to contribute? First, thanks a bunch! This project is a small
+project with just a few people behind it, so any help is appreciated!
+
+There are different ways to help us, regarding if you are a designer,
+a developer or an user.
+
+As a developer
+--------------
+
+If you want to contribute code, you can write it and then issue a pull request on
+github. Please, think about updating and running the tests before asking for
+a pull request as it will help us to maintain the code clean and running.
+
+To do so::
+
+ $ make test
+
+As a designer / Front-end developer
+-----------------------------------
+
+Feel free to provide us mockups or to involve yourself into the discussions
+hapenning on the github issue tracker. All ideas are welcome. Of course, if you
+know how to implement them, feel free to fork and make a pull request.
+
+End-user
+--------
+
+You are using the application and found a bug? You have some ideas about how to
+improve the project? Please tell us [by filling a new issue](https://github.com/spiral-project/ihatemoney/issues).
+Or, if you prefer, you can send me an email to `alexis@notmyidea.org` and I will
+update the issue tracker with your feedback.
+
+Thanks again!
+
+How to release?
+===============
+
+In order to prepare a new release, we are following the following steps:
+
+- Merge remaining pull requests;
+- Update :file:`CHANGELOG.rst` with the last changes;
+- Update :file:`CONTRIBUTORS`;
+- Update known good versions of dependencies in ``requirements.txt`` with this command (from inside the venv):
+
+.. code-block:: bash
+
+ $ pip freeze | grep -v -- '-e' > requirements.txt
+
+Once this is done, use the "release" instruction:
+
+.. code-block:: bash
+
+ $ make release
+
+And the new version should be published on PyPI.
diff --git a/docs/index.rst b/docs/index.rst
index 89a0106..8d96058 120000..100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1 +1,24 @@
-../README.rst \ No newline at end of file
+I hate money
+############
+
+«I hate money» is a web application made to ease shared budget management.
+It keeps track of who bought what, when, and for whom; and helps to settle the
+bills.
+
+
+Table of content
+================
+
+.. toctree::
+ :maxdepth: 1
+
+ installation
+ api
+ contributing
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/docs/installation.rst b/docs/installation.rst
new file mode 100644
index 0000000..3cd143d
--- /dev/null
+++ b/docs/installation.rst
@@ -0,0 +1,114 @@
+Installation
+############
+
+First, you need to get the source files. One way to get them is to download
+them from the github repository, using git::
+
+ git clone https://github.com/spiral-project/ihatemoney.git
+
+Requirements
+============
+
+«Ihatemoney» depends on:
+
+* **Python**: either 2.7, 3.4, 3.5 will work.
+* **A Backend**: to choose among MySQL, PostgreSQL, SQLite or Memory.
+
+We recommend to use `pip <https://pypi.python.org/pypi/pip/>`_ and
+`virtualenv <https://pypi.python.org/pypi/virtualenv>`_ but it will work
+without if you prefer.
+
+If you have everything installed, you can just issue::
+
+ make serve
+
+Alternatively, you can also use the `requirements.txt` file to install the
+dependencies yourself (that's what the `make serve` does). That would be::
+
+ pip install -r requirements.txt
+
+And then run the application::
+
+ cd budget
+ python run.py
+
+In any case, you can point your browser at `http://localhost:5000 <http://localhost:5000>`_.
+It's as simple as that!
+
+In case you want to update to newer versions, you can just run the "update" command::
+
+ make update
+
+Deploy it
+=========
+
+Now, if you want to deploy it on your own server, you have many options.
+Two of them are documented at the moment.
+
+*Of course, if you want to contribute another configuration, feel free to open a
+pull-request against this repository!*.
+
+With Apache and mod_wsgi
+------------------------
+
+1. Install Apache and mod_wsgi - libapache2-mod-wsgi(-py3) for Debian based and mod_wsgi for RedHat based distributions -
+2. Create an Apache virtual host based on the sample configuration file in `conf/apache-vhost.conf`
+3. Adapt it to your paths and specify your virtualenv path if you use one
+4. Activate the virtual host if needed and restart Apache
+
+With Nginx, Gunicorn and Supervisord
+------------------------------------
+
+1. Add the lines in conf/supervisord.conf to your supervisord.conf file.
+2. Copy and paste the content of conf/nginx.conf in your nginx conf file.
+3. reload both nginx and supervisord. It should be working ;)
+
+Don't forget to set the right permission for your files !
+
+Configuration
+=============
+
+ihatemoney relies on a configuration file. If you run the application for the
+first time, you will need to take a few moments to configure the application
+properly.
+
++----------------------------+---------------------------+----------------------------------------------------------------------------------------+
+| Setting name | Default | What does it do? |
++============================+===========================+========================================================================================+
+| SQLALCHEMY_DATABASE_URI | ``sqlite:///budget.db`` | Specifies the type of backend to use and its location. More information |
+| | | on the format used can be found on `the SQLAlchemy documentation`. |
++----------------------------+---------------------------+----------------------------------------------------------------------------------------+
+| SECRET_KEY | ``tralala`` | The secret key used to encrypt the cookies. **This needs to be changed**. |
++----------------------------+---------------------------+----------------------------------------------------------------------------------------+
+| MAIL_DEFAULT_SENDER | ``("Budget manager", | A python tuple describing the name and email adress to use when sending |
+| | "budget@notmyidea.org")`` | emails. |
++----------------------------+---------------------------+----------------------------------------------------------------------------------------+
+| ACTIVATE_DEMO_PROJECT | ``True`` | If set to `True`, a demo project will be available on the frontpage. |
++----------------------------+---------------------------+----------------------------------------------------------------------------------------+
+| | ``""`` | If not empty, the specified password must be entered to create new projects. |
+| ADMIN_PASSWORD | | To generate the proper password HASH, use ``./budget/manage.py generate_password_hash``|
+| | | and copy its output into the value of *ADMIN_PASSWORD*. |
++----------------------------+---------------------------+----------------------------------------------------------------------------------------+
+
+.. _`the SQLAlechemy documentation`: http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls
+
+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'
diff --git a/setup.py b/setup.py
index 49dab32..2aed3bd 100644
--- a/setup.py
+++ b/setup.py
@@ -43,7 +43,7 @@ ENTRY_POINTS = {
setup(name='ihatemoney',
version='1.1.dev0',
description='A simple shared budget manager web application.',
- long_description="{}\n\n{}".format(README, CHANGELOG),
+ long_description="{}\n\n{}".format(README.encode('utf-8'), CHANGELOG.encode('utf-8')),
license='Custom BSD Beerware',
classifiers=[
"Programming Language :: Python",