Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions TimeTrackerSOAP_Server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from wsgiref.simple_server import make_server
from datetime import datetime

# Versuch, Spyne zu importieren. Dies ist die Standard-Bibliothek für SOAP in Python.
# Attempt to import Spyne. This is the standard library for SOAP in Python.
try:
from spyne import Application, rpc, ServiceBase, Integer, Unicode, Boolean, Array, ComplexModel
from spyne.protocol.soap import Soap11
Expand All @@ -15,8 +15,8 @@
print("Bitte führen Sie folgenden Befehl aus: pip install spyne lxml")
sys.exit(1)

# Import der TimeTracker Logik
# Wir fügen das aktuelle Verzeichnis zum Pfad hinzu, damit tt.TimeTracker gefunden wird
# Import of TimeTracker logic
# We add the current directory to the path so that tt.TimeTracker can be found
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
try:
from tt.TimeTracker import TimeTracker
Expand All @@ -26,7 +26,7 @@

CONFIG_FILE = 'config.json'

# --- Datenmodelle für SOAP Antworten ---
# --- Data models for SOAP responses ---

class MainProjectModel(ComplexModel):
main_project_name = Unicode
Expand Down Expand Up @@ -58,10 +58,10 @@ class OperationResultModel(ComplexModel):
success = Boolean
message = Unicode

# --- Der SOAP Service ---
# --- The SOAP Service ---

class TimeControlService(ServiceBase):
# Wir initialisieren den Tracker in der Instanz.
# We initialize the tracker in the instance.
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.tracker = TimeTracker()
Expand Down Expand Up @@ -211,7 +211,7 @@ def get_current_work(ctx):

@rpc(Unicode, _returns=Unicode)
def generate_daily_report(ctx, report_date_str=None):
"""Generiert den Tagesbericht. Datum Format: YYYY-MM-DD oder leer für Heute."""
"""Generates the daily report. Date format: YYYY-MM-DD or empty for today."""
date_obj = None
if report_date_str:
try:
Expand All @@ -222,7 +222,7 @@ def generate_daily_report(ctx, report_date_str=None):

@rpc(Unicode, _returns=Unicode)
def generate_detailed_daily_report(ctx, report_date_str=None):
"""Generiert den detaillierten Tagesbericht. Datum Format: YYYY-MM-DD oder leer für Heute."""
"""Generates the detailed daily report. Date format: YYYY-MM-DD or empty for today."""
date_obj = None
if report_date_str:
try:
Expand All @@ -233,7 +233,7 @@ def generate_detailed_daily_report(ctx, report_date_str=None):

@rpc(Unicode, Unicode, _returns=Unicode)
def generate_date_range_report(ctx, start_date_str, end_date_str):
"""Generiert Bericht für Zeitraum. Datum Format: YYYY-MM-DD."""
"""Generates a report for a date range. Date format: YYYY-MM-DD."""
try:
start = datetime.strptime(start_date_str, "%Y-%m-%d").date()
end = datetime.strptime(end_date_str, "%Y-%m-%d").date()
Expand All @@ -250,22 +250,22 @@ def generate_main_project_report(ctx, main_project_name):
return ctx.service.tracker.generate_main_project_report(main_project_name)

def load_config():
"""Lädt die Konfiguration aus der config.json Datei."""
"""Loads the configuration from the config.json file."""
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, 'r') as f:
return json.load(f)
return {}

def main():
# Konfiguration laden
# Load configuration
config = load_config()
port = config.get('soap_port', 8600)

# Logging für Debugging-Zwecke aktivieren
# Enable logging for debugging purposes
logging.basicConfig(level=logging.INFO)
logging.getLogger('spyne.protocol.xml').setLevel(logging.INFO)

