changes by ssb

This commit is contained in:
Stefan Schmidt-Bilkenroth 2023-04-19 11:02:49 +02:00
parent 01d23d5e6e
commit d6f44ddf73
2 changed files with 113 additions and 50 deletions

View file

@ -93,7 +93,7 @@ def readConfig(configFile=None):
remoteURL = None remoteURL = None
except: except:
remoteURL = None remoteURL = None
#try to read energySaving Info #try to read energySaving Info
try: try:
val = int(config.get('energy','mode')) val = int(config.get('energy','mode'))
@ -105,7 +105,7 @@ def readConfig(configFile=None):
needsWrite=True needsWrite=True
energySavingMode = val energySavingMode = val
print("energySavingMode = ", energySavingMode) print("energySavingMode = ", energySavingMode)
if energySavingMode > 0: if energySavingMode > 0:
#when energy saving is disabled we do not need this stuff #when energy saving is disabled we do not need this stuff
h = 0 h = 0
@ -126,7 +126,7 @@ def readConfig(configFile=None):
config.set('energy','start',"0:00") config.set('energy','start',"0:00")
config.set('energy','stop',"0:00") config.set('energy','stop',"0:00")
needsWrite=True needsWrite=True
#we only needs this for wakeup blanked screen #we only needs this for wakeup blanked screen
#oh - we also need it, in case clock is not synced to NTP #oh - we also need it, in case clock is not synced to NTP
try: try:
@ -139,7 +139,7 @@ def readConfig(configFile=None):
config.set('energy','mode',"0") config.set('energy','mode',"0")
config.set('energy','start',"0:00") config.set('energy','start',"0:00")
config.set('energy','stop',"0:00") config.set('energy','stop',"0:00")
needsWrite=True needsWrite=True
if needsWrite == True: if needsWrite == True:
with open(configFile, 'w') as file: with open(configFile, 'w') as file:
@ -171,11 +171,11 @@ class RemoteData:
ui.showInfo("Die Daten werden geladen:",True) ui.showInfo("Die Daten werden geladen:",True)
#print("download to %s" % self.localZIP) #print("download to %s" % self.localZIP)
with open(self.localZIP, "wb") as zipped: with open(self.localZIP, "wb") as zipped:
for chunk in r.iter_content(chunk_size = 4096): for chunk in r.iter_content(chunk_size = 4*1024):
if chunk: if chunk:
zipped.write(chunk) zipped.write(chunk)
length += len(chunk) length += len(chunk)
ui.showInfo("Daten werden geladen: %d kB" % (length/1024)) ui.showInfo("Daten werden geladen: %d kB" % (length/1024), _clear = True)
#print("%d kB" % (length/1024), end="\r") #print("%d kB" % (length/1024), end="\r")
ui.showInfo("Daten wurden erfolgreich geladen: %d kB" % (length/1024)) ui.showInfo("Daten wurden erfolgreich geladen: %d kB" % (length/1024))
time.sleep(1) time.sleep(1)
@ -198,7 +198,7 @@ class RemoteData:
except: except:
print("Error while unzipping the downloaded data.") print("Error while unzipping the downloaded data.")
return False return False
if localPathExists: if localPathExists:
#move orignal localPath away #move orignal localPath away
shutil.move(localPath, localPath+".old") shutil.move(localPath, localPath+".old")
@ -219,7 +219,7 @@ class WatchTime():
self.startuptime = time.localtime() self.startuptime = time.localtime()
self.timer = None # reoccuring call self.timer = None # reoccuring call
self.enegerySaving = False # on restart we surely do not run in energy saving mode self.enegerySaving = False # on restart we surely do not run in energy saving mode
def setReceiver(self,receiver=None): def setReceiver(self,receiver=None):
if receiver == None: if receiver == None:
return return
@ -235,6 +235,9 @@ class WatchTime():
return t['h'] * 60 + t['m'] return t['h'] * 60 + t['m']
def checkNTPClock(self): def checkNTPClock(self):
if sys.platform.startswith('darwin') or sys.platform.startswith('win'):
# on macOS and WIndows timedatectl is not available, we assume the clock is sync'ed
self.synced = True
if self.synced != True: if self.synced != True:
# timedatectl show tells me, if the clock is synchronized via NTP # timedatectl show tells me, if the clock is synchronized via NTP
for line in subprocess.check_output(["timedatectl","show"]).split(): for line in subprocess.check_output(["timedatectl","show"]).split():
@ -242,7 +245,7 @@ class WatchTime():
self.synced=True self.synced=True
self.startuptime = time.localtime() self.startuptime = time.localtime()
print("NTP clock is synced") print("NTP clock is synced")
def checkTimeForShutdown(self): def checkTimeForShutdown(self):
#check if it is time to sutdown #check if it is time to sutdown
if energySavingDuration > 0: if energySavingDuration > 0:
@ -274,9 +277,9 @@ class WatchTime():
if running > shallRun: if running > shallRun:
#it runs longer than expected, so we shut down #it runs longer than expected, so we shut down
self.receiver.shutdown() self.receiver.shutdown()
return return
def checkTimeForBlank(self): def checkTimeForBlank(self):
isBlanked = self.receiver.window.blanked isBlanked = self.receiver.window.blanked
print( "Screen is Blanked?", isBlanked) print( "Screen is Blanked?", isBlanked)
@ -307,7 +310,7 @@ class WatchTime():
else: else:
#nothing to do - start and end time are equal #nothing to do - start and end time are equal
return return
if needsBlank == None: if needsBlank == None:
return return
elif needsBlank == True and isBlanked == False: elif needsBlank == True and isBlanked == False:
@ -326,7 +329,7 @@ class WatchTime():
if now > 195 and now < 210: if now > 195 and now < 210:
self.window.updateMedia() self.window.updateMedia()
#else: #else:
# if running > 24*60 # if running > 24*60
def checkTimedEvents(self): def checkTimedEvents(self):
#print("checkTimedEvents - mode:",energySavingMode, " duration:",energySavingDuration," start:",energySavingStart," stop:", energySavingEnd) #print("checkTimedEvents - mode:",energySavingMode, " duration:",energySavingDuration," start:",energySavingStart," stop:", energySavingEnd)
@ -350,7 +353,7 @@ class WatchTime():
else: else:
#we should never reach here #we should never reach here
abort() abort()
def update(self): def update(self):
if self.receiver == None: if self.receiver == None:
return return
@ -364,7 +367,7 @@ class WatchTime():
if DEBUG_PREVIEW == True: if DEBUG_PREVIEW == True:
delay = 1000 delay = 1000
self.timer = self.receiver.after(delay,self.update) self.timer = self.receiver.after(delay,self.update)
# this class creates an invisible window to catch keboard events # this class creates an invisible window to catch keboard events
class HiddenRoot(tk.Tk): class HiddenRoot(tk.Tk):
def __init__(self): def __init__(self):
@ -377,16 +380,16 @@ class HiddenRoot(tk.Tk):
self.window = MySlideShow(self) self.window = MySlideShow(self)
self.window.startSlideShow() self.window.startSlideShow()
def nextMedia(self): def nextMedia(self):
self.window.nextMedia() self.window.nextMedia()
def previousMedia(self): def previousMedia(self):
self.window.pixNum = self.window.pixNum -2 self.window.pixNum = self.window.pixNum -2
if self.window.pixNum < 0: if self.window.pixNum < 0:
self.window.pixNum = self.window.pixNum + len(self.window.mediaList) self.window.pixNum = self.window.pixNum + len(self.window.mediaList)
self.window.nextMedia() self.window.nextMedia()
def shutdown(self): def shutdown(self):
subprocess.check_call(["shutdown","--no-wall","+1"]) subprocess.check_call(["shutdown","--no-wall","+1"])
self.destroy() self.destroy()
@ -427,27 +430,46 @@ class Mediafile:
img.save(filename) img.save(filename)
w,h = img.size w,h = img.size
img.close() img.close()
subname = os.path.basename(filename).split('.')[0]
if '_#s' in subname:
duration = int(subname.split('_#s')[-1])
if duration > 0:
self.duration = duration*1000
self.valid = True self.valid = True
if DEBUG_PREVIEW == True: if DEBUG_PREVIEW == True:
print("image file: "+os.path.basename(filename)+"(%d"%w+"x%d)"%h, "resized:",resize) if self.duration == 0:
print("Bild Datei: "+os.path.basename(filename)+" (%d"%w+"x%d)"%h,
"skaliert:",int(resize), "Dauer: standard")
else:
print("Bild Datei: "+os.path.basename(filename)+" (%d"%w+"x%d)"%h,
"skaliert:",int(resize), "Dauer: %d Sekunden" % (self.duration/1000))
elif extension in movie_extensions: elif extension in movie_extensions:
media = caller.instance.media_new(filename) media = caller.instance.media_new(filename)
media.parse() media.parse()
self.duration = media.get_duration() self.duration = media.get_duration()
self.valid = True self.valid = True
if DEBUG_PREVIEW == True: if DEBUG_PREVIEW == True:
print("movie file: "+os.path.basename(filename)+ " (%d Sekunden)"%(self.duration/1000)) print("Film Datei: "+os.path.basename(filename)+ " (Dauer %d Sekunden)"%(self.duration/1000))
else: else:
print("unknwon file type: "+os.path.basename(filename)) print("unbekannte Datei: "+os.path.basename(filename))
if sys.platform.startswith('darwin'):
from ctypes import c_void_p, cdll
dylib = cdll.LoadLibrary('libtk8.6.dylib')
_GetNSView = dylib.TkMacOSXGetRootControl
_GetNSView.restype = c_void_p
_GetNSView.argtypes = (c_void_p,)
# print(_GetNSView)
del dylib
class MySlideShow(tk.Toplevel): class MySlideShow(tk.Toplevel):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
tk.Toplevel.__init__(self, *args, **kwargs) tk.Toplevel.__init__(self, *args, **kwargs)
#remove window decorations #remove window decorations
self.overrideredirect(True) self.overrideredirect(True)
self.info = None self.info = None
self.infoText = tk.StringVar() self.infoText = tk.StringVar()
self.infoText.set('')
#by default info widget is hidden #by default info widget is hidden
self.infoHidden = True self.infoHidden = True
self.bg = (0,0,0) self.bg = (0,0,0)
@ -461,25 +483,31 @@ class MySlideShow(tk.Toplevel):
#set the geometry of the playback window #set the geometry of the playback window
self.scr_w, self.scr_h = self.winfo_screenwidth(), self.winfo_screenheight() self.scr_w, self.scr_h = self.winfo_screenwidth(), self.winfo_screenheight()
if DEBUG_PREVIEW == None or DEBUG_PREVIEW == True: if DEBUG_PREVIEW == None or DEBUG_PREVIEW == True:
self.scr_w = int(self.scr_w / 4) self.scr_w = int(self.scr_w / 3.0)
self.scr_h = int(self.scr_h / 4) self.scr_h = int(self.scr_w * 9.0 / 16.0)
self.scr_t = self.scr_h*3 - 10 self.scr_t = self.winfo_screenheight() - self.scr_h - 10
self.scr_l = self.scr_w*3 - 10 self.scr_l = self.winfo_screenwidth() - self.scr_w - 10
self.font = "Courier 8" self.font = "Courier 10"
else: else:
self.scr_t = 0 self.scr_t = 0
self.scr_l = 0 self.scr_l = 0
self.font = "Courier 12" self.font = "Courier 12"
# hide the mouse cursor if not in debug mode # hide the mouse cursor if not in debug mode
self.config(cursor="none") self.config(cursor="none")
self.wm_attributes('-fullscreen',True)
self.wm_attributes('-topmost', True)
emptyMenu = tk.Menu(self)
self['menu'] = None
emptyMenu.delete(0,tk.END)
#This creates the widget where files are played back #This creates the widget where files are played back
self.player = None self.player = None
self.videopanel = tk.Frame(self, bg="black") self.videopanel = tk.Frame(self, bg="black")
self.videopanel.pack(side="top",fill=tk.BOTH,expand=1) self.videopanel.pack(side="top",fill=tk.BOTH,expand=1)
self.videopanel.update_idletasks()
#VLC player init #VLC player init
self.instance = vlc.Instance("--no-xlib --quiet --fullscreen --") self.instance = vlc.Instance("--quiet --fullscreen --")
self.player = self.instance.media_player_new() self.player = self.instance.media_player_new()
self.player.video_set_scale(0) self.player.video_set_scale(0)
#self.player.video_set_aspect_ratio('16:9') #self.player.video_set_aspect_ratio('16:9')
@ -489,8 +517,19 @@ class MySlideShow(tk.Toplevel):
#setup the window #setup the window
self.wm_geometry("{}x{}+{}+{}".format(self.scr_w, self.scr_h,self.scr_l,self.scr_t)) self.wm_geometry("{}x{}+{}+{}".format(self.scr_w, self.scr_h,self.scr_l,self.scr_t))
self.player.set_xwindow(self.GetHandle()) # this line messes up windows # different platforms require different assignment below
if sys.platform.startswith('linux'):
self.player.set_xwindow(self.GetHandle()) # this line messes up windows
elif sys.platform.startswith('darwin'):
# print(_GetNSView(self.GetHandle()))
self.player.set_nsobject(_GetNSView(self.GetHandle()))
elif sys.platform.startswith('win'):
self.player.set_hwnd(self.GetHandle()) # should work on windows
else:
print( "Unbekannte Platform (%s), das Skript wird abgebrochen:" % sys.platform )
exit(-1)
#some brief internal initializers #some brief internal initializers
self.mediaList = list() self.mediaList = list()
self.pixNum = 0 self.pixNum = 0
@ -511,21 +550,31 @@ class MySlideShow(tk.Toplevel):
# This creates an info widget # This creates an info widget
if self.infoHidden == True or self.info == None: if self.infoHidden == True or self.info == None:
self.infoHidden = False self.infoHidden = False
self.info = tk.Label(self, bg="#00FF44", font=self.font, height=-1, width=-1, textvariable=self.infoText, wraplength=self.scr_w-16) self.info = tk.Label(self, bg="#2F6B1A", font=self.font, height=-1, width=-1, textvariable=self.infoText, wraplength=self.scr_w-16)
self.info.place(x=8,y=6) self.info.place(x=16,y=32)
else: else:
self.infoHidden = True self.infoHidden = True
self.info.destroy() self.info.destroy()
self.info = None self.info = None
def showInfo(self,_text,_force=False): def showInfo(self,_text,_force=False,_clear=False):
if self.infoHidden == True and _force == True: if self.infoHidden == True and _force == True:
self.toggleInfo() self.toggleInfo()
self.infoText.set(_text) if len(_text.strip()) == 0:
return
if _clear == True:
lines = []
else:
lines = self.infoText.get().strip().split('\n')
if len(lines) > 18:
lines = lines[1:]
lines.append(_text.strip())
self.infoText.set('\n'.join(lines).strip())
self.update() self.update()
def hideInfo(self): def hideInfo(self):
self.infoText.set('')
if self.infoHidden == False: if self.infoHidden == False:
self.toggleInfo() self.toggleInfo()
@ -599,7 +648,7 @@ class MySlideShow(tk.Toplevel):
if self.timer != None: if self.timer != None:
self.after_cancel(self.timer) self.after_cancel(self.timer)
self.timer = None self.timer = None
def togglePlayback(self): def togglePlayback(self):
if self.paused == True: if self.paused == True:
self.resumePlayback() self.resumePlayback()
@ -625,7 +674,7 @@ class MySlideShow(tk.Toplevel):
self.resumePlayback() self.resumePlayback()
self.inited = True self.inited = True
self.nextMedia() self.nextMedia()
def blankScreenOn(self): def blankScreenOn(self):
#energy savings - start blank screen #energy savings - start blank screen
self.pausePlayback() self.pausePlayback()
@ -635,7 +684,7 @@ class MySlideShow(tk.Toplevel):
#while debugging we want screen blanking turn off right away #while debugging we want screen blanking turn off right away
time.sleep(5) time.sleep(5)
self.blankScreenOff() self.blankScreenOff()
def blankScreenOff(self): def blankScreenOff(self):
#energy savings - end blank screen #energy savings - end blank screen
self.blanked = False self.blanked = False
@ -650,7 +699,11 @@ readConfig()
try: try:
slideShow = HiddenRoot() slideShow = HiddenRoot()
except: except Exception as e:
if hasattr(e, 'message'):
print(e.message)
else:
print(e)
print("Es ist ein Tcl-Fehler aufgetreten. Das Skript muss im Desktop-Modus gestartet werden.") print("Es ist ein Tcl-Fehler aufgetreten. Das Skript muss im Desktop-Modus gestartet werden.")
exit(0) exit(0)
timedEvents = WatchTime() timedEvents = WatchTime()

