60 Commits
Beta-4 ... main

Author SHA1 Message Date
5acf461cc6 Merge pull request 'Beta-5' (#21) from Beta-5 into main
Reviewed-on: #21
2026-01-23 19:59:41 +00:00
36e90ce1fd update.bat aktualisiert 2026-01-23 19:58:24 +00:00
b62e50a354 installer.bat aktualisiert 2026-01-23 19:57:43 +00:00
9fd337f670 update.sh aktualisiert 2026-01-23 19:56:24 +00:00
5e454264a3 Merge pull request 'Beta-5' (#20) from Beta-5 into main
Reviewed-on: #20
2026-01-23 16:52:39 +00:00
a29b230482 update.sh aktualisiert 2026-01-23 16:51:54 +00:00
314b1c3ba7 update.bat aktualisiert 2026-01-23 16:51:27 +00:00
3c4212bd03 installer.bat aktualisiert 2026-01-23 16:50:53 +00:00
426d7bbcaf start_app.py aktualisiert 2026-01-22 12:07:37 +00:00
4aff839f36 Dateien nach "/" hochladen 2026-01-22 11:50:26 +00:00
5f9db6397d Merge pull request 'start_app.py aktualisiert' (#19) from Beta-5 into main
Reviewed-on: http://89.182.100.163:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/19
2026-01-22 11:48:58 +00:00
4f94fc9669 start_app.py aktualisiert 2026-01-22 11:47:53 +00:00
3574700386 Merge pull request 'start_app.py aktualisiert' (#18) from Beta-5 into main
Reviewed-on: http://89.182.100.163:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/18
2026-01-22 11:43:29 +00:00
5764f28984 start_app.py aktualisiert 2026-01-22 11:42:09 +00:00
592453c1ff Merge pull request 'pflanzen_gui.py aktualisiert' (#17) from Beta-5 into main
Reviewed-on: http://192.168.178.11:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/17
2026-01-22 11:34:18 +00:00
7352491d95 pflanzen_gui.py aktualisiert 2026-01-22 11:33:17 +00:00
afcd970b50 Merge pull request 'Beta-5' (#16) from Beta-5 into main
Reviewed-on: http://192.168.178.11:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/16
2026-01-22 11:29:44 +00:00
b317923438 Dateien nach "/" hochladen 2026-01-22 11:29:21 +00:00
e74d4b6d17 start4.bat gelöscht 2026-01-22 11:28:59 +00:00
4e9d746332 start4.bat gelöscht 2026-01-22 11:27:11 +00:00
016a063a66 Dateien nach "biobizz" hochladen 2026-01-22 11:26:19 +00:00
4ed400abb6 Dateien nach "biobizz" hochladen 2026-01-22 11:26:01 +00:00
cf55fcf610 Dateien nach "biobizz" hochladen 2026-01-22 11:25:12 +00:00
c33ffcd6a8 biobizz/Top·Max.jpg gelöscht 2026-01-22 11:24:33 +00:00
5a97b27a77 biobizz/Root·Juice.jpg gelöscht 2026-01-22 11:24:24 +00:00
2c65f30102 biobizz/PH+.jpg gelöscht 2026-01-22 11:24:16 +00:00
de4a06cc3a biobizz/ph-.jpg gelöscht 2026-01-22 11:24:08 +00:00
bb9383d896 biobizz/Light·Mix.jpg gelöscht 2026-01-22 11:24:01 +00:00
365f2b3553 biobizz/Fish·Mix.jpg gelöscht 2026-01-22 11:23:50 +00:00
bcbd3ab32a biobizz/coco mix.jpg gelöscht 2026-01-22 11:23:40 +00:00
46fca79ffa biobizz/calmag.jpg gelöscht 2026-01-22 11:23:22 +00:00
3a231c5333 biobizz/Bio·Heaven.jpg gelöscht 2026-01-22 11:23:13 +00:00
d5917b285d biobizz/Bio·Grow.jpg gelöscht 2026-01-22 11:23:03 +00:00
452e31c278 biobizz/Bio·Bloom.jpg gelöscht 2026-01-22 11:22:57 +00:00
8e8a5e80b6 biobizz/All·Mix.jpg gelöscht 2026-01-22 11:22:49 +00:00
6c715fa5ef biobizz/Alg·A·Mic.jpg gelöscht 2026-01-22 11:22:41 +00:00
128edc1ce9 biobizz/Acti·Vera.jpg gelöscht 2026-01-22 11:22:04 +00:00
56a3da70f7 Dateien nach "/" hochladen 2026-01-22 11:21:52 +00:00
2f15b7473e pflanzen_gui.py gelöscht 2026-01-22 11:21:34 +00:00
7f08b04859 start_app.py aktualisiert 2026-01-21 13:25:35 +00:00
2b5e8b149f start_app.py aktualisiert 2026-01-21 13:24:33 +00:00
9e208f3f7e start4.bat aktualisiert 2026-01-21 13:23:04 +00:00
22ad2e2c9d start4.bat aktualisiert 2026-01-21 13:16:06 +00:00
819d3f074e start4.bat aktualisiert 2026-01-21 13:15:42 +00:00
861e5dc33a Merge pull request 'update.bat aktualisiert' (#7) from Beta-5 into main
Reviewed-on: http://192.168.178.11:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/7
2026-01-21 13:14:18 +00:00
de0fe14e2d update.bat aktualisiert 2026-01-21 13:12:25 +00:00
fc0a6f9b90 Merge pull request 'update.bat aktualisiert' (#6) from Beta-5 into main
Reviewed-on: http://192.168.178.11:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/6
2026-01-21 13:10:57 +00:00
86d35fba6b Dateien nach "/" hochladen 2026-01-21 13:10:28 +00:00
168754137a start4.bat gelöscht 2026-01-21 13:10:05 +00:00
9e571f253f update.bat aktualisiert 2026-01-21 13:08:19 +00:00
bfb47d9d5e update.bat aktualisiert 2026-01-21 13:06:46 +00:00
3b342a16c7 Merge pull request 'Beta-5' (#5) from Beta-5 into main
Reviewed-on: http://192.168.178.11:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/5
2026-01-20 17:51:36 +00:00
01daa88707 Dateien nach "biobizz" hochladen 2026-01-20 17:31:05 +00:00
dfb9b1948e Dateien nach "biobizz" hochladen 2026-01-20 17:30:38 +00:00
5e10ff0cb2 Dateien nach "biobizz" hochladen 2026-01-20 17:29:38 +00:00
3716b685a0 Dateien nach "/" hochladen 2026-01-20 17:27:21 +00:00
a2ae52f294 Dateien nach "/" hochladen 2026-01-20 17:26:08 +00:00
b864e731b1 installer.bat aktualisiert 2026-01-19 17:31:55 +00:00
cbd5d695f9 Merge pull request 'Beta-4' (#2) from Beta-4 into main
Reviewed-on: http://192.168.178.11:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/2
2026-01-19 16:44:24 +00:00
f8f047c84d Merge pull request 'Beta-4' (#1) from Beta-4 into main
Reviewed-on: http://192.168.178.11:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer/pulls/1
2026-01-19 14:11:34 +00:00
20 changed files with 839 additions and 911 deletions

BIN
biobizz/Acti Vera.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
biobizz/Alg A Mic.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
biobizz/All Mix.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
biobizz/Bio Bloom.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
biobizz/Bio Grow.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
biobizz/Bio Heaven.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
biobizz/Fish Mix.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
biobizz/Light Mix.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
biobizz/PH+.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
biobizz/Root Juice.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
biobizz/Top Max.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
biobizz/calmag.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
biobizz/coco mix.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
biobizz/ph-.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -6,12 +6,15 @@ from mysql.connector import errorcode
PROTOKOLL_TABLE_NAME = 'pflanzenprotokoll'
PLANUNG_TABLE_NAME = 'pflanzenplanung'
def get_db_connection(config, with_db=False):
"""Versucht, eine Verbindung zur Datenbank herzustellen."""
def get_db_connection(config, with_db=True):
"""
Versucht, eine Verbindung zur Datenbank herzustellen.
Standardmäßig wird versucht, die in der Config angegebene DB direkt zu nutzen.
"""
port = config.get('port', 3306)
db_args = {}
if with_db:
if with_db and 'database' in config:
db_args['database'] = config['database']
try:
@@ -41,7 +44,7 @@ def setup_database_and_table(cursor, db_name):
cursor.execute(f"CREATE DATABASE IF NOT EXISTS {db_name} DEFAULT CHARACTER SET 'utf8'")
cursor.execute(f"USE {db_name}")
except mysql.connector.Error as err:
return False, f"Fehler beim Erstellen/Auswählen der Datenbank: {err}"
return False, f"Fehler beim Erstellen oder Auswählen der Datenbank: {err}"
# Protokoll-Tabelle (Ist-Werte)
PROTOKOLL_DESCRIPTION = f"""
@@ -54,6 +57,8 @@ def setup_database_and_table(cursor, db_name):
root_juice_ml_l FLOAT,
calmag_ml_l FLOAT,
bio_grow_ml_l FLOAT,
fish_mix_ml_l FLOAT,
bio_heaven_ml_l FLOAT,
acti_alc_ml_l FLOAT,
bio_bloom_ml_l FLOAT,
top_max_ml_l FLOAT,
@@ -73,6 +78,8 @@ def setup_database_and_table(cursor, db_name):
root_juice_ml_l FLOAT,
calmag_ml_l FLOAT,
bio_grow_ml_l FLOAT,
fish_mix_ml_l FLOAT,
bio_heaven_ml_l FLOAT,
acti_alc_ml_l FLOAT,
bio_bloom_ml_l FLOAT,
top_max_ml_l FLOAT,
@@ -86,56 +93,65 @@ def setup_database_and_table(cursor, db_name):
cursor.execute(PROTOKOLL_DESCRIPTION)
cursor.execute(PLANUNG_DESCRIPTION)
# Sicherstellen, dass die Spalte ec_wert existiert (für Updates bestehender Tabellen)
# Spalten nachträglich hinzufügen, falls sie fehlen (Migration)
for table in [PROTOKOLL_TABLE_NAME, PLANUNG_TABLE_NAME]:
# Fish-Mix
try:
cursor.execute(f"ALTER TABLE {table} ADD COLUMN fish_mix_ml_l FLOAT AFTER bio_grow_ml_l")
except: pass
# Bio-Heaven
try:
cursor.execute(f"ALTER TABLE {table} ADD COLUMN bio_heaven_ml_l FLOAT AFTER fish_mix_ml_l")
except: pass
# EC-Wert
try:
cursor.execute(f"ALTER TABLE {table} ADD COLUMN ec_wert FLOAT AFTER ph_wert_ziel")
except mysql.connector.Error as err:
if err.errno != 1060: # 1060 = Spalte existiert bereits, das ist okay
print(f"Hinweis bei Alter Table {table}: {err.msg}")
return True, "Datenbankstruktur erfolgreich eingerichtet."
except: pass
return True, "Datenbankstruktur erfolgreich eingerichtet oder aktualisiert."
except mysql.connector.Error as err:
return False, f"Fehler beim Erstellen der Tabellen: {err.msg}"
def insert_pflanzen_data(cnx, datensatz):
"""Fügt einen neuen IST-Datensatz (Protokoll) in die Tabelle ein und committet."""
"""Fügt einen neuen IST-Datensatz (Protokoll) in die Tabelle ein."""
cursor = cnx.cursor()
add_log = (f"INSERT INTO {PROTOKOLL_TABLE_NAME} "
"(pflanzen_name, woche, phase, lichtzyklus_h, root_juice_ml_l, "
"calmag_ml_l, bio_grow_ml_l, acti_alc_ml_l, bio_bloom_ml_l, "
"top_max_ml_l, ph_wert_ziel, ec_wert, erstellungsdatum) "
"VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)")
"calmag_ml_l, bio_grow_ml_l, fish_mix_ml_l, bio_heaven_ml_l, acti_alc_ml_l, "
"bio_bloom_ml_l, top_max_ml_l, ph_wert_ziel, ec_wert, erstellungsdatum) "
"VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)")
try:
cursor.execute(add_log, datensatz)
last_id = cursor.lastrowid
cnx.commit()
cursor.close()
return True, f"Datensatz erfolgreich eingefügt. (ID: {last_id})"
return True, f"Datensatz erfolgreich eingefügt. (ID: {last_id})"
except mysql.connector.Error as err:
cursor.close()
return False, f"Fehler beim Einfügen des Datensatzes: {err.msg}"
return False, f"Fehler beim Einfügen des Datensatzes: {err.msg}"
def save_pflanzen_plan(cnx, planungsdatensatz):
"""Speichert oder aktualisiert einen SOLL-Datensatz (Planung) in der Tabelle."""
"""Speichert oder aktualisiert einen SOLL-Datensatz in der Planungstabelle."""
cursor = cnx.cursor()
save_plan = f"""
INSERT INTO {PLANUNG_TABLE_NAME}
(pflanzen_name, woche, phase, lichtzyklus_h, root_juice_ml_l,
calmag_ml_l, bio_grow_ml_l, acti_alc_ml_l, bio_bloom_ml_l,
top_max_ml_l, ph_wert_ziel, ec_wert)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
calmag_ml_l, bio_grow_ml_l, fish_mix_ml_l, bio_heaven_ml_l, acti_alc_ml_l,
bio_bloom_ml_l, top_max_ml_l, ph_wert_ziel, ec_wert)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
phase = VALUES(phase),
lichtzyklus_h = VALUES(lichtzyklus_h),
root_juice_ml_l = VALUES(root_juice_ml_l),
calmag_ml_l = VALUES(calmag_ml_l),
bio_grow_ml_l = VALUES(bio_grow_ml_l),
fish_mix_ml_l = VALUES(fish_mix_ml_l),
bio_heaven_ml_l = VALUES(bio_heaven_ml_l),
acti_alc_ml_l = VALUES(acti_alc_ml_l),
bio_bloom_ml_l = VALUES(bio_bloom_ml_l),
top_max_ml_l = VALUES(top_max_ml_l),
@@ -147,20 +163,19 @@ def save_pflanzen_plan(cnx, planungsdatensatz):
cursor.execute(save_plan, planungsdatensatz)
cnx.commit()
cursor.close()
return True, "Planung erfolgreich gespeichert/aktualisiert."
return True, "Planung erfolgreich gespeichert/aktualisiert."
except mysql.connector.Error as err:
cursor.close()
return False, f"Fehler beim Speichern der Planung: {err.msg}"
return False, f"Fehler beim Speichern der Planung: {err.msg}"
def get_pflanzen_plan(config, plant_name, week):
"""Ruft den Plan für eine spezifische Pflanze und Woche ab."""
"""Holt einen spezifischen Plan (Soll-Werte) aus der DB."""
cnx, result = get_db_connection(config, with_db=True)
if cnx is None:
return None, None
cursor = cnx.cursor()
try:
query = f"SELECT * FROM {PLANUNG_TABLE_NAME} WHERE pflanzen_name = %s AND woche = %s"
cursor.execute(query, (plant_name, week))
@@ -171,21 +186,19 @@ def get_pflanzen_plan(config, plant_name, week):
cursor.close()
cnx.close()
return plan, column_names
except mysql.connector.Error:
except:
cursor.close()
cnx.close()
return None, None
def fetch_all_data(config):
"""Holt alle Protokolleinträge aus der Datenbank."""
"""Holt alle Datensätze aus dem Protokoll für die Anzeige."""
cnx, result = get_db_connection(config, with_db=True)
if cnx is None:
return None, result
cursor = cnx.cursor()
try:
cursor.execute(f"SELECT * FROM {PROTOKOLL_TABLE_NAME} ORDER BY erstellungsdatum DESC")
data = cursor.fetchall()
@@ -193,42 +206,36 @@ def fetch_all_data(config):
cursor.close()
cnx.close()
return data, column_names
except mysql.connector.Error as err:
cursor.close()
cnx.close()
if err.errno == errorcode.ER_NO_SUCH_TABLE:
return [], f"⚠️ Tabelle '{PROTOKOLL_TABLE_NAME}' existiert nicht. Speichern Sie zuerst einen Datensatz."
elif err.errno == errorcode.ER_BAD_DB_ERROR:
return [], f"⚠️ Datenbank '{config['database']}' existiert nicht."
return None, f"Fehler beim Abrufen der Daten: {err.msg}"
return None, f"❌ Fehler beim Abrufen der Daten: {err.msg}"
def delete_data_by_id(config, record_id):
"""Löscht einen Datensatz anhand seiner ID."""
"""Löscht einen spezifischen Datensatz anhand der ID."""
cnx, result = get_db_connection(config, with_db=True)
if cnx is None:
return False, result
cursor = cnx.cursor()
try:
delete_query = f"DELETE FROM {PROTOKOLL_TABLE_NAME} WHERE id = %s"
cursor.execute(delete_query, (record_id,))
query = f"DELETE FROM {PROTOKOLL_TABLE_NAME} WHERE id = %s"
cursor.execute(query, (record_id,))
cnx.commit()
rows_affected = cursor.rowcount
cursor.close()
cnx.close()
if rows_affected > 0:
return True, f"Datensatz (ID: {record_id}) erfolgreich gelöscht."
return True, f"Datensatz (ID: {record_id}) erfolgreich gelöscht."
else:
return False, f"Datensatz mit ID {record_id} nicht gefunden."
except mysql.connector.Error as err:
cursor.close()
cnx.close()
return False, f"Fehler beim Löschen des Datensatzes: {err.msg}"
return False, f"Fehler beim Löschen des Datensatzes: {err.msg}"
def test_db_connection(config):
@@ -255,6 +262,4 @@ def test_db_connection(config):
elif err.errno == errorcode.ER_BAD_DB_ERROR:
return False, f"⚠️ Datenbank '{config['database']}' existiert nicht. Wird beim Speichern erstellt."
else:
return False, f"Unbekannter Verbindungsfehler: {err.msg}"
except Exception as e:
return False, f"❌ Allgemeiner Fehler: {e}"
return False, f"Fehler: {err.msg}"

View File

@@ -2,7 +2,7 @@
setlocal enabledelayedexpansion
:: --- KONFIGURATION ---
set "REPO_URL="http://diggerwf.cloud:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer.git"
set "REPO_URL="https://git.diggerwf.cloud/diggerwf/Brokkoli-Giess-Plannung-Helfer.git"
set "BRANCH=main"
set "START_FILE=start4.bat"
:: ---------------------

File diff suppressed because it is too large Load Diff

View File

@@ -1,87 +1,122 @@
import sys
import subprocess
import tkinter as tk
from tkinter import messagebox
import os
# Konfiguration der benötigten Bibliotheken
# Format: (Modulname für import, Name für pip, Kurzbeschreibung)
REQUIRED_PACKAGES = [
("PIL", "Pillow", "fuer die Bildanzeige (Logo)"),
("mysql.connector", "mysql-connector-python", "fuer die Datenbankverbindung (MySQL)")
]
def ensure_pip():
"""Stellt sicher, dass pip aktuell ist, bevor Pakete installiert werden."""
try:
print("🔍 Bereite Paket-Manager (pip) vor...")
# Aktualisiert pip im Hintergrund (ohne Bestätigung)
subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "pip"],
stdout=subprocess.DEVNULL)
return True
except Exception as e:
print(f"⚠️ Warnung beim pip-Update: {e}")
return True # Wir versuchen es trotzdem weiter
def check_and_install_packages():
"""Prüft Abhängigkeiten und installiert sie bei Bedarf grafisch."""
# Unsichtbares Tkinter-Hauptfenster für Dialoge
root = tk.Tk()
root.withdraw()
all_ready = True
for import_name, pip_name, description in REQUIRED_PACKAGES:
try:
# Versuch, das Modul zu laden
__import__(import_name)
print(f"✅ Modul vorhanden: {import_name}")
except ImportError:
print(f"❌ Modul fehlt: {import_name}")
# Grafische Abfrage beim Nutzer
frage = (f"Die Bibliothek '{pip_name}' ({description}) fehlt.\n\n"
f"Soll sie jetzt automatisch installiert werden?")
if messagebox.askyesno("Abhängigkeit installieren", frage):
try:
# Pip vorbereiten (nur wenn wirklich installiert werden muss)
ensure_pip()
print(f"📥 Installiere {pip_name}...")
subprocess.check_call([sys.executable, "-m", "pip", "install", pip_name])
print(f"{pip_name} erfolgreich installiert.")
except Exception as e:
messagebox.showerror("Fehler", f"Installation von {pip_name} fehlgeschlagen:\n{e}")
all_ready = False
else:
messagebox.showwarning("Warnung", f"Ohne {pip_name} wird die App wahrscheinlich abstuerzen.")
all_ready = False
root.destroy()
return all_ready
def start_main_app():
"""Startet die eigentliche GUI-Datei."""
try:
print("🚀 Lade Pflanzenprotokoll-Oberflaeche...")
# Hier wird deine eigentliche Datei importiert und gestartet
import pflanzen_gui
app = pflanzen_gui.PflanzenApp()
app.mainloop()
except Exception as e:
error_msg = f"Kritischer Fehler beim Starten von pflanzen_gui.py:\n{e}"
print(error_msg)
# Kurzes Notfall-Fenster für den Fehler
temp_root = tk.Tk()
temp_root.withdraw()
messagebox.showerror("Programmfehler", error_msg)
temp_root.destroy()
if __name__ == "__main__":
# Schritt 1: Pakete prüfen
if check_and_install_packages():
# Schritt 2: Wenn alles okay ist, Haupt-App starten
start_main_app()
else:
import sys
import subprocess
import tkinter as tk
from tkinter import messagebox
import os
# Konfiguration der benötigten Bibliotheken
# Format: (Modulname für import, Name für pip, Kurzbeschreibung)
REQUIRED_PACKAGES = [
("PIL", "Pillow", "fuer die Bildanzeige (Logo)"),
("mysql.connector", "mysql-connector-python", "fuer die Datenbankverbindung (MySQL)"),
("pandas", "pandas", "fuer die Datenverarbeitung und Tabellen"),
("rich", "rich", "fuer formatierte Konsolenausgaben")
]
def ensure_pip():
"""Stellt sicher, dass pip aktuell ist, bevor Pakete installiert werden."""
try:
print("🔍 Bereite Paket-Manager (pip) vor...")
# Aktualisiert pip im Hintergrund (ohne Bestätigung)
# Unter Linux wird hier --break-system-packages genutzt, um die PEP 668 Sperre zu umgehen
cmd = [sys.executable, "-m", "pip", "install", "--upgrade", "pip"]
if sys.platform.startswith('linux'):
cmd.append("--break-system-packages")
subprocess.check_call(cmd, stdout=subprocess.DEVNULL)
return True
except Exception as e:
print(f"⚠️ Warnung beim pip-Update: {e}")
# Falls pip nicht gefunden wird, versuchen wir es unter Linux mit ensurepip
if sys.platform.startswith('linux'):
try:
print("🔄 Versuche pip via System-Paketmanager zu finden...")
subprocess.check_call([sys.executable, "-m", "ensurepip", "--default-pip"], stdout=subprocess.DEVNULL)
except:
pass
return True # Wir versuchen es trotzdem weiter
def check_and_install_packages():
"""Prüft Abhängigkeiten einzeln und installiert sie bei Bedarf grafisch."""
# Unsichtbares Tkinter-Hauptfenster für Dialoge
root = tk.Tk()
root.withdraw()
all_ready = True
for import_name, pip_name, description in REQUIRED_PACKAGES:
try:
# Gründliche Einzelprüfung: Versucht das Modul wirklich zu laden
if import_name == "pandas":
import pandas as pd
# Kleiner Funktionstest für Pandas
pd.DataFrame()
elif import_name == "PIL":
from PIL import Image, ImageTk
elif import_name == "rich":
import rich
from rich.console import Console
_ = Console()
else:
__import__(import_name)
print(f"✅ Modul vorhanden und funktionsfaehig: {import_name}")
except (ImportError, ModuleNotFoundError, Exception):
print(f"❌ Modul fehlt oder ist defekt: {import_name}")
# Grafische Abfrage beim Nutzer
is_linux = sys.platform.startswith('linux')
zusatz_info = "\n(Nutzt --break-system-packages unter Linux)" if is_linux else ""
frage = (f"Die Bibliothek '{pip_name}' ({description}) fehlt.\n\n"
f"Soll sie jetzt automatisch installiert werden?{zusatz_info}")
if messagebox.askyesno("Abhängigkeit installieren", frage):
try:
# Pip vorbereiten
ensure_pip()
print(f"📥 Installiere {pip_name}...")
# Installation über den aktuellen Python-Interpreter
install_cmd = [sys.executable, "-m", "pip", "install", pip_name]
# Fix für das 'externally-managed-environment' Problem unter Linux
if is_linux:
install_cmd.append("--break-system-packages")
subprocess.check_call(install_cmd)
print(f"{pip_name} erfolgreich installiert.")
except Exception as e:
messagebox.showerror("Fehler", f"Installation von {pip_name} fehlgeschlagen:\n{e}")
all_ready = False
else:
messagebox.showwarning("Warnung", f"Ohne {pip_name} wird die App wahrscheinlich abstuerzen.")
all_ready = False
root.destroy()
return all_ready
def start_main_app():
"""Startet die eigentliche GUI-Datei."""
try:
print("🚀 Lade Pflanzenprotokoll-Oberflaeche...")
# Hier wird deine eigentliche Datei importiert und gestartet
import pflanzen_gui
app = pflanzen_gui.PflanzenApp()
app.mainloop()
except Exception as e:
error_msg = f"Kritischer Fehler beim Starten von pflanzen_gui.py:\n{e}"
print(error_msg)
# Kurzes Notfall-Fenster für den Fehler
temp_root = tk.Tk()
temp_root.withdraw()
messagebox.showerror("Programmfehler", error_msg)
temp_root.destroy()
if __name__ == "__main__":
# Schritt 1: Jedes Paket einzeln prüfen
if check_and_install_packages():
# Schritt 2: Wenn alles okay ist, Haupt-App starten
start_main_app()
else:
print("❌ Start abgebrochen, da Komponenten fehlen.")

View File

@@ -1,99 +1,59 @@
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
:: 🎨 KONFIGURATION
set "REPO_URL=http://diggerwf.cloud:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer.git"
set "REPO_URL=https://git.diggerwf.cloud/diggerwf/Brokkoli-Giess-Plannung-Helfer.git"
set "BRANCH=main"
set "ORIGIN=origin"
set "REPO_DIR=%~dp0"
set "START_FILE=start4.bat"
set "SELF_NAME=update.bat"
set "TEMP_NAME=temp_updater.bat"
:: 🛡️ AUSNAHMEN-KONFIGURATION
:: Diese Dateien werden von Git beim Aufräumen (clean) ignoriert
set SKIP_PARAMS=-e "config.json" -e "settings.txt" -e "db_config.ini" -e "logs/" -e "saves/" -e "__pycache__"
set "SKIP_PARAMS=-e config.json -e settings.txt -e db_config.ini -e logs/ -e saves/ -e __pycache__"
cd /d "%REPO_DIR%"
:: 🔄 SCHRITT 0: BIN ICH DIE KOPIE (DER HELFER)?
:: Dieser Teil wird nur ausgeführt, wenn die temp_updater.bat aktiv ist
if "%~nx0"=="%TEMP_NAME%" (
echo 🛠️ Update-Modus aktiv...
echo Update-Modus aktiv...
timeout /t 2 >nul
:: Hier wird das Original auf der Festplatte überschrieben
git fetch origin %BRANCH% --quiet
git reset --hard origin/%BRANCH% --quiet
git fetch %ORIGIN% %BRANCH% --quiet
git reset --hard %ORIGIN%/%BRANCH% --quiet
git clean -fd %SKIP_PARAMS% >nul
echo ✅ Dateien wurden auf der Festplatte aktualisiert.
echo 🚀 Starte das neue Hauptskript...
:: Wir starten das Original-Skript neu und beenden die Kopie
call "%SELF_NAME%"
exit
pause
exit /b
)
:: 🗑️ SCHRITT 1: AUFRÄUMEN
:: Wenn das Original startet, löscht es eine eventuell vorhandene Kopie
if exist "%TEMP_NAME%" del /f /q "%TEMP_NAME%"
echo 🔍 Prüfe auf Updates für: !REPO_URL!
:: 🛠️ 2. GIT CHECK
echo Pruefe auf Updates...
git --version >nul 2>&1
if %errorlevel% neq 0 (
echo Git nicht gefunden! Installiere...
winget install --id Git.Git -e --source winget --accept-package-agreements --accept-source-agreements
echo Git nicht gefunden!
pause
exit /b
)
:: 🔄 3. UPDATE LOGIK
if exist ".git\" (
git remote set-url origin "!REPO_URL!"
git fetch origin %BRANCH% --quiet
git remote set-url %ORIGIN% "%REPO_URL%"
git fetch %ORIGIN% %BRANCH% || (echo Fehler: Server nicht erreichbar & pause & exit /b)
for /f "tokens=*" %%a in ('git rev-parse HEAD') do set "LOCAL_HASH=%%a"
for /f "tokens=1" %%a in ('git ls-remote origin %BRANCH%') do set "REMOTE_HASH=%%a"
echo 🏠 Lokal: !LOCAL_HASH:~0,7!
echo 🌐 Online: !REMOTE_HASH:~0,7!
for /f "tokens=1" %%a in ('git ls-remote %ORIGIN% %BRANCH%') do set "REMOTE_HASH=%%a"
echo Lokal: !LOCAL_HASH:~0,7!
echo Online: !REMOTE_HASH:~0,7!
if "!LOCAL_HASH!" neq "!REMOTE_HASH!" (
echo 🆕 Update verfügbar!
echo 📦 Erstelle temporäre Kopie zur Aktualisierung...
:: Wir kopieren uns selbst, damit die Kopie das Original überschreiben kann
echo Update verfuegbar...
copy /y "%SELF_NAME%" "%TEMP_NAME%" >nul
:: Wir starten die Kopie und BEENDEN dieses Skript sofort (Wichtig!)
call "%TEMP_NAME%"
exit
exit /b
) else (
echo Alles aktuell!
echo Alles aktuell.
)
) else (
echo 🏗️ Ersteinrichtung läuft... 🔧
echo Ersteinrichtung...
git init --quiet
git remote add origin "!REPO_URL!" 2>nul
git fetch --all --quiet
git reset --hard origin/%BRANCH% --quiet
git clean -fd %SKIP_PARAMS% >nul
echo 🔗 Repository erfolgreich eingerichtet!
git remote add %ORIGIN% "%REPO_URL%"
git fetch --all
git reset --hard %ORIGIN%/%BRANCH%
git clean -fd %SKIP_PARAMS%
)
echo.
echo ✨ System ist bereit.
:: 🚀 4. START DES HAUPTPROGRAMMS
if exist "!START_FILE!" (
echo 🚀 Starte !START_FILE! via CALL...
:: Hier wird CALL genutzt, damit das Fenster für dein Programm offen bleibt
call "!START_FILE!"
if exist "%START_FILE%" (
call "%START_FILE%"
) else (
echo ⚠️ !START_FILE! wurde nicht gefunden.
echo Fehler: %START_FILE% nicht gefunden!
pause
)
exit
::test
)

View File

@@ -4,7 +4,7 @@
ENDSTART="start.sh"
# GitHub-Repository-URL und Branch definieren
REPO_URL="http://diggerwf.cloud:8281/diggerwf/Brokkoli-Giess-Plannung-Helfer.git"
REPO_URL="https://git.diggerwf.cloud/diggerwf/Brokkoli-Giess-Plannung-Helfer.git"
BRANCH="main"
# Pfad zum Repository (aktueller Ordner)