Merge branch 'docker'
This commit is contained in:
commit
eef55729c2
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@ users/
|
||||
backup/
|
||||
Archiv/
|
||||
Docker/
|
||||
docker-work/
|
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@ -0,0 +1,24 @@
|
||||
FROM debian:latest
|
||||
RUN apt update && apt upgrade -y
|
||||
RUN apt install python3 python3-pip python3.11-venv locales -y
|
||||
RUN mkdir /app
|
||||
RUN mkdir /.venv
|
||||
RUN mkdir /backup
|
||||
RUN mkdir /settings
|
||||
RUN python3 -m venv /.venv
|
||||
RUN /.venv/bin/pip install nicegui
|
||||
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 && \
|
||||
locale-gen
|
||||
ENV LANG de_DE.UTF-8
|
||||
ENV LANGUAGE de_DE:de
|
||||
ENV LC_ALL de_DE.UTF-8
|
||||
|
||||
COPY main.py /app/main.py
|
||||
COPY favicon.svg /app/favicon.svg
|
||||
COPY lib /app/lib/
|
||||
EXPOSE 8090
|
||||
ENTRYPOINT ["/.venv/bin/python", "/app/main.py"]
|
||||
#ENTRYPOINT exec /app/.venv/bin/python /app/main.py --docker
|
11
docker-compose.yml
Normal file
11
docker-compose.yml
Normal file
@ -0,0 +1,11 @@
|
||||
services:
|
||||
test:
|
||||
image: test:0
|
||||
restart: always
|
||||
ports:
|
||||
- 8090:8090
|
||||
volumes:
|
||||
#- /home/alexander/Dokumente/Python/Zeiterfassung:/app
|
||||
- /home/alexander/Dokumente/Python/Zeiterfassung/docker-work/users:/users
|
||||
- /home/alexander/Dokumente/Python/Zeiterfassung/docker-work/backup:/backup
|
||||
- /home/alexander/Dokumente/Python/Zeiterfassung/docker-work/settings:/settings
|
26
lib/admin.py
26
lib/admin.py
@ -1,7 +1,6 @@
|
||||
from datetime import datetime
|
||||
|
||||
import dateutil.easter
|
||||
from PIL.SpiderImagePlugin import isInt
|
||||
from dateutil.easter import *
|
||||
|
||||
from nicegui import ui, app, events
|
||||
@ -45,6 +44,14 @@ def page_admin():
|
||||
updates_available = ValueBinder()
|
||||
updates_available.value = False
|
||||
|
||||
enabled_because_not_docker = ValueBinder
|
||||
if is_docker():
|
||||
enabled_because_not_docker.value = False
|
||||
scriptpath = "/app"
|
||||
backupfolder = "/backup"
|
||||
else:
|
||||
enabled_because_not_docker.value = True
|
||||
|
||||
with ui.tabs() as tabs:
|
||||
|
||||
time_overview = ui.tab('Zeitdaten')
|
||||
@ -760,7 +767,9 @@ Dies kann nicht rückgängig gemacht werden!''')
|
||||
|
||||
ui.markdown("Port:")
|
||||
port = ui.input(validation={"Nur ganzzahlige Portnummern erlaubt": lambda value: check_is_number(value),
|
||||
"Portnummer zu klein": lambda value: len(value)>=2}).tooltip("Geben Sie hier die Portnummer ein, unter der die Zeiterfassung erreichbar ist.").props('size=5')
|
||||
"Portnummer zu klein": lambda value: len(value)>=2}).tooltip("Geben Sie hier die Portnummer ein, unter der die Zeiterfassung erreichbar ist.").props('size=5').bind_enabled_from(enabled_because_not_docker, 'value')
|
||||
if is_docker():
|
||||
port.tooltip("Diese Einstellung ist beim Einsatz von Docker deaktiviert.")
|
||||
old_port = data["port"]
|
||||
port.value = old_port
|
||||
|
||||
@ -1396,7 +1405,7 @@ Dies kann nicht rückgängig gemacht werden!''')
|
||||
ui.label("Backupeinstellungen").classes('font-bold')
|
||||
with ui.grid(columns='auto auto auto'):
|
||||
ui.markdown("Backupordner:")
|
||||
backupfolder_input = ui.input(value=backupfolder).props(f"size={len(backupfolder)}")
|
||||
backupfolder_input = ui.input(value=backupfolder).props(f"size={len(backupfolder)}").bind_enabled_from(enabled_because_not_docker, 'value')
|
||||
def save_new_folder_name():
|
||||
if os.path.exists(backupfolder_input.value):
|
||||
write_adminsetting("backup_folder", backupfolder_input.value)
|
||||
@ -1408,7 +1417,9 @@ Dies kann nicht rückgängig gemacht werden!''')
|
||||
ui.label("exisitiert nicht und kann daher nicht verwendet werden.")
|
||||
ui.button("OK", on_click=dialog.close)
|
||||
dialog.open()
|
||||
ui.button("Speichern", on_click=save_new_folder_name).tooltip("Hiermit können Sie das Backupverzeichnis ändeern")
|
||||
save_backup_folder_button = ui.button("Speichern", on_click=save_new_folder_name).tooltip("Hiermit können Sie das Backupverzeichnis ändeern").bind_enabled_from(enabled_because_not_docker, 'value')
|
||||
if is_docker():
|
||||
save_backup_folder_button.tooltip("Diese Einstellung ist beim Einsatz von Docker deaktiviert.")
|
||||
|
||||
ui.markdown("API-Schlüssel:")
|
||||
backup_api_key_input = ui.input(value=api_key).tooltip("Hier den API-Schlüssel eintragen, der für Backuperzeugung mittels API-Aufruf verwendet werden soll.")
|
||||
@ -1468,7 +1479,10 @@ Dies kann nicht rückgängig gemacht werden!''')
|
||||
except ValueError:
|
||||
button_string = date_string
|
||||
ui.markdown(button_string)
|
||||
ui.markdown(f'{round(size/1_000_000,2)} MB')
|
||||
if size > 1_000_000:
|
||||
ui.markdown(f'{round(size/1_000_000,2)} MB')
|
||||
else:
|
||||
ui.markdown(f'{round(size / 1_000, 2)} kB')
|
||||
ui.markdown(version)
|
||||
ui.button(icon='download', on_click=lambda file=date_string: ui.download.file(
|
||||
os.path.join(scriptpath, backupfolder, f'{file}.zip'))).tooltip(
|
||||
@ -1529,7 +1543,7 @@ Dies kann nicht rückgängig gemacht werden!''')
|
||||
for file in files:
|
||||
add = os.path.join(root, file)
|
||||
target.write(add)
|
||||
target.write(usersettingsfilename)
|
||||
target.write(os.path.join(scriptpath, usersettingsfilename), arcname=usersettingsfilename)
|
||||
target.writestr("app_version.txt", data=app_version)
|
||||
backup_list.refresh()
|
||||
n.dismiss()
|
||||
|
@ -6,12 +6,21 @@ from pathlib import Path
|
||||
import hashlib
|
||||
|
||||
app_title = "Zeiterfassung"
|
||||
app_version = ("0.0.0")
|
||||
app_version = "0.0.0"
|
||||
|
||||
# Standardpfade
|
||||
scriptpath = str(Path(os.path.dirname(os.path.abspath(__file__))).parent.absolute())
|
||||
|
||||
def is_docker():
|
||||
cgroup = Path('/proc/self/cgroup')
|
||||
return Path('/.dockerenv').is_file() or (cgroup.is_file() and 'docker' in cgroup.read_text())
|
||||
|
||||
if is_docker():
|
||||
scriptpath = "/settings"
|
||||
backupfolder = "/backup"
|
||||
else:
|
||||
scriptpath = str(Path(os.path.dirname(os.path.abspath(__file__))).parent.absolute())
|
||||
backupfolder = str(os.path.join(scriptpath, "backup"))
|
||||
userfolder = "users"
|
||||
backupfolder = str(os.path.join(scriptpath, "backup"))
|
||||
|
||||
# Dateinamen
|
||||
|
||||
|
21
lib/users.py
21
lib/users.py
@ -14,25 +14,26 @@ import shutil
|
||||
import re
|
||||
|
||||
from lib.definitions import userfolder, scriptpath, usersettingsfilename, photofilename, status_in, status_out, \
|
||||
standard_adminsettings, standard_usersettings, va_file
|
||||
|
||||
standard_adminsettings, standard_usersettings, va_file, is_docker
|
||||
|
||||
# Benutzerklasse
|
||||
|
||||
class user:
|
||||
def __init__(self, name):
|
||||
self.userfolder = os.path.join(scriptpath, userfolder, name)
|
||||
if not is_docker():
|
||||
self.userfolder = os.path.join(scriptpath, userfolder, name)
|
||||
else:
|
||||
self.userfolder = os.path.join("/users", name)
|
||||
self.settingsfile = os.path.join(self.userfolder, usersettingsfilename)
|
||||
self.photofile = os.path.join(self.userfolder, photofilename)
|
||||
|
||||
# Stammdaten einlesen
|
||||
try:
|
||||
with open(self.settingsfile) as json_file:
|
||||
#try:
|
||||
with open(self.settingsfile) as json_file:
|
||||
data = json.load(json_file)
|
||||
|
||||
except:
|
||||
print("Fehler beim Erstellen des Datenarrays.")
|
||||
#Hier muss noch Fehlerbehandlungcode hin
|
||||
#except:
|
||||
# print("Fehler beim Erstellen des Datenarrays.")
|
||||
# #TODO Hier muss noch Fehlerbehandlungcode hin
|
||||
|
||||
self.password = data["password"]
|
||||
self.workhours = data["workhours"]
|
||||
@ -301,10 +302,8 @@ class user:
|
||||
return { }
|
||||
|
||||
def write_notes(self, year, month, day, note_dict):
|
||||
print(os.path.join(self.userfolder, f"{int(year)}-{int(month)}.json"))
|
||||
with open(os.path.join(self.userfolder, f"{int(year)}-{int(month)}.json"), "r") as json_file:
|
||||
json_data = json.load(json_file)
|
||||
print(json_data)
|
||||
if len(note_dict) == 1:
|
||||
user_info = list(note_dict)[0]
|
||||
json_data["notes"][str(day)] = { }
|
||||
|
@ -15,8 +15,7 @@ import argparse
|
||||
|
||||
from lib.web_ui import hash_password
|
||||
|
||||
|
||||
class Commandline_Header:
|
||||
def commandline_header():
|
||||
message_string = f"{app_title} {app_version}"
|
||||
underline = ""
|
||||
for i in range(len(message_string)):
|
||||
@ -37,8 +36,7 @@ def main():
|
||||
|
||||
def startup_message():
|
||||
|
||||
Commandline_Header()
|
||||
|
||||
commandline_header()
|
||||
url_string = ""
|
||||
for i in list(app.urls):
|
||||
url_string += f"{i}, "
|
||||
@ -60,8 +58,13 @@ if __name__ in ("__main__", "__mp_main__"):
|
||||
parser = argparse.ArgumentParser(description=f'{app_title} {app_version}')
|
||||
parser.add_argument('--admin-access', help='Zugangsdaten für Administrator einstellen', action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
if is_docker():
|
||||
scriptpath = "/app"
|
||||
backupfolder = "/backup"
|
||||
|
||||
if args.admin_access:
|
||||
Commandline_Header()
|
||||
commandline_header()
|
||||
print("Lade Administrationseinstellungen")
|
||||
admin_settings = load_adminsettings()
|
||||
print("Geben Sie den neuen Benutzernamen für den Administrationsbenutzer an:")
|
@ -73,6 +73,7 @@
|
||||
"2030-10-30": "Reformationstag",
|
||||
"2030-12-25": "1. Weihnachtsfeiertag",
|
||||
"2030-12-26": "2. Weihnachtsfeiertag",
|
||||
"2025-06-11": "Testeintrag"
|
||||
"2025-06-11": "Testeintrag",
|
||||
"2025-05-31": "Testeintrag"
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"archived": 0,
|
||||
"archived": 1,
|
||||
"total_hours": 0,
|
||||
"absence": {}
|
||||
"absence": {},
|
||||
"overtime": -406441
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user