134 Commits
0.0.9 ... 0.5.0

Author SHA1 Message Date
86c8b76736 W
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-04-16 19:14:09 +02:00
c85b68b072 we
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 19:10:37 +02:00
c8648788d0 bett
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 19:07:08 +02:00
fe5ad6ba8d patzh
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 19:02:18 +02:00
512e89205c button
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 18:57:54 +02:00
dbb99ba47a elo
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 18:56:59 +02:00
9c42e0fc63 weig
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 18:50:08 +02:00
92508a23ae bigger
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 18:34:36 +02:00
8c3155434a bigger
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 18:30:59 +02:00
777ad92b22 bigger
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 18:26:02 +02:00
708ce6dd3d elosa
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 17:46:45 +02:00
75b66806a2 elkisa
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 17:42:29 +02:00
6b5c3c36ca elisa
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-16 17:38:38 +02:00
7f90ad4c05 back
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-11 16:45:20 +02:00
9dee350323 test
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-11 16:39:40 +02:00
c3c3b4f83d test
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-11 16:35:36 +02:00
727e2f60c4 input
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-04-09 20:27:57 +02:00
a411f59e00 runden
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-09 20:22:59 +02:00
be531a7ccf runden
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-09 20:17:35 +02:00
6e94925fda changes
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-09 20:10:04 +02:00
814c5b17e3 old nutri
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-04-08 23:09:45 +02:00
e66e54c424 sd
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-04-07 20:00:16 +02:00
0ad4c9e398 fee
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-07 19:53:41 +02:00
ce86d35b25 ter
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-07 19:49:12 +02:00
19552bf774
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-07 19:23:15 +02:00
b74f136f81 jetzt
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-07 19:16:12 +02:00
b52dbaec57 bug
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-07 19:10:34 +02:00
2769d0a33a bug
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-07 19:02:10 +02:00
5ac1a9f5a9 editable
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-07 18:52:37 +02:00
ab3378ec4d ls
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 16:52:05 +02:00
5e4ab261a7 change
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-04-04 13:41:43 +02:00
14227f0058 cahnge
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 13:37:36 +02:00
ed62772643 label
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 13:32:22 +02:00
43b74dc3c2 style
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 13:29:03 +02:00
1643aa65d4 change
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 13:24:33 +02:00
a44b0ecf58 bug
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 13:14:04 +02:00
0f3ff65605 local storage
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 13:09:13 +02:00
32df39efb8 bug
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 13:03:25 +02:00
b85b7957c6 change
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:53:05 +02:00
bee94df6e6 change table
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:46:24 +02:00
79cf147345 change table
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:41:41 +02:00
c9d50b6018 missing var
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:34:51 +02:00
8d853a8a43 protion option
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:30:18 +02:00
3e6d743fd4 back
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:25:51 +02:00
888f8717b5 revert
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:19:23 +02:00
eddd739c71 commented out
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:15:35 +02:00
7213cb4757 no scan
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-04-04 12:08:16 +02:00
204e2e4dd7 portion option
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-04-03 22:06:15 +02:00
11469a2865 removed xss
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-02-06 15:54:58 +01:00
9a4160e4e1 removed xss
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-06 15:51:14 +01:00
54c67cf5c2 no xss
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-06 15:46:53 +01:00
c7bf411f01 another trivy test, 11
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-06 13:20:03 +01:00
67c4981cbe another trivy test, 10
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 13:17:34 +01:00
6211ea95a4 another trivy test, 9
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 12:52:09 +01:00
3cee043e28 another trivy test, 8
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 12:50:01 +01:00
6fe351e110 another trivy test, 7
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 12:47:42 +01:00
7429d4a4f0 another trivy test, 6
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 12:45:24 +01:00
515657b1fd another trivy test, 5
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 12:38:55 +01:00
605ddc00d0 another trivy test, 4
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 12:36:49 +01:00
7e00994a37 another trivy test, 3
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 12:32:06 +01:00
fb1249d37b another trivy test, 2
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-06 10:31:23 +01:00
d9195187f3 another trivy test
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 10:29:14 +01:00
161aea553c test outaged alpine image
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-06 10:12:29 +01:00
7c3ae15c67 use Werkzeug 3.0.1 again
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-06 09:54:16 +01:00
d535fe3743 test trivy
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-06 09:49:55 +01:00
56ed58b6d4 password test
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-06 09:19:13 +01:00
863fcef491 add trivy into ci script and separate database for test instance
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-06 09:10:09 +01:00
807f1de774 test
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-02-01 17:41:56 +01:00
677874a0e1 left version
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 17:35:41 +01:00
81fc7ade5f test
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 17:34:28 +01:00
b941819b73 test
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 17:27:43 +01:00
dcc1336d62 test
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 17:22:08 +01:00
99bd1841cb try
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 17:21:30 +01:00
16f8c23c38 round
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 17:11:43 +01:00
cb84e3cdc0 table consistant
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 17:06:30 +01:00
ca734fda32 version left
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 17:03:29 +01:00
4f6d3de79c search
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 16:57:01 +01:00
bf245e215a fix
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 16:49:50 +01:00
443eb9ef00 fix
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 16:48:54 +01:00
ce38d6cf24 delete in db
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
2024-02-01 16:43:31 +01:00
5c8f057843 button color
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 16:34:54 +01:00
85afd501ce version id, 2
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-02-01 09:55:40 +01:00
4dbc156439 version id
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-02-01 09:48:54 +01:00
fd3e8751fe order by name
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-02-01 09:28:26 +01:00
21ea1aa56f Merge branch 'main' of gitea.hottis.de:moerp/elo-rezept-rechner
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-31 16:46:36 +01:00
eefc8d5b21 fix image tag 2024-01-31 16:46:31 +01:00
41010b8a7b small fix
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-31 16:27:17 +01:00
43583fb7f3 color
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-31 16:17:37 +01:00
1f5b4163e7 fix
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-31 16:11:17 +01:00
38d3381ecd test instance
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-31 15:51:31 +01:00
db769ca053 postfix instead of prefix, 2
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-31 15:31:03 +01:00
536e933fef postfix instead of prefix 2024-01-31 15:30:53 +01:00
d469a7cf2c test deployment
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-31 15:27:22 +01:00
d308fd662a logging, 4
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 15:05:58 +01:00
a9a8a36cb9 logging, 3
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 14:53:04 +01:00
845e4ec673 logging, 2
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 14:46:18 +01:00
d82770158c logging
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 13:49:14 +01:00
3852d78725 table adjusted
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 13:43:21 +01:00
fd057e3415 token stuff, 4
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 13:15:03 +01:00
e4fe5b9831 token stuff, 3
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 13:09:26 +01:00
6a9b938ab9 token stuff, 2
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 13:03:04 +01:00
367e76f9f1 token stuff
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-31 12:47:35 +01:00
e59b184da5 style
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-30 23:11:29 +01:00
c318cd21e0 delete button
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 22:56:22 +01:00
224e6a9147 Merge branch 'main' of gitea.hottis.de:moerp/Elo-rezept-rechner
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 22:24:51 +01:00
8f15a05a4e more table 2024-01-30 22:24:48 +01:00
f0fcbc3c56 trigger pipeline
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 20:43:17 +01:00
1e8ae0105a to many row
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-30 19:38:49 +01:00
f39c902ace fail
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-30 19:15:48 +01:00
ff26644f06 fail
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 18:51:52 +01:00
5f63092a67 f
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 18:51:02 +01:00
1fc9dd70df Merge branch 'main' of gitea.hottis.de:moerp/Elo-rezept-rechner
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 18:48:08 +01:00
794b50e041 token 2024-01-30 18:47:57 +01:00
5583bc2b60 color 2024-01-30 18:44:45 +01:00
5f34449601 token
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-30 18:26:27 +01:00
8bc3857482 Merge branch 'main' of gitea.hottis.de:moerp/elo-rezept-rechner
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 18:19:14 +01:00
5c7fe128c8 token 2024-01-30 18:19:05 +01:00
3a17338358 Merge branch 'main' of gitea.hottis.de:moerp/Elo-rezept-rechner
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 18:08:15 +01:00
4761910092 changes 2024-01-30 18:07:16 +01:00
2c499b363b Merge branch 'main' of gitea.hottis.de:moerp/elo-rezept-rechner
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 17:03:14 +01:00
39e2f2634d small
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-30 17:03:00 +01:00
ffa6944e7b fix auth for add_nut... 2024-01-30 17:02:58 +01:00
449dba1d7e Merge branch 'main' of gitea.hottis.de:moerp/elo-rezept-rechner
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 16:56:03 +01:00
b6d1367019 test 2024-01-30 16:55:44 +01:00
2ff8757b74 style 2024-01-30 16:50:15 +01:00
7f06e900bb test 2024-01-30 16:27:16 +01:00
4c2338c34a test
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-30 16:24:45 +01:00
5f8d49f054 test 2024-01-30 16:19:08 +01:00
5cfba1c068 favicon
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-01-30 15:52:49 +01:00
09a670727f favicon
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-01-30 15:50:39 +01:00
f4a4597223 start pipeline, 2 2024-01-30 15:49:37 +01:00
70815f0172 start pipeline 2024-01-30 15:49:06 +01:00
e4e8e19466 small cahnges
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
2024-01-30 15:33:54 +01:00
2228f0cfb5 db fix 2024-01-30 15:29:46 +01:00
19 changed files with 701 additions and 130 deletions

