mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-04-29 09:52:36 +02:00
Merge pull request #308 from spiral-project/almet/fix-template-inclusion-packaging
Include all .j2 files in the packaged version.
This commit is contained in:
commit
34a2161650
13 changed files with 58 additions and 18 deletions
|
@ -6,7 +6,10 @@ This document describes changes between each past release.
|
||||||
2.1 (unreleased)
|
2.1 (unreleased)
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
- Nothing changed yet.
|
Fixed
|
||||||
|
=====
|
||||||
|
|
||||||
|
- Fix the "IOError" crash when running `ihatemoney generate-config` (#308)
|
||||||
|
|
||||||
|
|
||||||
2.0 (2017-12-27)
|
2.0 (2017-12-27)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
include *.rst
|
include *.rst
|
||||||
recursive-include ihatemoney *.rst *.py *.yaml *.po *.mo *.html *.css *.js *.eot *.svg *.woff *.txt *.png *.ini *.cfg
|
recursive-include ihatemoney *.rst *.py *.yaml *.po *.mo *.html *.css *.js *.eot *.svg *.woff *.txt *.png *.ini *.cfg *.j2
|
||||||
include LICENSE CONTRIBUTORS CHANGELOG.rst requirements.txt
|
include LICENSE CONTRIBUTORS CHANGELOG.rst requirements.txt
|
||||||
|
|
|
@ -3,3 +3,4 @@ tox
|
||||||
pytest
|
pytest
|
||||||
Flask-Testing
|
Flask-Testing
|
||||||
Flake8
|
Flake8
|
||||||
|
mock; python_version < '3.3'
|
||||||
|
|
|
@ -4,7 +4,7 @@ import os
|
||||||
import pkgutil
|
import pkgutil
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
from getpass import getpass
|
import getpass
|
||||||
|
|
||||||
from flask_script import Manager, Command, Option
|
from flask_script import Manager, Command, Option
|
||||||
from flask_migrate import Migrate, MigrateCommand
|
from flask_migrate import Migrate, MigrateCommand
|
||||||
|
@ -20,11 +20,11 @@ class GeneratePasswordHash(Command):
|
||||||
"""Get password from user and hash it without printing it in clear text."""
|
"""Get password from user and hash it without printing it in clear text."""
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
password = getpass(prompt='Password: ')
|
password = getpass.getpass(prompt='Password: ')
|
||||||
print(generate_password_hash(password))
|
print(generate_password_hash(password))
|
||||||
|
|
||||||
|
|
||||||
class ConfigTemplate(Command):
|
class GenerateConfig(Command):
|
||||||
def get_options(self):
|
def get_options(self):
|
||||||
return [
|
return [
|
||||||
Option('config_file', choices=[
|
Option('config_file', choices=[
|
||||||
|
@ -74,7 +74,7 @@ def main():
|
||||||
manager = Manager(app)
|
manager = Manager(app)
|
||||||
manager.add_command('db', MigrateCommand)
|
manager.add_command('db', MigrateCommand)
|
||||||
manager.add_command('generate_password_hash', GeneratePasswordHash)
|
manager.add_command('generate_password_hash', GeneratePasswordHash)
|
||||||
manager.add_command('generate-config', ConfigTemplate)
|
manager.add_command('generate-config', GenerateConfig)
|
||||||
manager.run()
|
manager.run()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ Hi,
|
||||||
|
|
||||||
Someone using the email address {{ g.project.contact_email }} invited you to share your expenses for "{{ g.project.name }}".
|
Someone using the email address {{ g.project.contact_email }} invited you to share your expenses for "{{ g.project.name }}".
|
||||||
|
|
||||||
It's as simple as saying what did you paid for, for who, and how much did it cost you, we are caring about the rest.
|
It's as simple as saying what did you pay for, for whom, and how much did it cost you, we are caring about the rest.
|
||||||
|
|
||||||
You can log in using this link: {{ url_for(".authenticate", _external=True, token=g.project.generate_token()) }}.
|
You can log in using this link: {{ url_for(".authenticate", _external=True, token=g.project.generate_token()) }}.
|
||||||
Once logged in you can use the following link which is easier to remember: {{ url_for(".list_bills", _external=True) }}
|
Once logged-in, you can use the following link which is easier to remember: {{ url_for(".list_bills", _external=True) }}
|
||||||
If your cookie gets deleted or if you log out, you will need to log back in using the first link.
|
If your cookie gets deleted or if you log out, you will need to log back in using the first link.
|
||||||
|
|
||||||
Enjoy,
|
Enjoy,
|
|
@ -1,11 +1,11 @@
|
||||||
Salut,
|
Salut,
|
||||||
|
|
||||||
Quelqu'un avec l'addresse email "{{ g.project.contact_email }}" vous à invité à partager vos dépenses pour "{{ g.project.name }}".
|
Quelqu'un avec l'adresse "{{ g.project.contact_email }}" vous à invité à partager vos dépenses pour "{{ g.project.name }}".
|
||||||
|
|
||||||
C'est aussi simple que de dire qui à payé pour quoi, pour qui, et combien celà à coûté, on s'occuppe du reste.
|
C'est aussi simple que de dire qui à payé pour quoi, pour qui, et combien celà à coûté, on s’occupe du reste.
|
||||||
|
|
||||||
Vous pouvez vous authentifier avec le lien suivant: {{ url_for(".authenticate", _external=True, token=g.project.generate_token()) }}.
|
Vous pouvez vous authentifier avec le lien suivant: {{ url_for(".authenticate", _external=True, token=g.project.generate_token()) }}.
|
||||||
Une fois authentifié, vous pouvez utiliser le lien suivant qui est plus facile à mémoriser: {{ url_for(".list_bills", _external=True) }}
|
Une fois authentifié, vous pouvez utiliser le lien suivant qui est plus facile à mémoriser: {{ url_for(".list_bills", _external=True) }}
|
||||||
Si votre cookie est supprimé ou si vous vous déconnectez, voous devrez vous réauthentifier en utilisant le premier lien.
|
Si votre cookie est supprimé ou si vous vous déconnectez, vous devrez vous authentifier à nouveau en utilisant le premier lien.
|
||||||
|
|
||||||
Have fun,
|
Have fun,
|
|
@ -1,8 +1,8 @@
|
||||||
Hi,
|
Hi,
|
||||||
|
|
||||||
You requested to reset the password of the following project: "{{ project.name }}".
|
You requested to reset the password of the following project: "{{ project.name }}".
|
||||||
You can reset it here: {{ url_for(".reset_password", _external=True, token=project.generate_token(expiration=3600)) }}.
|
You can reset it here: {{ url_for(".reset_password", _external=True, token=project.generate_token(expiration=3600)) }}.
|
||||||
This link is only valid for 1 hour.
|
This link is only valid for one hour.
|
||||||
|
|
||||||
Hope this helps,
|
Hope this helps,
|
||||||
Some weird guys (with beards)
|
Some weird guys (with beards)
|
|
@ -4,6 +4,10 @@ try:
|
||||||
import unittest2 as unittest
|
import unittest2 as unittest
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import unittest # NOQA
|
import unittest # NOQA
|
||||||
|
try:
|
||||||
|
from unittest.mock import patch
|
||||||
|
except ImportError:
|
||||||
|
from mock import patch
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
@ -16,6 +20,7 @@ from flask import session
|
||||||
from flask_testing import TestCase
|
from flask_testing import TestCase
|
||||||
|
|
||||||
from ihatemoney.run import create_app, db, load_configuration
|
from ihatemoney.run import create_app, db, load_configuration
|
||||||
|
from ihatemoney.manage import GenerateConfig, GeneratePasswordHash
|
||||||
from ihatemoney import models
|
from ihatemoney import models
|
||||||
from ihatemoney import utils
|
from ihatemoney import utils
|
||||||
|
|
||||||
|
@ -1406,5 +1411,27 @@ class ServerTestCase(IhatemoneyTestCase):
|
||||||
self.assertStatus(200, req)
|
self.assertStatus(200, req)
|
||||||
|
|
||||||
|
|
||||||
|
class CommandTestCase(BaseTestCase):
|
||||||
|
def test_generate_config(self):
|
||||||
|
""" Simply checks that all config file generation
|
||||||
|
- raise no exception
|
||||||
|
- produce something non-empty
|
||||||
|
"""
|
||||||
|
cmd = GenerateConfig()
|
||||||
|
for config_file in cmd.get_options()[0].kwargs['choices']:
|
||||||
|
with patch('sys.stdout', new=six.StringIO()) as stdout:
|
||||||
|
cmd.run(config_file)
|
||||||
|
print(stdout.getvalue())
|
||||||
|
self.assertNotEqual(len(stdout.getvalue().strip()), 0)
|
||||||
|
|
||||||
|
def test_generate_password_hash(self):
|
||||||
|
cmd = GeneratePasswordHash()
|
||||||
|
with patch('sys.stdout', new=six.StringIO()) as stdout, \
|
||||||
|
patch('getpass.getpass', new=lambda prompt: 'secret'): # NOQA
|
||||||
|
cmd.run()
|
||||||
|
print(stdout.getvalue())
|
||||||
|
self.assertEqual(len(stdout.getvalue().strip()), 187)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -242,7 +242,7 @@ def create_project():
|
||||||
message_title = _("You have just created '%(project)s' "
|
message_title = _("You have just created '%(project)s' "
|
||||||
"to share your expenses", project=g.project.name)
|
"to share your expenses", project=g.project.name)
|
||||||
|
|
||||||
message_body = render_template("reminder_mail.%s" %
|
message_body = render_template("reminder_mail.%s.j2" %
|
||||||
get_locale().language)
|
get_locale().language)
|
||||||
|
|
||||||
msg = Message(message_title,
|
msg = Message(message_title,
|
||||||
|
@ -273,7 +273,7 @@ def remind_password():
|
||||||
project = Project.query.get(form.id.data)
|
project = Project.query.get(form.id.data)
|
||||||
|
|
||||||
# send a link to reset the password
|
# send a link to reset the password
|
||||||
password_reminder = "password_reminder.%s" % get_locale().language
|
password_reminder = "password_reminder.%s.j2" % get_locale().language
|
||||||
current_app.mail.send(Message(
|
current_app.mail.send(Message(
|
||||||
"password recovery",
|
"password recovery",
|
||||||
body=render_template(password_reminder, project=project),
|
body=render_template(password_reminder, project=project),
|
||||||
|
@ -395,7 +395,7 @@ def invite():
|
||||||
if form.validate():
|
if form.validate():
|
||||||
# send the email
|
# send the email
|
||||||
|
|
||||||
message_body = render_template("invitation_mail.%s" %
|
message_body = render_template("invitation_mail.%s.j2" %
|
||||||
get_locale().language)
|
get_locale().language)
|
||||||
|
|
||||||
message_title = _("You have been invited to share your "
|
message_title = _("You have been invited to share your "
|
||||||
|
|
13
tox.ini
13
tox.ini
|
@ -6,22 +6,31 @@ skip_missing_interpreters = True
|
||||||
|
|
||||||
commands =
|
commands =
|
||||||
python --version
|
python --version
|
||||||
py.test ihatemoney/tests/tests.py
|
py.test --pyargs ihatemoney.tests.tests
|
||||||
|
|
||||||
deps =
|
deps =
|
||||||
-rdev-requirements.txt
|
-rdev-requirements.txt
|
||||||
-rrequirements.txt
|
-rrequirements.txt
|
||||||
|
|
||||||
install_command = pip install --pre {opts} {packages}
|
# To be sure we are importing ihatemoney pkg from pip-installed version
|
||||||
|
changedir = /tmp
|
||||||
|
|
||||||
|
install_command =
|
||||||
|
pip install --pre {opts} {packages}
|
||||||
|
pip install .
|
||||||
|
|
||||||
|
|
||||||
[testenv:docs]
|
[testenv:docs]
|
||||||
commands = sphinx-build -a -n -b html -d docs/_build/doctrees docs docs/_build/html
|
commands = sphinx-build -a -n -b html -d docs/_build/doctrees docs docs/_build/html
|
||||||
deps =
|
deps =
|
||||||
-rdocs/requirements.txt
|
-rdocs/requirements.txt
|
||||||
|
changedir = {toxinidir}
|
||||||
|
|
||||||
[testenv:lint]
|
[testenv:lint]
|
||||||
commands = flake8 ihatemoney
|
commands = flake8 ihatemoney
|
||||||
deps =
|
deps =
|
||||||
-rdev-requirements.txt
|
-rdev-requirements.txt
|
||||||
|
changedir = {toxinidir}
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
exclude = migrations
|
exclude = migrations
|
||||||
|
|
Loading…
Reference in a new issue