Changeset - ade19bdcb84a
[Not reviewed]
crypto
0 4 0
Dennis Fink - 3 years ago 2022-01-19 18:22:05
dennis.fink@c3l.lu
Implement new conversion method for cryptocurrencies
4 files changed with 92 insertions and 17 deletions:
0 comments (0 inline, 0 general)
c3l_membership/templates/member.html
Show inline comments
 
@@ -44,80 +44,81 @@
 
        <div>{{ form.city.data if form.city.data else "".join(["<i>",_("Not specified"),"</i>"])|safe }}</div>
 
      </div>
 
      <div>
 
        <div>{% trans %}State/County/Province:{% endtrans %}</div>
 
        <div>{{ form.state.data if form.state.data else "".join(["<i>",_("Not specified"),"</i>"])|safe }}</div>
 
      </div>
 
      <div>
 
        <div>{% trans %}Country:{% endtrans %}</div>
 
        <div>{{ form.country.data if form.country.data else "".join(["<i>",_("Not specified"),"</i>"])|safe }}</div>
 
      </div>
 
      <div>
 
        <div>{% trans %}Membership Plan:{% endtrans%}</div>
 
        <div>{{ form.membership.data }}</div>
 
      </div>
 
      <div>
 
        <div>{% trans %}Student:{% endtrans %}</div>
 
        <div>{{ _("Yes") if form.student.data else _("No") }}</div>
 
      </div>
 
      <div>
 
        <div>{% trans %}Starving:{% endtrans %}</div>
 
        <div>{{ _("Yes") if form.starving.data else _("No") }}</div>
 
      </div>
 
      <div>
 
        <div>{% trans %}Payment:{% endtrans %}</div>
 
        <div>{{ form.payment.data }}</div>
 
        <div>{{ form.payment.data.lower() }}</div>
 
      </div>
 
      <div>
 
        <div>{% trans %}Agreed to Terms &amp; Conditions:{% endtrans %}</div>
 
        <div>{{ _("Yes") if form.terms.data else _("No") }}</div>
 
      </div>
 
      <div>
 
        <div>{% trans %}Minor Member:{% endtrans %}</div>
 
        <div>{{ _("Yes") if form.minor_member.data else _("No") }}</div>
 
      </div>
 
    </div>
 
    <p>{% trans %}Send this document to the Chaos Computer Club Lëtzebuerg!{% endtrans %}</p>
 
    {% if form.payment.data == 'wire transfer' %}
 
      <ul class="bank">
 
        <li>{% trans %}Account Holder:{% endtrans %} Chaos Computer Club Lëtzebuerg</li>
 
        <li>BIC/Swift: BCEELULLXXX</li>
 
        <li>IBAN: LU29 0019 2855 3890 4000</li>
 
        <li>{% trans %}Message:{% endtrans %} Membership fee {{ year }} {{ form.username.data }}</li>
 
        <li>{% trans %}Amount: {{ price }}€{% endtrans %}</li>
 
      </ul>
 
    {% elif form.payment.data == 'cash' %}
 
      <p>{% trans %}Please bring {{ price }}€ with you the next time you meet us!{% endtrans %}</p>
 
    {% elif form.payment.data in config["CRYPTOCURRENCIES"] %}
 
      <div class="cryptocontainer">
 
        <div>
 
          <ul class="cryptotext">
 
            <li><b>{% trans %}Address:{% endtrans %}</b> {{ config["CRYPTOCURRENCIES"][form.payment.data]["ADDRESS"] }}</li>
 
            <li><b>{% trans %}Label:{% endtrans %}</b> Membership Fee</li>
 
            <li><b>{% trans %}Message:{% endtrans %}</b> {{ year }} {{ form.username.data }}</li>
 
            <li><b>{% trans %}Amount:{% endtrans %}</b> {{ price }} {{ config["CRYPTOCURRENCIES"][form.payment.data]["COMMODITY"] }}</li>
 
          </ul>
 
        </div>
 
        {% set crypto_url=config["CRYPTOCURRENCIES"][form.payment.data]["URL"].format(amount=price, year=year, username=form.username.data) %}
 
        {% set address = config["CRYPTOCURRENCIES"][form.payment.data]["ADDRESS"] %}
 
        {% set crypto_url=config["CRYPTOCURRENCIES"][form.payment.data]["URL"].format(address=address, amount=price, year=year, username=form.username.data) %}
 
        <div><img class="cryptoqrcode" src="{{ qrcode(crypto_url) }}" /></div>
 
      </div>
 
    {% elif form.payment.data == 'digicash' %}
 
      <div class="digicash">
 
        {% set digicash_url='https://pos.digica.sh/qrcode/generator?merchantId=CHAOSPC1&amount={amount}&transactionReference=Membership_{username}'.format(amount=price, username=form.username.data) %}
 
        <div><p>{% trans %}Pay with digicash!{% endtrans %}</p></div>
 
        <div><img src="{{ digicash_url }}" /></div>
 
      </div>
 
    {% endif %}
 
    <div class="signature">
 
      <p class="membersignature">{% trans %}Luxembourg, the{% endtrans %}</p>
 
      <p class="adminsignature">
 
        {{ _("Signature of your legal representative") if form.minor_member.data else _("Your signature") }}
 
      </p>
 
    </div>
 
    <footer>
 
      <hr />
 
      <b>C</b>haos <b>C</b>omputer <b>C</b>lub <b>L</b>ëtzebuerg A.S.B.L.<br />
 
      Halle Victor Hugo - 60 Avenue Victor Hugo L-1750 Luxembourg (Europe)<br />
 
      info@c3l.lu - <a href="https://c3l.lu">http://c3l.lu</a>
 
    </footer>
 
  </body>
 