View File

@ -2,7 +2,7 @@ steps:
build:
image: plugins/kaniko
settings:
repo: gitea.hottis.de/moerp/elo-rezept-rechner
repo: ${FORGE_NAME}/${CI_REPO}
registry:
from_secret: container_registry
tags: latest,${CI_COMMIT_SHA},${CI_COMMIT_TAG}
@ -10,10 +10,34 @@ steps:
from_secret: container_registry_username
password:
from_secret: container_registry_password
build_args:
- VERSION_ID1=${CI_COMMIT_SHA}
- VERSION_ID2=${CI_COMMIT_TAG}
dockerfile: Dockerfile
when:
- event: [push, tag]
# scan_image:
# image: aquasec/trivy
# commands:
# - trivy image $FORGE_NAME/$CI_REPO:$CI_COMMIT_SHA --quiet --exit-code 1
deploytest:
image: portainer/kubectl-shell:latest
secrets:
- source: kube_config
target: KUBE_CONFIG_CONTENT
- source: encryption_key
target: ENCRYPTION_KEY
- source: secrets_checksum
target: MD5_CHECKSUM
commands:
- printf "$KUBE_CONFIG_CONTENT" > /tmp/kubeconfig
- export KUBECONFIG=/tmp/kubeconfig
- ./deployment/deploy.sh test
when:
- event: [push, tag]
deploy:
image: portainer/kubectl-shell:latest
secrets:

View File

@ -1,6 +1,8 @@
FROM python:3.12-alpine3.19
ARG APP_DIR="/opt/app"
ARG VERSION_ID1="x"
ARG VERSION_ID2="alpha"
COPY ./src/ ${APP_DIR}/
COPY start.sh ${APP_DIR}/
@ -8,11 +10,14 @@ COPY start.sh ${APP_DIR}/
WORKDIR ${APP_DIR}
RUN \
apk add --no-cache build-base libpq-dev && \
pip install -r requirements.txt
apk add --no-cache build-base libpq-dev npm && \
pip install --upgrade pip && \
pip install -r requirements.txt && \
if [ "${VERSION_ID2}" != "" ]; then VERSION_ID=${VERSION_ID2}; else VERSION_ID=${VERSION_ID1}; fi && \
sed -i -e 's/VERSION_ID/'$VERSION_ID'/' ${APP_DIR}/templates/index.html && \
sed -i -e 's/VERSION_ID/'"$VERSION_ID"'/' ${APP_DIR}/templates/nutrition.html
EXPOSE 8080
CMD "./start.sh"

View File

@ -1,5 +1,7 @@
#!/bin/bash
if [ "$ENCRYPTION_KEY" = "" ]; then
echo "ENCRYPTION_KEY not set"
exit 1
@ -10,6 +12,7 @@ if [ "$MD5_CHECKSUM" = "" ]; then
exit 1
fi
SECRETS_CIPHERTEXT_FILE=secrets.enc
SECRETS_PLAINTEXT_FILE=/tmp/secrets
TMP_FILE=`mktemp`

View File

@ -46,10 +46,10 @@ metadata:
spec:
tls:
- hosts:
- nutri.hottis.de
- nutri%POSTFIX%.hottis.de
secretName: nutri-cert
rules:
- host: nutri.hottis.de
- host: nutri%POSTFIX%.hottis.de
http:
paths:
- path: /

View File

