Compare commits
No commits in common. "0358ef44e4f2c1b8852a0f570899365934ed2a1d" and "7898345a06c23dee96226a25a9a529832a57ef59" have entirely different histories.
0358ef44e4
...
7898345a06
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,8 +5,6 @@ Testplan.md
|
|||||||
.venv
|
.venv
|
||||||
users/
|
users/
|
||||||
backup/
|
backup/
|
||||||
settings/
|
|
||||||
Archiv/
|
Archiv/
|
||||||
Docker/
|
Docker/
|
||||||
docker-work/
|
docker-work/
|
||||||
Wiki/
|
|
||||||
13
Dockerfile
13
Dockerfile
@ -1,13 +1,14 @@
|
|||||||
FROM python:latest
|
FROM debian:latest
|
||||||
RUN apt update && apt upgrade -y
|
RUN apt update && apt upgrade -y
|
||||||
RUN apt install locales -y
|
RUN apt install python3 python3-pip python3.11-venv locales -y
|
||||||
RUN mkdir /app
|
RUN mkdir /app
|
||||||
RUN mkdir /.venv
|
RUN mkdir /.venv
|
||||||
RUN mkdir /backup
|
RUN mkdir /backup
|
||||||
RUN mkdir /settings
|
RUN mkdir /settings
|
||||||
RUN pip install nicegui
|
RUN python3 -m venv /.venv
|
||||||
RUN pip install segno
|
RUN /.venv/bin/pip install nicegui
|
||||||
RUN pip install python-dateutil
|
RUN /.venv/bin/pip install segno
|
||||||
|
RUN /.venv/bin/pip install python-dateutil
|
||||||
|
|
||||||
RUN sed -i '/de_DE.UTF-8/s/^# //g' /etc/locale.gen && \
|
RUN sed -i '/de_DE.UTF-8/s/^# //g' /etc/locale.gen && \
|
||||||
locale-gen
|
locale-gen
|
||||||
@ -18,4 +19,4 @@ ENV LC_ALL de_DE.UTF-8
|
|||||||
COPY main.py /app/main.py
|
COPY main.py /app/main.py
|
||||||
COPY lib /app/lib/
|
COPY lib /app/lib/
|
||||||
EXPOSE 8090
|
EXPOSE 8090
|
||||||
ENTRYPOINT ["python", "/app/main.py"]
|
ENTRYPOINT ["/.venv/bin/python", "/app/main.py"]
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import os
|
|||||||
server = 'gitea.am-td.de'
|
server = 'gitea.am-td.de'
|
||||||
server_user = 'alexander'
|
server_user = 'alexander'
|
||||||
|
|
||||||
#if os.getuid() == 0:
|
if os.getuid() == 0:
|
||||||
subprocess.run(["docker", "build", "--force-rm", "-t", f"{server}/{server_user}/{app_title.lower()}:{app_version}", "."])
|
subprocess.run(["docker", "build", "--force-rm", "-t", f"{server}/{server_user}/{app_title.lower()}:{app_version}", "."])
|
||||||
if input("docker-compose erstellen j=JA ") == "j":
|
if input("docker-compose erstellen j=JA ") == "j":
|
||||||
userfolder = input("Pfad für Benutzerdaten /users:")
|
userfolder = input("Pfad für Benutzerdaten /users:")
|
||||||
@ -27,5 +27,5 @@ services:
|
|||||||
|
|
||||||
with open('docker-compose.yml', 'w') as docker_compose:
|
with open('docker-compose.yml', 'w') as docker_compose:
|
||||||
docker_compose.write(docker_compose_content)
|
docker_compose.write(docker_compose_content)
|
||||||
#else:
|
else:
|
||||||
# print("Es werden Root-Rechte benötigt.")
|
print("Es werden Root-Rechte benötigt.")
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
zeiterfassung:
|
zeiterfassung:
|
||||||
image: gitea.am-td.de/alexander/zeiterfassung:beta-2025.0.2
|
image: gitea.am-td.de/alexander/zeiterfassung:beta-2025.0.1
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 8090:8090
|
- 8090:8090
|
||||||
environment:
|
environment:
|
||||||
- PYTHONUNBUFFERED=1
|
- PYTHONUNBUFFERED=1
|
||||||
volumes:
|
volumes:
|
||||||
- ./users:/users
|
- ./docker-work/users:/users
|
||||||
- ./backup:/backup
|
- ./docker-work/backup:/backup
|
||||||
- ./settings:/settings
|
- ./docker-work/settings:/settings
|
||||||
- /etc/localtime:/etc/localtime:ro
|
|
||||||
93
lib/admin.py
93
lib/admin.py
@ -4,7 +4,6 @@ import dateutil.easter
|
|||||||
from dateutil.easter import *
|
from dateutil.easter import *
|
||||||
|
|
||||||
from nicegui import ui, app, events
|
from nicegui import ui, app, events
|
||||||
from nicegui.functions.navigate import navigate
|
|
||||||
from nicegui.html import button
|
from nicegui.html import button
|
||||||
from nicegui.events import KeyEventArguments
|
from nicegui.events import KeyEventArguments
|
||||||
|
|
||||||
@ -45,10 +44,6 @@ def page_admin():
|
|||||||
|
|
||||||
updates_available = ValueBinder()
|
updates_available = ValueBinder()
|
||||||
updates_available.value = False
|
updates_available.value = False
|
||||||
delete_binder = ValueBinder()
|
|
||||||
delete_binder.value = True
|
|
||||||
delete_info = ValueBinder()
|
|
||||||
delete_info.value = False
|
|
||||||
|
|
||||||
enabled_because_not_docker = ValueBinder
|
enabled_because_not_docker = ValueBinder
|
||||||
if is_docker():
|
if is_docker():
|
||||||
@ -70,13 +65,6 @@ def page_admin():
|
|||||||
def update_userlist():
|
def update_userlist():
|
||||||
nonlocal userlist
|
nonlocal userlist
|
||||||
userlist = list_users()
|
userlist = list_users()
|
||||||
# Benutzerliste um No Time Users bereinigen
|
|
||||||
users_to_remove = [ ]
|
|
||||||
for entry in userlist:
|
|
||||||
if entry in get_no_time_users_list():
|
|
||||||
users_to_remove.append(entry)
|
|
||||||
for i in users_to_remove:
|
|
||||||
userlist.remove(i)
|
|
||||||
|
|
||||||
update_userlist()
|
update_userlist()
|
||||||
|
|
||||||
@ -771,27 +759,17 @@ def page_admin():
|
|||||||
with ui.tab_panel(settings):
|
with ui.tab_panel(settings):
|
||||||
with ui.grid(columns='auto auto'):
|
with ui.grid(columns='auto auto'):
|
||||||
with ui.card():
|
with ui.card():
|
||||||
ui.label("Benutzereinstellungen:").classes('text-bold')
|
ui.label("Administrationsbenutzer:").classes('text-bold')
|
||||||
with ui.grid(columns=2).classes('items-center'):
|
with ui.grid(columns=2).classes('items-baseline'):
|
||||||
|
|
||||||
|
ui.label("Benutzername des Adminstrators:")
|
||||||
|
admin_user = ui.input().tooltip("Geben Sie hier den Benutzernamen für den Adminstationsnutzer ein")
|
||||||
|
admin_user.value = data["admin_user"]
|
||||||
|
ui.label("Passwort des Administrators:")
|
||||||
|
admin_password = ui.input(password=True).tooltip("Geben Sie hier das Passwort für den Administationsnutzer ein. Merken Sie sich dieses Passwort gut. Es kann nicht über das Webinterface zurückgesetzt werden.")
|
||||||
|
|
||||||
ui.label("Benutzer mit Administrationsrechten:")
|
|
||||||
user_switch_list = []
|
|
||||||
with ui.grid(columns=2).classes('gap-y-0'):
|
|
||||||
for i in list_users():
|
|
||||||
user_switch_list.append(ui.switch(i))
|
|
||||||
for i in user_switch_list:
|
|
||||||
if i.text in get_admin_list():
|
|
||||||
i.value = True
|
|
||||||
secret = data["secret"]
|
secret = data["secret"]
|
||||||
ui.separator().classes('col-span-2')
|
|
||||||
ui.label("Benutzer ohne Zeiterfassung:")
|
|
||||||
no_time_user_switch_list = [ ]
|
|
||||||
with ui.grid(columns=2).classes('gap-y-0'):
|
|
||||||
for i in list_users():
|
|
||||||
no_time_user_switch_list.append(ui.switch(i))
|
|
||||||
for item in no_time_user_switch_list:
|
|
||||||
if item.text in get_no_time_users_list():
|
|
||||||
item.value = True
|
|
||||||
with ui.card():
|
with ui.card():
|
||||||
ui.label("Systemeinstellungen:").classes('text-bold')
|
ui.label("Systemeinstellungen:").classes('text-bold')
|
||||||
with ui.grid(columns=2).classes('items-baseline'):
|
with ui.grid(columns=2).classes('items-baseline'):
|
||||||
@ -1067,30 +1045,11 @@ def page_admin():
|
|||||||
holiday_section()
|
holiday_section()
|
||||||
|
|
||||||
def save_admin_settings():
|
def save_admin_settings():
|
||||||
admin_users = { }
|
write_adminsetting("admin_user", admin_user.value)
|
||||||
admin_counter = -1
|
if admin_password.value != "":
|
||||||
for i in user_switch_list:
|
write_adminsetting("admin_password", hash_password(admin_password.value))
|
||||||
if i.value == True:
|
|
||||||
admin_counter += 1
|
|
||||||
admin_users[str(admin_counter)] = i.text
|
|
||||||
if len(admin_users) == 0:
|
|
||||||
with ui.dialog() as dialog, ui.card():
|
|
||||||
ui.label("Es wurde kein Administrationsbenutzer ausgewählt. Mindestens ein Benutzer muss Administrationsrechte haben.")
|
|
||||||
ui.button("OK", on_click=dialog.close)
|
|
||||||
dialog.open()
|
|
||||||
else:
|
else:
|
||||||
|
write_adminsetting("admin_password", data["admin_password"])
|
||||||
no_time_users = { }
|
|
||||||
no_time_users_counter = -1
|
|
||||||
for i in no_time_user_switch_list:
|
|
||||||
if i.value == True:
|
|
||||||
no_time_users_counter += 1
|
|
||||||
no_time_users[str(no_time_users_counter)] = i.text
|
|
||||||
|
|
||||||
old_no_time_users_list = get_no_time_users_list()
|
|
||||||
|
|
||||||
write_adminsetting("admin_user", admin_users)
|
|
||||||
write_adminsetting("no_time_users", no_time_users)
|
|
||||||
write_adminsetting("port", port.value)
|
write_adminsetting("port", port.value)
|
||||||
write_adminsetting("secret", secret)
|
write_adminsetting("secret", secret)
|
||||||
write_adminsetting("touchscreen", touchscreen_switch.value)
|
write_adminsetting("touchscreen", touchscreen_switch.value)
|
||||||
@ -1112,12 +1071,6 @@ def page_admin():
|
|||||||
reset_visibility.value = False
|
reset_visibility.value = False
|
||||||
timetable.refresh()
|
timetable.refresh()
|
||||||
|
|
||||||
if not set(old_no_time_users_list) == set(get_no_time_users_list()):
|
|
||||||
with ui.dialog() as infobox, ui.card():
|
|
||||||
ui.label("Benutzer ohne Zeiterfassung wurden geändert. Die Seite wird neu geladen.")
|
|
||||||
ui.button("OK", on_click=ui.navigate.reload)
|
|
||||||
infobox.open()
|
|
||||||
|
|
||||||
with ui.button("Speichern", on_click=save_admin_settings):
|
with ui.button("Speichern", on_click=save_admin_settings):
|
||||||
with ui.tooltip():
|
with ui.tooltip():
|
||||||
ui.label("Hiermit werden sämtliche oben gemachten Einstellungen gespeichert.\nGgf. müssen Sie die Seite neu laden um die Auswirkungen sichtbar zu machen.").style('white-space: pre-wrap')
|
ui.label("Hiermit werden sämtliche oben gemachten Einstellungen gespeichert.\nGgf. müssen Sie die Seite neu laden um die Auswirkungen sichtbar zu machen.").style('white-space: pre-wrap')
|
||||||
@ -1127,6 +1080,7 @@ def page_admin():
|
|||||||
workhours = [ ]
|
workhours = [ ]
|
||||||
|
|
||||||
with ui.row():
|
with ui.row():
|
||||||
|
|
||||||
def user_selection_changed():
|
def user_selection_changed():
|
||||||
try:
|
try:
|
||||||
if user_selection.value != None:
|
if user_selection.value != None:
|
||||||
@ -1135,12 +1089,7 @@ def page_admin():
|
|||||||
fullname_input.value = current_user.fullname
|
fullname_input.value = current_user.fullname
|
||||||
#password_input.value = current_user.password
|
#password_input.value = current_user.password
|
||||||
usersettingscard.visible = True
|
usersettingscard.visible = True
|
||||||
if current_user.username in get_admin_list():
|
|
||||||
delete_info.value = True
|
|
||||||
delete_binder.value = False
|
|
||||||
else:
|
|
||||||
delete_info.value = False
|
|
||||||
delete_binder.value = True
|
|
||||||
api_key_input.value = current_user.api_key
|
api_key_input.value = current_user.api_key
|
||||||
|
|
||||||
api_link_column.clear()
|
api_link_column.clear()
|
||||||
@ -1213,7 +1162,7 @@ def page_admin():
|
|||||||
ui.label("Benutzername wurde geändert.").classes('text-bold')
|
ui.label("Benutzername wurde geändert.").classes('text-bold')
|
||||||
ui.label(f"Benutzerdaten werden in den neuen Ordner {username_input.value} verschoben.")
|
ui.label(f"Benutzerdaten werden in den neuen Ordner {username_input.value} verschoben.")
|
||||||
ui.label("Sollen die Einstellungen gespeichert werden?")
|
ui.label("Sollen die Einstellungen gespeichert werden?")
|
||||||
with ui.row().classes('w-full justify-center'):
|
with ui.row():
|
||||||
ui.button("Speichern", on_click=save_settings)
|
ui.button("Speichern", on_click=save_settings)
|
||||||
ui.button("Abbrechen", on_click=dialog.close)
|
ui.button("Abbrechen", on_click=dialog.close)
|
||||||
dialog.open()
|
dialog.open()
|
||||||
@ -1266,9 +1215,9 @@ def page_admin():
|
|||||||
|
|
||||||
with ui.dialog() as dialog, ui.card():
|
with ui.dialog() as dialog, ui.card():
|
||||||
ui.label("Sollen die Änderungen an den Arbeitsstunden und/oder Urlaubstagen gespeichert werden?")
|
ui.label("Sollen die Änderungen an den Arbeitsstunden und/oder Urlaubstagen gespeichert werden?")
|
||||||
with ui.row().classes('justify-center w-full'):
|
with ui.row():
|
||||||
ui.button("Speichern", on_click=save_settings)
|
ui.button("Speichern", on_click=save_settings)
|
||||||
ui.button("Abbrechen", on_click=dialog.close)
|
ui.button("Abrrechen", on_click=dialog.close)
|
||||||
dialog.open()
|
dialog.open()
|
||||||
|
|
||||||
def delete_workhour_entry():
|
def delete_workhour_entry():
|
||||||
@ -1372,18 +1321,16 @@ def page_admin():
|
|||||||
ui.button("Neu", on_click=new_api_key).tooltip("Neuen API-Schlüssel erzeugen. Wird erst beim Klick auf Speichern übernommen und entsprechende Links und QR-Codes aktualisiert")
|
ui.button("Neu", on_click=new_api_key).tooltip("Neuen API-Schlüssel erzeugen. Wird erst beim Klick auf Speichern übernommen und entsprechende Links und QR-Codes aktualisiert")
|
||||||
ui.label('Aufruf zum Stempeln:')
|
ui.label('Aufruf zum Stempeln:')
|
||||||
global api_link_column
|
global api_link_column
|
||||||
with ui.expansion("").classes('w-full'):
|
|
||||||
with ui.column().classes('gap-0') as api_link_column:
|
with ui.column().classes('gap-0') as api_link_column:
|
||||||
global stamp_link
|
global stamp_link
|
||||||
stamp_link = [ ]
|
stamp_link = [ ]
|
||||||
for i in app.urls:
|
for i in app.urls:
|
||||||
stamp_link.append(ui.link(f'{i}/api/stamp/"API-Schüssel"'))
|
stamp_link.append(ui.link(f'{i}/api/stamp/"API-Schüssel"'))
|
||||||
|
|
||||||
ui.label("Administratoren können nicht gelöscht werden. Um das Konto zu löschen, müssen Sie ihm zuerst die Administrationsrechte entziehen.").bind_visibility_from(delete_info, 'value').classes('font-bold text-red')
|
|
||||||
with ui.grid(columns=2):
|
with ui.grid(columns=2):
|
||||||
ui.button("Speichern", on_click=save_user_settings).tooltip("Klicken Sie hier um die Änderungen zu speichern.")
|
ui.button("Speichern", on_click=save_user_settings).tooltip("Klicken Sie hier um die Änderungen zu speichern.")
|
||||||
ui.button("Löschen", on_click=del_user).bind_enabled_from(delete_binder, 'value')
|
ui.button("Löschen", on_click=del_user)
|
||||||
|
|
||||||
|
|
||||||
usersettings_card()
|
usersettings_card()
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ from pathlib import Path
|
|||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
app_title = "Zeiterfassung"
|
app_title = "Zeiterfassung"
|
||||||
app_version = "beta-2025.0.2"
|
app_version = "beta-2025.0.1"
|
||||||
|
|
||||||
# Standardpfade
|
# Standardpfade
|
||||||
|
|
||||||
@ -36,9 +36,8 @@ status_out = "ausgestempelt"
|
|||||||
|
|
||||||
# Standardadmin Settings:
|
# Standardadmin Settings:
|
||||||
|
|
||||||
standard_adminsettings = { "admin_user": {
|
standard_adminsettings = { "admin_user": "admin",
|
||||||
0: "admin"},
|
"admin_password": "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",
|
||||||
"no_time_users": { },
|
|
||||||
"port": "8090",
|
"port": "8090",
|
||||||
"secret": "ftgzuhjikg,mt5jn46uzer8sfi9okrmtzjhndfierko5zltjhdgise",
|
"secret": "ftgzuhjikg,mt5jn46uzer8sfi9okrmtzjhndfierko5zltjhdgise",
|
||||||
"times_on_touchscreen": True,
|
"times_on_touchscreen": True,
|
||||||
@ -56,9 +55,9 @@ standard_adminsettings = { "admin_user": {
|
|||||||
# Standard User Settings:
|
# Standard User Settings:
|
||||||
|
|
||||||
standard_usersettings = {
|
standard_usersettings = {
|
||||||
"username": "admin",
|
"username": "default",
|
||||||
"fullname": "Administrator",
|
"fullname": "Standardbenutzer",
|
||||||
"password": "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918",
|
"password": "37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f",
|
||||||
"api_key": "1234567890",
|
"api_key": "1234567890",
|
||||||
"workhours": { }
|
"workhours": { }
|
||||||
}
|
}
|
||||||
|
|||||||
41
lib/login.py
Normal file
41
lib/login.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from nicegui import ui, app
|
||||||
|
from lib.web_ui import *
|
||||||
|
|
||||||
|
from lib.users import *
|
||||||
|
from lib.definitions import *
|
||||||
|
from calendar import monthrange
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import calendar
|
||||||
|
import locale
|
||||||
|
|
||||||
|
@ui.page('/login')
|
||||||
|
def page_login():
|
||||||
|
|
||||||
|
# Settingsdatei einlesen
|
||||||
|
data = load_adminsettings()
|
||||||
|
|
||||||
|
def login():
|
||||||
|
nonlocal data
|
||||||
|
|
||||||
|
if username.value == data["admin_user"]:
|
||||||
|
print(f"Input Hash: {hash_password(password.value)} gespeichert: {data['admin_password']}")
|
||||||
|
if hash_password(password.value) == data["admin_password"]:
|
||||||
|
app.storage.user['authenticated'] = True
|
||||||
|
ui.navigate.to("/admin")
|
||||||
|
else:
|
||||||
|
ui.notify("Login fehlgeschlagen")
|
||||||
|
|
||||||
|
#ui.markdown(f"## {app_title} {app_version}")
|
||||||
|
#ui.markdown("Bitte einloggen")
|
||||||
|
|
||||||
|
pageheader("Bitte einloggen:")
|
||||||
|
|
||||||
|
with ui.grid(columns=2):
|
||||||
|
ui.markdown("Benutzer:")
|
||||||
|
username = ui.input('Benutzername')
|
||||||
|
ui.markdown("Passwort:")
|
||||||
|
password = ui.input('Passwort', password=True)
|
||||||
|
ui.button(text="Login", on_click=lambda: login())
|
||||||
@ -41,15 +41,15 @@ def page_touchscreen():
|
|||||||
def set_columns(width):
|
def set_columns(width):
|
||||||
nonlocal number_of_columns
|
nonlocal number_of_columns
|
||||||
if width > 1400:
|
if width > 1400:
|
||||||
number_of_columns = 5
|
number_of_columns = 6
|
||||||
elif width > 1200:
|
elif width > 1200:
|
||||||
number_of_columns = 4
|
number_of_columns = 5
|
||||||
elif width > 900:
|
elif width > 900:
|
||||||
number_of_columns = 3
|
number_of_columns = 4
|
||||||
elif width > 750:
|
elif width > 750:
|
||||||
number_of_columns = 2
|
number_of_columns = 3
|
||||||
else:
|
else:
|
||||||
number_of_columns = 1
|
number_of_columns = 2
|
||||||
user_buttons.refresh()
|
user_buttons.refresh()
|
||||||
|
|
||||||
ui.on('resize', lambda e: set_columns(e.args['width']))
|
ui.on('resize', lambda e: set_columns(e.args['width']))
|
||||||
@ -71,12 +71,11 @@ def page_touchscreen():
|
|||||||
</script>
|
</script>
|
||||||
''')
|
''')
|
||||||
|
|
||||||
with ui.grid(columns=number_of_columns).classes('w-full'):
|
with ui.grid(columns=number_of_columns).classes('w-full center'):
|
||||||
|
|
||||||
for name in userlist:
|
for name in userlist:
|
||||||
current_user = user(name)
|
current_user = user(name)
|
||||||
if not current_user.username in get_no_time_users_list():
|
current_button = ui.button(on_click=lambda name=name: button_click(name)).classes(f'w-md h-full min-h-[{admin_settings["button_height"]}px]')
|
||||||
current_button = ui.button(on_click=lambda name=name: button_click(name)).classes(f'h-full min-h-[{admin_settings["button_height"]}px]')
|
|
||||||
|
|
||||||
with current_button:
|
with current_button:
|
||||||
with ui.grid(columns='1fr 1fr').classes('w-full h-full py-5 items-start'):
|
with ui.grid(columns='1fr 1fr').classes('w-full h-full py-5 items-start'):
|
||||||
@ -121,7 +120,7 @@ def page_touchscreen():
|
|||||||
<path style="fill:#D61E1E;" d="M85.85,60.394c-9.086,7.86-17.596,16.37-25.456,25.456l349.914,349.914
|
<path style="fill:#D61E1E;" d="M85.85,60.394c-9.086,7.86-17.596,16.37-25.456,25.456l349.914,349.914
|
||||||
c9.086-7.861,17.596-16.37,25.456-25.456L85.85,60.394z"/>
|
c9.086-7.861,17.596-16.37,25.456-25.456L85.85,60.394z"/>
|
||||||
</svg>'''
|
</svg>'''
|
||||||
ui.html(no_photo_svg, sanitize=False)
|
ui.html(no_photo_svg)
|
||||||
with ui.column().classes('' if admin_settings["photos_on_touchscreen"] else 'col-span-2'):
|
with ui.column().classes('' if admin_settings["photos_on_touchscreen"] else 'col-span-2'):
|
||||||
ui.label(current_user.fullname).classes('text-left text-xl text.bold')
|
ui.label(current_user.fullname).classes('text-left text-xl text.bold')
|
||||||
if admin_settings["times_on_touchscreen"]:
|
if admin_settings["times_on_touchscreen"]:
|
||||||
|
|||||||
10
lib/users.py
10
lib/users.py
@ -578,13 +578,3 @@ def write_adminsetting(key: str, value):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
print(f"Kein Einstellungsschlüssel {key} vorhanden.")
|
print(f"Kein Einstellungsschlüssel {key} vorhanden.")
|
||||||
|
|
||||||
def get_admin_list():
|
|
||||||
adnin_settings = load_adminsettings()
|
|
||||||
admin_list = load_adminsettings()["admin_user"]
|
|
||||||
return admin_list.values()
|
|
||||||
|
|
||||||
def get_no_time_users_list():
|
|
||||||
adnin_settings = load_adminsettings()
|
|
||||||
admin_list = load_adminsettings()["no_time_users"]
|
|
||||||
return admin_list.values()
|
|
||||||
|
|
||||||
|
|||||||
@ -38,24 +38,8 @@ class login_mask:
|
|||||||
def login():
|
def login():
|
||||||
nonlocal data
|
nonlocal data
|
||||||
|
|
||||||
if username.value in get_admin_list():
|
if username.value == data["admin_user"]:
|
||||||
current_user = user(username.value)
|
if hash_password(password.value) == data["admin_password"]:
|
||||||
if hash_password(password.value) == current_user.password:
|
|
||||||
if not username.value in get_no_time_users_list():
|
|
||||||
with ui.dialog() as forward_dialog, ui.card():
|
|
||||||
ui.label("Wollen Sie den Administrationsbereich oder den Datenbereich aufrufen?")
|
|
||||||
def admin_area():
|
|
||||||
app.storage.user['admin_authenticated'] = True
|
|
||||||
ui.navigate.to('/admin')
|
|
||||||
def time_area():
|
|
||||||
app.storage.user['active_user'] = current_user.username
|
|
||||||
ui.navigate.to(self.target)
|
|
||||||
with ui.grid(columns=2).classes('justify-center w-full'):
|
|
||||||
ui.button("Administrationsbereich", on_click=admin_area)
|
|
||||||
ui.button("Datenbereich", on_click=time_area)
|
|
||||||
|
|
||||||
forward_dialog.open()
|
|
||||||
else:
|
|
||||||
app.storage.user['admin_authenticated'] = True
|
app.storage.user['admin_authenticated'] = True
|
||||||
ui.navigate.to("/admin")
|
ui.navigate.to("/admin")
|
||||||
else:
|
else:
|
||||||
|
|||||||
38
main.py
38
main.py
@ -4,6 +4,7 @@ import os.path
|
|||||||
|
|
||||||
from lib.web_ui import *
|
from lib.web_ui import *
|
||||||
from lib.admin import *
|
from lib.admin import *
|
||||||
|
from lib.login import *
|
||||||
from lib.users import *
|
from lib.users import *
|
||||||
from lib.touchscreen import *
|
from lib.touchscreen import *
|
||||||
from lib.definitions import *
|
from lib.definitions import *
|
||||||
@ -32,7 +33,7 @@ def main():
|
|||||||
|
|
||||||
list_users()
|
list_users()
|
||||||
|
|
||||||
#homepage()
|
homepage()
|
||||||
|
|
||||||
def startup_message():
|
def startup_message():
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ def main():
|
|||||||
ui.toggle.default_props('rounded')
|
ui.toggle.default_props('rounded')
|
||||||
ui.row.default_classes('items-baseline')
|
ui.row.default_classes('items-baseline')
|
||||||
|
|
||||||
ui.run(root=homepage, favicon='⏲', port=port, storage_secret=secret, language='de-DE', show_welcome_message=False)
|
ui.run(favicon='⏲', port=port, storage_secret=secret, language='de-DE', show_welcome_message=False)
|
||||||
|
|
||||||
if __name__ in ("__main__", "__mp_main__"):
|
if __name__ in ("__main__", "__mp_main__"):
|
||||||
parser = argparse.ArgumentParser(description=f'{app_title} {app_version}')
|
parser = argparse.ArgumentParser(description=f'{app_title} {app_version}')
|
||||||
@ -84,34 +85,11 @@ if __name__ in ("__main__", "__mp_main__"):
|
|||||||
print("Sollen diese Einstellungen übernommen werden? j=Ja")
|
print("Sollen diese Einstellungen übernommen werden? j=Ja")
|
||||||
question = input()
|
question = input()
|
||||||
if question == "j":
|
if question == "j":
|
||||||
if not os.path.exists(userfolder):
|
admin_settings["admin_user"] = admin_user
|
||||||
os.makedirs(userfolder)
|
admin_settings["admin_password"] = hash_password(admin_password)
|
||||||
print("Kein Ordner mit Benutzerdaten gefunden. Lege ihn an.")
|
json_dict = json.dumps(admin_settings, indent=4)
|
||||||
if not os.path.exists(os.path.join(userfolder, admin_user)):
|
with open(os.path.join(scriptpath, usersettingsfilename), "w") as outputfile:
|
||||||
print("Benutzer existiert noch nicht. Lege ihn an.")
|
outputfile.write(json_dict)
|
||||||
os.makedirs(os.path.join(userfolder, admin_user))
|
|
||||||
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"] = "Administrator"
|
|
||||||
settings_to_write["username"] = admin_user
|
|
||||||
# API-Key erzeugen
|
|
||||||
string_to_hash = f'{admin_user}_{datetime.datetime.now().timestamp()}'
|
|
||||||
hash_string = hashlib.shake_256(bytes(string_to_hash, 'utf-8')).hexdigest(20)
|
|
||||||
settings_to_write["api_key"] = hash_string
|
|
||||||
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}/{admin_user}/{usersettingsfilename}", 'w') as json_file:
|
|
||||||
json_dict = json.dumps(standard_usersettings, indent=4)
|
|
||||||
json_file.write(json_dict)
|
|
||||||
current_user = user(admin_user)
|
|
||||||
current_user.password = hash_password(admin_password)
|
|
||||||
current_user.write_settings()
|
|
||||||
admin_users_list = load_adminsettings()["admin_user"]
|
|
||||||
admin_users_list[str(len(admin_users_list))] = admin_user
|
|
||||||
write_adminsetting("admin_user", admin_users_list)
|
|
||||||
print("Daten geschrieben")
|
print("Daten geschrieben")
|
||||||
quit()
|
quit()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"admin_user": {
|
|
||||||
"0": "admin"
|
|
||||||
},
|
|
||||||
"no_time_users": {
|
|
||||||
"0": "admin"
|
|
||||||
},
|
|
||||||
"port": "8090",
|
|
||||||
"secret": "ftgzuhjikg,mt5jn46uzer8sfi9okrmtzjhndfierko5zltjhdgise",
|
|
||||||
"times_on_touchscreen": true,
|
|
||||||
"photos_on_touchscreen": true,
|
|
||||||
"touchscreen": true,
|
|
||||||
"picture_height": 200,
|
|
||||||
"button_height": "300",
|
|
||||||
"user_notes": true,
|
|
||||||
"vacation_application": true,
|
|
||||||
"backup_folder": "/home/alexander/Dokumente/Python/Zeiterfassung/backup",
|
|
||||||
"backup_api_key": "6fed93dc4a35308b2c073a8a6f3284afe1fb9946",
|
|
||||||
"holidays": {}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user