</html>
c3l_membership/views.py
Show inline comments
 
import re
 
import subprocess
 
from datetime import date
 

	
 
import requests
 
from flask import Blueprint, current_app, g, render_template, request
 
from flask_babel import gettext
 
from flask_weasyprint import HTML, render_pdf
 

	
 
from .forms import MembershipForm
 

	
 
root_page = Blueprint("root", __name__, url_prefix="/<lang_code>")
 

	
 
xml_template = "<member><numm>{name}</numm><gebuertsdag>{birthday:%d.%m.%Y}</gebuertsdag><address>{address}</address><nick>{username}</nick><email>{email}</email><status>{status}</status><stemmrecht>{voting}</stemmrecht></member>"
 

	
 

	
 
@root_page.url_defaults
 
def add_lang_code(endpoint, values):
 
    values.setdefault("lang_code", g.lang_code)
 

	
 

	
 
@root_page.url_value_preprocessor
 
def pull_lang_code(endpoint, values):
 
    lang_code = values.pop("lang_code")
 
    if lang_code != "favicon.ico":
 
        g.lang_code = lang_code
 

	
 

	
 
@root_page.route("/", methods=("GET", "POST"))
 
def index():
 
    form = MembershipForm()
 

	
 
    choices = [
 
        ("cash", gettext("by cash")),
 
        ("wire transfer", gettext("by wire transfer")),
 
    ]
 

	
 
    if current_app.config["DIGICASH_ENABLED"]:
 
        choices.append(("digicash", gettext("by DigiCash")))
 

	
 
    for cryptocurrency_label, options in current_app.config["CRYPTOCURRENCIES"].items():
 
        if options["ENABLED"]:
 
            choices.append(
 
                (
 
                    cryptocurrency_label,
 
                    " ".format((gettext("by"), options)),
 
                    " ".join((gettext("by"), cryptocurrency_label.title())),
 
                ),
 
            )
 

	
 
    form.payment.choices = choices
 

	
 
    if form.validate_on_submit():
 

	
 
        xml_data = {}
 

	
 
        if (
 
            form.minor_member.data
 
            or form.student.data
 
            or form.membership.data == "supporting"
 
        ):
 
            price = current_app.config["SUPPORTING_FEE"]
 
            xml_data["voting"] = 0
 
        elif form.membership.data == "regular":
 
            price = current_app.config["REGULAR_FEE"]
 
            xml_data["voting"] = 1
 

	
 
        if form.starving.data:
 
            price = 1
 
            xml_data["status"] = "Starving"
 
            status = "Starving"
 
        elif form.minor_member.data or form.student.data:
 
            xml_data["status"] = "Student"
 
            status = "Student"
 
        elif form.membership.data == "supporting":
 
            xml_data["status"] = "Supporter"
 
            status = "Supporter"
 
        else:
 
            xml_data["status"] = "Regular"
 
            status = "Regular"
 

	
 
        xml_data["status"] = status
 
        xml_data["name"] = form.fullname.data
 
        xml_data["birthday"] = (
 
            form.birthday.data if form.birthday.data is not None else date(9999, 12, 12)
 
        )
 
        xml_data["username"] = form.username.data
 
        xml_data["email"] = form.email.data
 
        xml_data["address"] = " ".join(
 
            (
 
                form.street.data,
 
                form.zip.data,
 
                form.city.data,
 
                form.state.data,
 
                form.country.data,
 
            )
 
        )
 
        xml_data["address"] = re.sub("\s+", " ", xml_data["address"])
 

	
 
        if form.payment.data in current_app.config["CRYPTOCURRENCIES"]:
 
            price = subprocess.run(
 
                [
 
                    current_app.config["CRYPTOCURRENCIES_CONVERSION_SCRIPT"],
 
                    str(price),
 
                    form.payment.data,
 
                ],
 
                capture_output=True,
 
                encoding="utf-8",
 
            ).stdout
 

	
 
            current_conversion_r = requests.get(
 
                current_app.config["CONVERSION_URL"], timeout=30
 
            )
 
            try:
 
                current_conversion_r.raise_for_status()
 
            except:
 
                return 500
 
            else:
 
                current_conversion = current_conversion_r.json()
 
                commodity = current_app.config["CRYPTOCURRENCIES"][form.payment.data][
 
                    "COMMODITY"
 
                ]
 
                price = current_conversion[commodity][status.upper()]
 
        elif form.payment.data == "digicash":
 
            price = price * 100
 

	
 
        now = date.today()
 
        year = now.year
 
        xml_data["date"] = now
 

	
 
        xml = xml_template.format(**xml_data)
 
        html = render_template(
 
            "member.html", form=form, price=price, year=year, xml=xml
 
        )
 
        return render_pdf(HTML(string=html))
 
    return render_template("index.html", form=form)