View file

@ -17,6 +17,16 @@ try:
except: except:
modules.append("python-vlc") modules.append("python-vlc")
try:
import PIL
except:
modules.append('pillow')
try:
import requests
except:
modules.append('requests')
master=None master=None
# try: # try:
# import crontab # import crontab
@ -88,7 +98,7 @@ except:
if "noautostart" in sys.argv: if "noautostart" in sys.argv:
removeAutostart() removeAutostart()
print("Das Autostart-Objekt wurde entfernt.") print("Das Autostart-Objekt wurde entfernt.")
else: else:
print("Es ist ein Tcl-Fehler aufgetreten. Das Skript muss im Desktop-Modus gestartet werden.") print("Es ist ein Tcl-Fehler aufgetreten. Das Skript muss im Desktop-Modus gestartet werden.")
print("""Folgende Kommandos sind erlaubt: print("""Folgende Kommandos sind erlaubt:
@ -195,7 +205,7 @@ def setDirty(action=None, ign=None):
return True return True
def setEntryDirty(action=None, ign=None): def setEntryDirty(action=None, ign=None):
#this gets called #this gets called
global isDirty global isDirty
#print("setDirty() called", sys._getframe().f_back.f_code.co_name, "###", action, "###", ign) #print("setDirty() called", sys._getframe().f_back.f_code.co_name, "###", action, "###", ign)
if action != None and int(action) >= 0: if action != None and int(action) >= 0:
@ -241,20 +251,20 @@ def readConfig(configFile=None):
except: except:
val = None val = None
remoteURL.set("") remoteURL.set("")
#read energ - mode #read energ - mode
try: try:
energyMode.set(int(config.get('energy','mode'))) energyMode.set(int(config.get('energy','mode')))
except: except:
energyMode.set(0) energyMode.set(0)
#read energy - start #read energy - start
try: try:
val = config.get('energy', 'start') val = config.get('energy', 'start')
except: except:
val = "" val = ""
energyStart.set(val) energyStart.set(val)
#read energy - stop #read energy - stop
try: try:
val = config.get('energy', 'stop') val = config.get('energy', 'stop')
@ -317,7 +327,7 @@ def buildGUI_1():
row.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X) row.pack(side=tk.TOP,padx=dx,pady=dy,expand=tk.YES,fill=tk.X)
lab.pack(side=tk.LEFT,pady=dy,padx=dx) lab.pack(side=tk.LEFT,pady=dy,padx=dx)
obj.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx) obj.pack(side=tk.RIGHT,expand=tk.YES,fill=tk.X,padx=dx)
def buildGUI_2(): def buildGUI_2():
#add autostart checkbox #add autostart checkbox
doAutostart.set(checkAutostartfile()) doAutostart.set(checkAutostartfile())
@ -390,7 +400,7 @@ def buildGUI_6():
lab.pack(side=tk.LEFT,pady=dy,padx=dx) 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=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) obj2.pack(side=tk.LEFT,fill=tk.X,padx=dx)
def buildGUI_7(): def buildGUI_7():
#add checkbox for Debug Preview Mode #add checkbox for Debug Preview Mode
row=tk.Frame(master,bd=1,relief=tk.SUNKEN) row=tk.Frame(master,bd=1,relief=tk.SUNKEN)
@ -418,8 +428,8 @@ def buildGUI():
buildGUI_6() buildGUI_6()
buildGUI_7() buildGUI_7()
buildGUI_8() buildGUI_8()
readConfig() readConfig()
master.minsize(600,300) master.minsize(600,300)