diff --git a/ihatemoney/forms.py b/ihatemoney/forms.py
index 67f4ec19..d0bcb556 100644
--- a/ihatemoney/forms.py
+++ b/ihatemoney/forms.py
@@ -215,16 +215,3 @@ class InviteForm(FlaskForm):
except email_validator.EmailNotValidError:
raise ValidationError(_("The email %(email)s is not valid",
email=email))
-
-
-class ExportForm(FlaskForm):
- export_type = SelectField(
- _("What do you want to download ?"),
- validators=[Required()],
- coerce=str,
- choices=[("bills", _("bills")), ("transactions", _("transactions"))])
- export_format = SelectField(
- _("Export file format"),
- validators=[Required()],
- coerce=str,
- choices=[("csv", "csv"), ("json", "json")])
diff --git a/ihatemoney/static/css/main.css b/ihatemoney/static/css/main.css
index ec8c8413..574baa38 100644
--- a/ihatemoney/static/css/main.css
+++ b/ihatemoney/static/css/main.css
@@ -442,6 +442,11 @@ tr:hover .extra-info {
border-bottom: 0.2em solid transparent;
height: 1.2em;
}
+
+.download-project .icon svg {
+ fill: white;
+}
+
.icon.plus svg {
margin-right: 3px;
}
diff --git a/ihatemoney/static/images/file-alt.svg b/ihatemoney/static/images/file-alt.svg
new file mode 100644
index 00000000..e1f980c8
--- /dev/null
+++ b/ihatemoney/static/images/file-alt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ihatemoney/static/images/file-csv-solid.svg b/ihatemoney/static/images/file-csv-solid.svg
new file mode 100644
index 00000000..f527c04a
--- /dev/null
+++ b/ihatemoney/static/images/file-csv-solid.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ihatemoney/templates/edit_project.html b/ihatemoney/templates/edit_project.html
index a5e85c33..dcbbbc86 100644
--- a/ihatemoney/templates/edit_project.html
+++ b/ihatemoney/templates/edit_project.html
@@ -8,12 +8,48 @@
{% endblock %}
{% block content %}
-
{{ _("Edit this project") }}
-
-{{ _("Download this project's data") }}
-
+{{ _("Edit project") }}
+
+
+
+
+{{ _("Download project's data") }}
+
+
+
+
+
{{ _('Download the list of bills with owner, amount, reason,... ') }}
+
+
+
+
{{ _('Download the list of transactions needed to settle the current bills.') }}
+
+
+
{% endblock %}
diff --git a/ihatemoney/tests/tests.py b/ihatemoney/tests/tests.py
index d29ec628..12ad1286 100644
--- a/ihatemoney/tests/tests.py
+++ b/ihatemoney/tests/tests.py
@@ -912,10 +912,7 @@ class BudgetTestCase(IhatemoneyTestCase):
})
# generate json export of bills
- resp = self.client.post("/raclette/edit", data={
- 'export_format': 'json',
- 'export_type': 'bills'
- })
+ resp = self.client.get("/raclette/export/bills.json")
expected = [{
'date': '2017-01-01',
'what': 'refund',
@@ -941,10 +938,7 @@ class BudgetTestCase(IhatemoneyTestCase):
self.assertEqual(json.loads(resp.data.decode('utf-8')), expected)
# generate csv export of bills
- resp = self.client.post("/raclette/edit", data={
- 'export_format': 'csv',
- 'export_type': 'bills'
- })
+ resp = self.client.get("/raclette/export/bills.csv")
expected = [
"date,what,amount,payer_name,payer_weight,owers",
"2017-01-01,refund,13.33,tata,1.0,fred",
@@ -959,20 +953,14 @@ class BudgetTestCase(IhatemoneyTestCase):
)
# generate json export of transactions
- resp = self.client.post("/raclette/edit", data={
- 'export_format': 'json',
- 'export_type': 'transactions'
- })
+ resp = self.client.get("/raclette/export/transactions.json")
expected = [{"amount": 127.33, "receiver": "fred", "ower": "alexis"},
{"amount": 55.34, "receiver": "fred", "ower": "tata"},
{"amount": 2.00, "receiver": "fred", "ower": "p\xe9p\xe9"}]
self.assertEqual(json.loads(resp.data.decode('utf-8')), expected)
# generate csv export of transactions
- resp = self.client.post("/raclette/edit", data={
- 'export_format': 'csv',
- 'export_type': 'transactions'
- })
+ resp = self.client.get("/raclette/export/transactions.csv")
expected = ["amount,receiver,ower",
"127.33,fred,alexis",
@@ -986,23 +974,9 @@ class BudgetTestCase(IhatemoneyTestCase):
set(received_lines[i].strip("\r").split(","))
)
- # wrong export_format should return a 200 and export form
- resp = self.client.post("/raclette/edit", data={
- 'export_format': 'wrong_export_format',
- 'export_type': 'transactions'
- })
-
- self.assertEqual(resp.status_code, 200)
- self.assertIn('id="export_format" name="export_format"', resp.data.decode('utf-8'))
-
- # wrong export_type should return a 200 and export form
- resp = self.client.post("/raclette/edit", data={
- 'export_format': 'json',
- 'export_type': 'wrong_export_type'
- })
-
- self.assertEqual(resp.status_code, 200)
- self.assertIn('id="export_format" name="export_format"', resp.data.decode('utf-8'))
+ # wrong export_format should return a 404
+ resp = self.client.get("/raclette/export/transactions.wrong")
+ self.assertEqual(resp.status_code, 404)
class APITestCase(IhatemoneyTestCase):
diff --git a/ihatemoney/web.py b/ihatemoney/web.py
index b70bc5fd..8ab32171 100644
--- a/ihatemoney/web.py
+++ b/ihatemoney/web.py
@@ -11,7 +11,7 @@ and `add_project_id` for a quick overview)
import os
from flask import (
- Blueprint, current_app, flash, g, redirect, render_template, request,
+ abort, Blueprint, current_app, flash, g, redirect, render_template, request,
session, url_for, send_file, send_from_directory
)
from flask_mail import Message
@@ -25,8 +25,7 @@ from functools import wraps
from ihatemoney.models import db, Project, Person, Bill
from ihatemoney.forms import (
AdminAuthenticationForm, AuthenticationForm, EditProjectForm,
- InviteForm, MemberForm, PasswordReminder, ResetPasswordForm, ProjectForm, get_billform_for,
- ExportForm
+ InviteForm, MemberForm, PasswordReminder, ResetPasswordForm, ProjectForm, get_billform_for
)
from ihatemoney.utils import Redirect303, list_of_dicts2json, list_of_dicts2csv, LoginThrottler
@@ -309,7 +308,6 @@ def reset_password():
@main.route("//edit", methods=["GET", "POST"])
def edit_project():
edit_form = EditProjectForm()
- export_form = ExportForm()
if request.method == "POST":
if edit_form.validate():
project = edit_form.update(g.project)
@@ -317,28 +315,6 @@ def edit_project():
db.session.commit()
return redirect(url_for(".list_bills"))
-
- if export_form.validate():
- export_format = export_form.export_format.data
- export_type = export_form.export_type.data
-
- if export_type == 'transactions':
- export = g.project.get_transactions_to_settle_bill(
- pretty_output=True)
- if export_type == "bills":
- export = g.project.get_pretty_bills(
- export_format=export_format)
-
- if export_format == "json":
- file2export = list_of_dicts2json(export)
- if export_format == "csv":
- file2export = list_of_dicts2csv(export)
-
- return send_file(file2export,
- attachment_filename="%s-%s.%s" %
- (g.project.id, export_type, export_format),
- as_attachment=True
- )
else:
edit_form.name.data = g.project.name
edit_form.contact_email.data = g.project.contact_email
@@ -346,7 +322,6 @@ def edit_project():
return render_template(
"edit_project.html",
edit_form=edit_form,
- export_form=export_form,
current_view="edit_project"
)
@@ -359,6 +334,29 @@ def delete_project():
return redirect(request.headers.get('Referer') or url_for('.home'))
+@main.route("//export/.")
+def export_project(file, format):
+ if file == 'transactions':
+ export = g.project.get_transactions_to_settle_bill(pretty_output=True)
+ elif file == "bills":
+ export = g.project.get_pretty_bills(export_format=format)
+ else:
+ abort(404, 'No such export type')
+
+ if format == "json":
+ file2export = list_of_dicts2json(export)
+ elif format == "csv":
+ file2export = list_of_dicts2csv(export)
+ else:
+ abort(404, 'No such export format')
+
+ return send_file(
+ file2export,
+ attachment_filename="%s-%s.%s" % (g.project.id, file, format),
+ as_attachment=True
+ )
+
+
@main.route("/exit")
def exit():
# delete the session