poetry.lock
Show inline comments
 
@@ -51,59 +51,78 @@ cffi = ">=1.1.0"
 
doc = ["sphinx", "sphinx-rtd-theme"]
 
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
 
xcb = ["xcffib (>=0.3.2)"]
 

	
 
[[package]]
 
name = "cairosvg"
 
version = "2.5.2"
 
description = "A Simple SVG Converter based on Cairo"
 
category = "main"
 
optional = false
 
python-versions = ">=3.5"
 

	
 
[package.dependencies]
 
cairocffi = "*"
 
cssselect2 = "*"
 
defusedxml = "*"
 
pillow = "*"
 
tinycss2 = "*"
 

	
 
[package.extras]
 
doc = ["sphinx", "sphinx-rtd-theme"]
 
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
 

	
 
[[package]]
 
name = "certifi"
 
version = "2021.10.8"
 
description = "Python package for providing Mozilla's CA Bundle."
 
category = "main"
 
optional = false
 
python-versions = "*"
 

	
 
[[package]]
 
name = "cffi"
 
version = "1.15.0"
 
description = "Foreign Function Interface for Python calling C code."
 
category = "main"
 
optional = false
 
python-versions = "*"
 

	
 
[package.dependencies]
 
pycparser = "*"
 

	
 
[[package]]
 
name = "charset-normalizer"
 
version = "2.0.10"
 
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
 
category = "main"
 
optional = false
 
python-versions = ">=3.5.0"
 

	
 
[package.extras]
 
unicode_backport = ["unicodedata2"]
 

	
 
