Soooo many changes

This commit is contained in:
Felix Breidenstein 2021-04-12 22:53:01 +02:00
parent e88acbeb13
commit 0c61ee7e71
9 changed files with 420 additions and 55 deletions

287
poetry.lock generated
View file

@ -20,6 +20,52 @@ docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
[[package]]
name = "cairocffi"
version = "1.2.0"
description = "cffi-based cairo bindings for Python"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
cffi = ">=1.1.0"
[package.extras]
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 = "cffi"
version = "1.14.5"
description = "Foreign Function Interface for Python calling C code."
category = "main"
optional = false
python-versions = "*"
[package.dependencies]
pycparser = "*"
[[package]] [[package]]
name = "click" name = "click"
version = "7.1.2" version = "7.1.2"
@ -47,6 +93,30 @@ python-versions = "*"
[package.dependencies] [package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""} colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "cssselect2"
version = "0.4.1"
description = "cssselect2"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
tinycss2 = "*"
webencodings = "*"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
test = ["pytest", "pytest-cov", "pytest-flake8", "pytest-isort", "coverage"]
[[package]]
name = "defusedxml"
version = "0.7.1"
description = "XML bomb protection for Python stdlib modules"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]] [[package]]
name = "flask" name = "flask"
version = "1.1.2" version = "1.1.2"
@ -66,6 +136,24 @@ dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinxco
docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"]
dotenv = ["python-dotenv"] dotenv = ["python-dotenv"]
[[package]]
name = "html5lib"
version = "1.1"
description = "HTML parser based on the WHATWG HTML specification"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.dependencies]
six = ">=1.9"
webencodings = "*"
[package.extras]
all = ["genshi", "chardet (>=2.2)", "lxml"]
chardet = ["chardet (>=2.2)"]
genshi = ["genshi"]
lxml = ["lxml"]
[[package]] [[package]]
name = "importlib-metadata" name = "importlib-metadata"
version = "2.0.0" version = "2.0.0"
@ -151,6 +239,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
pyparsing = ">=2.0.2" pyparsing = ">=2.0.2"
six = "*" six = "*"
[[package]]
name = "pillow"
version = "8.2.0"
description = "Python Imaging Library (Fork)"
category = "main"
optional = false
python-versions = ">=3.6"
[[package]] [[package]]
name = "pluggy" name = "pluggy"
version = "0.13.1" version = "0.13.1"
@ -192,6 +288,14 @@ category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "pycparser"
version = "2.20"
description = "C parser in Python"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]] [[package]]
name = "pyparsing" name = "pyparsing"
version = "2.4.7" version = "2.4.7"
@ -200,6 +304,14 @@ category = "main"
optional = false optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
[[package]]
name = "pyphen"
version = "0.10.0"
description = "Pure Python module to hyphenate text"
category = "main"
optional = false
python-versions = "*"
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "6.1.2" version = "6.1.2"
@ -223,6 +335,17 @@ toml = "*"
checkqa_mypy = ["mypy (==0.780)"] checkqa_mypy = ["mypy (==0.780)"]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
[[package]]
name = "python-dateutil"
version = "2.8.1"
description = "Extensions to the standard Python datetime module"
category = "main"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
[package.dependencies]
six = ">=1.5"
[[package]] [[package]]
name = "pyyaml" name = "pyyaml"
version = "5.3.1" version = "5.3.1"
@ -271,6 +394,21 @@ postgresql_psycopg2binary = ["psycopg2-binary"]
postgresql_psycopg2cffi = ["psycopg2cffi"] postgresql_psycopg2cffi = ["psycopg2cffi"]
pymysql = ["pymysql"] pymysql = ["pymysql"]
[[package]]
name = "tinycss2"
version = "1.1.0"
description = "tinycss2"
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]] [[package]]
name = "toml" name = "toml"
version = "0.10.1" version = "0.10.1"
@ -287,6 +425,36 @@ category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "weasyprint"
version = "52.4"
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"
description = "Character encoding aliases for legacy web content"
category = "main"
optional = false
python-versions = "*"
[[package]] [[package]]
name = "werkzeug" name = "werkzeug"
version = "1.0.1" version = "1.0.1"
@ -322,7 +490,7 @@ testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.6.1" python-versions = "^3.6.1"
content-hash = "c4cb6fe1f4dd6ad3b6c732daba2c2492fd267b18add95471b0e3251724c934d1" content-hash = "05801cd5e8b55510bd46861fd13f119c0269d3b343e22aa86c261eca50455d09"
[metadata.files] [metadata.files]
atomicwrites = [ atomicwrites = [
@ -333,6 +501,52 @@ attrs = [
{file = "attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"}, {file = "attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"},
{file = "attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"}, {file = "attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"},
] ]
cairocffi = [
{file = "cairocffi-1.2.0.tar.gz", hash = "sha256:9a979b500c64c8179fec286f337e8fe644eca2f2cd05860ce0b62d25f22ea140"},
]
cairosvg = [
{file = "CairoSVG-2.5.2-py3-none-any.whl", hash = "sha256:98c276b7e4f0caf01e5c7176765c104ffa1aa1461d63b2053b04ab663cf7052b"},
{file = "CairoSVG-2.5.2.tar.gz", hash = "sha256:b0b9929cf5dba005178d746a8036fcf0025550f498ca54db61873322384783bc"},
]
cffi = [
{file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"},
{file = "cffi-1.14.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1"},
{file = "cffi-1.14.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa"},
{file = "cffi-1.14.5-cp27-cp27m-win32.whl", hash = "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3"},
{file = "cffi-1.14.5-cp27-cp27m-win_amd64.whl", hash = "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5"},
{file = "cffi-1.14.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482"},
{file = "cffi-1.14.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6"},
{file = "cffi-1.14.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045"},
{file = "cffi-1.14.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa"},
{file = "cffi-1.14.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406"},
{file = "cffi-1.14.5-cp35-cp35m-win32.whl", hash = "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369"},
{file = "cffi-1.14.5-cp35-cp35m-win_amd64.whl", hash = "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315"},
{file = "cffi-1.14.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892"},
{file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"},
{file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"},
{file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"},
{file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"},
{file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"},
{file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"},
{file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"},
{file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"},
{file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"},
{file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"},
{file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"},
{file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"},
{file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"},
{file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"},
{file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"},
{file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"},
{file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"},
{file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"},
{file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"},
{file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"},
{file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"},
{file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"},
{file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"},
{file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"},
]
click = [ click = [
{file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
{file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
@ -345,10 +559,22 @@ colorful = [
{file = "colorful-0.5.4-py2.py3-none-any.whl", hash = "sha256:8d264b52a39aae4c0ba3e2a46afbaec81b0559a99be0d2cfe2aba4cf94531348"}, {file = "colorful-0.5.4-py2.py3-none-any.whl", hash = "sha256:8d264b52a39aae4c0ba3e2a46afbaec81b0559a99be0d2cfe2aba4cf94531348"},
{file = "colorful-0.5.4.tar.gz", hash = "sha256:86848ad4e2eda60cd2519d8698945d22f6f6551e23e95f3f14dfbb60997807ea"}, {file = "colorful-0.5.4.tar.gz", hash = "sha256:86848ad4e2eda60cd2519d8698945d22f6f6551e23e95f3f14dfbb60997807ea"},
] ]
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"},
]
flask = [ flask = [
{file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"}, {file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"},
{file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"}, {file = "Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"},
] ]
html5lib = [
{file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"},
{file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"},
]
importlib-metadata = [ importlib-metadata = [
{file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"}, {file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"},
{file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"}, {file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"},
@ -412,6 +638,41 @@ packaging = [
{file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"},
{file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"},
] ]
pillow = [
{file = "Pillow-8.2.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:dc38f57d8f20f06dd7c3161c59ca2c86893632623f33a42d592f097b00f720a9"},
{file = "Pillow-8.2.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a013cbe25d20c2e0c4e85a9daf438f85121a4d0344ddc76e33fd7e3965d9af4b"},
{file = "Pillow-8.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8bb1e155a74e1bfbacd84555ea62fa21c58e0b4e7e6b20e4447b8d07990ac78b"},
{file = "Pillow-8.2.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c5236606e8570542ed424849f7852a0ff0bce2c4c8d0ba05cc202a5a9c97dee9"},
{file = "Pillow-8.2.0-cp36-cp36m-win32.whl", hash = "sha256:12e5e7471f9b637762453da74e390e56cc43e486a88289995c1f4c1dc0bfe727"},
{file = "Pillow-8.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5afe6b237a0b81bd54b53f835a153770802f164c5570bab5e005aad693dab87f"},
{file = "Pillow-8.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:cb7a09e173903541fa888ba010c345893cd9fc1b5891aaf060f6ca77b6a3722d"},
{file = "Pillow-8.2.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0d19d70ee7c2ba97631bae1e7d4725cdb2ecf238178096e8c82ee481e189168a"},
{file = "Pillow-8.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:083781abd261bdabf090ad07bb69f8f5599943ddb539d64497ed021b2a67e5a9"},
{file = "Pillow-8.2.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:c6b39294464b03457f9064e98c124e09008b35a62e3189d3513e5148611c9388"},
{file = "Pillow-8.2.0-cp37-cp37m-win32.whl", hash = "sha256:01425106e4e8cee195a411f729cff2a7d61813b0b11737c12bd5991f5f14bcd5"},
{file = "Pillow-8.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3b570f84a6161cf8865c4e08adf629441f56e32f180f7aa4ccbd2e0a5a02cba2"},
{file = "Pillow-8.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:031a6c88c77d08aab84fecc05c3cde8414cd6f8406f4d2b16fed1e97634cc8a4"},
{file = "Pillow-8.2.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:66cc56579fd91f517290ab02c51e3a80f581aba45fd924fcdee01fa06e635812"},
{file = "Pillow-8.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c32cc3145928c4305d142ebec682419a6c0a8ce9e33db900027ddca1ec39178"},
{file = "Pillow-8.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:624b977355cde8b065f6d51b98497d6cd5fbdd4f36405f7a8790e3376125e2bb"},
{file = "Pillow-8.2.0-cp38-cp38-win32.whl", hash = "sha256:5cbf3e3b1014dddc45496e8cf38b9f099c95a326275885199f427825c6522232"},
{file = "Pillow-8.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:463822e2f0d81459e113372a168f2ff59723e78528f91f0bd25680ac185cf797"},
{file = "Pillow-8.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:95d5ef984eff897850f3a83883363da64aae1000e79cb3c321915468e8c6add5"},
{file = "Pillow-8.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b91c36492a4bbb1ee855b7d16fe51379e5f96b85692dc8210831fbb24c43e484"},
{file = "Pillow-8.2.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d68cb92c408261f806b15923834203f024110a2e2872ecb0bd2a110f89d3c602"},
{file = "Pillow-8.2.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f217c3954ce5fd88303fc0c317af55d5e0204106d86dea17eb8205700d47dec2"},
{file = "Pillow-8.2.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5b70110acb39f3aff6b74cf09bb4169b167e2660dabc304c1e25b6555fa781ef"},
{file = "Pillow-8.2.0-cp39-cp39-win32.whl", hash = "sha256:a7d5e9fad90eff8f6f6106d3b98b553a88b6f976e51fce287192a5d2d5363713"},
{file = "Pillow-8.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:238c197fc275b475e87c1453b05b467d2d02c2915fdfdd4af126145ff2e4610c"},
{file = "Pillow-8.2.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:0e04d61f0064b545b989126197930807c86bcbd4534d39168f4aa5fda39bb8f9"},
{file = "Pillow-8.2.0-pp36-pypy36_pp73-manylinux2010_i686.whl", hash = "sha256:63728564c1410d99e6d1ae8e3b810fe012bc440952168af0a2877e8ff5ab96b9"},
{file = "Pillow-8.2.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:c03c07ed32c5324939b19e36ae5f75c660c81461e312a41aea30acdd46f93a7c"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:4d98abdd6b1e3bf1a1cbb14c3895226816e666749ac040c4e2554231068c639b"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_i686.whl", hash = "sha256:aac00e4bc94d1b7813fe882c28990c1bc2f9d0e1aa765a5f2b516e8a6a16a9e4"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:22fd0f42ad15dfdde6c581347eaa4adb9a6fc4b865f90b23378aa7914895e120"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:e98eca29a05913e82177b3ba3d198b1728e164869c613d76d0de4bde6768a50e"},
{file = "Pillow-8.2.0.tar.gz", hash = "sha256:a787ab10d7bb5494e5f76536ac460741788f1fbce851068d73a87ca7c35fc3e1"},
]
pluggy = [ pluggy = [
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
@ -427,14 +688,26 @@ py = [
pycountry = [ pycountry = [
{file = "pycountry-20.7.3.tar.gz", hash = "sha256:81084a53d3454344c0292deebc20fcd0a1488c136d4900312cbd465cf552cb42"}, {file = "pycountry-20.7.3.tar.gz", hash = "sha256:81084a53d3454344c0292deebc20fcd0a1488c136d4900312cbd465cf552cb42"},
] ]
pycparser = [
{file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
]
pyparsing = [ pyparsing = [
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
] ]
pyphen = [
{file = "Pyphen-0.10.0-py3-none-any.whl", hash = "sha256:624b036eafe6f38fad3e79ee676ec711a8ce634feb9f34ac615bbaf73e662111"},
{file = "Pyphen-0.10.0.tar.gz", hash = "sha256:719b21dfb4b04fbc11cc0f6112418535fe35474021120cccfffc43a25fe63128"},
]
pytest = [ pytest = [
{file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"}, {file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"},
{file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"}, {file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"},
] ]
python-dateutil = [
{file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
]
pyyaml = [ pyyaml = [
{file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"},
{file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"},
@ -496,6 +769,10 @@ sqlalchemy = [
{file = "SQLAlchemy-1.3.20-cp39-cp39-win_amd64.whl", hash = "sha256:d05cef4a164b44ffda58200efcb22355350979e000828479971ebca49b82ddb1"}, {file = "SQLAlchemy-1.3.20-cp39-cp39-win_amd64.whl", hash = "sha256:d05cef4a164b44ffda58200efcb22355350979e000828479971ebca49b82ddb1"},
{file = "SQLAlchemy-1.3.20.tar.gz", hash = "sha256:d2f25c7f410338d31666d7ddedfa67570900e248b940d186b48461bd4e5569a1"}, {file = "SQLAlchemy-1.3.20.tar.gz", hash = "sha256:d2f25c7f410338d31666d7ddedfa67570900e248b940d186b48461bd4e5569a1"},
] ]
tinycss2 = [
{file = "tinycss2-1.1.0-py3-none-any.whl", hash = "sha256:0353b5234bcaee7b1ac7ca3dea7e02cd338a9f8dcbb8f2dcd32a5795ec1e5f9a"},
{file = "tinycss2-1.1.0.tar.gz", hash = "sha256:fbdcac3044d60eb85fdb2aa840ece43cf7dbe798e373e6ee0be545d4d134e18a"},
]
toml = [ toml = [
{file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"},
{file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"},
@ -504,6 +781,14 @@ wcwidth = [
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
] ]
weasyprint = [
{file = "WeasyPrint-52.4-py3-none-any.whl", hash = "sha256:cec6747baac7bd4638cc10e6fab6052b58c4d33b54100022a94e0559218c6cb3"},
{file = "WeasyPrint-52.4.tar.gz", hash = "sha256:8b648d35b1e828ce321078fe593ef9267c35280242fd8f673c91f48e417a4a5f"},
]
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 = [ werkzeug = [
{file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"},
{file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"},

View file

@ -16,6 +16,8 @@ colorful = "^0.5.4"
schwifty = "^2020.9.0" schwifty = "^2020.9.0"
prompt-toolkit = "^3.0.8" prompt-toolkit = "^3.0.8"
pytest = "^6.1.2" pytest = "^6.1.2"
python-dateutil = "^2.8.1"
WeasyPrint = "^52.4"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]

View file

@ -46,7 +46,6 @@ def command(profile, dry_run, verbose):
def apply_rules(t, rules): def apply_rules(t, rules):
tags = []
for r in rules: for r in rules:
iban = r.get("iban") iban = r.get("iban")
name_regex = r.get("name") name_regex = r.get("name")
@ -64,6 +63,5 @@ def apply_rules(t, rules):
if not re.search(desc_regex, t.description): if not re.search(desc_regex, t.description):
continue continue
tags.extend(r["tags"].split(",")) # return as soon as we found the first matching rule
return [x.strip() for x in r["tags"].split(",")]
return tags

View file

@ -5,7 +5,7 @@ import sys
from pathlib import Path from pathlib import Path
from schmeckels import importer, serve, autosort, validate, info, sort, models # ,report from schmeckels import importer, serve, autosort, validate, info, sort, models, report
from schmeckels.helper import build_database_filename, create_dirs, build_rules_filename from schmeckels.helper import build_database_filename, create_dirs, build_rules_filename
from sqlalchemy import create_engine from sqlalchemy import create_engine
@ -49,5 +49,5 @@ def main():
cli.add_command(autosort.command) cli.add_command(autosort.command)
cli.add_command(validate.command) cli.add_command(validate.command)
cli.add_command(info.command) cli.add_command(info.command)
# cli.add_command(report.command) cli.add_command(report.command)
cli() cli()

View file

@ -20,9 +20,19 @@ CONFIG_DIR = os.path.join(XDG_CONFIG_HOME, "schmeckels")
DATA_DIR = os.path.join(XDG_DATA_HOME, "schmeckels") DATA_DIR = os.path.join(XDG_DATA_HOME, "schmeckels")
def format_amount(cents): def format_amount(d):
amount = cents / 100 if type(d) is dict:
return f"{amount:,.2f}" for k,v in d.items():
amount = v / 100
d[k] = f"{amount:,.2f}"
return d
elif type(d) is int:
amount = d / 100
return f"{amount:,.2f}"
else:
print(d)
raise Exception()
def create_dirs(): def create_dirs():
@ -89,7 +99,6 @@ def get_rules(profile_name):
def create_tag(name, profile, session): def create_tag(name, profile, session):
t = session.query(models.Tag).filter(models.Tag.name == name).first() t = session.query(models.Tag).filter(models.Tag.name == name).first()
if not t: if not t:
print(name)
t = models.Tag(name=name) t = models.Tag(name=name)
session.add(t) session.add(t)
session.commit() session.commit()

View file

@ -1,13 +1,14 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
from schmeckels.models import Category, Transaction from schmeckels.models import Tag, Transaction
from schmeckels.helper import get_session from schmeckels.helper import get_session, format_amount
import sys import sys
import click import click
from bottle import template from jinja2 import Environment, FileSystemLoader
from sqlalchemy import func, and_
from weasyprint import HTML
from sqlalchemy import func from sqlalchemy import func
from weasyprint import HTML from weasyprint import HTML
from datetime import date from datetime import date
from helper import format_amount
from pprint import pprint from pprint import pprint
@ -16,23 +17,43 @@ from pprint import pprint
@click.option("--year", "-y") @click.option("--year", "-y")
def command(profile, year): def command(profile, year):
if not year: if not year:
year = date.today().year year = date.today().year()
start_date = date(day=1, month=1, year=int(year))
end_date = date(day=1, month=12, year=int(year))
# Get a list of all tags
session = get_session(profile) session = get_session(profile)
main_categories = session.query(Category).filter(Category.parent_id == None).all() tags = session.query(Tag).filter_by(reporting=True).all()
data = {"Einnahmen": {}, "Ausgaben": {}}
data = {} for tag in tags:
name = tag.name.split(":")[1]
tag_sum = (
session.query(func.sum(Transaction.amount))
.filter(and_(Transaction.date >= start_date, Transaction.date <= end_date))
.filter(Transaction.tags.any(id=tag.id))
.first()[0]
)
for mc in main_categories: if tag_sum:
data[mc.name] = {} if float(tag_sum) > 0:
sub_categories = session.query(Category).filter(Category.parent_id == mc.id).all() data["Einnahmen"][name] = format_amount(tag_sum)
for sc in sub_categories: else:
transactions = session.query(Transaction).filter(Transaction.category_id == sc.id).all() data["Ausgaben"][name] = format_amount(tag_sum)
data[mc.name][sc.name] = format_amount(sum([x.amount for x in transactions]))
context = {"year": year, "data": data} pprint(data)
context = {
"year": year,
"tags": data,
"sum_in": sum([float(v) for k, v in data["Einnahmen"].items()]),
"sum_out": sum([float(v) for k, v in data["Ausgaben"].items()]),
}
context["diff"] = context["sum_in"] + context["sum_out"]
tpl = template("views/report.tpl", context)
filename = "output/report_{}_{}.pdf".format(profile, year) filename = "output/report_{}_{}.pdf".format(profile, year)
HTML(string=tpl).write_pdf(filename) env = Environment(loader=FileSystemLoader("schmeckels/templates/"))
template = env.get_template("report.tpl")
html_out = template.render(context)
HTML(string=html_out).write_pdf(filename)
print("Report saved to {}".format(filename)) print("Report saved to {}".format(filename))

View file

@ -1,9 +1,11 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
from flask import Flask, render_template, request, redirect, flash from flask import Flask, render_template, request, redirect, flash
from schmeckels.helper import get_session, format_amount from schmeckels.helper import get_session, format_amount
from datetime import datetime, timedelta, date from datetime import datetime, date
from dateutil.relativedelta import relativedelta
from sqlalchemy import func, and_ from sqlalchemy import func, and_
import click import click
from math import floor
import calendar import calendar
from schmeckels.models import Transaction, Tag from schmeckels.models import Transaction, Tag
from schmeckels.helper import import_transactions from schmeckels.helper import import_transactions
@ -19,14 +21,14 @@ def index():
tag_sum_out = {} tag_sum_out = {}
# Get a list of all tags # Get a list of all tags
tags = session.query(Tag).all() tags = session.query(Tag).filter_by(reporting=True).all()
# Get start and end of last month # Get start and end of timerange
now = datetime.now() months = 12
last_month = now - timedelta(days=now.day) today = datetime.now()
num_days = calendar.monthrange(last_month.year, 2)[1] start_month = today - relativedelta(months=months)
start_date = date(last_month.year, 2, 1) start_date = date(start_month.year, start_month.month, 1)
end_date = date(last_month.year, 2, num_days) end_date = today
for tag in tags: for tag in tags:
tag_sum = ( tag_sum = (
@ -37,20 +39,26 @@ def index():
) )
if tag_sum: if tag_sum:
if tag_sum >= 0: if tag_sum >= 0:
tag_sum_in[tag] = tag_sum tag_sum_in[tag] = {"sum":tag_sum, "monthly": floor(tag_sum/months)}
else: else:
tag_sum_out[tag] = tag_sum tag_sum_out[tag] = {"sum":tag_sum, "monthly": floor(tag_sum/months)}
monthly_sum = { "in": format_amount(sum([v["monthly"] for k,v in tag_sum_in.items()])),
"out":format_amount(sum([v["monthly"] for k,v in tag_sum_out.items()]))}
tag_sum_in = { tag_sum_in = {
k: format_amount(v) for k, v in sorted(tag_sum_in.items(), key=lambda item: float(item[1]), reverse=True) k: format_amount(v) for k, v in sorted(tag_sum_in.items(), key=lambda item: float(item[1]["sum"]), reverse=True)
} }
tag_sum_out = {k: format_amount(v) for k, v in sorted(tag_sum_out.items(), key=lambda item: float(item[1]))} tag_sum_out = {k: format_amount(v) for k, v in sorted(tag_sum_out.items(), key=lambda item: float(item[1]["sum"]))}
return render_template("index.html", tag_sum_in=tag_sum_in, tag_sum_out=tag_sum_out, date=start_date)
return render_template("index.html", tag_sum_in=tag_sum_in, tag_sum_out=tag_sum_out, months=months, monthly_sum=monthly_sum)
@app.route("/tags") @app.route("/tags")
def tags(): def tags():
tags = session.query(Tag).all() tags = session.query(Tag).all()
#Sort alphabetically
tags = sorted(tags, key=lambda item:item.name)
return render_template("tags.html", tags=tags) return render_template("tags.html", tags=tags)

View file

@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block main %} {% block main %}
<h1 class="text-2xl font-bold text-indigo-500">Overview for {{ date.strftime("%B %Y") }} </h1> <h1 class="text-2xl font-bold text-indigo-500">Overview for last {{ months }} months </h1>
<h2 class="text-xl font-bold text-green-500">Incoming</h2> <h2 class="text-xl font-bold text-green-500">Incoming</h2>
<div style="display:flex; flex-direction: row;"> <div style="display:flex; flex-direction: row;">
@ -11,13 +11,20 @@
<tr> <tr>
<th>Tag</th> <th>Tag</th>
<th>Sum</th> <th>Sum</th>
<th>⌀/Month</th>
</tr> </tr>
{% for tag,sum in tag_sum_in.items() %} {% for tag,data in tag_sum_in.items() %}
<tr> <tr>
<td>{{ tag.name }}</td> <td>{{ tag.name }}</td>
<td class="text-right">{{ sum }} €</td> <td class="text-right pl-3">{{ data["sum"] }} €</td>
<td class="text-right pl-3">{{ data["monthly"] }} €</td>
</tr> </tr>
{% endfor %} {% endfor %}
<tr>
<td><b>SUMME</b></td>
<td class="text-right pl-3"></td>
<td class="text-right pl-3">{{ monthly_sum["in"] }} €</td>
</tr>
</table> </table>
{% else %} {% else %}
No tagged transactions for this month. No tagged transactions for this month.
@ -37,13 +44,20 @@
<tr> <tr>
<th>Tag</th> <th>Tag</th>
<th>Sum</th> <th>Sum</th>
<th>⌀/Month</th>
</tr> </tr>
{% for tag,sum in tag_sum_out.items() %} {% for tag,data in tag_sum_out.items() %}
<tr> <tr>
<td>{{ tag.name }}</td> <td>{{ tag.name }}</td>
<td class="text-right">{{ sum }} €</td> <td class="text-right pl-3">{{ data["sum"] }} €</td>
<td class="text-right pl-3">{{ data["monthly"] }} €</td>
</tr> </tr>
{% endfor %} {% endfor %}
<tr>
<td><b>SUMME</b></td>
<td class="text-right pl-3"></td>
<td class="text-right pl-3">{{ monthly_sum["out"] }} €</td>
</tr>
</table> </table>
{% else %} {% else %}
No tagged transactions for this month. No tagged transactions for this month.
@ -59,9 +73,9 @@
{% block script %} {% block script %}
<script> <script>
var pieData_in = [ var pieData_in = [
{% for tag, sum in tag_sum_in.items() %} {% for tag, data in tag_sum_in.items() %}
{ {
value: "{{sum}}".replace(",", ""), value: "{{data['sum']}}".replace(",", ""),
label: "{{ tag.name }}", label: "{{ tag.name }}",
color : "{{ tag.color() }}" color : "{{ tag.color() }}"
}, },
@ -70,9 +84,9 @@
new Chart(document.getElementById("chart_in").getContext("2d")).Pie(pieData_in); new Chart(document.getElementById("chart_in").getContext("2d")).Pie(pieData_in);
var pieData_out = [ var pieData_out = [
{% for tag, sum in tag_sum_out.items() %} {% for tag, data in tag_sum_out.items() %}
{ {
value: "{{sum}}".replace(",", ""), value: "{{data['sum']}}".replace(",", ""),
label: "{{ tag.name }}", label: "{{ tag.name }}",
color : "{{ tag.color() }}" color : "{{ tag.color() }}"
}, },

View file

@ -55,6 +55,11 @@
font-weight: bold; font-weight: bold;
color: green; color: green;
} }
.topborder {
border-top: 1px solid #000;
}
</style> </style>
</head> </head>
@ -64,17 +69,40 @@
<hr /> <hr />
<div class="content"> <div class="content">
% for name, entries in data.items(): <h4>Einnahmen</h4>
<h4>{{ name }}</h4>
<table> <table>
% for sc, amount in entries.items(): {% for name, amount in tags.Einnahmen.items() %}
<tr> <tr>
<td class="category-name">{{ sc }}</td> <td class="category-name">{{ name }}</td>
<td class="amount"> {{ amount }} €</td> <td class="amount"> {{ amount }} €</td>
</tr> </tr>
% end {% endfor %}
<tr>
<td></td>
<td class="topborder amount">{{ "%.2f"|format(sum_in) }} €</td>
</tr>
</table>
<h4>Ausgaben</h4>
<table>
{% for name, amount in tags.Ausgaben.items() %}
<tr>
<td class="category-name">{{ name }}</td>
<td class="amount"> {{ amount }} €</td>
</tr>
{% endfor %}
<tr class="topborder">
<td></td>
<td class="topborder amount">{{ "%.2f"|format(sum_out) }} €</td>
</tr>
</table>
<table style="margin-top: 4rem;">
<tr>
<td></td>
<td class="topborder amount">{{ "%.2f"|format(diff) }} €</td>
</tr>
</table> </table>
% end
</body> </body>