# Definition der SOAP-Anwendung
# Definition of the SOAP application
application = Application(
[TimeControlService],
tns='spyne.examples.timecontrol',
Expand Down
12 changes: 6 additions & 6 deletions install.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import subprocess
import os

# Versuch, importlib.metadata zu importieren, um installierte Pakete zu prüfen (Python 3.8+)
# Attempt to import importlib.metadata to check installed packages (Python 3.8+)
try:
from importlib.metadata import distributions
except ImportError:
Expand All @@ -13,7 +13,7 @@

def check_and_install_requirements():
"""
Liest requirements.txt, prüft auf fehlende Pakete und installiert diese nach.
Reads requirements.txt, checks for missing packages and installs them.
"""
requirements_file = 'requirements.txt'

Expand All @@ -25,7 +25,7 @@ def check_and_install_requirements():

requirements_to_install = []

# Datei einlesen
# Read file
try:
with open(requirements_file, 'r', encoding='utf-8') as f:
lines = []
Expand All @@ -38,21 +38,21 @@ def check_and_install_requirements():
sys.exit(1)

if distributions:
# Installierte Pakete ermitteln (Namen normalisiert auf Kleinschreibung)
# Determine installed packages (names normalized to lowercase)
installed_packages = {
dist.metadata['Name'].lower()
for dist in distributions()
if dist.metadata and dist.metadata['Name']
}

for req in lines:
# Paketnamen extrahieren (z.B. aus 'requests==2.28.1' -> 'requests')
# Extract package names (e.g. from 'requests==2.28.1' -> 'requests')
pkg_name = req.split('==')[0].split('>=')[0].split('<=')[0].split('<')[0].split('>')[0].strip()

if pkg_name.lower() not in installed_packages:
requirements_to_install.append(req)
else:
# Fallback: Wenn wir installierte Pakete nicht prüfen können, überlassen wir pip die Prüfung
# Fallback: If we cannot check installed packages, we let pip handle the check
requirements_to_install = lines

if requirements_to_install:
Expand Down
9 changes: 6 additions & 3 deletions sl/SL_Menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,14 @@ def view_task_planning():
except (ValueError, TypeError):
continue

# Start the overview at the current weekday
current_weekday = datetime.now().weekday()
for i in range(7):
if i in tasks_by_day:
st.subheader(weekday_names[i])
day_idx = (current_weekday + i) % 7
if day_idx in tasks_by_day:
st.subheader(weekday_names[day_idx])
# Layout für jede Aufgabe mit Bearbeiten-Button
for t_idx, task in enumerate(tasks_by_day[i]):
for t_idx, task in enumerate(tasks_by_day[day_idx]):
col_task, col_start_btn, col_edit_btn = st.columns([10, 1, 1])
with col_task:
name = task['task_name']
Expand Down
11 changes: 6 additions & 5 deletions tt/TimeTracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,22 +483,23 @@ def list_tasks(self, main_project_name=None, status_filter='all', planning_filte
is_today = task.get("today", False)

if planning_filter == 'today':
# Zeige Aufgaben nur, wenn das Fälligkeitsdatum exakt heute ist.
# Das 'today'-Flag wird hierbei ignoriert.
# Show tasks only if the due date is exactly today.
# The 'today' flag is ignored here.
if not (due_date == today_str):
continue
elif planning_filter == 'tomorrow':
if due_date != tomorrow_str:
continue
elif planning_filter == 'weekly':
if not (due_date and today_str <= due_date <= next_week_str):
# Zeige exakt 7 Tage ab heute (heute inklusive, heute + 7 exklusive)
if not (due_date and today_str <= due_date < next_week_str):
continue
elif planning_filter == 'overdue':
if not (due_date and due_date < today_str):
continue
elif planning_filter == 'unplanned':
# Ein Task ist ungeplant, wenn er kein Fälligkeitsdatum hat.
# Das 'today'-Flag (Stern) spielt hierbei keine Rolle mehr.
# A task is unplanned if it has no due date.
# The 'today' flag (star) no longer plays a role here.
if due_date:
continue

Expand Down
Loading