From 3a4282fd75e3b3317b2b08b4aa2e6ac154310e73 Mon Sep 17 00:00:00 2001 From: Alexis Metaireau Date: Fri, 7 Jul 2017 00:06:56 +0200 Subject: Absolute imports & some other improvements (#243) * Use absolute imports and rename package to ihatemoney * Add a ihatemoney command * Factorize application creation logic * Refactor the tests * Update the wsgi.py module with the new create_app() function * Fix some styling thanks to Flake8. * Automate Flake8 check in the CI. --- ihatemoney/templates/add_bill.html | 17 +++ ihatemoney/templates/add_member.html | 9 ++ ihatemoney/templates/authenticate.html | 19 +++ ihatemoney/templates/create_project.html | 8 ++ ihatemoney/templates/dashboard.html | 21 ++++ ihatemoney/templates/debug.html | 1 + ihatemoney/templates/display_errors.html | 5 + ihatemoney/templates/edit_member.html | 17 +++ ihatemoney/templates/edit_project.html | 19 +++ ihatemoney/templates/forms.html | 168 +++++++++++++++++++++++++ ihatemoney/templates/home.html | 56 +++++++++ ihatemoney/templates/invitation_mail.en | 10 ++ ihatemoney/templates/invitation_mail.fr | 9 ++ ihatemoney/templates/layout.html | 98 +++++++++++++++ ihatemoney/templates/list_bills.html | 128 +++++++++++++++++++ ihatemoney/templates/password_reminder.en | 8 ++ ihatemoney/templates/password_reminder.fr | 7 ++ ihatemoney/templates/password_reminder.html | 8 ++ ihatemoney/templates/recent_projects.html | 8 ++ ihatemoney/templates/reminder_mail.en | 9 ++ ihatemoney/templates/reminder_mail.fr | 8 ++ ihatemoney/templates/send_invites.html | 20 +++ ihatemoney/templates/settle_bills.html | 34 +++++ ihatemoney/templates/sidebar_table_layout.html | 14 +++ 24 files changed, 701 insertions(+) create mode 100644 ihatemoney/templates/add_bill.html create mode 100644 ihatemoney/templates/add_member.html create mode 100644 ihatemoney/templates/authenticate.html create mode 100644 ihatemoney/templates/create_project.html create mode 100644 ihatemoney/templates/dashboard.html create mode 100644 ihatemoney/templates/debug.html create mode 100644 ihatemoney/templates/display_errors.html create mode 100644 ihatemoney/templates/edit_member.html create mode 100644 ihatemoney/templates/edit_project.html create mode 100644 ihatemoney/templates/forms.html create mode 100644 ihatemoney/templates/home.html create mode 100644 ihatemoney/templates/invitation_mail.en create mode 100644 ihatemoney/templates/invitation_mail.fr create mode 100644 ihatemoney/templates/layout.html create mode 100644 ihatemoney/templates/list_bills.html create mode 100644 ihatemoney/templates/password_reminder.en create mode 100644 ihatemoney/templates/password_reminder.fr create mode 100644 ihatemoney/templates/password_reminder.html create mode 100644 ihatemoney/templates/recent_projects.html create mode 100644 ihatemoney/templates/reminder_mail.en create mode 100644 ihatemoney/templates/reminder_mail.fr create mode 100644 ihatemoney/templates/send_invites.html create mode 100644 ihatemoney/templates/settle_bills.html create mode 100644 ihatemoney/templates/sidebar_table_layout.html (limited to 'ihatemoney/templates') diff --git a/ihatemoney/templates/add_bill.html b/ihatemoney/templates/add_bill.html new file mode 100644 index 0000000..595f363 --- /dev/null +++ b/ihatemoney/templates/add_bill.html @@ -0,0 +1,17 @@ +{% extends "layout.html" %} + +{% block js %} + $('#cancel-form').click(function(){location.href={{ url_for(".list_bills") }};}); +{% endblock %} + + +{% block top_menu %} +{{ _("Back to the list") }} +{% endblock %} + +{% block content %} + +
+ {{ forms.add_bill(form, edit) }} +
+{% endblock %} diff --git a/ihatemoney/templates/add_member.html b/ihatemoney/templates/add_member.html new file mode 100644 index 0000000..8ddfd52 --- /dev/null +++ b/ihatemoney/templates/add_member.html @@ -0,0 +1,9 @@ +{% extends "layout.html" %} +{% block js %} + auto_hide_default_text('#name'); +{% endblock %} +{% block content %} +
+ {{ forms.add_member(form) }} +
+{% endblock %} diff --git a/ihatemoney/templates/authenticate.html b/ihatemoney/templates/authenticate.html new file mode 100644 index 0000000..f241c48 --- /dev/null +++ b/ihatemoney/templates/authenticate.html @@ -0,0 +1,19 @@ +{% extends "layout.html" %} +{% block content %} +

Authentication

+ +{% if create_project %} +

{{ _("The project you are trying to access do not exist, do you want +to") }} {{ _("create it") }}{{ _("?") }} +

+{% endif %} +{% if admin_auth %} +
+ {{ forms.admin(form) }} +
+{% else %} +
+ {{ forms.authenticate(form) }} +
+{% endif %} +{% endblock %} diff --git a/ihatemoney/templates/create_project.html b/ihatemoney/templates/create_project.html new file mode 100644 index 0000000..9d4fde9 --- /dev/null +++ b/ihatemoney/templates/create_project.html @@ -0,0 +1,8 @@ +{% extends "layout.html" %} + +{% block content %} +

{{ _("Create a new project") }}

+
+ {{ forms.create_project(form) }} +
+{% endblock %} diff --git a/ihatemoney/templates/dashboard.html b/ihatemoney/templates/dashboard.html new file mode 100644 index 0000000..3f50915 --- /dev/null +++ b/ihatemoney/templates/dashboard.html @@ -0,0 +1,21 @@ +{% extends "layout.html" %} +{% block content %} + + + + {% for project in projects|sort(attribute='name') %} + + + {% if project.has_bills() %} + + + {% else %} + + + {% endif %} + + {% endfor %} + +
{{ _("Project") }}{{ _("Number of members") }}{{ _("Number of bills") }}{{_("Newest bill")}}{{_("Oldest bill")}}
{{ project.name }}{{ project.members | count }}{{ project.get_bills().count() }}{{ project.get_bills().all()[0].date }}{{ project.get_bills().all()[-1].date }}
+{% endblock %} + diff --git a/ihatemoney/templates/debug.html b/ihatemoney/templates/debug.html new file mode 100644 index 0000000..6f97667 --- /dev/null +++ b/ihatemoney/templates/debug.html @@ -0,0 +1 @@ +Yeah diff --git a/ihatemoney/templates/display_errors.html b/ihatemoney/templates/display_errors.html new file mode 100644 index 0000000..9e19605 --- /dev/null +++ b/ihatemoney/templates/display_errors.html @@ -0,0 +1,5 @@ +{% for field_name, field_errors in form.errors.items() if field_errors %} + {% for error in field_errors %} +

{{ form[field_name].label.text }}: {{ error }}

+ {% endfor %} +{% endfor %} diff --git a/ihatemoney/templates/edit_member.html b/ihatemoney/templates/edit_member.html new file mode 100644 index 0000000..5f097f9 --- /dev/null +++ b/ihatemoney/templates/edit_member.html @@ -0,0 +1,17 @@ +{% extends "layout.html" %} + +{% block js %} + $('#cancel-form').click(function(){location.href={{ url_for(".list_bills") }};}); +{% endblock %} + + +{% block top_menu %} +{{ _("Back to the list") }} +{% endblock %} + +{% block content %} + +
+ {{ forms.edit_member(form, edit) }} +
+{% endblock %} diff --git a/ihatemoney/templates/edit_project.html b/ihatemoney/templates/edit_project.html new file mode 100644 index 0000000..a5e85c3 --- /dev/null +++ b/ihatemoney/templates/edit_project.html @@ -0,0 +1,19 @@ +{% extends "layout.html" %} + +{% block js %} + $('#delete-project').click(function () + { + $(this).html("{{_("you sure?")}}"); + }); +{% endblock %} + +{% block content %} +

{{ _("Edit this project") }}

+
+{{ forms.edit_project(edit_form) }} +

+

{{ _("Download this project's data") }}

+
+{{ forms.export_project(export_form) }} +
+{% endblock %} diff --git a/ihatemoney/templates/forms.html b/ihatemoney/templates/forms.html new file mode 100644 index 0000000..ffdd165 --- /dev/null +++ b/ihatemoney/templates/forms.html @@ -0,0 +1,168 @@ +{% macro input(field, multiple=False, class='form-control', inline=False) -%} +
+ {% if field.type != "SubmitField" %} + {% if inline %} + {{ field.label(class="col-3") }} + {% else %} + {{ field.label() }} + {% endif %} + {% endif %} +
+ {% if multiple == True %} + {{ field(multiple=True, class=class) }} + {% else %} + {{ field(class=class) | safe }} + {% endif %} + {% if field.description %} +

{{ field.description }}

+ {% endif %} +
+
+{% endmacro %} + +{% macro submit(field, cancel=False, home=False) -%} +
+ + {% if home %} + {{ _("Can't remember the password?") }} + {% endif %} + {% if cancel %} + + {% endif %} +
+{% endmacro %} + +{% macro authenticate(form, home=False) %} + + {% include "display_errors.html" %} + + {{ form.hidden_tag() }} + {{ input(form.id) }} + {{ input(form.password) }} + {% if not home %} + {{ submit(form.submit, home=True) }} + {% endif %} + +{% endmacro %} + +{% macro admin(form) %} + + {% include "display_errors.html" %} + + {{ form.hidden_tag() }} + {{ input(form.admin_password) }} + {{ submit(form.submit) }} + +{% endmacro %} + +{% macro create_project(form, home=False) %} + + {% include "display_errors.html" %} + {{ form.hidden_tag() }} + {% if not home %} + {{ input(form.id) }} + {% endif %} + {{ input(form.name) }} + {{ input(form.password) }} + {{ input(form.contact_email) }} + {% if not home %} + {{ submit(form.submit, home=True) }} + {% endif %} + +{% endmacro %} + +{% macro edit_project(form) %} + + {% include "display_errors.html" %} + {{ form.hidden_tag() }} + {{ input(form.name) }} + {{ input(form.password) }} + {{ input(form.contact_email) }} +
+ + {{ _("delete") }} +
+ +{% endmacro %} + +{% macro add_bill(form, edit=False, title=True) %} + +
+ {% if title %}{% if edit %}{{ _("Edit this bill") }} {% else %}{{ _("Add a bill") }} {% endif %}{% endif %} + {% include "display_errors.html" %} + {{ form.hidden_tag() }} + {{ input(form.date, class="form-control datepicker", inline=True) }} + {{ input(form.what, inline=True) }} + {{ input(form.payer, inline=True, class="form-control custom-select") }} + {{ input(form.amount, inline=True) }} + +
+ +
+ +
+
+
+
+ {{ form.submit(class="btn btn-primary") }} + {% if not edit %} {{ form.submit2(class="btn") }}{% endif %} +
+ +{% endmacro %} + +{% macro add_member(form) %} +{{ form.hidden_tag() }} +
+ + {{ form.name(placeholder=_("Type user name here"), class="form-control") }} + +
+{% endmacro %} + +{% macro edit_member(form, title=True) %} +
+ {% if title %}{{ _("Edit this member") }}{% endif %} + {% include "display_errors.html" %} + {{ form.hidden_tag() }} + {{ input(form.name) }} + {{ input(form.weight) }} +
+
+ {{ form.submit(class="btn btn-primary") }} +
+{% endmacro %} + + +{% macro invites(form) %} + {{ form.hidden_tag() }} + {{ input(form.emails) }} +
+ + {{ _("No, thanks") }} +
+{% endmacro %} + +{% macro export_project(form) %} +
+ {{ form.hidden_tag() }} + {{ input(form.export_type) }} + {{ input(form.export_format) }} +
+
+ +
+{% endmacro %} + +{% macro remind_password(form) %} + + {% include "display_errors.html" %} + {{ form.hidden_tag() }} + {{ input(form.id) }} + {{ submit(form.submit) }} + +{% endmacro %} diff --git a/ihatemoney/templates/home.html b/ihatemoney/templates/home.html new file mode 100644 index 0000000..9bfe467 --- /dev/null +++ b/ihatemoney/templates/home.html @@ -0,0 +1,56 @@ +{% extends "layout.html" %} + + +{% block body %} + + +
+
+
+
+ {{ _("Log to an existing project") }}... + {{ forms.authenticate(auth_form, home=True) }} +
+ +
+
+
+ {% if is_admin_mode_enabled %} + ...{{ _("or create a new one") }} + {% else %} +
+
+ ...{{ _("or create a new one") }} + {{ forms.create_project(project_form, home=True) }} +
+
+ +
+
+ {% endif %} +
+ +{% endblock %} + +{% block js %} + +$('#creation-form #password').tooltip({ + title: '{{ _("This access code will be sent to your friends. It is stored as-is by the server, so don\\'t reuse a personal password!") }}', + trigger: 'focus', + placement: 'right' +}); + +{% endblock %} diff --git a/ihatemoney/templates/invitation_mail.en b/ihatemoney/templates/invitation_mail.en new file mode 100644 index 0000000..03f5141 --- /dev/null +++ b/ihatemoney/templates/invitation_mail.en @@ -0,0 +1,10 @@ +Hi, + +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. + +You can access it here: {{ config['SITE_URL'] }}{{ url_for(".list_bills") }} and the private code is "{{ g.project.password }}". + +Enjoy, +Some weird guys (with beards) diff --git a/ihatemoney/templates/invitation_mail.fr b/ihatemoney/templates/invitation_mail.fr new file mode 100644 index 0000000..53698dd --- /dev/null +++ b/ihatemoney/templates/invitation_mail.fr @@ -0,0 +1,9 @@ +Salut, + +Quelqu'un avec l'addresse email "{{ 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. + +Vous pouvez accéder à la page ici: {{ config['SITE_URL'] }}{{ url_for(".list_bills") }} et le code est "{{ g.project.password }}". + +Have fun, diff --git a/ihatemoney/templates/layout.html b/ihatemoney/templates/layout.html new file mode 100644 index 0000000..6ecff41 --- /dev/null +++ b/ihatemoney/templates/layout.html @@ -0,0 +1,98 @@ +{% import "forms.html" as forms %} + + + + {{ _("Account manager") }}{% block title %}{% endblock %} + + + + + + + + {% block head %}{% endblock %} + + + +
+ +
+ +
+{% block body %} + {% block sidebar %}{% endblock %} +
+ {% block content %}{% endblock %} +
+
+{% endblock %} + +{% for message in get_flashed_messages() %} +
{{ message }}
+{% endfor %} + +{% block footer %} + +{% endblock %} + + + diff --git a/ihatemoney/templates/list_bills.html b/ihatemoney/templates/list_bills.html new file mode 100644 index 0000000..4029bc9 --- /dev/null +++ b/ihatemoney/templates/list_bills.html @@ -0,0 +1,128 @@ +{% extends "sidebar_table_layout.html" %} + +{% block title %} - {{ g.project.name }}{% endblock %} +{% block head %} + + +{% endblock %} +{% block js %} + {% if add_bill %} $('#new-bill').click(); {% endif %} + + // Hide all members actions + $('.action').each(function(){ + $(this).hide(); + }); + + // ask for confirmation before removing an user + $('.action.delete').each(function(){ + var link = $(this).find('button'); + link.click(function(){ + if ($(this).hasClass("confirm")){ + return true; + } + $(this).html("{{_("you sure?")}}"); + $(this).addClass("confirm"); + return false; + }); + }); + + // display the remove button on mouse over (and hide them per default) + $('.balance tr').hover(function(){ + $(this).find('.action').show(); + }, function(){ + $(this).find('.action').hide(); + }); + + var highlight_owers = function(){ + var ower_ids = $(this).attr("owers").split(','); + var payer_id = $(this).attr("payer"); + $.each(ower_ids, function(i, val){ + $('#bal-member-'+val).addClass("ower_line"); + }); + $("#bal-member-"+payer_id).addClass("payer_line"); + }; + + var unhighlight_owers = function(){ + $('[id^="bal-member-"]').removeClass("ower_line payer_line"); + }; + + $('#bill_table tbody tr').hover(highlight_owers, unhighlight_owers); + +{% endblock %} + +{% block sidebar %} +
+ {{ forms.add_member(member_form) }} +
+ +
+ + {% set balance = g.project.balance %} + {% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id]|round(2) != 0 %} + + + {% if member.activated %} + + {% else %} + + {% endif %} + + + {% endfor %} +
{{ member.name }} + (x{{ member.weight|minimal_round(1) }}) + +
+
+
+
+
+
+
+ {% if balance[member.id]|round(2) > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }} +
+
+{% endblock %} + +{% block content %} +
{{ _("The project identifier is") }} {{ g.project.id }}, {{ _("remember it!") }}
+{{ _("Add a new bill") }} + + + + {% if bills.count() > 0 %} + + + + {% for bill in bills %} + + + + + + + + + {% endfor %} + +
{{ _("When?") }}{{ _("Who paid?") }}{{ _("For what?") }}{{ _("For whom?") }}{{ _("How much?") }}{{ _("Actions") }}
{{ bill.date }}{{ bill.payer }}{{ bill.what }}{{ bill.owers|join(', ', 'name') }} {{ "%0.2f"|format(bill.amount) }} ({{ "%0.2f"|format(bill.pay_each()) }} {{ _("each") }}) + {{ _('edit') }} + {{ _('delete') }} +
+ + {% else %} +

{{ _("Nothing to list yet. You probably want to") }} {{ _("add a bill") }} ?

+ {% endif %} +{% endblock %} diff --git a/ihatemoney/templates/password_reminder.en b/ihatemoney/templates/password_reminder.en new file mode 100644 index 0000000..31210aa --- /dev/null +++ b/ihatemoney/templates/password_reminder.en @@ -0,0 +1,8 @@ +Hi, + +You requested to be reminded about your password for "{{ project.name }}". + +You can access it here: {{ config['SITE_URL'] }}{{ url_for(".list_bills", project_id=project.id) }}, the private code is "{{ project.password }}". + +Hope this helps, +Some weird guys (with beards) diff --git a/ihatemoney/templates/password_reminder.fr b/ihatemoney/templates/password_reminder.fr new file mode 100644 index 0000000..58f04e3 --- /dev/null +++ b/ihatemoney/templates/password_reminder.fr @@ -0,0 +1,7 @@ +Salut, + +Vous avez demandez des informations sur votre mot de passe pour "{{ project.name }}". + +Vous pouvez y accéder ici {{ config['SITE_URL'] }}{{ url_for(".list_bills", project_id=project.id) }}, le code d'accès est "{{ project.password }}". + +Faites en bon usage ! diff --git a/ihatemoney/templates/password_reminder.html b/ihatemoney/templates/password_reminder.html new file mode 100644 index 0000000..8f46289 --- /dev/null +++ b/ihatemoney/templates/password_reminder.html @@ -0,0 +1,8 @@ +{% extends "layout.html" %} + +{% block content %} +

{{ _("Password reminder") }}

+
+{{ forms.remind_password(form) }} +
+{% endblock %} diff --git a/ihatemoney/templates/recent_projects.html b/ihatemoney/templates/recent_projects.html new file mode 100644 index 0000000..df4972d --- /dev/null +++ b/ihatemoney/templates/recent_projects.html @@ -0,0 +1,8 @@ +{% if 'projects' in session %} +

{{ _("Your projects") }}

+ +{% endif %} diff --git a/ihatemoney/templates/reminder_mail.en b/ihatemoney/templates/reminder_mail.en new file mode 100644 index 0000000..fe57be2 --- /dev/null +++ b/ihatemoney/templates/reminder_mail.en @@ -0,0 +1,9 @@ +Hi, + +You have just (or someone else using your email address) created the project "{{ g.project.name }}" to share your expenses. + +You can access it here: {{ config['SITE_URL'] }}{{ url_for(".list_bills") }} (the identifier is {{ g.project.id }}), +and the private code is "{{ g.project.password }}". + +Enjoy, +Some weird guys (with beards) diff --git a/ihatemoney/templates/reminder_mail.fr b/ihatemoney/templates/reminder_mail.fr new file mode 100644 index 0000000..8130218 --- /dev/null +++ b/ihatemoney/templates/reminder_mail.fr @@ -0,0 +1,8 @@ +Hey, + +Vous venez de créer le projet "{{ g.project.name }}" pour partager vos dépenses. + +Vous pouvez y accéder ici: {{ config['SITE_URL'] }}{{ url_for(".list_bills") }} (l'identifieur est {{ g.project.id }}), +et le code d'accès "{{ g.project.password }}". + +Faites en bon usage ! diff --git a/ihatemoney/templates/send_invites.html b/ihatemoney/templates/send_invites.html new file mode 100644 index 0000000..7b3bdc5 --- /dev/null +++ b/ihatemoney/templates/send_invites.html @@ -0,0 +1,20 @@ +{% extends "layout.html" %} + +{% block sidebar %} +
    +
  1. {{ _("Create the project") }}
  2. +
  3. {{ _("Invite people") }}
  4. +
  5. {{ _("Use it!") }}
  6. +
+{% endblock %} +{% block content %} +

{{ _("Invite people to join this project") }}

+

{{ _("Specify a (comma separated) list of email adresses you want to notify about the +creation of this budget management project and we will send them an email for you.") }}

+

{{ _("If you prefer, you can") }} {{ _("skip this step") }} {{ _("and notify them yourself") }}

+ +{% include "display_errors.html" %} +
+ {{ forms.invites(form) }} +
+{% endblock %} diff --git a/ihatemoney/templates/settle_bills.html b/ihatemoney/templates/settle_bills.html new file mode 100644 index 0000000..b67a9b8 --- /dev/null +++ b/ihatemoney/templates/settle_bills.html @@ -0,0 +1,34 @@ +{% extends "sidebar_table_layout.html" %} + +{% block sidebar %} +
+ + {% set balance = g.project.balance %} + {% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id]|round(2) != 0 %} + + + + + {% endfor %} +
{{ member.name }} + {% if balance[member.id]|round(2) > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }} +
+
+{% endblock %} + + +{% block content %} + + + + {% for bill in bills %} + + + + + + {% endfor %} + +
{{ _("Who pays?") }}{{ _("To whom?") }}{{ _("How much?") }}
{{ bill.ower }}{{ bill.receiver }}{{ "%0.2f"|format(bill.amount) }}
+ +{% endblock %} diff --git a/ihatemoney/templates/sidebar_table_layout.html b/ihatemoney/templates/sidebar_table_layout.html new file mode 100644 index 0000000..239acb3 --- /dev/null +++ b/ihatemoney/templates/sidebar_table_layout.html @@ -0,0 +1,14 @@ +{% extends "layout.html" %} + +{% block body %} +
+ + +
+ {% block content %}{% endblock %} +
+ +
+{% endblock %} -- cgit v1.1