diff --git a/admin.py b/admin.py index b3dc822..b733fe2 100644 --- a/admin.py +++ b/admin.py @@ -68,22 +68,26 @@ def page_admin(): def update_user(): current_user = user(time_user.value) available_years = current_user.get_years() - select_year.clear() - select_year.set_options(available_years) try: - select_year.value = str(datetime.datetime.now().year) - except: - select_year.value = list(available_years)[0] - try: - select_month.value = datetime.datetime.now().month - except: - select_month.value = list(available_months)[0] + select_year.clear() + select_year.set_options(available_years) + + try: + select_year.value = str(datetime.datetime.now().year) + except: + select_year.value = list(available_years)[0] + try: + select_month.value = datetime.datetime.now().month + except: + select_month.value = list(available_months)[0] + except NameError: + pass userlist = list_users() ui.markdown("Benutzer:") - time_user = ui.select(options=userlist, value=userlist[0], on_change=update_user) - + time_user = ui.select(options=userlist, on_change=update_user) + time_user.value = userlist[0] user_to_select_for_start = userlist[0] current_year = datetime.datetime.now().year @@ -147,11 +151,13 @@ def page_admin(): ui.button("Nein", on_click=dialog.close) dialog.open() - if archive_status: + if archive_status == True: with ui.row().classes('text-right col-span-6 justify-center'): ui.button("Archiviert", on_click=revoke_archive_status).classes('bg-transparent text-black') ui.separator() calendar_card.classes('bg-yellow') + else: + calendar_card.classes('bg-white') # Überschriften ui.markdown("**Datum**") ui.markdown("**Buchungen**") @@ -329,6 +335,8 @@ def page_admin(): hours_to_work = int(current_user.get_day_workhours(select_year.value, select_month.value, day)) if hours_to_work < 0: ui.space() + day_type.content="Kein Arbeitsverhältnis" + day_type.set_visibility(True) else: ui.markdown(f"{convert_seconds_to_hours(int(hours_to_work) * 3600)}").classes('text-right') if int(hours_to_work) == 0: @@ -733,8 +741,6 @@ def page_admin(): with ui.tab_panel(users): ui.markdown("###Benutzerverwaltung") - userlist = list_users() - userlist.sort() workhours = [ ] with ui.row(): @@ -811,11 +817,12 @@ def page_admin(): def del_definitely(): current_user.del_user() - userlist = list_users() - userlist.sort() - user_selection.clear() - user_selection.set_options(userlist) - user_selection.value = userlist[0] + #userlist = list_users() + #userlist.sort() + #user_selection.clear() + #user_selection.set_options(userlist) + #user_selection.value = userlist[0] + user_ui.refresh() dialog.close() ui.notify("Benutzer gelöscht") @@ -878,10 +885,37 @@ def page_admin(): ui.button("OK", on_click=dialog.close) dialog.open() - with ui.column(): - user_selection = ui.select(options=userlist, with_input=True, on_change=user_selection_changed) - user_selection.value = userlist[0] - ui.button("Neu") + def dialog_new_user(): + def create_new_user(): + if user_name_input.validate(): + print(user_name_input.value) + new_user(user_name_input.value) + userlist = list_users() + user_ui.refresh() + dialog.close() + else: + ui.notify("Ungültiger Benutzername") + + with ui.dialog() as dialog, ui.card(): + ui.markdown("Geben Sie den Benutzernamen für das neue Konto an:") + user_name_input = ui.input(label="Benutzername", validation={'Leerer Benutzername nicht erlaubt': lambda value: len(value) != 0, + 'Leerzeichen im Benutzername nicht erlaubt': lambda value: " " not in value}) + with ui.row(): + ui.button("OK", on_click=create_new_user) + ui.button("Abbrechen", on_click=dialog.close) + dialog.open() + + @ui.refreshable + def user_ui(): + userlist = list_users() + userlist.sort() + + with ui.column(): + global user_selection + user_selection = ui.select(options=userlist, with_input=True, on_change=user_selection_changed) + user_selection.value = userlist[0] + ui.button("Neu", on_click=dialog_new_user) + user_ui() with ui.column(): with ui.card() as usersettingscard: diff --git a/definitions.py b/definitions.py index 679c89b..08f0639 100644 --- a/definitions.py +++ b/definitions.py @@ -20,6 +20,24 @@ photofilename = "photo.jpg" status_in = "eingestempelt" status_out = "ausgestempelt" +# Standardadmin Settings: + +standard_adminsettings = { "admin_user": "admin", + "admin_password": "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918", + "port": "8090", + "secret": "ftgzuhjikg,mt5jn46uzer8sfi9okrmtzjhndfierko5zltjhdgise", + "holidays": { } + } + +# Standard User Settings: + +standard_usersettings = { + "username": "default", + "fullname": "Standardbenutzer", + "password": "37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f", + "workhours": { } +} + # Abesenheiten absence_entries = {"U": { "name": "Urlaub", diff --git a/homepage.py b/homepage.py index 2aa6540..75e866e 100644 --- a/homepage.py +++ b/homepage.py @@ -18,7 +18,11 @@ def homepage(): if login_is_valid(): ui.page_title("Zeiterfassung") - current_user = user(app.storage.user["active_user"]) + try: + current_user = user(app.storage.user["active_user"]) + except: + del(app.storage.user["active_user"]) + ui.navigate.to('/') pageheader(f"Willkommen, {current_user.fullname}") today = datetime.datetime.now() diff --git a/main.py b/main.py index 1b73ccf..937b047 100644 --- a/main.py +++ b/main.py @@ -14,12 +14,12 @@ import json def main(): # Einstellungen einlesen - with open(f"{scriptpath}/settings.json") as json_file: - data = json.load(json_file) - + data = load_adminsettings() port = int(data["port"]) secret = data["secret"] + list_users() + homepage() def startup_message(): diff --git a/settings.json b/settings.json index b1a23bc..b4e0b21 100644 --- a/settings.json +++ b/settings.json @@ -1,12 +1,7 @@ { "admin_user": "admin", - "admin_password": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92", + "admin_password": "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918", "port": "8090", "secret": "ftgzuhjikg,mt5jn46uzer8sfi9okrmtzjhndfierko5zltjhdgise", - "holidays": { - "2024-05-01": "Tag der Arbeit", - "2024-12-25": "1. Weihnachtsfeiertag", - "2025-01-01": "Neujahr", - "2025-05-01": "Tag der Arbeit" - } + "holidays": {} } \ No newline at end of file diff --git a/settings.json_bak b/settings.json_bak new file mode 100644 index 0000000..b1a23bc --- /dev/null +++ b/settings.json_bak @@ -0,0 +1,12 @@ +{ + "admin_user": "admin", + "admin_password": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92", + "port": "8090", + "secret": "ftgzuhjikg,mt5jn46uzer8sfi9okrmtzjhndfierko5zltjhdgise", + "holidays": { + "2024-05-01": "Tag der Arbeit", + "2024-12-25": "1. Weihnachtsfeiertag", + "2025-01-01": "Neujahr", + "2025-05-01": "Tag der Arbeit" + } +} \ No newline at end of file diff --git a/users.py b/users.py index 34fba12..163a1d9 100644 --- a/users.py +++ b/users.py @@ -9,7 +9,7 @@ import json import shutil import re -from definitions import userfolder, scriptpath, usersettingsfilename, photofilename, status_in, status_out +from definitions import userfolder, scriptpath, usersettingsfilename, photofilename, status_in, status_out, standard_adminsettings, standard_usersettings # Benutzerklasse @@ -64,8 +64,8 @@ class user: self.timestamp() # Nach zugehörigem JSON-File suchen und bei Bedarf anlegen + json_filename = f"{self.get_stamp_file()}.json" try: - json_filename = f"{self.get_stamp_file()}.json" with open(json_filename, 'r') as json_file: pass except: @@ -94,9 +94,9 @@ class user: if len(lines)== 0: print(f"Keine Einträge") elif len(lines) % 2 == 0: - return (status_out) + return status_out else: - return (status_in) + return status_in def last_2_timestmaps(self): @@ -107,8 +107,8 @@ class user: if len(lines) > 2: second_last_line = int(lines[-2]) last_line = int(lines[-1]) - last_2_timestmaps = [second_last_line, last_line] - return last_2_timestmaps + last_2_timestamps = [second_last_line, last_line] + return last_2_timestamps elif len(lines) == 1: return int(lines[0]) @@ -117,10 +117,10 @@ class user: def write_settings(self): dict = { } - dict["username"] = (self.username) - dict["fullname"] = (self.fullname) - dict["password"] = (self.password) - dict["workhours"] = (self.workhours) + dict["username"] = self.username + dict["fullname"] = self.fullname + dict["password"] = self.password + dict["workhours"] = self.workhours json_dict = json.dumps(dict, indent=4) @@ -143,7 +143,7 @@ class user: month = str(starting_date[0])[5:7] day = str(starting_date[0])[8:10] - return (year, month, day) + return [year, month, day] def get_years(self): years = [ ] @@ -196,7 +196,7 @@ class user: if month not in available_months: available_months.append(month) available_months.sort() - return(available_months) + return available_months def get_timestamps(self, year, month): try: @@ -216,9 +216,9 @@ class user: try: with open(f"{self.userfolder}/{year}-{month}.json", 'r') as json_file: data = json.load(json_file) - return (data["archived"]) + return data["archived"] except: - return(-1) + return -1 def archive_hours(self, year, month, overtime: int): @@ -291,6 +291,7 @@ class user: json_file.write(json_dict) def get_day_workhours(self, year, month, day): + global hours_to_work workhour_entries = list(self.workhours) workhour_entries.sort() day_to_check = datetime.datetime(int(year), int(month), int(day)) @@ -375,23 +376,54 @@ class user: print(total_time) print(in_time_stamp) - return([total_time, in_time_stamp]) + return [total_time, in_time_stamp] # Benutzer auflisten def list_users(): + + if not os.path.exists(userfolder): + print("Kein Benutzerverzeichnis gefunden. Lege es an.") + os.makedirs(userfolder) + users = [d for d in os.listdir(userfolder) if os.path.isdir(os.path.join(userfolder, d))] + if len(users) == 0: + print("Keine Benutzer gefunden. Lege Standardbenutzer an.") + new_user("default") + users = [d for d in os.listdir(userfolder) if os.path.isdir(os.path.join(userfolder, d))] + users.sort() return users +def new_user(username: str): + if not os.path.exists(userfolder): + os.makedirs(userfolder) + if not os.path.exists(f"{userfolder}/{username}"): + os.makedirs(f"{userfolder}/{username}") + start_date_dt = datetime.datetime.now() + start_date = start_date_dt.strftime("%Y-%m-%d") + settings_to_write = standard_usersettings + settings_to_write["workhours"][start_date] = { } + settings_to_write["fullname"] = username + settings_to_write["username"] = username + for i in range(1, 8): + settings_to_write["workhours"][start_date][str(i)] = 0 + settings_to_write["workhours"][start_date]["vacation"] = 0 + with open(f"{userfolder}/{username}/{usersettingsfilename}", 'w') as json_file: + json_dict = json.dumps(standard_usersettings, indent=4) + json_file.write(json_dict) + # Admineinstellungen auslesen def load_adminsettings(): # Settingsdatei einlesen + settings_filename = f"{scriptpath}/{usersettingsfilename}" + if not os.path.exists(settings_filename): + print("Keine Einstellungsdatei gefunden. Lege Standarddatei an.") + with open(settings_filename, 'w') as json_file: + json_dict = json.dumps(standard_adminsettings, indent=4) + json_file.write(json_dict) try: - with open(f"{scriptpath}/{usersettingsfilename}") as json_file: + with open(settings_filename) as json_file: data = json.load(json_file) - json_file.close() - return(data) + return data except: - return(-1) - - + return -1 diff --git a/web_ui.py b/web_ui.py index c1f4048..7624aa1 100644 --- a/web_ui.py +++ b/web_ui.py @@ -23,9 +23,6 @@ class ValueBinder: def __init__(self): self.value = "" -def cookie_hash(user, password): - return hashlib.sha256(b"{user}{app.storage.user['id']}{password}").hexdigest() - def hash_password(password): return hashlib.sha256(bytes(password, 'utf-8')).hexdigest() @@ -98,9 +95,9 @@ def convert_seconds_to_hours(seconds): minutes = str(minutes) if sign == "-": - return(f"-{hours}:{minutes}") + return f"-{hours}:{minutes}" else: - return(f"{hours}:{minutes}") + return f"{hours}:{minutes}" def login_is_valid(user = -1):