[[package]]
 
name = "click"
 
version = "8.0.3"
 
description = "Composable command line interface toolkit"
 
category = "main"
 
optional = false
 
python-versions = ">=3.6"
 

	
 
[package.dependencies]
 
colorama = {version = "*", markers = "platform_system == \"Windows\""}
 
importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
 

	
 
[[package]]
 
name = "colorama"
 
version = "0.4.4"
 
description = "Cross-platform colored terminal text."
 
category = "main"
 
optional = false
 
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 

	
 
[[package]]
 
name = "cssselect2"
 
version = "0.4.1"
 
description = "cssselect2"
 
category = "main"
 
@@ -407,95 +426,126 @@ version = "2021.3"
 
description = "World timezone definitions, modern and historical"
 
category = "main"
 
optional = false
 
python-versions = "*"
 

	
 
[[package]]
 
name = "qrcode"
 
version = "7.3.1"
 
description = "QR Code image generator"
 
category = "main"
 
optional = false
 
python-versions = ">=3.6"
 

	
 
[package.dependencies]
 
colorama = {version = "*", markers = "platform_system == \"Windows\""}
 

	
 
[package.extras]
 
all = ["zest.releaser", "tox", "pytest", "pytest", "pytest-cov", "pillow"]
 
dev = ["tox", "pytest"]
 
maintainer = ["zest.releaser"]
 
pil = ["pillow"]
 
test = ["pytest", "pytest-cov"]
 

	
 
[[package]]
 
name = "requests"
 
version = "2.27.1"
 
description = "Python HTTP for Humans."
 
category = "main"
 
optional = false
 
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
 

	
 
[package.dependencies]
 
certifi = ">=2017.4.17"
 
charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
 
idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
 
urllib3 = ">=1.21.1,<1.27"
 

	
 
[package.extras]
 
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
 
use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
 

	
 
[[package]]
 
name = "six"
 
version = "1.16.0"
 
description = "Python 2 and 3 compatibility utilities"
 
category = "main"
 
optional = false
 
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
 

	
 
[[package]]
 
name = "tinycss2"
 
version = "1.1.1"
 
description = "A tiny CSS parser"
 
category = "main"
 
optional = false
 
python-versions = ">=3.6"
 

	
 
[package.dependencies]
 
webencodings = ">=0.4"
 

	
 
[package.extras]
 
doc = ["sphinx", "sphinx-rtd-theme"]
 
test = ["pytest", "pytest-cov", "pytest-flake8", "pytest-isort", "coverage"]
 

	
 
[[package]]
 
name = "tomli"
 
version = "1.2.3"
 
description = "A lil' TOML parser"
 
category = "dev"
 
optional = false
 
python-versions = ">=3.6"
 

	
 
[[package]]
 
name = "typed-ast"
 
version = "1.5.1"
 
description = "a fork of Python 2 and 3 ast modules with type comment support"
 
category = "dev"
 
optional = false
 
python-versions = ">=3.6"
 

	
 
[[package]]
 
name = "typing-extensions"
 
version = "4.0.1"
 
description = "Backported and Experimental Type Hints for Python 3.6+"
 
category = "main"
 
optional = false
 
python-versions = ">=3.6"
 

	
 
[[package]]
 
name = "urllib3"
 
version = "1.26.8"
 
description = "HTTP library with thread-safe connection pooling, file post, and more."
 
category = "main"
 
optional = false
 
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
 

	
 
[package.extras]
 
brotli = ["brotlipy (>=0.6.0)"]
 
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
 
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
 

	
 
[[package]]
 
name = "weasyprint"
 
version = "52.5"
 
description = "The Awesome Document Factory"
 
category = "main"
 
optional = false
 
python-versions = ">=3.6"
 

	
 
[package.dependencies]
 
cairocffi = ">=0.9.0"
 
CairoSVG = ">=2.4.0"
 
cffi = ">=0.6"
 
cssselect2 = ">=0.1"
 
html5lib = ">=0.999999999"
 
Pillow = ">=4.0.0"
 
Pyphen = ">=0.9.1"
 
