2023-11-06 18:49:49 +01:00
|
|
|
#! /usr/bin/python3
|
2021-04-06 21:04:10 +02:00
|
|
|
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import tkinter as tk
|
2021-07-07 16:31:32 +02:00
|
|
|
from tkinter import messagebox
|
2021-06-25 18:57:36 +02:00
|
|
|
import time
|
2021-04-06 21:04:10 +02:00
|
|
|
|
|
|
|
# imporrt the standard to read and write config files
|
|
|
|
import configparser
|
|
|
|
|
|
|
|
#list of required modules
|
|
|
|
modules=list()
|
|
|
|
try:
|
|
|
|
import vlc
|
|
|
|
except:
|
|
|
|
modules.append("python-vlc")
|
|
|
|
|
2023-04-19 11:02:49 +02:00
|
|
|
try:
|
|
|
|
import PIL
|
|
|
|
except:
|
|
|
|
modules.append('pillow')
|
|
|
|
|
|
|
|
try:
|
|
|
|
import requests
|
|
|
|
except:
|
|
|
|
modules.append('requests')
|
|
|
|
|
2021-06-25 18:57:36 +02:00
|
|
|
master=None
|
2023-11-06 18:49:49 +01:00
|
|
|
#when setup can't find the conf file, inited is set to True
|
|
|
|
inited = False
|
|
|
|
#URL for the Intro-Screens, use as default, if conf is inited
|
|
|
|
introURL="https://wolke.netzbegruenung.de/s/2TPGWN5FtWYy2d8/download"
|
|
|
|
|
|
|
|
#set "dirty" flag to False
|
|
|
|
#any change should set it to True, so we can ask on quit to save data
|
|
|
|
isDirty=False
|
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
|
2021-05-26 12:17:29 +02:00
|
|
|
# try:
|
|
|
|
# import crontab
|
|
|
|
# except:
|
|
|
|
# modules.append("python-crontab")
|
2021-04-06 21:04:10 +02:00
|
|
|
|
|
|
|
def createAutostart():
|
|
|
|
'''
|
|
|
|
create the auto start file gruene_signale.desktop in $HOME/.config/autostart/
|
|
|
|
also create intermediate paths if the do not exist
|
|
|
|
when the file already exists, nothing is done
|
|
|
|
'''
|
|
|
|
autostartfile = os.path.expanduser("~/.config/autostart/gruene_signale.desktop")
|
|
|
|
whereami = os.path.dirname(os.path.realpath(__file__))
|
2021-06-09 15:07:30 +02:00
|
|
|
contents = """[Desktop Entry]
|
2021-04-06 21:04:10 +02:00
|
|
|
Type=Application
|
|
|
|
Name=Green Signals Autostart
|
2021-06-09 15:07:30 +02:00
|
|
|
Comment=Starten der Slideshow von Gruene Signale
|
2021-04-06 21:04:10 +02:00
|
|
|
NoDisplay=false
|
2023-11-06 18:49:49 +01:00
|
|
|
Exec=sh -c 'cd %(path)s && %(path)s/venv/bin/python3 gruene_signale.py'
|
2021-04-06 21:04:10 +02:00
|
|
|
"""
|
|
|
|
if os.path.isfile(autostartfile) == False:
|
|
|
|
if os.path.exists(os.path.dirname(autostartfile)) == False:
|
|
|
|
os.makedirs(os.path.dirname(autostartfile))
|
|
|
|
file=open(autostartfile,"w")
|
|
|
|
file.write(contents%{'path':whereami})
|
|
|
|
file.close()
|
|
|
|
|
|
|
|
def removeAutostart():
|
|
|
|
'''
|
|
|
|
check if the auto start file exists, and if it does, remove it
|
|
|
|
'''
|
|
|
|
autostartfile = os.path.expanduser("~/.config/autostart/gruene_signale.desktop")
|
|
|
|
if os.path.isfile(autostartfile) == True:
|
|
|
|
os.remove(autostartfile)
|
|
|
|
|
|
|
|
def checkAutostartfile():
|
|
|
|
'''
|
|
|
|
check if the auto start file gruene_signale.desktop already exists
|
|
|
|
returns True, if it does, False if not
|
|
|
|
'''
|
|
|
|
autostartfile = os.path.expanduser("~/.config/autostart/gruene_signale.desktop")
|
|
|
|
return int(os.path.isfile(autostartfile))
|
|
|
|
|
|
|
|
def installModules():
|
|
|
|
global modules
|
|
|
|
failed=list()
|
|
|
|
for module in modules:
|
|
|
|
try:
|
2021-06-25 18:57:36 +02:00
|
|
|
#subprocess.check_call(["sleep", "5"])
|
2021-04-06 21:04:10 +02:00
|
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", module])
|
|
|
|
except:
|
|
|
|
print("install module %s failed" % module)
|
|
|
|
failed.append(module)
|
|
|
|
modules=failed
|
|
|
|
|
2021-06-25 18:57:36 +02:00
|
|
|
class Popup(tk.Toplevel):
|
|
|
|
"""modal window requires a master"""
|
|
|
|
def __init__(self, master, **kwargs):
|
|
|
|
geo = '%(w)dx%(h)d+%(x)d+%(y)d' % {'x':master.winfo_x()+4,'y':master.winfo_y()+4,'w':master.winfo_width()-8,'h':master.winfo_height()-8}
|
|
|
|
print(geo)
|
|
|
|
tk.Toplevel.__init__(self, master, **kwargs)
|
|
|
|
self.overrideredirect(True)
|
|
|
|
self.geometry(geo) # set the position and size of the popup
|
|
|
|
self.configure(bg="DarkSeaGreen1")
|
|
|
|
|
|
|
|
lbl = tk.Label(self, text="Module werden installiert.",bg="DarkSeaGreen1")
|
|
|
|
lbl.place(relx=.5, rely=.5, anchor='c')
|
|
|
|
|
|
|
|
# The following commands keep the popup on top.
|
|
|
|
# Remove these if you want a program with 2 responding windows.
|
|
|
|
# These commands must be at the end of __init__
|
|
|
|
self.transient(master) # set to be on top of the main window
|
|
|
|
self.grab_set() # hijack all commands from the master (clicks on the main window are ignored)
|
|
|
|
|
|
|
|
def open_popup():
|
|
|
|
if master != None:
|
|
|
|
print("OPEN POPUP")
|
|
|
|
master.popup = Popup(master)
|
|
|
|
master.update()
|
|
|
|
|
|
|
|
def close_popup():
|
|
|
|
if master != None:
|
|
|
|
master.popup.destroy()
|
|
|
|
master.update()
|
|
|
|
|
|
|
|
def installModulesGUI(i=0,event=None):
|
|
|
|
global modules
|
|
|
|
open_popup()
|
|
|
|
installModules()
|
|
|
|
close_popup()
|
|
|
|
if len(modules)==0:
|
|
|
|
master.installButton.configure(bg="pale green")
|
|
|
|
master.installButton.configure(state='disabled')
|
|
|
|
master.installButton.configure(text='bereits installiert.')
|
|
|
|
|
2021-04-12 14:15:42 +02:00
|
|
|
def validateTimeFields(input,newchar,action,name):
|
|
|
|
if action == "focusout":
|
|
|
|
if ":" in input:
|
|
|
|
hour=int(input.split(":")[0])
|
|
|
|
minute=int(input.split(":")[1])
|
|
|
|
if hour < 0 or hour > 23 or minute < 0 or minute > 59:
|
2021-07-07 16:31:32 +02:00
|
|
|
messagebox.showerror("Eingabefehler", "Bitte geben sie eine gueltige Uhrzeit ein oder die Anzahl der Stunden mit vorangestelltem -")
|
2021-04-12 14:15:42 +02:00
|
|
|
master.nametowidget(name).focus()
|
|
|
|
return False
|
|
|
|
else:
|
|
|
|
print(name)
|
|
|
|
if ".start" in name:
|
|
|
|
energyStart.set("%(h)d:%(m)02d" % {'h':hour, 'm':minute})
|
|
|
|
elif ".stop" in name:
|
|
|
|
energyStop.set("%(h)d:%(m)02d" % {'h':hour, 'm':minute})
|
|
|
|
return True
|
|
|
|
if newchar == "-" and len(input) < 2:
|
|
|
|
setDirty()
|
|
|
|
return True
|
|
|
|
elif len(input)>0 and input[0] == "-" and newchar in "0123456789":
|
|
|
|
setDirty()
|
|
|
|
return True
|
|
|
|
elif newchar not in '01234567890:.':
|
2021-04-07 15:56:54 +02:00
|
|
|
return False
|
2021-06-25 18:57:36 +02:00
|
|
|
if action != "forced":
|
|
|
|
setDirty()
|
2021-04-07 15:56:54 +02:00
|
|
|
return True;
|
|
|
|
|
2021-06-25 18:57:36 +02:00
|
|
|
def setDirty(action=None, ign=None):
|
|
|
|
#this is called for buttons etc.
|
2021-04-06 21:04:10 +02:00
|
|
|
global isDirty
|
2021-06-25 18:57:36 +02:00
|
|
|
#print("setDirty() called", sys._getframe().f_back.f_code.co_name, "###", action, "###", ign)
|
2021-04-06 21:04:10 +02:00
|
|
|
isDirty = True
|
2021-04-07 15:56:54 +02:00
|
|
|
return True
|
|
|
|
|
2021-06-25 18:57:36 +02:00
|
|
|
def setEntryDirty(action=None, ign=None):
|
2023-04-19 11:02:49 +02:00
|
|
|
#this gets called
|
2021-06-25 18:57:36 +02:00
|
|
|
global isDirty
|
|
|
|
#print("setDirty() called", sys._getframe().f_back.f_code.co_name, "###", action, "###", ign)
|
|
|
|
if action != None and int(action) >= 0:
|
|
|
|
isDirty = True
|
|
|
|
return True
|
|
|
|
|
2021-04-06 21:04:10 +02:00
|
|
|
|
|
|
|
def readConfig(configFile=None):
|
2021-04-07 15:56:54 +02:00
|
|
|
global bild_dauer, DEBUG_PREVIEW, localPath, remoteURL, isDirty, inited
|
|
|
|
global energyStart, energyStop, energyMode
|
2021-04-06 21:04:10 +02:00
|
|
|
if configFile == None:
|
|
|
|
configFile = os.path.dirname(os.path.realpath(__file__)) + os.sep + "gruene_signale.conf"
|
2021-04-07 15:56:54 +02:00
|
|
|
if os.path.exists(configFile) == False:
|
|
|
|
inited = True
|
2021-04-06 21:04:10 +02:00
|
|
|
config = configparser.ConfigParser()
|
|
|
|
config.read(configFile)
|
2021-04-07 15:56:54 +02:00
|
|
|
#read bild - dauer
|
2021-04-06 21:04:10 +02:00
|
|
|
try:
|
|
|
|
bild_dauer.set(int(config.get('bilder', 'dauer')))
|
|
|
|
except:
|
|
|
|
bild_dauer.set(10)
|
|
|
|
isDirty = True
|
|
|
|
|
2021-04-07 15:56:54 +02:00
|
|
|
#read debug - preview
|
2021-04-06 21:04:10 +02:00
|
|
|
try:
|
|
|
|
val = config.get('debug', 'preview')
|
|
|
|
except:
|
|
|
|
val = "0"
|
|
|
|
if val == "1":
|
|
|
|
DEBUG_PREVIEW.set(1)
|
|
|
|
|
2021-04-07 15:56:54 +02:00
|
|
|
#read pfad - lokal
|
2021-04-06 21:04:10 +02:00
|
|
|
try:
|
|
|
|
val = os.path.realpath(config.get('pfad', 'lokal'))
|
|
|
|
except:
|
|
|
|
val = os.path.dirname(os.path.realpath(__file__)) + os.sep + "slideshow"
|
|
|
|
localPath.set(val)
|
|
|
|
|
|
|
|
#try to read the remote URL, if not given, work offline
|
|
|
|
try:
|
|
|
|
val = config.get('pfad', 'remote')
|
|
|
|
remoteURL.set(val)
|
|
|
|
except:
|
|
|
|
val = None
|
|
|
|
remoteURL.set("")
|
2023-04-19 11:02:49 +02:00
|
|
|
|
2021-04-07 15:56:54 +02:00
|
|
|
#read energ - mode
|
|
|
|
try:
|
|
|
|
energyMode.set(int(config.get('energy','mode')))
|
|
|
|
except:
|
|
|
|
energyMode.set(0)
|
2023-04-19 11:02:49 +02:00
|
|
|
|
2021-04-07 15:56:54 +02:00
|
|
|
#read energy - start
|
|
|
|
try:
|
|
|
|
val = config.get('energy', 'start')
|
|
|
|
except:
|
|
|
|
val = ""
|
|
|
|
energyStart.set(val)
|
2023-04-19 11:02:49 +02:00
|
|
|
|
2021-04-07 15:56:54 +02:00
|
|
|
#read energy - stop
|
|
|
|
try:
|
|
|
|
val = config.get('energy', 'stop')
|
|
|
|
except:
|
|
|
|
val = ""
|
|
|
|
energyStop.set(val)
|
2021-04-06 21:04:10 +02:00
|
|
|
|
|
|
|
def writeConfig(configFile=None):
|
|
|
|
if configFile == None:
|
|
|
|
configFile = os.path.dirname(os.path.realpath(__file__)) + os.sep + "gruene_signale.conf"
|
|
|
|
config = configparser.ConfigParser()
|
|
|
|
config.read(configFile)
|
|
|
|
|
2021-04-07 15:56:54 +02:00
|
|
|
required_sections = ['bilder','filme','pfad','debug','energy']
|
|
|
|
for sect in required_sections:
|
|
|
|
if sect not in config.sections():
|
|
|
|
config.add_section( sect )
|
|
|
|
|
2021-04-06 21:04:10 +02:00
|
|
|
config.set('bilder','dauer',"%d" % bild_dauer.get())
|
|
|
|
config.set('debug', 'preview',"%d" % DEBUG_PREVIEW.get())
|
|
|
|
config.set('pfad', 'lokal',localPath.get().strip())
|
|
|
|
config.set('pfad', 'remote',remoteURL.get().strip())
|
2021-04-07 15:56:54 +02:00
|
|
|
config.set('energy', 'mode', "%d" % energyMode.get())
|
|
|
|
config.set('energy', 'start', energyStart.get())
|
|
|
|
config.set('energy', 'stop', energyStop.get())
|
2021-04-06 21:04:10 +02:00
|
|
|
|
|
|
|
with open(configFile, 'w') as file:
|
|
|
|
config.write(file)
|
|
|
|
|
|
|
|
def save():
|
2021-04-07 15:56:54 +02:00
|
|
|
global isDirty,inited
|
2021-04-06 21:04:10 +02:00
|
|
|
if isDirty == False:
|
|
|
|
return;
|
|
|
|
writeConfig()
|
|
|
|
if checkAutostartfile() == 1 and doAutostart.get() == 0:
|
|
|
|
removeAutostart()
|
|
|
|
if checkAutostartfile() == 0 and doAutostart.get() == 1:
|
|
|
|
createAutostart()
|
|
|
|
isDirty=False
|
2021-04-07 15:56:54 +02:00
|
|
|
inited=False
|
2021-04-06 21:04:10 +02:00
|
|
|
|
|
|
|
def quit():
|
2021-06-25 18:57:36 +02:00
|
|
|
if isDirty == True:
|
2021-07-07 16:31:32 +02:00
|
|
|
result = messagebox.askyesno("ungesicherte Daten","Sollen die Einstellungen vor dem Beenden gespeichert werden?")
|
2021-06-25 18:57:36 +02:00
|
|
|
if result:
|
|
|
|
save()
|
2021-04-06 21:04:10 +02:00
|
|
|
master.destroy()
|
|
|
|
exit(0)
|
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI_1(dx, dy):
|
2021-04-12 14:15:42 +02:00
|
|
|
#add button or notification if Python modules (see above) needs to be installed
|
|
|
|
row=tk.Frame(master,bd=1,relief=tk.SUNKEN)
|
|
|
|
lab=tk.Label(row,text="Python Module",width=30,anchor='w')
|
|
|
|
if len(modules) == 0:
|
2021-06-25 18:57:36 +02:00
|
|
|
obj=tk.Button(row,text="bereits installiert",bg="pale green",state='disabled')
|
2021-04-12 14:15:42 +02:00
|
|
|
else:
|
2021-06-25 18:57:36 +02:00
|
|
|
obj=tk.Button(row,text="Installieren",command=installModulesGUI,fg="red")
|
|
|
|
master.installButton = obj
|
2021-04-12 14:15:42 +02:00
|
|
|
row.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
2023-04-19 11:02:49 +02:00
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI_2(dx, dy):
|
2021-04-12 14:15:42 +02:00
|
|
|
#add autostart checkbox
|
2021-06-16 16:07:27 +02:00
|
|
|
doAutostart.set(checkAutostartfile())
|
2021-04-12 14:15:42 +02:00
|
|
|
row=tk.Frame(master,bd=1,relief=tk.SUNKEN)
|
2021-06-09 15:07:30 +02:00
|
|
|
lab=tk.Label(row,text="Gruene Signale automatisch starten",width=30,anchor='w')
|
2021-04-12 14:15:42 +02:00
|
|
|
obj=tk.Checkbutton(row,text="aktiv",variable=doAutostart,command=setDirty)
|
|
|
|
row.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI_3(dx, dy, anyEntryCallback):
|
2021-04-12 14:15:42 +02:00
|
|
|
#add entry field for local path
|
|
|
|
row=tk.Frame(master,bd=1,relief=tk.SUNKEN)
|
|
|
|
lab=tk.Label(row,text="lokaler Pfad",width=30,anchor='w')
|
2021-06-25 18:57:36 +02:00
|
|
|
obj=tk.Entry(row,textvariable=localPath,validate="key",validatecommand=(anyEntryCallback, '%d', '%P'))
|
2021-04-12 14:15:42 +02:00
|
|
|
row.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI_4(dx, dy, anyEntryCallback):
|
2021-04-12 14:15:42 +02:00
|
|
|
#add entry field for remoteURL
|
|
|
|
row=tk.Frame(master,bd=1,relief=tk.SUNKEN)
|
2021-06-09 15:07:30 +02:00
|
|
|
lab=tk.Label(row,text="Remote-URL (wenn leer: Offline-Modus)",width=30,anchor='w')
|
2021-04-12 14:15:42 +02:00
|
|
|
if inited == True:
|
|
|
|
remoteURL.set(introURL)
|
2021-06-25 18:57:36 +02:00
|
|
|
obj=tk.Entry(row,textvariable=remoteURL,validate="key",validatecommand=(anyEntryCallback, '%d','%P'))
|
2021-04-12 14:15:42 +02:00
|
|
|
row.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI_5(dx, dy):
|
2021-04-12 14:15:42 +02:00
|
|
|
#add scale widget for duration
|
|
|
|
row=tk.Frame(master,bd=1,relief=tk.SUNKEN)
|
2021-06-09 15:07:30 +02:00
|
|
|
lab=tk.Label(row,text="Anzeigedauer der Bilder (Sekunden)",width=30,anchor='w')
|
2021-04-12 14:15:42 +02:00
|
|
|
obj=tk.Scale(row,from_=5,to=120,variable=bild_dauer,orient=tk.HORIZONTAL,command=setDirty)
|
|
|
|
row.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI_6(dx, dy, timeEntryCallback):
|
2021-04-12 14:15:42 +02:00
|
|
|
#MARK: add controls for energy savings
|
|
|
|
row1=tk.Frame(master,bd=1,relief=tk.SUNKEN)
|
|
|
|
row1.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
|
|
|
|
row2=tk.Frame(row1,bd=1,relief=tk.FLAT)
|
|
|
|
row2.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
|
|
|
|
row3=tk.Frame(row1,bd=1,relief=tk.FLAT)
|
|
|
|
row3.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
row4=tk.Frame(row1,bd=1,relief=tk.FLAT)
|
|
|
|
row4.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
|
|
|
|
lab=tk.Label(row2,text="Energiesparoptionen",width=30,anchor='w')
|
|
|
|
obj0=tk.Radiobutton(row2,text="ohne",variable=energyMode,command=setDirty,value=0)
|
|
|
|
obj1=tk.Radiobutton(row2,text="RasPi ausschalten",variable=energyMode,command=setDirty,value=1)
|
|
|
|
obj2=tk.Radiobutton(row2,text="Monitor deaktivieren",variable=energyMode,command=setDirty,value=2)
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj2.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
|
|
|
obj1.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
|
|
|
obj0.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
|
|
|
|
|
|
|
lab=tk.Label(row3,text="",width=30,anchor='w')
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
lab=tk.Label(row3,text="um",width=3,anchor='w')
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj1=tk.Entry(row3,name="start",textvariable=energyStart,validate="all",validatecommand=(timeEntryCallback, '%P','%S', "%V", "%W"))
|
|
|
|
obj1.pack(side=tk.LEFT,fill=tk.X,padx=dx)
|
|
|
|
|
|
|
|
lab=tk.Label(row3,text="bis",width=3,anchor='w')
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj2=tk.Entry(row3,name="stop",textvariable=energyStop,validate="all",validatecommand=(timeEntryCallback, '%P', '%S', "%V", "%W"))
|
|
|
|
obj2.pack(side=tk.LEFT,fill=tk.X,padx=dx)
|
2023-04-19 11:02:49 +02:00
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI_7(dx, dy):
|
2021-04-12 14:15:42 +02:00
|
|
|
#add checkbox for Debug Preview Mode
|
|
|
|
row=tk.Frame(master,bd=1,relief=tk.SUNKEN)
|
|
|
|
lab=tk.Label(row,text="Debug Preview Modus",width=30,anchor='w')
|
|
|
|
obj=tk.Checkbutton(row,text="aktiv",variable=DEBUG_PREVIEW,command=setDirty)
|
|
|
|
row.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
|
|
|
|
lab.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
obj.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
|
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI_8(dx, dy):
|
2021-04-12 14:15:42 +02:00
|
|
|
#add buttons
|
|
|
|
row=tk.Frame(master)
|
2021-06-09 15:07:30 +02:00
|
|
|
saveButton=tk.Button(row,text="Speichern",command=save,pady=4,padx=dx)
|
2021-04-12 14:15:42 +02:00
|
|
|
saveButton.pack(side=tk.LEFT,pady=dy,padx=dx)
|
|
|
|
quitButton=tk.Button(row,text="Beenden",command=quit,pady=4,padx=dx)
|
|
|
|
quitButton.pack(side=tk.RIGHT,pady=dy,padx=dx)
|
|
|
|
row.pack(side=tk.BOTTOM)
|
|
|
|
|
2023-11-06 00:35:29 +01:00
|
|
|
def buildGUI(dx, dy, timeEntryCallback, anyEntryCallback):
|
|
|
|
buildGUI_1(dx, dy)
|
|
|
|
buildGUI_2(dx, dy)
|
|
|
|
buildGUI_3(dx, dy, anyEntryCallback)
|
|
|
|
buildGUI_4(dx, dy, anyEntryCallback)
|
|
|
|
buildGUI_5(dx, dy)
|
|
|
|
buildGUI_6(dx, dy, timeEntryCallback)
|
|
|
|
buildGUI_7(dx, dy)
|
|
|
|
buildGUI_8(dx, dy)
|
|
|
|
|
|
|
|
def createVenv():
|
|
|
|
if sys.prefix == sys.base_prefix:
|
|
|
|
print( "Not running in a virtual environment" )
|
|
|
|
if not os.path.exists( "./venv/bin/python3" ):
|
|
|
|
splash = tk.Tk()
|
2023-11-06 18:49:49 +01:00
|
|
|
splash.geometry("440x120+660+400")
|
|
|
|
# splash.title("Einstellungen: Gruene Signale")
|
|
|
|
splash.configure(bg="DarkSeaGreen1")
|
2023-11-06 00:35:29 +01:00
|
|
|
splash.overrideredirect(True)
|
2023-11-06 18:49:49 +01:00
|
|
|
label = tk.Label(splash, text="Bitte ein wenig Geduld", bg="DarkSeaGreen1", font=("System", 24))
|
|
|
|
label.pack(padx=4, pady=4, ipady=4)
|
|
|
|
label2 = tk.Label(splash, text="Es wird eine virtuelle Umgebung angelegt.", bg="DarkSeaGreen1", font=("System", 14))
|
|
|
|
label2.pack(padx=4, pady=0, ipady=4)
|
2023-11-06 00:35:29 +01:00
|
|
|
splash.update()
|
|
|
|
print( "Create a new virtual environment" )
|
|
|
|
subprocess.check_call([sys.executable, "-m", "venv", "./venv"] )
|
|
|
|
splash.destroy()
|
|
|
|
splash.update()
|
|
|
|
print( "Restart in virtual environment" )
|
|
|
|
p=subprocess.Popen(["./venv/bin/python3", "setup.py"], start_new_session=True )
|
|
|
|
#p.wait()
|
|
|
|
exit(0)
|
|
|
|
# print( "running in a virtual environment" )
|
|
|
|
return
|
|
|
|
|
|
|
|
def main():
|
2023-11-06 18:49:49 +01:00
|
|
|
global master #, dx, dy
|
2023-11-06 00:35:29 +01:00
|
|
|
createVenv()
|
|
|
|
|
2023-11-06 18:49:49 +01:00
|
|
|
#init variables used in config file and some other places
|
|
|
|
global doAutostart, bild_dauer, DEBUG_PREVIEW, localPath, remoteURL, energyMode, energyStart, energyStop
|
|
|
|
|
|
|
|
#the main window
|
|
|
|
try:
|
|
|
|
master=tk.Tk()
|
|
|
|
except:
|
|
|
|
if len(sys.argv)>1:
|
|
|
|
# started from command line with arguments
|
|
|
|
if "modinst" in sys.argv:
|
|
|
|
installModules()
|
|
|
|
print("Die Module wurden erfolgreich installiert.")
|
|
|
|
if "autostart" in sys.argv:
|
|
|
|
createAutostart()
|
|
|
|
print("Das Autostart-Objekt wurde erstellt.")
|
|
|
|
if "noautostart" in sys.argv:
|
|
|
|
removeAutostart()
|
|
|
|
print("Das Autostart-Objekt wurde entfernt.")
|
|
|
|
|
|
|
|
else:
|
|
|
|
print("Es ist ein Tcl-Fehler aufgetreten. Das Skript muss im Desktop-Modus gestartet werden.")
|
|
|
|
print("""Folgende Kommandos sind erlaubt:
|
|
|
|
modinst: wenn notwendig werden fehlende Python Module installiert
|
|
|
|
autostart: Das Autostart-Objekt wird geschrieben
|
|
|
|
noautostart: Das Autostart-Objekt wird entfernt
|
|
|
|
|
|
|
|
Die weiteren Enstellungen koennen in der Datei gruene-signal.conf angepasst werden.""")
|
|
|
|
exit(0)
|
|
|
|
|
|
|
|
doAutostart=tk.IntVar()
|
|
|
|
bild_dauer=tk.IntVar()
|
|
|
|
DEBUG_PREVIEW=tk.IntVar()
|
|
|
|
localPath=tk.StringVar()
|
|
|
|
remoteURL=tk.StringVar()
|
|
|
|
energyMode=tk.IntVar()
|
|
|
|
energyStart=tk.StringVar()
|
|
|
|
energyStop=tk.StringVar()
|
|
|
|
|
|
|
|
readConfig()
|
2023-11-06 00:35:29 +01:00
|
|
|
master.minsize(600,300)
|
|
|
|
master.geometry("800x450+560+300")
|
|
|
|
master.title("Einstellungen: Gruene Signale")
|
|
|
|
master.option_add('*Dialog.msg.font', 'System 10')
|
|
|
|
|
|
|
|
#register callbacks for entry fields
|
|
|
|
timeEntryCallback = master.register(validateTimeFields)
|
|
|
|
anyEntryCallback = master.register(setEntryDirty)
|
|
|
|
|
|
|
|
#fixed value for pady and padx used by pack() function
|
|
|
|
dy=2
|
|
|
|
dx=4
|
|
|
|
|
|
|
|
buildGUI(dx, dy, timeEntryCallback, anyEntryCallback)
|
|
|
|
master.mainloop()
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|