Merge branch 'api-stamping' into web_ui
This commit is contained in:
commit
d740b8e2b6
28
admin.py
28
admin.py
@ -280,7 +280,7 @@ def page_admin():
|
|||||||
ui.button("Abbrechen", on_click=edit_dialog.close)
|
ui.button("Abbrechen", on_click=edit_dialog.close)
|
||||||
|
|
||||||
edit_dialog.open()
|
edit_dialog.open()
|
||||||
for i in range(len(timestamps_dict[day])):
|
for i in range(0, len(timestamps_dict[day]), 2):
|
||||||
try:
|
try:
|
||||||
temp_pair = [ timestamps_dict[day][i] , timestamps_dict[day][i+1] ]
|
temp_pair = [ timestamps_dict[day][i] , timestamps_dict[day][i+1] ]
|
||||||
with ui.card().classes('bg-inherit'):
|
with ui.card().classes('bg-inherit'):
|
||||||
@ -289,7 +289,7 @@ def page_admin():
|
|||||||
timestamp_button = ui.button(datetime.datetime.fromtimestamp(int(j)).strftime('%H:%M'), on_click=lambda t_stamp=j, day=day: edit_entry(t_stamp, day))
|
timestamp_button = ui.button(datetime.datetime.fromtimestamp(int(j)).strftime('%H:%M'), on_click=lambda t_stamp=j, day=day: edit_entry(t_stamp, day))
|
||||||
if archive_status:
|
if archive_status:
|
||||||
timestamp_button.disable()
|
timestamp_button.disable()
|
||||||
except:
|
except Exception as e:
|
||||||
if len(timestamps_dict[day]) % 2 != 0:
|
if len(timestamps_dict[day]) % 2 != 0:
|
||||||
with ui.card().classes('bg-inherit'):
|
with ui.card().classes('bg-inherit'):
|
||||||
timestamp_button = ui.button(datetime.datetime.fromtimestamp(int(timestamps_dict[day][i])).strftime('%H:%M'), on_click=lambda t_stamp=timestamps_dict[day][i], day=day: edit_entry(t_stamp, day))
|
timestamp_button = ui.button(datetime.datetime.fromtimestamp(int(timestamps_dict[day][i])).strftime('%H:%M'), on_click=lambda t_stamp=timestamps_dict[day][i], day=day: edit_entry(t_stamp, day))
|
||||||
@ -754,6 +754,14 @@ def page_admin():
|
|||||||
#password_input.value = current_user.password
|
#password_input.value = current_user.password
|
||||||
usersettingscard.visible = True
|
usersettingscard.visible = True
|
||||||
|
|
||||||
|
api_key_input.value = current_user.api_key
|
||||||
|
|
||||||
|
api_link_column.clear()
|
||||||
|
for i in app.urls:
|
||||||
|
link = ui.link(f'{i}/api/stamp/"API-Schlüssel"', f'{i}/api/stamp/{api_key_input.value}')
|
||||||
|
link.tooltip("ACHTUNG: Klick auf den Link löst Stempelaktion aus!")
|
||||||
|
link.move(api_link_column)
|
||||||
|
|
||||||
workhours_select.clear()
|
workhours_select.clear()
|
||||||
workhour_list = list(current_user.workhours)
|
workhour_list = list(current_user.workhours)
|
||||||
workhour_list.sort()
|
workhour_list.sort()
|
||||||
@ -792,6 +800,7 @@ def page_admin():
|
|||||||
current_user.username = username_input.value
|
current_user.username = username_input.value
|
||||||
current_user.fullname = fullname_input.value
|
current_user.fullname = fullname_input.value
|
||||||
current_user.password = hash_password(password_input.value)
|
current_user.password = hash_password(password_input.value)
|
||||||
|
current_user.api_key = api_key_input.value
|
||||||
current_user.write_settings()
|
current_user.write_settings()
|
||||||
password_input.value = ""
|
password_input.value = ""
|
||||||
userlist = list_users()
|
userlist = list_users()
|
||||||
@ -920,7 +929,7 @@ def page_admin():
|
|||||||
with ui.column():
|
with ui.column():
|
||||||
with ui.card() as usersettingscard:
|
with ui.card() as usersettingscard:
|
||||||
ui.markdown("**Benutzereinstellungen**")
|
ui.markdown("**Benutzereinstellungen**")
|
||||||
with ui.grid(columns=2):
|
with ui.grid(columns="auto 1fr") as usersettingsgrid:
|
||||||
|
|
||||||
ui.markdown("Benutzername:")
|
ui.markdown("Benutzername:")
|
||||||
username_input = ui.input()
|
username_input = ui.input()
|
||||||
@ -929,9 +938,20 @@ def page_admin():
|
|||||||
ui.markdown("Passwort")
|
ui.markdown("Passwort")
|
||||||
password_input = ui.input(password=True)
|
password_input = ui.input(password=True)
|
||||||
password_input.value = ""
|
password_input.value = ""
|
||||||
|
ui.markdown("API-Schlüssel:")
|
||||||
|
with ui.row():
|
||||||
|
api_key_input = ui.input().props('size=37')
|
||||||
|
def new_api_key():
|
||||||
|
api_key_input.value = hashlib.shake_256(bytes(f'{username_input.value}_{datetime.datetime.now().timestamp()}', 'utf-8')).hexdigest(20)
|
||||||
|
ui.button("Neu", on_click=new_api_key)
|
||||||
|
ui.markdown('Aufruf zum Stempeln:')
|
||||||
|
with ui.column().classes('gap-0') as api_link_column:
|
||||||
|
stamp_link = [ ]
|
||||||
|
for i in app.urls:
|
||||||
|
stamp_link.append(ui.link(f'{i}/api/stamp/"API-Schüssel"'))
|
||||||
|
|
||||||
with ui.grid(columns=2):
|
with ui.grid(columns=2):
|
||||||
ui.button("Speichern", on_click=save_user_settings)
|
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)
|
ui.button("Löschen", on_click=del_user)
|
||||||
|
|
||||||
with ui.card() as photocard:
|
with ui.card() as photocard:
|
||||||
|
31
api.py
31
api.py
@ -97,7 +97,7 @@ def page_overview_month(username: str, year: int, month: int):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# Buchungen behandeln
|
# Buchungen behandeln
|
||||||
for i in range(len(timestamps_dict[day])):
|
for i in range(0, len(timestamps_dict[day]), 2):
|
||||||
try:
|
try:
|
||||||
temp_pair = [timestamps_dict[day][i], timestamps_dict[day][i + 1]]
|
temp_pair = [timestamps_dict[day][i], timestamps_dict[day][i + 1]]
|
||||||
booking_text = booking_text + str(datetime.fromtimestamp(temp_pair[0]).strftime('%H:%M')) + "-" + str(datetime.fromtimestamp(temp_pair[1]).strftime('%H:%M')) + "<br>"
|
booking_text = booking_text + str(datetime.fromtimestamp(temp_pair[0]).strftime('%H:%M')) + "-" + str(datetime.fromtimestamp(temp_pair[1]).strftime('%H:%M')) + "<br>"
|
||||||
@ -395,3 +395,32 @@ def page_overview_absence(username: str, year: int):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
login = login_mask(target=f'/api/absence/{username}/{year}')
|
login = login_mask(target=f'/api/absence/{username}/{year}')
|
||||||
|
|
||||||
|
@ui.page('/api/stamp/{api_key}')
|
||||||
|
def page_api_stamp(api_key: str):
|
||||||
|
userlist = list_users()
|
||||||
|
user_dict = { }
|
||||||
|
# Dictionary mit Usernamen befüllen
|
||||||
|
for i in userlist:
|
||||||
|
user_dict[i] = ""
|
||||||
|
for entry in list(user_dict):
|
||||||
|
try:
|
||||||
|
temp_user = user(entry)
|
||||||
|
user_dict[entry] = temp_user.api_key
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
found_key = False
|
||||||
|
|
||||||
|
ui.page_title(f'{app_title} {app_version}')
|
||||||
|
|
||||||
|
for user_key, api_value in user_dict.items():
|
||||||
|
if api_key == api_value:
|
||||||
|
current_user = user(user_key)
|
||||||
|
current_user.timestamp()
|
||||||
|
found_key = True
|
||||||
|
ui.label(f'Zeitstempel {datetime.now().strftime("%H:%M")} für {current_user.fullname} eingetragen')
|
||||||
|
break
|
||||||
|
|
||||||
|
if found_key == False:
|
||||||
|
ui.label("Keinen passenden Benutzer gefunden")
|
||||||
|
@ -35,6 +35,7 @@ standard_usersettings = {
|
|||||||
"username": "default",
|
"username": "default",
|
||||||
"fullname": "Standardbenutzer",
|
"fullname": "Standardbenutzer",
|
||||||
"password": "37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f",
|
"password": "37a8eec1ce19687d132fe29051dca629d164e2c4958ba141d5f4133a33f0688f",
|
||||||
|
"api_key": "1234567890",
|
||||||
"workhours": { }
|
"workhours": { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ from web_ui import *
|
|||||||
|
|
||||||
@ui.page('/')
|
@ui.page('/')
|
||||||
def homepage():
|
def homepage():
|
||||||
|
ui.page_title(f'{app_title} {app_version}')
|
||||||
if login_is_valid():
|
if login_is_valid():
|
||||||
|
|
||||||
ui.page_title("Zeiterfassung")
|
|
||||||
try:
|
try:
|
||||||
current_user = user(app.storage.user["active_user"])
|
current_user = user(app.storage.user["active_user"])
|
||||||
except:
|
except:
|
||||||
@ -49,7 +49,6 @@ def homepage():
|
|||||||
|
|
||||||
def update_timer():
|
def update_timer():
|
||||||
time_in_total = time_so_far + int((datetime.datetime.now().timestamp() - current_user.get_worked_time(today.year, today.month, today.day)[1]))
|
time_in_total = time_so_far + int((datetime.datetime.now().timestamp() - current_user.get_worked_time(today.year, today.month, today.day)[1]))
|
||||||
print(time_in_total)
|
|
||||||
working_hours.set_content(convert_seconds_to_hours(time_in_total))
|
working_hours.set_content(convert_seconds_to_hours(time_in_total))
|
||||||
|
|
||||||
working_timer = ui.timer(1.0, update_timer)
|
working_timer = ui.timer(1.0, update_timer)
|
||||||
|
8
users.py
8
users.py
@ -1,5 +1,5 @@
|
|||||||
# Zeiterfassung
|
# Zeiterfassung
|
||||||
|
import hashlib
|
||||||
# User bezogene Funktionen
|
# User bezogene Funktionen
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@ -32,6 +32,7 @@ class user:
|
|||||||
self.workhours = data["workhours"]
|
self.workhours = data["workhours"]
|
||||||
self.username = data["username"]
|
self.username = data["username"]
|
||||||
self.fullname = data["fullname"]
|
self.fullname = data["fullname"]
|
||||||
|
self.api_key = data["api_key"]
|
||||||
|
|
||||||
def get_stamp_file(self, time_stamp=None):
|
def get_stamp_file(self, time_stamp=None):
|
||||||
if time_stamp == None:
|
if time_stamp == None:
|
||||||
@ -121,6 +122,7 @@ class user:
|
|||||||
dict["fullname"] = self.fullname
|
dict["fullname"] = self.fullname
|
||||||
dict["password"] = self.password
|
dict["password"] = self.password
|
||||||
dict["workhours"] = self.workhours
|
dict["workhours"] = self.workhours
|
||||||
|
dict["api_key"] = self.api_key
|
||||||
|
|
||||||
json_dict = json.dumps(dict, indent=4)
|
json_dict = json.dumps(dict, indent=4)
|
||||||
|
|
||||||
@ -405,6 +407,10 @@ def new_user(username: str):
|
|||||||
settings_to_write["workhours"][start_date] = { }
|
settings_to_write["workhours"][start_date] = { }
|
||||||
settings_to_write["fullname"] = username
|
settings_to_write["fullname"] = username
|
||||||
settings_to_write["username"] = username
|
settings_to_write["username"] = username
|
||||||
|
# API-Key erzeugen
|
||||||
|
string_to_hash = f'{username}_{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):
|
for i in range(1, 8):
|
||||||
settings_to_write["workhours"][start_date][str(i)] = 0
|
settings_to_write["workhours"][start_date][str(i)] = 0
|
||||||
settings_to_write["workhours"][start_date]["vacation"] = 0
|
settings_to_write["workhours"][start_date]["vacation"] = 0
|
||||||
|
@ -1,2 +1,8 @@
|
|||||||
1746385124
|
1746385124
|
||||||
1746388680
|
1746388680
|
||||||
|
1746607385
|
||||||
|
1746607536
|
||||||
|
1746607833
|
||||||
|
1746608922
|
||||||
|
1746609024
|
||||||
|
1746609037
|
||||||
|
@ -33,5 +33,6 @@
|
|||||||
"7": 0,
|
"7": 0,
|
||||||
"vacation": "30"
|
"vacation": "30"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"api_key": "de4403f629a30450b2df1aa619a1c06112035499"
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
"username": "testuser10",
|
"username": "testuser10",
|
||||||
"fullname": "Diego Dieci",
|
"fullname": "Diego Dieci",
|
||||||
"password": "123456789",
|
"password": "123456789",
|
||||||
|
"api_key": "807518cd5bd85c1e4855d340f9b77b23eac21b7f",
|
||||||
"workhours": {
|
"workhours": {
|
||||||
"2024-04-01": {
|
"2024-04-01": {
|
||||||
"1": "1",
|
"1": "1",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"username": "testuser3",
|
"username": "testuser3",
|
||||||
"fullname": "Karl Klammer",
|
"fullname": "Karl Klammer",
|
||||||
"password": "123456789",
|
"password": "123456789",
|
||||||
|
"api_key": "0219f98ec471ea4e2ac6bd6c14b96051aae5209b",
|
||||||
"workhours": {
|
"workhours": {
|
||||||
"2024-04-01": {
|
"2024-04-01": {
|
||||||
"1": "4",
|
"1": "4",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user