tinycss2 = ">=1.0.0"
 

	
 
[package.extras]
 
doc = ["sphinx", "sphinx-rtd-theme"]
 
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
 

	
 
[[package]]
 
name = "webencodings"
 
version = "0.5.1"
 
@@ -523,66 +573,70 @@ category = "main"
 
optional = false
 
python-versions = ">=3.7"
 

	
 
[package.dependencies]
 
MarkupSafe = "*"
 

	
 
[package.extras]
 
email = ["email-validator"]
 

	
 
[[package]]
 
name = "zipp"
 
version = "3.6.0"
 
description = "Backport of pathlib-compatible object wrapper for zip files"
 
category = "main"
 
optional = false
 
python-versions = ">=3.6"
 

	
 
[package.extras]
 
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
 
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
 

	
 
[metadata]
 
lock-version = "1.1"
 
python-versions = ">=3.7.0,<4"
 
content-hash = "e6337b7e5ae01abe852dbd202497fef50c09546e0a0f98f26b3ee81beb262237"
 
content-hash = "09986a21dfa3c1e41f48db17b04f4f3bade80e86642fecd895ad3df4b9cf061e"
 

	
 
[metadata.files]
 
babel = [
 
    {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"},
 
    {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"},
 
]
 
black = [
 
    {file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"},
 
    {file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"},
 
]
 
cairocffi = [
 
    {file = "cairocffi-1.3.0.tar.gz", hash = "sha256:108a3a7cb09e203bdd8501d9baad91d786d204561bd71e9364e8b34897c47b91"},
 
]
 
cairosvg = [
 
    {file = "CairoSVG-2.5.2-py3-none-any.whl", hash = "sha256:98c276b7e4f0caf01e5c7176765c104ffa1aa1461d63b2053b04ab663cf7052b"},
 
    {file = "CairoSVG-2.5.2.tar.gz", hash = "sha256:b0b9929cf5dba005178d746a8036fcf0025550f498ca54db61873322384783bc"},
 
]
 
certifi = [
 
    {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"},
 
    {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"},
 
]
 
cffi = [
 
    {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"},
 
    {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"},
 
    {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"},
 
    {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"},
 
    {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"},
 
    {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"},
 
    {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"},
 
    {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"},
 
    {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"},
 
    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"},
 
    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"},
 
    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"},
 
    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"},
 
    {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"},
 
    {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"},
 
    {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"},
 
    {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"},
 
    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"},
 
    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"},
 
    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"},
 
    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"},
 
    {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"},
 
    {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"},
 
@@ -593,48 +647,52 @@ cffi = [
 
    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"},
 
    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"},
 
    {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"},
 
    {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"},
 
    {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"},
 
    {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"},
 
    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"},
 
    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"},
 
    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"},
 
    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"},
 
    {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"},
 
    {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"},
 
    {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"},
 
    {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"},
 
    {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"},
 
    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"},
 
    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"},
 
    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"},
 
    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"},
 
    {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"},
 
    {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"},
 
    {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"},
 
    {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"},
 
]
 
charset-normalizer = [
 
    {file = "charset-normalizer-2.0.10.tar.gz", hash = "sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd"},
 
    {file = "charset_normalizer-2.0.10-py3-none-any.whl", hash = "sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"},
 
]
 
click = [
 
    {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"},
 
    {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"},
 
]
 
colorama = [
 
    {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
 
    {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
 
]
 
cssselect2 = [
 
    {file = "cssselect2-0.4.1-py3-none-any.whl", hash = "sha256:2f4a9f20965367bae459e3bb42561f7927e0cfe5b7ea1692757cf67ef5d7dace"},
 
    {file = "cssselect2-0.4.1.tar.gz", hash = "sha256:93fbb9af860e95dd40bf18c3b2b6ed99189a07c0f29ba76f9c5be71344664ec8"},
 
]
 
defusedxml = [
 
    {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
 
    {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
 
]
 
djhtml = [
 
    {file = "djhtml-1.4.11.tar.gz", hash = "sha256:1b0b3d7c4d7207ec729d4720b3b5aa632d220bbee8df2f711d17457a2ce1ebc9"},
 
]
 
dnspython = [
 
    {file = "dnspython-2.1.0-py3-none-any.whl", hash = "sha256:95d12f6ef0317118d2a1a6fc49aac65ffec7eb8087474158f42f26a639135216"},
 
    {file = "dnspython-2.1.0.zip", hash = "sha256:e4a87f0b573201a0f3727fa18a516b055fd1107e0e5477cded4a2de497df1dd4"},
 
]
 
email-validator = [
 
@@ -826,81 +884,89 @@ pillow = [
 
    {file = "Pillow-8.4.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4901622493f88b1a29bd30ec1a2f683782e57c3c16a2dbc7f2595ba01f639df"},
 
    {file = "Pillow-8.4.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c471a734240653a0ec91dec0996696eea227eafe72a33bd06c92697728046b"},
 
    {file = "Pillow-8.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc"},
 
    {file = "Pillow-8.4.0.tar.gz", hash = "sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed"},
 
]
 
platformdirs = [
 
    {file = "platformdirs-2.4.1-py3-none-any.whl", hash = "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca"},
 
    {file = "platformdirs-2.4.1.tar.gz", hash = "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"},
 
]
 
pycparser = [
 
    {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
 
    {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
 
]
 
pyphen = [
 
    {file = "pyphen-0.12.0-py3-none-any.whl", hash = "sha256:459020cd320eb200c0c5ba46b98b2278fd34c5546f520fdcd2ce5f8d733eb994"},
 
    {file = "pyphen-0.12.0.tar.gz", hash = "sha256:b7d3dfc24b6f2178cdb2b1757ace0bd5d222de3e62c28d22ac578c5f22a13e9b"},
 
]
 
pytz = [
 
    {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
 
    {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
 
]
 
qrcode = [
 
    {file = "qrcode-7.3.1.tar.gz", hash = "sha256:375a6ff240ca9bd41adc070428b5dfc1dcfbb0f2507f1ac848f6cded38956578"},
 
]
 
requests = [
 
    {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
 
    {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
 
]
 
six = [
 
    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
 
    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
 
]
 
tinycss2 = [
 
    {file = "tinycss2-1.1.1-py3-none-any.whl", hash = "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8"},
 
    {file = "tinycss2-1.1.1.tar.gz", hash = "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf"},
 
]
 
tomli = [
 
    {file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"},
 
    {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"},
 
]
 
typed-ast = [
 
    {file = "typed_ast-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d8314c92414ce7481eee7ad42b353943679cf6f30237b5ecbf7d835519e1212"},
 
    {file = "typed_ast-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b53ae5de5500529c76225d18eeb060efbcec90ad5e030713fe8dab0fb4531631"},
 
    {file = "typed_ast-1.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:24058827d8f5d633f97223f5148a7d22628099a3d2efe06654ce872f46f07cdb"},
 
    {file = "typed_ast-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a6d495c1ef572519a7bac9534dbf6d94c40e5b6a608ef41136133377bba4aa08"},
 
    {file = "typed_ast-1.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:de4ecae89c7d8b56169473e08f6bfd2df7f95015591f43126e4ea7865928677e"},
 
    {file = "typed_ast-1.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:256115a5bc7ea9e665c6314ed6671ee2c08ca380f9d5f130bd4d2c1f5848d695"},
 
    {file = "typed_ast-1.5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7c42707ab981b6cf4b73490c16e9d17fcd5227039720ca14abe415d39a173a30"},
 
    {file = "typed_ast-1.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:71dcda943a471d826ea930dd449ac7e76db7be778fcd722deb63642bab32ea3f"},
 
    {file = "typed_ast-1.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4f30a2bcd8e68adbb791ce1567fdb897357506f7ea6716f6bbdd3053ac4d9471"},
 
    {file = "typed_ast-1.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ca9e8300d8ba0b66d140820cf463438c8e7b4cdc6fd710c059bfcfb1531d03fb"},
 
    {file = "typed_ast-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9caaf2b440efb39ecbc45e2fabde809cbe56272719131a6318fd9bf08b58e2cb"},
 
    {file = "typed_ast-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c9bcad65d66d594bffab8575f39420fe0ee96f66e23c4d927ebb4e24354ec1af"},
 
    {file = "typed_ast-1.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:591bc04e507595887160ed7aa8d6785867fb86c5793911be79ccede61ae96f4d"},
 
    {file = "typed_ast-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:a80d84f535642420dd17e16ae25bb46c7f4c16ee231105e7f3eb43976a89670a"},
 
    {file = "typed_ast-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:38cf5c642fa808300bae1281460d4f9b7617cf864d4e383054a5ef336e344d32"},
 
    {file = "typed_ast-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b6ab14c56bc9c7e3c30228a0a0b54b915b1579613f6e463ba6f4eb1382e7fd4"},
 
    {file = "typed_ast-1.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2b8d7007f6280e36fa42652df47087ac7b0a7d7f09f9468f07792ba646aac2d"},
 
    {file = "typed_ast-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:b6d17f37f6edd879141e64a5db17b67488cfeffeedad8c5cec0392305e9bc775"},
 
    {file = "typed_ast-1.5.1.tar.gz", hash = "sha256:484137cab8ecf47e137260daa20bafbba5f4e3ec7fda1c1e69ab299b75fa81c5"},
 
]
 
typing-extensions = [
 
    {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"},
 
    {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"},
 
]
 
urllib3 = [
 
    {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"},
 
    {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"},
 
]
 
weasyprint = [
 
    {file = "WeasyPrint-52.5-py3-none-any.whl", hash = "sha256:3433d657049a65d7d63f545fd71f5efa8aae7f05d24e49e01a757973fd3799f1"},
 
    {file = "WeasyPrint-52.5.tar.gz", hash = "sha256:b37ea02d75ca04babd7becad7341426be332ae560d8f02d664bfa1e9afb18481"},
 
]
 
webencodings = [
 
    {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
 
    {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
 
]
 
werkzeug = [
 
    {file = "Werkzeug-2.0.2-py3-none-any.whl", hash = "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f"},
 
    {file = "Werkzeug-2.0.2.tar.gz", hash = "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a"},
 
]
 
wtforms = [
 
    {file = "WTForms-3.0.1-py3-none-any.whl", hash = "sha256:837f2f0e0ca79481b92884962b914eba4e72b7a2daaf1f939c890ed0124b834b"},
 
    {file = "WTForms-3.0.1.tar.gz", hash = "sha256:6b351bbb12dd58af57ffef05bc78425d08d1914e0fd68ee14143b7ade023c5bc"},
 
]
 
zipp = [
 
    {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"},
 
    {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"},
 
]
pyproject.toml
Show inline comments
 
[tool.poetry]
 
name = "c3l-membership"
 
version = "1.1.1"
 
description = ""
 
authors = ["Dennis Fink <dennis.fink@c3l.lu>"]
 
license = "GPL-3.0-or-later"
 
include = ["c3l_membership/static/*", "c3l_membership/template/*", "c3l_membership/translations/*"]
 

	
 
[tool.poetry.dependencies]
 
python = ">=3.7.0,<4"
 
Flask = "^2.0.2"
 
Flask-QRcode = "^3.0.0"
 
Flask-WeasyPrint = "^0.6"
 
Flask-WTF = "^1.0.0"
 
email-validator = "^1.1.3"
 
WTForms="^3.0.1"
 
WeasyPrint="52.5"
 
djhtml = "^1.4.11"
 
Flask-Babel = "^2.0.0"
 
requests = "^2.27.1"
 

	
 
[tool.poetry.dev-dependencies]
 
black = "^21.12b0"
 
mypy = "^0.930"
 
isort = "^5.10.1"
 

	
 

	
 
[build-system]
 
requires = ["poetry-core>=1.0.0"]
 
build-backend = "poetry.core.masonry.api"
0 comments (0 inline, 0 general)