@ -1,13 +1,19 @@
#!/bin/bash
if [ "$1" == "test" ]; then
POSTFIX="-test"
IMAGE_TAG=${CI_COMMIT_SHA}
else
POSTFIX=""
fi
if [ "$IMAGE_TAG" == "" ]; then
echo "Make sure IMAGE_TAG is set"
exit 1
fi
IMAGE_NAME=gitea.hottis.de/moerp/elo-rezept-rechner
NAMESPACE=moerp
NAMESPACE=moerp${POSTFIX}
DEPLOYMENT_DIR=$PWD/deployment
pushd $DEPLOYMENT_DIR > /dev/null
@ -15,7 +21,7 @@ pushd $DEPLOYMENT_DIR > /dev/null
. /tmp/secrets
rm /tmp/secrets
CLIENT_SECRETS=`cat oidc-config.json | sed -e's!%CLIENT_SECRET%!'$CLIENT_SECRET'!'`
CLIENT_SECRETS=`cat oidc-config${POSTFIX}.json | sed -e's!%CLIENT_SECRET%!'$CLIENT_SECRET'!'`
kubectl create namespace $NAMESPACE \
--dry-run=client \
@ -30,13 +36,14 @@ kubectl create secret generic nutri-secrets \
--from-literal=CLIENT_SECRETS="$CLIENT_SECRETS" \
--from-literal=PGUSER="$PGUSER" \
--from-literal=PGPASSWORD="$PGPASSWORD" \
--from-literal=PGDATABASE="$PGDATABASE" \
--from-literal=PGDATABASE="$PGDATABASE$POSTFIX" \
--from-literal=PGHOST="timescaledb.database.svc.cluster.local" \
--from-literal=PGSSLMODE="require" | \
kubectl apply -f - -n $NAMESPACE
cat $DEPLOYMENT_DIR/deploy-yml.tmpl | \
sed -e 's,%IMAGE%,'$IMAGE_NAME':'$IMAGE_TAG','g | \
sed -e 's,%POSTFIX%,'$POSTFIX','g | \
kubectl apply -f - -n $NAMESPACE
popd > /dev/null

View File

@ -0,0 +1,13 @@
{
"web": {
"issuer": "https://auth2.hottis.de/realms/hottis",
"auth_uri": "https://auth2.hottis.de/ealms/hottis/protocol/openid-connect/auth",
"client_id": "nutri",
"client_secret": "%CLIENT_SECRET%",
"redirect_uris": [
"https://nutri-test.hottis.de/*"
],
"userinfo_uri": "https://auth2.hottis.de/realms/hottis/protocol/openid-connect/userinfo",
"token_uri": "https://auth2.hottis.de/realms/hottis/protocol/openid-connect/token"
}
}

View File

