From ee022f032df5d57c9ee560d0727af9236674da06 Mon Sep 17 00:00:00 2001 From: Lynne <> Date: Wed, 19 Sep 2018 20:03:19 +0200 Subject: [PATCH 1/5] Add a dynamic currency system. --- fosspay/blueprints/html.py | 9 ++++++--- fosspay/currency.py | 21 +++++++++++++++++++++ scripts/index.js | 1 + templates/admin.html | 20 ++++++++++---------- templates/goal.html | 18 +++++++++--------- templates/index.html | 5 +++-- templates/panel.html | 4 ++-- 7 files changed, 52 insertions(+), 26 deletions(-) create mode 100644 fosspay/currency.py diff --git a/fosspay/blueprints/html.py b/fosspay/blueprints/html.py index ac6e01d..8ba98a6 100644 --- a/fosspay/blueprints/html.py +++ b/fosspay/blueprints/html.py @@ -6,6 +6,7 @@ from fosspay.database import db from fosspay.common import * from fosspay.config import _cfg, load_config from fosspay.email import send_thank_you, send_password_reset +from fosspay.currency import currency import os import locale @@ -75,7 +76,7 @@ def index(): patreon_count=patreon_count, patreon_sum=patreon_sum, lp_count=lp_count, - lp_sum=lp_sum) + lp_sum=lp_sum, currency=currency) @html.route("/setup", methods=["POST"]) def setup(): @@ -103,6 +104,7 @@ def admin(): first=first, projects=projects, donations=donations, + currency=currency, one_times=lambda p: sum([d.amount for d in p.donations if d.type == DonationType.one_time]), recurring=lambda p: sum([d.amount for d in p.donations if d.type == DonationType.monthly and d.active]), recurring_ever=lambda p: sum([d.amount * d.payments for d in p.donations if d.type == DonationType.monthly]), @@ -202,7 +204,7 @@ def donate(): try: charge = stripe.Charge.create( amount=amount, - currency="usd", + currency=_cfg("currency"), customer=user.stripe_customer, description="Donation to " + _cfg("your-name") ) @@ -276,7 +278,8 @@ def reset_password(token): def panel(): return render_template("panel.html", one_times=lambda u: [d for d in u.donations if d.type == DonationType.one_time], - recurring=lambda u: [d for d in u.donations if d.type == DonationType.monthly and d.active]) + recurring=lambda u: [d for d in u.donations if d.type == DonationType.monthly and d.active], + currency=currency) @html.route("/cancel/") @loginrequired diff --git a/fosspay/currency.py b/fosspay/currency.py new file mode 100644 index 0000000..d2e396a --- /dev/null +++ b/fosspay/currency.py @@ -0,0 +1,21 @@ +from fosspay.config import _cfg + +class Currency: + def __init__(self, symbol, position): + self.symbol = symbol + self.position = position + + def amount(self, amount): + if self.position == "right": + return amount + self.symbol + else: + return self.symbol + amount + +currencies = { + 'usd' : Currency("$", "left"), + 'eur' : Currency("€", "right") + # ... More currencies can be added here +} + +currency = currencies[_cfg("currency")] + diff --git a/scripts/index.js b/scripts/index.js index d679b45..0041b77 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -78,6 +78,7 @@ description: donation.type == "monthly" ? i18n["Monthly Donation"] : i18n["One-time Donation"], panelLabel: i18n["Donate "] + "{{amount}}", amount: donation.amount, + currency: currency, token: function(token) { e.target.setAttribute("disabled", ""); e.target.textContent = i18n["Submitting..."]; diff --git a/templates/admin.html b/templates/admin.html index bc7f7c2..aeb2177 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -65,24 +65,24 @@ {{ project.name }} - ${{ "{:.2f}".format(one_times(project) / 100) }} - ${{ "{:.2f}".format(recurring(project) / 100) }} - ${{ "{:.2f}".format(recurring_ever(project) / 100) }} + {{ currency.amount("{:.2f}".format(one_times(project) / 100)) }} + {{ currency.amount("{:.2f}".format(recurring(project) / 100)) }} + {{ currency.amount("{:.2f}".format(recurring_ever(project) / 100)) }} {% endfor %} (not specified) - ${{ "{:.2f}".format(unspecified_one_times / 100) }} - ${{ "{:.2f}".format(unspecified_recurring / 100) }} - ${{ "{:.2f}".format(unspecified_recurring_ever / 100) }} + {{ currency.amount("{:.2f}".format(unspecified_one_times / 100)) }} + {{ currency.amount("{:.2f}".format(unspecified_recurring / 100)) }} + {{ currency.amount("{:.2f}".format(unspecified_recurring_ever / 100)) }} Total - ${{ "{:.2f}".format(total_one_time / 100) }} - ${{ "{:.2f}".format(total_recurring / 100) }} - ${{ "{:.2f}".format(total_recurring_ever / 100) }} + {{ currency.amount("{:.2f}".format(total_one_time / 100)) }} + {{ currency.amount("{:.2f}".format(total_recurring / 100)) }} + {{ currency.amount("{:.2f}".format(total_recurring_ever / 100)) }} @@ -118,7 +118,7 @@ {{ donation.user.email }} {{ donation.project.name if donation.project else "" }} {{ donation.comment if donation.comment else "" }} - ${{ "{:.2f}".format(donation.amount / 100) }} + {{ currency.amount("{:.2f}".format(donation.amount / 100)) }} {{ "Once" if str(donation.type) == "DonationType.one_time" else "Monthly" }} {{ "(cancelled)" if not donation.active else "" }} diff --git a/templates/goal.html b/templates/goal.html index 8be983f..b98c514 100644 --- a/templates/goal.html +++ b/templates/goal.html @@ -23,21 +23,21 @@ class="progress-bar progress-bar-primary" style="width: {{ recurring_progress * 100 }}%; line-height: 2.5" > - ${{ "{:.0f}".format(recurring_sum / 100) }} + {{ currency.amount("{:.0f}".format(recurring_sum / 100)) }}
- ${{ "{:.0f}".format(patreon_sum / 100) }} + {{ currency.amount("{:.0f}".format(patreon_sum / 100)) }}
- ${{ "{:.0f}".format(lp_sum / 100) }} + {{ currency.amount("{:.0f}".format(lp_sum / 100)) }}
{% endif %} @@ -47,13 +47,13 @@
{% if patreon_count or lp_count %}

- ${{ "{:.2f}".format(recurring_sum / 100) }}/mo + {{ currency.amount("{:.2f}".format(recurring_sum / 100)) }}/mo via {{ domain }} ({{ recurring_count }} supporter{{ "s" if recurring_count != 1 else "" }})

{% if patreon_count %}

- ${{ "{:.2f}".format(patreon_sum / 100) }}/mo + {{ currency.amount("{:.2f}".format(patreon_sum / 100)) }}/mo via - ${{ "{:.2f}".format(lp_sum / 100) }}/mo + {{ currency.amount("{:.2f}".format(lp_sum / 100)) }}/mo via - ${{ "{:.2f}".format(total_sum / 100)}}/mo + {{ currency.amount("{:.2f}".format(total_sum / 100))}}/mo of - ${{ "{:.2f}".format(goal / 100) }}/mo + {{ currency.amount("{:.2f}".format(goal / 100)) }}/mo goal

{% else %}

- Supported with ${{ "{:.2f}".format(total_sum / 100) }} + Supported with ${{ currency.amount("{:.2f}".format(total_sum / 100)) }} from {{ total_count }} supporters!

{% endif %} diff --git a/templates/index.html b/templates/index.html index 620aa9a..20882fd 100644 --- a/templates/index.html +++ b/templates/index.html @@ -15,6 +15,7 @@ const i18n = { "Submitting...": "Submitting...", "Donate": "Donate" }; +const currency = "{{ _cfg("currency") }}"; {% if user %} window.email = "{{user.email}}"; @@ -65,7 +66,7 @@ window.email = "{{user.email}}";
+ >{{ currency.amount(amt) }}
{% endfor %}
@@ -78,7 +79,7 @@ window.email = "{{user.email}}";
- $ + {{ currency.symbol }}
diff --git a/templates/panel.html b/templates/panel.html index fe11a8d..2877b83 100644 --- a/templates/panel.html +++ b/templates/panel.html @@ -30,7 +30,7 @@ {{ donation.created.strftime("%Y-%m-%d") }} - ${{ "{:.2f}".format(donation.amount / 100) }} + {{ currency.amount("{:.2f}".format(donation.amount / 100)) }} {{ donation.project.name if donation.project else "Not specified" }} {% endfor %} @@ -51,7 +51,7 @@ {% for donation in one_times(user) %} {{ donation.created.strftime("%Y-%m-%d") }} - ${{ "{:.2f}".format(donation.amount / 100) }} + {{ currency.amount("{:.2f}".format(donation.amount / 100)) }} {{ donation.project.name if donation.project else "Not specified" }} {% endfor %} From 7be17efc8bc542f625ad2fe0a5918baa3edb6fd7 Mon Sep 17 00:00:00 2001 From: Lynne <> Date: Wed, 19 Sep 2018 20:14:39 +0200 Subject: [PATCH 2/5] Change currency in emails. --- emails/declined | 2 +- emails/thank-you | 4 ++-- fosspay/email.py | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/emails/declined b/emails/declined index 7cf6fdc..777baec 100644 --- a/emails/declined +++ b/emails/declined @@ -1,5 +1,5 @@ An attempt was just made to charge your card for your monthly donation to -{{your_name}} for ${{amount}}. Unfortunately, your card was declined. +{{your_name}} for {{amount}}. Unfortunately, your card was declined. The donation has been disabled. If you would like to, you may create a new recurring donation here: diff --git a/emails/thank-you b/emails/thank-you index 6d45485..7e1e8a9 100644 --- a/emails/thank-you +++ b/emails/thank-you @@ -3,10 +3,10 @@ Thank you for donating! Receipt: {{#monthly}} -Monthly donation ${{amount}} +Monthly donation {{amount}} {{/monthly}} {{^monthly}} -One-time donation ${{amount}} +One-time donation {{amount}} {{/monthly}} You can view and manage your donations online here: diff --git a/fosspay/email.py b/fosspay/email.py index 78601b0..96b21b2 100644 --- a/fosspay/email.py +++ b/fosspay/email.py @@ -10,6 +10,7 @@ from flask import url_for from fosspay.database import db from fosspay.objects import User from fosspay.config import _cfg, _cfgi +from fosspay.currency import currency def send_thank_you(user, amount, monthly): if _cfg("smtp-host") == "": @@ -24,7 +25,7 @@ def send_thank_you(user, amount, monthly): "user": user, "root": _cfg("protocol") + "://" + _cfg("domain"), "your_name": _cfg("your-name"), - "amount": "{:.2f}".format(amount / 100), + "amount": currency.amount("{:.2f}".format(amount / 100)), "monthly": monthly, "your_email": _cfg("your-email") }))) @@ -70,7 +71,7 @@ def send_declined(user, amount): "user": user, "root": _cfg("protocol") + "://" + _cfg("domain"), "your_name": _cfg("your-name"), - "amount": "{:.2f}".format(amount / 100) + "amount": currency.amount("{:.2f}".format(amount / 100)) }))) message['Subject'] = "Your monthly donation was declined." message['From'] = _cfg("smtp-from") From 0a1b3603471dbeb0b8350fdd06ce216bcaf741fe Mon Sep 17 00:00:00 2001 From: Lynne <> Date: Wed, 19 Sep 2018 20:29:23 +0200 Subject: [PATCH 3/5] Change default config file for dynamic currency system --- config.ini.example | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config.ini.example b/config.ini.example index e945675..574425a 100644 --- a/config.ini.example +++ b/config.ini.example @@ -31,6 +31,11 @@ connection-string=postgresql://postgres@localhost/fosspay stripe-secret= stripe-publish= +# Currency to use +# "usd" for dollar, "eur" for euro +# refer to stripe documentation for details : https://stripe.com/docs/currencies +currency=usd + # Separate with spaces default-amounts=3 5 10 20 # Which one to pick when they arrive? From 456d97225eb018c09aab030cc2760d3949f82280 Mon Sep 17 00:00:00 2001 From: emy Date: Wed, 19 Sep 2018 21:24:07 +0200 Subject: [PATCH 4/5] French translation adapted to dynamic currency system. --- contrib/fr/overrides/admin.html | 20 ++++++++++---------- contrib/fr/overrides/goal.html | 20 ++++++++++---------- contrib/fr/overrides/index.html | 6 ++++-- contrib/fr/overrides/layout.html | 2 +- contrib/fr/overrides/panel.html | 4 ++-- templates/goal.html | 2 +- templates/index.html | 2 ++ 7 files changed, 30 insertions(+), 26 deletions(-) diff --git a/contrib/fr/overrides/admin.html b/contrib/fr/overrides/admin.html index 2b6026e..df8f551 100644 --- a/contrib/fr/overrides/admin.html +++ b/contrib/fr/overrides/admin.html @@ -64,24 +64,24 @@ {{ project.name }} - {{ "{:.2f}".format(one_times(project) / 100) }}€ - {{ "{:.2f}".format(recurring(project) / 100) }}€ - {{ "{:.2f}".format(recurring_ever(project) / 100) }}€ + {{ currency.amount("{:.2f}".format(one_times(project) / 100)) }} + {{ currency.amount("{:.2f}".format(recurring(project) / 100)) }} + {{ currency.amount("{:.2f}".format(recurring_ever(project) / 100)) }} {% endfor %} (non précisé) - {{ "{:.2f}".format(unspecified_one_times / 100) }}€ - {{ "{:.2f}".format(unspecified_recurring / 100) }}€ - {{ "{:.2f}".format(unspecified_recurring_ever / 100) }}€ + {{ currency.amount("{:.2f}".format(unspecified_one_times / 100)) }} + {{ currency.amount("{:.2f}".format(unspecified_recurring / 100)) }} + {{ currency.amount("{:.2f}".format(unspecified_recurring_ever / 100)) }} Total - {{ "{:.2f}".format(total_one_time / 100) }}€ - {{ "{:.2f}".format(total_recurring / 100) }}€ - {{ "{:.2f}".format(total_recurring_ever / 100) }}€ + {{ currency.amount("{:.2f}".format(total_one_time / 100)) }} + {{ currency.amount("{:.2f}".format(total_recurring / 100)) }} + {{ currency.amount("{:.2f}".format(total_recurring_ever / 100)) }} @@ -117,7 +117,7 @@
{{ donation.user.email }} {{ donation.project.name if donation.project else "" }} {{ donation.comment if donation.comment else "" }} - {{ "{:.2f}".format(donation.amount / 100) }}€ + {{ currency.amount("{:.2f}".format(donation.amount / 100)) }} {{ "Unique" if str(donation.type) == "DonationType.one_time" else "Mensuel" }} {{ "(cancelled)" if not donation.active else "" }} diff --git a/contrib/fr/overrides/goal.html b/contrib/fr/overrides/goal.html index bd464fb..deed792 100644 --- a/contrib/fr/overrides/goal.html +++ b/contrib/fr/overrides/goal.html @@ -23,21 +23,21 @@ class="progress-bar progress-bar-primary" style="width: {{ recurring_progress * 100 }}%; line-height: 2.5" > - {{ "{:.0f}".format(recurring_sum / 100) }}€ + {{ currency.amount("{:.0f}".format(recurring_sum / 100)) }}
- {{ "{:.0f}".format(patreon_sum / 100) }}€ + {{ currency.amount("{:.0f}".format(patreon_sum / 100)) }}
- {{ "{:.0f}".format(lp_sum / 100) }}€ + {{ currency.amount("{:.0f}".format(lp_sum / 100)) }}
{% endif %} @@ -47,13 +47,13 @@ diff --git a/contrib/fr/overrides/index.html b/contrib/fr/overrides/index.html index f5b8ef2..c3ab241 100644 --- a/contrib/fr/overrides/index.html +++ b/contrib/fr/overrides/index.html @@ -17,6 +17,8 @@ const i18n = { }; // Fin de traduction +const currency = "{{ _cfg("currency") }}"; + {% if user %} window.email = "{{user.email}}"; {% endif %} @@ -66,7 +68,7 @@ window.email = "{{user.email}}";
+ >{{ currency.amount(amt) }}
{% endfor %}
@@ -79,7 +81,7 @@ window.email = "{{user.email}}";
- + {{ currency.symbol }}
diff --git a/contrib/fr/overrides/layout.html b/contrib/fr/overrides/layout.html index 41c90d8..3d541a7 100644 --- a/contrib/fr/overrides/layout.html +++ b/contrib/fr/overrides/layout.html @@ -5,7 +5,7 @@ {% block title %} - Donations pour {{_cfg("your-name")}} + Donner au {{_cfg("your-name")}} {% endblock %} {% block styles %}{% endblock %} diff --git a/contrib/fr/overrides/panel.html b/contrib/fr/overrides/panel.html index fd7ca8c..2947b7e 100644 --- a/contrib/fr/overrides/panel.html +++ b/contrib/fr/overrides/panel.html @@ -30,7 +30,7 @@ {{ donation.created.strftime("%d-%m-%Y") }} - {{ "{:.2f}".format(donation.amount / 100) }}€ + {{ currency.amount("{:.2f}".format(donation.amount / 100)) }} {{ donation.project.name if donation.project else "Non précisé" }} {% endfor %} @@ -51,7 +51,7 @@ {% for donation in one_times(user) %} {{ donation.created.strftime("%d-%m-%Y") }} - {{ "{:.2f}".format(donation.amount / 100) }}€ + {{ currency.amount("{:.2f}".format(donation.amount / 100)) }} {{ donation.project.name if donation.project else "Non précisé" }} {% endfor %} diff --git a/templates/goal.html b/templates/goal.html index b98c514..e433617 100644 --- a/templates/goal.html +++ b/templates/goal.html @@ -83,7 +83,7 @@

{% else %}

- Supported with ${{ currency.amount("{:.2f}".format(total_sum / 100)) }} + Supported with {{ currency.amount("{:.2f}".format(total_sum / 100)) }} from {{ total_count }} supporters!

{% endif %} diff --git a/templates/index.html b/templates/index.html index 20882fd..e843931 100644 --- a/templates/index.html +++ b/templates/index.html @@ -15,6 +15,8 @@ const i18n = { "Submitting...": "Submitting...", "Donate": "Donate" }; +// End of translation of index.js + const currency = "{{ _cfg("currency") }}"; {% if user %} From e7da56aaac052f175fc100586bf508a367b84b58 Mon Sep 17 00:00:00 2001 From: emy Date: Wed, 19 Sep 2018 21:52:39 +0200 Subject: [PATCH 5/5] Fixed indentation error --- templates/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/index.html b/templates/index.html index e843931..ddd5db1 100644 --- a/templates/index.html +++ b/templates/index.html @@ -68,7 +68,7 @@ window.email = "{{user.email}}";
+ >{{ currency.amount(amt) }}
{% endfor %}
@@ -81,7 +81,7 @@ window.email = "{{user.email}}";
- {{ currency.symbol }} + {{ currency.symbol }}