first
This commit is contained in:
11
.gitea/workflows/docker.yml
Normal file
11
.gitea/workflows/docker.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
name: start compose
|
||||||
|
|
||||||
|
on:
|
||||||
|
- pull_request
|
||||||
|
- push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
start-compose:
|
||||||
|
steps:
|
||||||
|
- name: restart Compose
|
||||||
|
run: docker compose up
|
||||||
25
Dockerfile
Normal file
25
Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
FROM python:3.14.0a3-alpine3.21
|
||||||
|
|
||||||
|
# Set up environment variables for Python
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
# Create and set the working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy only the requirements file first to leverage Docker caching
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy the entire application code
|
||||||
|
# COPY . .
|
||||||
|
|
||||||
|
# Expose the port your application will run on
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Specify the command to run on container start
|
||||||
|
CMD ["python", "app.py"]
|
||||||
46
app.py
Normal file
46
app.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from flask import Flask, render_template, request, session
|
||||||
|
|
||||||
|
import modify_csv
|
||||||
|
import read_cat
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.secret_key = "Start1234!"
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
def index():
|
||||||
|
return render_template(
|
||||||
|
"index.html",
|
||||||
|
sitename="Ausgaben der Familie",
|
||||||
|
data=modify_csv.read_csv_file(),
|
||||||
|
sum_all=modify_csv.sum_all(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/add_ausgabe")
|
||||||
|
def add_ausgabe():
|
||||||
|
return render_template(
|
||||||
|
"add_ausgabe.html",
|
||||||
|
url="output",
|
||||||
|
select_id_text="add_value",
|
||||||
|
select_id="add_disc",
|
||||||
|
data=read_cat.read_cat_file(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/output")
|
||||||
|
def csv_output():
|
||||||
|
modify_csv.write_csv_file(
|
||||||
|
betrag=request.form["add_value"], select_dist=request.form["add_disc"]
|
||||||
|
)
|
||||||
|
return render_template(
|
||||||
|
"index.html",
|
||||||
|
csv_value_text=request.form["add_value"],
|
||||||
|
csv_value_disc=request.form["add_disc"],
|
||||||
|
data=modify_csv.read_csv_file(),
|
||||||
|
sum_all=modify_csv.sum_all(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(port=5080, host="0.0.0.0", debug=True)
|
||||||
16
ausgaben.csv
Normal file
16
ausgaben.csv
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
datum,ausgaben,beschreibung
|
||||||
|
2025-01-09,123,Essen
|
||||||
|
2025-01-09,23.34,Essen
|
||||||
|
2025-01-09,100,Essen
|
||||||
|
2025-01-09,1500,Miete
|
||||||
|
2025-01-09,0,Arbeit
|
||||||
|
2025-01-14,123.34,Essen
|
||||||
|
2025-01-20,2423.3,Essen
|
||||||
|
2025-01-20,23,Essen
|
||||||
|
2025-01-20,234.45,Arbeit
|
||||||
|
2025-03-02,333,Essen
|
||||||
|
2025-03-02,2.34,Essen
|
||||||
|
2025-03-02,12345.2,Essen
|
||||||
|
2025-03-05,10,Essen
|
||||||
|
2025-03-05,10,Essen
|
||||||
|
2025-03-19,12,Media
|
||||||
|
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
python-app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
ports:
|
||||||
|
- "5080:5080"
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
restart: on-failure:3
|
||||||
68
modify_csv.py
Executable file
68
modify_csv.py
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#! /usr/bin/env python3.13
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
|
||||||
|
def create_csv_file(csv_path="ausgaben.csv"):
|
||||||
|
if not os.path.exists(csv_path):
|
||||||
|
print(csv_path, "wird angelegt !!")
|
||||||
|
to_write_header = ["datum", "ausgaben", "beschreibung"]
|
||||||
|
with open(csv_path, "w") as wfile:
|
||||||
|
writer = csv.writer(wfile)
|
||||||
|
writer.writerow(to_write_header)
|
||||||
|
return "INFO :", csv_path, "wurde angelegt"
|
||||||
|
else:
|
||||||
|
return "INFO :", csv_path, "existiert bereits"
|
||||||
|
|
||||||
|
|
||||||
|
def read_csv_file(csv_file="ausgaben.csv"):
|
||||||
|
if os.path.exists(csv_file):
|
||||||
|
read_csv_file_ausgabe = []
|
||||||
|
|
||||||
|
with open(csv_file, "r") as ocsv:
|
||||||
|
read_csv_full = csv.DictReader(ocsv)
|
||||||
|
for csv_lines in read_csv_full:
|
||||||
|
read_csv_file_ausgabe.append(
|
||||||
|
{
|
||||||
|
"datum": csv_lines["datum"],
|
||||||
|
"ausgabe": csv_lines["ausgaben"],
|
||||||
|
"beschreibung": csv_lines["beschreibung"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return read_csv_file_ausgabe
|
||||||
|
else:
|
||||||
|
create_csv_file()
|
||||||
|
read_csv_file()
|
||||||
|
|
||||||
|
|
||||||
|
def write_csv_file(
|
||||||
|
csv_file="ausgaben.csv", date_time=date.today(), betrag=float, select_dist="Essen"
|
||||||
|
):
|
||||||
|
|
||||||
|
import_list = [date_time, betrag, select_dist]
|
||||||
|
with open(csv_file, "a") as wfile:
|
||||||
|
writer = csv.writer(wfile)
|
||||||
|
writer.writerow(import_list)
|
||||||
|
|
||||||
|
|
||||||
|
def sum_all():
|
||||||
|
sum_rech = float(0)
|
||||||
|
for val_csv in read_csv_file():
|
||||||
|
sum_rech = float(sum_rech) + float(val_csv["ausgabe"])
|
||||||
|
return round(sum_rech, 2)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(sum_all())
|
||||||
|
# Apply multiple filters
|
||||||
|
# print(create_csv_file())
|
||||||
|
# print(read_csv_file())
|
||||||
|
# for i in read_csv_file():
|
||||||
|
# query_str = i["datum"][:-3]
|
||||||
|
# if query_str == "2025-01":
|
||||||
|
# print(i["datum"], " ist in 2025-01")
|
||||||
|
# if i["datum"] < date("2025", "01", "01"):
|
||||||
|
# print(True)
|
||||||
|
# webbrowser.open("file://" + os.path.realpath("ausgabe.html"))
|
||||||
10
read_cat.py
Normal file
10
read_cat.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
def read_cat_file(filename="cat_file"):
|
||||||
|
out_list = []
|
||||||
|
with open(filename, "r") as cat:
|
||||||
|
for line in cat:
|
||||||
|
out_list.append(line.rstrip())
|
||||||
|
return out_list
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(read_cat_file())
|
||||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
flask==2.3.3
|
||||||
22
templates/add_ausgabe.html
Normal file
22
templates/add_ausgabe.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<form action="{{ url }}" method="POST">
|
||||||
|
<input type="number"
|
||||||
|
step="0.01"
|
||||||
|
min="1"
|
||||||
|
max="10000"
|
||||||
|
placeholder="Ausgaben"
|
||||||
|
name="{{ select_id_text }}"
|
||||||
|
id="{{ select_id_text }}">
|
||||||
|
|
||||||
|
<select name="{{ select_id }}" id="{{ select_id }}">
|
||||||
|
{% for name in data %}
|
||||||
|
<option value="{{ name }}">{{ name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button type="submit"> Eingabe </button>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
11
templates/base.html
Normal file
11
templates/base.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title> {{ sitename }} </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h3> {{ sitename }} </h3>
|
||||||
|
{% block body %}
|
||||||
|
{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
24
templates/index.html
Normal file
24
templates/index.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>
|
||||||
|
<h4>Diese Seite zeigt unsere Ausgaben</h4>
|
||||||
|
Ausgabe hinzufügen <a href="/add_ausgabe">Klick</a> .
|
||||||
|
</p>
|
||||||
|
<table border="1" width="50%">
|
||||||
|
<tr>
|
||||||
|
<th>Datum</th>
|
||||||
|
<th>Ausgaben</th>
|
||||||
|
<th>Beschreibung</th>
|
||||||
|
</tr>
|
||||||
|
{% for name in data %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ name.get("datum") }}</td>
|
||||||
|
<td>{{ name.get("ausgabe") }}</td>
|
||||||
|
<td> {{ name.get("beschreibung") }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<p><br><h5>Gesamt: {{sum_all}}</h5>
|
||||||
|
<p> Nächste Schritte </p>
|
||||||
|
{% endblock %}
|
||||||
22
templates/output.html
Normal file
22
templates/output.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<p>
|
||||||
|
Ausgabe = {{ csv_value_text }} <br> Beschreibung = {{csv_value_disc}}
|
||||||
|
<br>
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Ausgaben</th>
|
||||||
|
<th>Beschreibung</th>
|
||||||
|
</tr>
|
||||||
|
{% for name in data %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ name.get("ausgabe") }}</td>
|
||||||
|
<td> {{ name.get("beschreibung") }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p><br><h5>Gesamt: {{sum_all}}</h5>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user