@ -5,6 +5,8 @@ from werkzeug.middleware.proxy_fix import ProxyFix
import os
import json
import psycopg2
import logging
from math import ceil, floor
app = Flask(__name__)
app.config.update({
@ -18,9 +20,9 @@ app.config.update({
})
oidc = OpenIDConnect(app)
app.logger.handlers = logging.getLogger('gunicorn.error').handlers
datapw = 'dasrtwegdffgtewrt4335wferg'
def calculate_nutrition(food, weight):
try:
@ -28,7 +30,7 @@ def calculate_nutrition(food, weight):
with conn.cursor() as cursor:
# Abfrage der Nährwertdaten aus der Datenbank
cursor.execute('SELECT kcal, EW, Fett, KH, BST, CA FROM nutrition_table WHERE name = ?', (food,))
cursor.execute('SELECT kcal, EW, Fett, KH, BST, CA FROM nutrition_table WHERE name = %s', (food,))
result = cursor.fetchone()
@ -36,12 +38,12 @@ def calculate_nutrition(food, weight):
# Runden und Berechnen der Nährwerte basierend auf dem Gewicht
kcal, ew, fett, kh, bst, ca = result
nutrition_values = [
round(kcal * weight / 100), # kcal gerundet auf ganze Zahl
round(ew * weight / 100, 1), # EW gerundet auf eine Dezimalstelle
round(fett * weight / 100, 1), # Fett gerundet auf eine Dezimalstelle
round(kh * weight / 100, 1), # KH gerundet auf eine Dezimalstelle
round(bst * weight / 100, 1), # BST gerundet auf eine Dezimalstelle
round(ca * weight / 100) # CA gerundet auf ganze Zahl
schulrunden(kcal * weight / 100, ist_kcal=True), # kcal gerundet auf ganze Zahl
schulrunden(ew * weight / 100, 1), # EW gerundet auf eine Dezimalstelle
schulrunden(fett * weight / 100, 1), # Fett gerundet auf eine Dezimalstelle
schulrunden(kh * weight / 100, 1), # KH gerundet auf eine Dezimalstelle
schulrunden(bst * weight / 100, 1), # BST gerundet auf eine Dezimalstelle
schulrunden(ca * weight / 100) # CA gerundet auf ganze Zahl
]
return nutrition_values
else:
@ -51,6 +53,24 @@ def calculate_nutrition(food, weight):
conn.close()
def schulrunden(zahl, stellen=0, ist_kcal=False):
# Wenn es sich um kcal handelt und der Wert vor der Rundung zwischen 0 und 1 liegt
if ist_kcal and 0 < zahl < 1:
return 1
faktor = 10 ** stellen
zahl = zahl * faktor
basis = floor(zahl)
if zahl - basis >= 0.5:
gerundet = basis + 1
else:
gerundet = basis
return gerundet / faktor
# Index-Route
@app.route('/')
@oidc.require_login
@ -65,9 +85,8 @@ def get_products():
try:
conn = psycopg2.connect()
with conn.cursor() as cursor:
cursor.execute('SELECT name FROM nutrition_table')
cursor.execute('SELECT name FROM nutrition_table ORDER BY name')
products = cursor.fetchall()
print("ter")
return {'products': [product[0] for product in products]}
finally:
if conn:
@ -98,27 +117,38 @@ def add_lm():
return "Lebensmittel nicht gefunden.", 404
def convert_decimal(value):
try:
return float(value.replace(',', '.'))
except (ValueError, TypeError):
return 0.0 # Rückgabe eines Standardwertes im Fehlerfall
@app.route('/add_nutrition', methods=['POST'])
@oidc.accept_token(require_token=True, scopes_required=['openid'])
@oidc.accept_token(['openid'])
def add_nutrition():
food = request.form.get('food')
kcal = float(request.form.get('kcal'))
ew = float(request.form.get('ew'))
fett = float(request.form.get('fett'))
kh = float(request.form.get('kh'))
bst = float(request.form.get('bst'))
ca = float(request.form.get('ca'))
app.logger.info("add_nutrition")
food = request.form.get('food')
kcal = convert_decimal(request.form.get('kcal'))
ew = convert_decimal(request.form.get('ew'))
fett = convert_decimal(request.form.get('fett'))
kh = convert_decimal(request.form.get('kh'))
bst = convert_decimal(request.form.get('bst'))
ca = convert_decimal(request.form.get('ca'))
print("test")
# Verbindung zur Datenbank herstellen und Daten einfügen
try:
conn = psycopg2.connect()
with conn.cursor() as cursor:
cursor.execute("INSERT INTO nutrition_table (name, kcal, ew, fett, kh, bst, ca) VALUES (?, ?, ?, ?, ?, ?, ?)",
cursor.execute("INSERT INTO nutrition_table (name, kcal, ew, fett, kh, bst, ca) VALUES (%s, %s, %s, %s, %s, %s, %s)",
(food, kcal, ew, fett, kh, bst, ca))
conn.commit()
return redirect(url_for('nutrition'))
except Exception as e:
app.logger.warn(f"error in add_nutrition: {e}")
return jsonify({"error": str(e)}), 500
finally:
if conn:
conn.close()
@ -129,10 +159,72 @@ def add_nutrition():
def nutrition():
return render_template('nutrition.html')
@app.route('/get_token')
@oidc.require_login
def get_token():
return jsonify(token=oidc.get_access_token())
app = ProxyFix(app, x_for=1, x_host=1)
@app.route('/get_database_entries')
@oidc.require_login
def get_database_entries():
try:
# Ersetzen Sie diese Werte mit Ihren Datenbank-Verbindungsinformationen
conn = psycopg2.connect()
cursor = conn.cursor()
with conn.cursor() as cursor:
cursor.execute("SELECT name, kcal, ew, fett, kh, bst, ca FROM nutrition_table ORDER BY name")
entries = cursor.fetchall()
# Umwandeln der Daten in ein JSON-freundliches Format
entries_list = []
for entry in entries:
entries_list.append({
"food": entry[0],
"kcal": entry[1],
"ew": entry[2],
"fett": entry[3],
"kh": entry[4],
"bst": entry[5],
"ca": entry[6]
})
return jsonify(entries_list)
except Exception as e:
return jsonify({"error": str(e)}), 500
finally:
if conn:
conn.close()
@app.route('/delete_nutrition', methods=['POST'])
@oidc.accept_token(['openid'])
def delete_nutrition():
data = request.get_json()
foodNames = data['foodNames']
if not foodNames:
return jsonify({'error': 'Keine Lebensmittel zum Löschen angegeben'}), 400
try:
conn = psycopg2.connect()
with conn.cursor() as cursor:
query = "DELETE FROM nutrition_table WHERE name = ANY(%s)"
cursor.execute(query, (foodNames,))
conn.commit()
return jsonify({'message': 'Erfolgreich gelöscht'}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
finally:
if conn:
conn.close()
@app.route('/random')
def random_page():
# Diese Route gibt die HTML-Seite 'random.html' zurück
return render_template('random.html')
exposed_app = ProxyFix(app, x_for=1, x_host=1)

View File

@ -13,13 +13,16 @@ cursor = conn.cursor()
# Erstellen der Tabelle (falls noch nicht vorhanden)
cursor.execute('''
CREATE TABLE IF NOT EXISTS nutrition_table (
name TEXT,
id serial not null,
name TEXT not null,
kcal REAL,
EW REAL,
Fett REAL,
KH REAL,
BST REAL,
Ca REAL
Ca REAL,
constraint nutrition_table_pk primary key (id),
constraint nutrition_table_name_uk unique (name)
)
''')

View File

@ -6,7 +6,6 @@ Hühnerei,137,11.9,9.3,1.5,0.0,51
Pflanzenmargarine,722,0.2,80.0,0.4,0.0,8
Sahne 30%,309,2.4,31.7,3.4,0.0,80
Maisstärke,353,0.4,0.1,85.9,1.0,0
Paniermehl,368,10.1,2.1,73.5,5.3,50
Weizengrieß,335,9.6,0.8,69.0,7.1,17
Mehl405,343,9.8,1.0,71.8,4.0,15
Rapsöl,884,0,100.0,0,0,0
@ -43,13 +42,11 @@ Knoblauch,145,6.1,0.1,28.4,1.8,38
Senf,88,6.0,4.0,6.0,1.0,124
Blattspinat roh,21,2.7,0.3,0.6,2.6,117
Buttermilch,37,3.5,0.5,4.0,0.0,109
Himbeere,37,1.3,0.3,4.8,4.7,40
Salz dill gurken,9,0.4,0.1,1.3,0.5,18
Schmand 20%,205,2.8,20.0,3.6,0.0,100
Aspikpulver,338,84.2,0.1,0.0,0.0,11
Lachs atlantischer,210,20.4,13.4,0.3,0.0,4
Pinienkerne,589,24.0,50.7,7.3,7.2,26
Zwieback,385,9.9,4.3,73.1,5.2,42
Speisequark,72,13.5,0.3,3.2,0.0,92
Basilikum,47,3.1,0.8,5.1,3.1,369
Mayonaise 50%,490,0.5,52.0,5.0,0.0,10
@ -83,7 +80,6 @@ Naturreis,349,7.2,2.2,74.1,2.2,16
Mehl Type 405,343,9.8,1.0,71.8,4.0,15
Mehl Type 550,346,9.8,1.1,72.0,4.3,17
Milchreis,316,6.4,0.8,80.2,1.1,6
Kartoffelstärke,341,0.6,0.1,83.1,0.1,35
Hmilch fettarm 1.5%,47,3.4,1.5,4.9,0.0,123
Edamer 30%,254,26.4,16.2,0,0.0,800
Gouda alt 48%,414,24.6,33.7,0.1,0.0,871
@ -98,7 +94,6 @@ Butterkeks,441,8.2,11.0,74.7,3.3,47
Zwieback,385,9.9,4.3,73.1,5.2,42
Schokolade 75% Kakaomasse,598,7.8,42.6,35.0,10.9,73
Paniermehl,368,10.1,0.1,73.5,5.3,50
Senf,88,6.0,4.0,6.0,1.0,124
Schinken geräuchert,152,20.7,7.7,0.0,0.0,2
Rinderkeule,148,20.0,7.6,0.0,0.0,6
Kirsche süß,62,0.9,0.3,13.3,1.3,17
@ -107,7 +102,6 @@ Eisbergsalat,16,1.0,0.2,2.0,1.1,19
Endivie,18,1.8,0.2,1.2,1.9,54
Feldsalat,18,1.8,0.4,0.8,1.5,32
Gurke,14,0.6,0.2,1.8,0.9,15
Kopfsalat,14,1.2,0.2,1.1,1.4,20
Schalotte,25,1.5,0.2,3.3,1.5,37
Gemüsebrühe verz,7,1.6,0,0,0,12
Fleischbrühe,4,0.2,0,1,0,5
@ -122,7 +116,6 @@ Paprika rot,43,1.3,0.5,6.4,3.6,10
Knollensellerie,27,1.6,0.3,2.3,4.2,50
Erdbeeren tiefgefroren,38,0.9,0.4,5.8,2.1,24
Himbeeren tiefgefroren,45,1.4,0.3,5.0,4.8,42
Dill,65,3.7,0.8,8.0,5.3,230
Kerbel,58,4.1,0.6,6.2,5.3,400
Majoran,52,2.1,1.1,6.9,2.9,322
Oregano,72,2.2,2.0,9.7,2.5,310

1 name kcal EW Fett KH BST Ca
6 Pflanzenmargarine 722 0.2 80.0 0.4 0.0 8
7 Sahne 30% 309 2.4 31.7 3.4 0.0 80
8 Maisstärke 353 0.4 0.1 85.9 1.0 0
Paniermehl 368 10.1 2.1 73.5 5.3 50
9 Weizengrieß 335 9.6 0.8 69.0 7.1 17
10 Mehl405 343 9.8 1.0 71.8 4.0 15
11 Rapsöl 884 0 100.0 0 0 0
42 Senf 88 6.0 4.0 6.0 1.0 124
43 Blattspinat roh 21 2.7 0.3 0.6 2.6 117
44 Buttermilch 37 3.5 0.5 4.0 0.0 109
Himbeere 37 1.3 0.3 4.8 4.7 40
45 Salz dill gurken 9 0.4 0.1 1.3 0.5 18
46 Schmand 20% 205 2.8 20.0 3.6 0.0 100
47 Aspikpulver 338 84.2 0.1 0.0 0.0 11
48 Lachs atlantischer 210 20.4 13.4 0.3 0.0 4
49 Pinienkerne 589 24.0 50.7 7.3 7.2 26
Zwieback 385 9.9 4.3 73.1 5.2 42
50 Speisequark 72 13.5 0.3 3.2 0.0 92
51 Basilikum 47 3.1 0.8 5.1 3.1 369
52 Mayonaise 50% 490 0.5 52.0 5.0 0.0 10
80 Mehl Type 405 343 9.8 1.0 71.8 4.0 15
81 Mehl Type 550 346 9.8 1.1 72.0 4.3 17
82 Milchreis 316 6.4 0.8 80.2 1.1 6
Kartoffelstärke 341 0.6 0.1 83.1 0.1 35
83 Hmilch fettarm 1.5% 47 3.4 1.5 4.9 0.0 123
84 Edamer 30% 254 26.4 16.2 0 0.0 800
85 Gouda alt 48% 414 24.6 33.7 0.1 0.0 871
94 Zwieback 385 9.9 4.3 73.1 5.2 42
95 Schokolade 75% Kakaomasse 598 7.8 42.6 35.0 10.9 73
96 Paniermehl 368 10.1 0.1 73.5 5.3 50
Senf 88 6.0 4.0 6.0 1.0 124
97 Schinken geräuchert 152 20.7 7.7 0.0 0.0 2
98 Rinderkeule 148 20.0 7.6 0.0 0.0 6
99 Kirsche süß 62 0.9 0.3 13.3 1.3 17
102 Endivie 18 1.8 0.2 1.2 1.9 54
103 Feldsalat 18 1.8 0.4 0.8 1.5 32
104 Gurke 14 0.6 0.2 1.8 0.9 15
Kopfsalat 14 1.2 0.2 1.1 1.4 20
105 Schalotte 25 1.5 0.2 3.3 1.5 37
106 Gemüsebrühe verz 7 1.6 0 0 0 12
107 Fleischbrühe 4 0.2 0 1 0 5
116 Knollensellerie 27 1.6 0.3 2.3 4.2 50
117 Erdbeeren tiefgefroren 38 0.9 0.4 5.8 2.1 24
118 Himbeeren tiefgefroren 45 1.4 0.3 5.0 4.8 42
Dill 65 3.7 0.8 8.0 5.3 230
119 Kerbel 58 4.1 0.6 6.2 5.3 400
120 Majoran 52 2.1 1.1 6.9 2.9 322
121 Oregano 72 2.2 2.0 9.7 2.5 310

BIN
src/static/images/elisa.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
src/static/images/elo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
src/static/images/marie.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

View File

@ -34,18 +34,42 @@ button:not(:disabled):hover {
}
button#remove-button {
background-color: #f443366f; /* Helles Rot */
background-color: #640000; /* Helles Rot */
}
button#remove-button:disabled {
background-color: #cccccc;
color: #666666;
}
button#remove-button:not(:disabled):hover {
background-color: #d32f2f3d; /* Dunkleres Rot */
background-color: #490000; /* Dunkleres Rot */
}
table {
width: 100%;
border-collapse: collapse;
border-collapse: separate; /* Erlaubt die Anwendung von border-radius */
border-spacing: 0;
border-radius: 10px;
}
table th:first-child {
border-top-left-radius: 10px;
}
table th:last-child {
border-top-right-radius: 10px;
}
table tr:last-child td:first-child {
border-bottom-left-radius: 10px;
}
table tr:last-child td:last-child {
border-bottom-right-radius: 10px;
}
table, th, td {
border: 1px solid #ddd;
}
@ -65,7 +89,7 @@ tr:nth-child(even) {
}
.selected, tr.selected {
background-color: #ffdd99; /* Hervorhebung der Auswahl */
background-color: #efcccc; /* Hervorhebung der Auswahl */
}
tr:hover:not(.selected) {
@ -82,9 +106,20 @@ tr:hover:not(.selected) {
border-radius: 10px;
}
#navbar .navbar-header {
display: flex;
align-items: center;
}
#navbar h1 {
margin: 0;
font-size: 24px;
display: inline-block;
}
#navbar .versionid {
margin-left: 20px;
display: inline-block;
}
#navbar ul {
@ -106,13 +141,10 @@ tr:hover:not(.selected) {
transition: background-color 0.3s;
}
#navbar a:hover {
#navbar a:hover, #navbar a.active {
background-color: #007344; /* Etwas helleres Grün */
}
#navbar a.active {
background-color: #008C50; /* Mittleres Grün */
}
.content {
@ -121,3 +153,115 @@ tr:hover:not(.selected) {
padding: 20px;
margin: 20px 0;
}
#nutrition-input-table th, #nutrition-input-table td {
border: 1px solid #ddd; /* Fügt Ränder hinzu */
padding: 8px; /* Fügt Innenabstand hinzu */
text-align: left; /* Ausrichtung des Textes */
}
#nutrition-input-table input {
width: 100%; /* Eingabefelder nehmen die volle Breite der Zelle ein */
box-sizing: border-box; /* Box-Modell für die Breitenberechnung */
}
@media screen and (max-width: 600px) {
#nutrition-input-table {
display: block;
overflow-x: auto; /* Ermöglicht horizontales Scrollen auf kleinen Bildschirmen */
}
}
.table-container {
overflow-y: auto;
max-height: 500px; /* Passen Sie die Höhe nach Bedarf an */
border-radius: 10px;
margin-top: 20px;
}
#database-nutrition-table {
width: 100%;
border-collapse: separate; /* Erlaubt die Anwendung von border-radius */
border-spacing: 0;
}
#database-nutrition-table th, #database-nutrition-table td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
#database-nutrition-table tr.selected {
background-color: #efcccc;
}
#password-prompt {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: center;
}
button#delete-row-button {
background-color: #640000; /* Helles Rot */
}
button#delete-row-button:disabled {
background-color: #cccccc;
color: #666666;
}
button#delete-row-button:not(:disabled):hover {
background-color: #490000; /* Dunkleres Rot */
}
button#cancel-button {
background-color: #640000; /* Helles Rot */
}
button#cancel-button:disabled {
background-color: #cccccc;
color: #666666;
}
button#cancel-button:not(:disabled):hover {
background-color: #490000; /* Dunkleres Rot */
}
.form-layout {
display: flex;
flex-direction: column;
}
.form-row {
margin-bottom: 10px;
}
button#submit-button {
background-image: url('images/elisa.jpg'); /* Pfad zum Bild */
background-size: contain; /* Passt das Bild innerhalb des Buttons an, ohne es zu strecken */
background-repeat: no-repeat; /* Verhindert das Wiederholen des Bildes */
background-position: center; /* Zentriert das Bild im Button */
color: transparent; /* Macht den Text unsichtbar, damit nur das Bild sichtbar ist */
width: 62px; /* Setzt die Breite automatisch entsprechend des Inhalts */
height: 85px; /* Passt die Höhe an, um das Bild vollständig anzuzeigen */
padding: 10px 20px; /* Hinzufügen von etwas Platz um das Bild */
}
button#remove-button {
background-image: url('images/marie2.jpg'); /* Pfad zum Bild */
background-size: contain; /* Passt das Bild innerhalb des Buttons an, ohne es zu strecken */
background-repeat: no-repeat; /* Verhindert das Wiederholen des Bildes */
background-position: center; /* Zentriert das Bild im Button */
color: transparent; /* Macht den Text unsichtbar, damit nur das Bild sichtbar ist */
width: 78px; /* Setzt die Breite automatisch entsprechend des Inhalts */
height: 85px; /* Passt die Höhe an, um das Bild vollständig anzuzeigen */
padding: 10px 20px; /* Hinzufügen von etwas Platz um das Bild */
}

View File

@ -2,15 +2,16 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Nährwertberechnungs-App</title>
<title>Elo's Rezept Rechner</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
<link rel="shortcut icon" href="../static/images/favicon.ico">
<script>
// JavaScript-Funktion, um die Produkte beim Laden der Seite zu holen
document.addEventListener('DOMContentLoaded', function() {
cleanUpLocalStorage();
restorePortions()
restoreTableFromLocalStorage();
updateTotalNutrition();
fetch('/get_products')
.then(response => response.json())
@ -33,6 +34,65 @@
});
});
document.getElementById('portions').addEventListener('input', function() {
const portions = this.value;
localStorage.setItem('savedPortions', portions); // Speichern der Portionen im localStorage
recalculateTableBasedOnPortions(); // Bestehende Funktion, um die Tabelle zu aktualisieren
});
function restorePortions() {
const savedPortions = localStorage.getItem('savedPortions');
if (savedPortions) {
document.getElementById('portions').value = savedPortions;
recalculateTableBasedOnPortions(); // Falls notwendig, um die Tabelle direkt zu aktualisieren
}
}
function recalculateTableBasedOnPortions() {
const portions = parseInt(document.getElementById('portions').value, 10) || 1;
let entries = JSON.parse(localStorage.getItem('nutritionEntries')) || [];
entries.forEach((entry, index) => {
const newWeight = Math.ceil(entry.weight / portions);
// Da die Server-Anfrage möglicherweise nicht sofort antwortet, passen wir den Index an, um die korrekte Zeile zu aktualisieren.
fetchUpdatedNutrition(entry.food, newWeight, index + 1); // +1, um den Kopfzeilenindex zu überspringen
});
}
function fetchUpdatedNutrition(food, weight, rowIndex) {
fetch(`/add_lm?food=${encodeURIComponent(food)}&weight=${encodeURIComponent(weight)}`)
.then(response => response.json())
.then(data => {
// Direktes Aktualisieren der Zeile mit den neuen Daten
const table = document.getElementById('nutrition-table');
if (table.rows[rowIndex]) {
updateRowWithNewData(table.rows[rowIndex], weight, data);
}
updateTotalNutrition(); // Aktualisiert die Gesamtnährwerte
})
.catch(error => {
console.error('Fehler:', error);
// Behandlung spezifischer Fehler, z.B. Zurücksetzen der Werte oder Anzeigen einer Fehlermeldung
});
}
function updateRowWithNewData(row, weight, nutritionData) {
if (nutritionData && row.cells.length > 7) {
row.cells[1].innerText = weight; // Aktualisiere Gewicht
row.cells[2].innerText = nutritionData.kcal;
row.cells[3].innerText = nutritionData.ew;
row.cells[4].innerText = nutritionData.fett;
row.cells[5].innerText = nutritionData.kh;
row.cells[6].innerText = nutritionData.bst;
row.cells[7].innerText = nutritionData.ca;
} else {
// Fehlerbehandlung, falls die Datenstruktur nicht wie erwartet ist
console.error('Unvollständige Daten erhalten: ', nutritionData);
}
}
function restoreTableFromLocalStorage() {
let entries = JSON.parse(localStorage.getItem('nutritionEntries')) || [];
let oneHourAgo = new Date().getTime() - (60 * 60 * 1000);
@ -50,14 +110,14 @@
const table = document.getElementById('nutrition-table');
const row = table.insertRow();
row.insertCell(0).innerHTML = food;
row.insertCell(1).innerHTML = weight;
row.insertCell(2).innerHTML = nutritionData.kcal;
row.insertCell(3).innerHTML = nutritionData.ew;
row.insertCell(4).innerHTML = nutritionData.fett;
row.insertCell(5).innerHTML = nutritionData.kh;
row.insertCell(6).innerHTML = nutritionData.bst;
row.insertCell(7).innerHTML = nutritionData.ca;
row.insertCell(0).innerText = food;
row.insertCell(1).innerText = weight;
row.insertCell(2).innerText = nutritionData.kcal;
row.insertCell(3).innerText = nutritionData.ew;
row.insertCell(4).innerText = nutritionData.fett;
row.insertCell(5).innerText = nutritionData.kh;
row.insertCell(6).innerText = nutritionData.bst;
row.insertCell(7).innerText = nutritionData.ca;
}
@ -96,9 +156,13 @@
function removeEntryFromLocalStorage(rowData) {
let entries = JSON.parse(localStorage.getItem('nutritionEntries')) || [];
entries = entries.filter(entry => entry.food !== rowData.food || entry.weight !== rowData.weight);
// Konvertieren von rowData.weight in eine Zahl, um eine korrekte Vergleichsbasis zu schaffen
const weightToCompare = parseFloat(rowData.weight);
// Verwendung einer strikten Gleichheitsprüfung für beide Werte
entries = entries.filter(entry => entry.food !== rowData.food || parseFloat(entry.weight) !== weightToCompare);
localStorage.setItem('nutritionEntries', JSON.stringify(entries));
}
}
function updateRemoveButtonState() {
const selectedRows = document.querySelectorAll('#nutrition-table .selected').length;
@ -112,11 +176,29 @@
document.getElementById('submit-button').disabled = !(food && weight);
}
function schulrunden(zahl) {
// Multipliziere die Zahl mit 10, um die relevante Dezimalstelle vor das Komma zu bekommen
zahl = zahl * 10;
// Wende Math.ceil an, um auf die nächste ganze Zahl aufzurunden,
// aber nur, wenn der Dezimalteil >= 0.5 ist. Andernfalls verwende Math.floor.
zahl = (zahl - Math.floor(zahl) >= 0.5) ? Math.ceil(zahl) : Math.floor(zahl);
// Teile durch 10, um die ursprüngliche Skalierung wiederherzustellen,
// aber mit der erforderlichen Rundung
return zahl / 10;
}
function addProduct() {
const foodInput = document.getElementById('my_combobox');
const weightInput = document.getElementById('weight');
const portionsInput = document.getElementById('portions');
const food = foodInput.value;
const weight = weightInput.value;
let weight = parseFloat(weightInput.value);
const portions = portionsInput.value ? parseInt(portionsInput.value, 10) : 1;
// Teilen des Gewichts durch die Anzahl der Portionen und Aufrunden
weight = schulrunden(weight / portions);
fetch(`/add_lm?food=${encodeURIComponent(food)}&weight=${encodeURIComponent(weight)}`)
@ -125,14 +207,14 @@
const table = document.getElementById('nutrition-table');
const row = table.insertRow();
// Fügt die einzelnen Nährwerte zur neuen Zeile hinzu
row.insertCell(0).innerHTML = food;
row.insertCell(1).innerHTML = weight;
row.insertCell(2).innerHTML = data.kcal;
row.insertCell(3).innerHTML = data.ew;
row.insertCell(4).innerHTML = data.fett;
row.insertCell(5).innerHTML = data.kh;
row.insertCell(6).innerHTML = data.bst;
row.insertCell(7).innerHTML = data.ca;
row.insertCell(0).innerText = food;
row.insertCell(1).innerText = weight;
row.insertCell(2).innerText = data.kcal;
row.insertCell(3).innerText = data.ew;
row.insertCell(4).innerText = data.fett;
row.insertCell(5).innerText = data.kh;
row.insertCell(6).innerText = data.bst;
row.insertCell(7).innerText = data.ca;
foodInput.value = ''; // Zurücksetzen des Lebensmittel-Eingabefeldes
weightInput.value = ''; // Zurücksetzen des Gewicht-Eingabefeldes
@ -176,7 +258,10 @@ function updateTotalNutrition() {
</head>
<body>
<nav id="navbar">
<h1>Elos Rezept Rechner</h1>
<div class="navbar-header">
<h1>Elo's Rezept Rechner</h1>
<li class="versionid">VERSION_ID</li>
</div>
<ul>
<li><a href="/" class="active">Rechner</a></li>
<li><a href="/nutrition">Neue Lebensmittel</a></li>
@ -185,16 +270,24 @@ function updateTotalNutrition() {
<div class="content">
<form onsubmit="event.preventDefault(); addProduct();" id="product-form">
<form onsubmit="event.preventDefault(); addProduct();" id="product-form" class="form-layout">
<div class="form-row">
<label for="portions">Wählen Sie die Anzahl an Portionen</label>
<input type="number" id="portions" name="portions" placeholder="Portionen" min="1" value="1" oninput="recalculateTableBasedOnPortions()">
</div>
<div class="form-row">
<label for="my_combobox">Wählen Sie ein Lebensmittel</label>
<input list="products" name="my_combobox" id="my_combobox" placeholder="Lebensmittel" oninput="updateButtonState()" autocomplete="off">
<datalist id="products">
<!-- Produkte werden hier dynamisch eingefügt -->
</datalist>
<input type="number" id="weight" name="weight" placeholder="Gramm" oninput="updateButtonState()">
<input type="number" id="weight" name="weight" placeholder="Gramm" step="0.1" min="0" oninput="updateButtonState()">
<button type="submit" id="submit-button" disabled>Hinzufügen</button>
</div>
</form>
<table id="nutrition-table">
<tr>
<th>Lebensmittel</th>
@ -208,9 +301,11 @@ function updateTotalNutrition() {
</tr>
<!-- Zeilen werden hier dynamisch hinzugefügt -->
</table>
<button id="remove-button" onclick="removeSelectedRow()" disabled>Entfernen</button>
<button id="remove-button" onclick="removeSelectedRow()" disabled></button>
<table id="total-nutrition-table">
<tr>
<th>Lebensmittel</th>
<th>Gewicht (g)</th>
<th>kcal</th>
<th>EW</th>
<th>Fett</th>
@ -219,6 +314,8 @@ function updateTotalNutrition() {
<th>CA</th>
</tr>
<tr>
<td>Gesamtwerte</td>
<td>-</td>
<td id="total-kcal">0</td>
<td id="total-ew">0</td>
<td id="total-fett">0</td>

View File

@ -2,8 +2,10 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Neue Lebensmittel hinzufügen</title>
<title>Elo's Rezept Rechner</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
<link rel="shortcut icon" href="../static/images/favicon.ico">
<script>
function updateSubmitButtonState() {
const inputs = document.querySelectorAll('#nutrition-form input');
@ -11,19 +13,34 @@
document.getElementById('submit-button').disabled = !allFilled;
}
function addNutritionEntry() {
function getBearerToken(callback) {
fetch('/get_token')
.then(response => response.json())
.then(data => {
callback(data.token);
})
.catch(error => {
console.error('Fehler beim Abrufen des Tokens:', error);
});
}
function addNutritionEntry() {
getBearerToken(token => {
const form = document.getElementById('nutrition-form');
const formData = new FormData(form);
fetch('/add_nutrition', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token
},
body: formData
}).then(response => {
// Behandlung der Serverantwort
// Beispielsweise das Formular zurücksetzen
form.reset();
updateSubmitButtonState();
loadDatabaseEntries();
}).catch(error => {
console.error('Fehler:', error);
});
@ -36,19 +53,143 @@
// Deaktiviere den "Hinzufügen"-Button wieder
document.getElementById('submit-button').disabled = true;
}
});
}
document.addEventListener('DOMContentLoaded', function() {
const table = document.getElementById('database-nutrition-table');
table.addEventListener('click', function(e) {
if (e.target.tagName === 'TD') {
e.target.parentNode.classList.toggle('selected');
updateDeleteButtonState();
}
});
updateDeleteButtonState();
});
function deleteSelectedRows() {
const table = document.getElementById('database-nutrition-table');
const selectedRows = Array.from(table.querySelectorAll('tr.selected'));
const foodNames = selectedRows.map(row => row.cells[0].innerText); // Annahme, der Name des Lebensmittels befindet sich in der ersten Zelle
if (foodNames.length > 0) {
// Holen des Tokens und Senden einer Anfrage an das Backend, um die Einträge zu löschen
getBearerToken(token => {
fetch('/delete_nutrition', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
},
body: JSON.stringify({foodNames: foodNames})
}).then(response => {
if (response.ok) {
// Erfolgreich gelöscht, entferne Zeilen aus der Tabelle
selectedRows.forEach(row => {
table.deleteRow(row.rowIndex);
});
} else {
console.error('Fehler beim Löschen der Datenbank-Einträge');
}
}).catch(error => console.error('Fehler:', error));
});
}
}
function showPasswordPrompt() {
document.getElementById('delete-row-button').style.display = 'none';
document.getElementById('password-prompt').style.display = 'block';
}
function hidePasswordPrompt() {
document.getElementById('delete-row-button').style.display = 'block';
document.getElementById('password-prompt').style.display = 'none';
}
function deleteRowsIfPasswordCorrect() {
const password = document.getElementById('password-input').value;
if (password === 'geheim') {
deleteSelectedRows(); // Funktion, die die ausgewählten Zeilen löscht
hidePasswordPrompt();
} else {
alert('Falsches Passwort!');
}
}
function updateDeleteButtonState() {
const selectedRows = document.querySelectorAll('#database-nutrition-table .selected').length;
const deleteButton = document.getElementById('delete-row-button');
deleteButton.disabled = selectedRows === 0;
if (selectedRows === 0) {
hidePasswordPrompt(); // Versteckt die Passwort-Eingabe, falls keine Zeile ausgewählt ist
}
}
function loadDatabaseEntries() {
fetch('/get_database_entries') // Pfad zur entsprechenden Flask-Route
.then(response => response.json())
.then(data => {
const tableBody = document.getElementById('database-nutrition-table').getElementsByTagName('tbody')[0];
tableBody.innerHTML = '';
data.forEach(entry => {
const row = tableBody.insertRow();
row.insertCell(0).innerHTML = entry.food;
row.insertCell(1).innerHTML = entry.kcal;
row.insertCell(2).innerHTML = entry.ew;
row.insertCell(3).innerHTML = entry.fett;
row.insertCell(4).innerHTML = entry.kh;
row.insertCell(5).innerHTML = entry.bst;
row.insertCell(6).innerHTML = entry.ca;
// ... Fügen Sie weitere Zellen für die anderen Werte hinzu ...
});
})
.catch(error => console.error('Fehler:', error));
}
document.addEventListener('DOMContentLoaded', loadDatabaseEntries);
function filterTable() {
const searchInput = document.getElementById('search-input');
const filterText = searchInput.value.toUpperCase();
const table = document.getElementById('database-nutrition-table');
const rows = table.getElementsByTagName('tr');
for (let i = 1; i < rows.length; i++) { // Beginnen bei 1, um die Kopfzeile auszulassen
const cell = rows[i].getElementsByTagName('td')[0]; // Angenommen, der zu suchende Text befindet sich in der ersten Spalte
if (cell) {
const textValue = cell.textContent || cell.innerText;
if (textValue.toUpperCase().indexOf(filterText) > -1) {
rows[i].style.display = ""; // Zeile anzeigen
} else {
rows[i].style.display = "none"; // Zeile verstecken
}
}
}
}
function openImagePage() {
window.open('random', '_blank'); // Öffnet die neue Seite in einem neuen Tab
}
</script>
</head>
<body>
<nav id="navbar">
<h1>Elos Rezept Rechner</h1>
<div class="navbar-header">
<h1>Elo's Rezept Rechner</h1>
<li class="versionid">VERSION_ID</li>
</div>
<ul>
<li><a href="/">Rechner</a></li>
<li><a href="/nutrition" class="active">Neue Lebensmittel</a></li>
</ul>
</nav>
<div class="content">
<form onsubmit="event.preventDefault(); addNutritionEntry();" method="POST" id="nutrition-form">
<table id="nutrition-input-table">
@ -62,17 +203,54 @@
<th>CA</th>
</tr>
<tr>
<td><input type="text" name="food" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="kcal" pattern="\d+(\.\d{1,2})?" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="ew" pattern="\d+(\.\d{1,2})?" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="fett" pattern="\d+(\.\d{1,2})?" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="kh" pattern="\d+(\.\d{1,2})?" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="bst" pattern="\d+(\.\d{1,2})?" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="ca" pattern="\d+(\.\d{1,2})?" oninput="updateSubmitButtonState()"></td>
<td><input type="text" name="food" placeholder="Lebensmittel" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="kcal" pattern="\d+([.,]\d{1,2})?" placeholder="g" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="ew" pattern="\d+([.,]\d{1,2})?" placeholder="g" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="fett" pattern="\d+([.,]\d{1,2})?" placeholder="g" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="kh" pattern="\d+([.,]\d{1,2})?" placeholder="g" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="bst" pattern="\d+([.,]\d{1,2})?" placeholder="g" oninput="updateSubmitButtonState()"></td>
<td><input <input type="text" name="ca" pattern="\d+([.,]\d{1,2})?" placeholder="mg" oninput="updateSubmitButtonState()"></td>
</tr>
</table>
<button type="submit" id="submit-button" disabled>Hinzufügen</button>
</form>
<div class="search-container">
<input type="text" id="search-input" placeholder="Lebensmittel suchen..." oninput="filterTable()">
<button onclick="openImagePage()" style="background-image: url('../static/images/marie.jpg'); border: none; cursor: pointer; background-size: cover; width: 62px; height: 85px; vertical-align: middle;">
<!-- Der Text wird durch den transparenten Text ersetzt, falls nötig -->
<span style="opacity: 0;">Öffnen</span>
</button>
</div>
<div class="table-container">
<table id="database-nutrition-table">
<thead>
<tr>
<th>Lebensmittel</th>
<th>kcal</th>
<th>EW</th>
<th>Fett</th>
<th>KH</th>
<th>BST</th>
<th>CA</th>
</tr>
</thead>
<tbody>
<!-- Die Zeilen werden dynamisch aus der Datenbank geladen -->
</tbody>
</table>
</div>
<button id="delete-row-button" onclick="showPasswordPrompt()">Zeilen löschen</button>
<div id="password-prompt" style="display: none;">
<input type="password" id="password-input" placeholder="Passwort">
<button id="ok-button" onclick="deleteRowsIfPasswordCorrect()">OK</button>
<button id="cancel-button" onclick="hidePasswordPrompt()">Abbrechen</button>
</div>
</div>
</body>
</html>

10
src/templates/random.html Normal file
View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bildansicht</title>
</head>
<body style="margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh;">
<img src="../static/images/elo.jpg" alt="Elo Bild" style="max-width: 100%; max-height: 100%;">
</body>
</html>

View File

@ -1,4 +1,6 @@
#!/bin/sh
gunicorn 'Run:app' --bind 0.0.0.0:8080 --log-level=info --workers=4
gunicorn 'Run:exposed_app' --bind 0.0.0.0:8080 --log-level=debug --workers=4