Echter Wochentag angeben anstatt "Morgen"

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Cryptor
User
Beiträge: 7
Registriert: Montag 6. Mai 2019, 11:20

Hallo
Ich bin eigentlich zu alt um Python noch zu lernen.
Ich bastel aber gerne an Convertern für Linux SAT Receiver rum, dort ist der Code in Python, ich guck mir viele Codes an und mach das meiste eigentlich per Copy & Paste :D
Nun zu meinem Problem:
Ich hab einen EPG Screen gebastelt, dort wird mir unten Rechts die Primetime angezeigt: Die Zeit 20:15 ist so im Code drin, allerdings hab ich dort:
Problem Nr.1 Nur einen englischen Wochentag: Mon anstatt Mo
Problem Nr.2 : Wenn die Sendung um 20:15 vorbei ist, kommt dort anstatt des Wochentages der Text : Morgen 20:15 - Ist das vielleicht auch möglich das man sich dort den richtigen Wochentag anzeigen lassen kann, in dem Beispiel dann halt: Di 20:15

Bild

Code: Alles auswählen

# -*- coding: utf-8 -*-
from enigma import eEPGCache, eServiceReference
from Components.Converter.Converter import Converter
from Components.Element import cached
from datetime import datetime, timedelta
from time import localtime, strftime, mktime, time
from Components.config import config


class CerxPrimetimeEvent(Converter, object):
	def __init__(self, type):
		Converter.__init__(self, type)
		self.epgcache = eEPGCache.getInstance()
		  			
	@cached
	def getText(self):
		entry = ''
		ref = self.source.service
		info = ref and self.source.info
		if info is None:
			return entry
		primeTimeEvent = self.source.getCurrentEvent()
		if primeTimeEvent:
			
			if not self.epgcache.startTimeQuery(eServiceReference(ref.toString()), primeTimeEvent.getBeginTime()):
				tomorrow = False
				actualtime = localtime(time())
				now = localtime(time())
				prime = datetime(now.tm_year, now.tm_mon, now.tm_mday, 20, 15)
				if time() > mktime(prime.timetuple()):
					tomorrow = True
					prime += timedelta(days=1)
				primeTime = int(mktime(prime.timetuple()))
				if not self.epgcache.startTimeQuery(eServiceReference(ref.toString()), primeTime):
					event = self.epgcache.getNextTimeEntry()
					if event and (event.getBeginTime() <= int(mktime(prime.timetuple()))):
						if tomorrow == False:
							entry = "%s - %s" % (strftime("%a %H:%M", localtime(event.getBeginTime())), event.getEventName()) 
						else:
							entry = "%s - %s" % (strftime("Morgen " + "%H:%M", localtime(event.getBeginTime())), event.getEventName())
		return entry
	text = property(getText)
	def changed(self, changedvalue):
		Converter.changed(self, changedvalue)
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du den Code liest, wirst Du schnell die Stelle finden, wo "Morgen" ausgegeben wird. Wenn Du das nicht möchtest, dann mach das einfach nicht.

Wie Wochentage ausgegeben wird, hängt an der Locale-Einstellung, also z.B:

Code: Alles auswählen

locale.setlocale(locale.LC_TIME, 'de_DE.UTF-8')
stellt Zeiten auf Deutsch um.
Warum mixst Du time und datetime? Sinnvoll wäre, alles mit Datetime zu machen. Schlecht ist, dass Du dreimal die aktuelle Zeit abfrägst, das kann zu Inkonsistenzen führen.
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht Tabs.
Cryptor
User
Beiträge: 7
Registriert: Montag 6. Mai 2019, 11:20

Erstmal Danke für die Anwort:
Wie gesagt habe ich keine Ahnung, der Code ist nicht von mir.
Ich weiß nichtmal wo da time und datetime vermischt werden.
Wenn ich das "Morgen" jetzt lösche wird ja garnichts mehr angezeigt, ich möchte ja dafür den Folgetag des aktuellen Tag anzeigen anzeigen lassen.

Wo genau im Code kommt denn das hier:

Code: Alles auswählen

locale.setlocale(locale.LC_TIME, 'de_DE.UTF-8')
rein ?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Cryptor: so ein Grundverständnis von Python brauchst Du schon, um den Code abändern zu können, z.B. zu wissen, was eine if-Abfrage ist.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das locale ist eine globale Einstellung, und sollte daher an den Anfang. Allerdings ist es eben weil es global ist auch nicht ungefaehrlich, es kann sein, dass andere Aspekte des gesamten(!) Systems davon betroffen sind.

Und was das "Morgen" angeht - wenn ich dich richtig verstehe, soll doch einfach nur immer das gleiche, naemlich der Tag, ausgegeben werden. Du musst also die "if tomorrow == False"-Anweisung rauswerfen, und stattdessen nur den ersten Zweig ihrer ausfuehren.

Code: Alles auswählen

if event and (event.getBeginTime() <= int(mktime(prime.timetuple()))):
			entry = "%s - %s" % (strftime("%a %H:%M", localtime(event.getBeginTime())), event.getEventName())
Cryptor
User
Beiträge: 7
Registriert: Montag 6. Mai 2019, 11:20

Den heutigen Tag , also das was um Mo 20:15 läuft (Primetime) bekomme ich ja mit dieser Zeile

Code: Alles auswählen

entry = "%s - %s" % (strftime("%a %H:%M", localtime(event.getBeginTime())), event.getEventName()) 
Wenn die Sendungen jetzt abgelaufen ist um 22:00 dann erscheint die 2. Zeile

Code: Alles auswählen

entry = "%s - %s" % (strftime("Morgen " + "%H:%M", localtime(event.getBeginTime())), event.getEventName())
Da ja dann im EPG nun Morgen 20:15 steht wollte ich das so machen das da eben dann der folgende Tag richtig steht in dem Beispiel dann:
Di 20:15

Das mit dem deutschen Wochentag hab ich immer noch nicht verstanden. Wenn ich den Code oben bei mir einfüge kommt eine Fehlermeldung das irgendwas nicht definiert wäre. Könnte sich nicht einer bitte den Code schnappen und mir dann einfügen und hier posten, also im Ganzen :D
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du schon moechtest, das man dir hier im ganzen Code liefert, dann koenntest du im Gegenzug wenigstens die Fehlermeldung hier vernuenftig reproduzieren. Denn auf "irgendwas nicht definiert waere" kann man nur sagen "musst du irgendwas anders machen". Wir haben kein Enigma-System, wir koennen das also nicht testen.

Und was an meiner Antwort ist dir nicht klar? So wie du das beschreibst, willst du einfach nur das die Bedingung eben nicht unterscheided zwischen morgen und jedem anderen Tag (heute inklusive). Es also immer so zu machen wie im ersten Fall sollte dein Problem loesen.
Cryptor
User
Beiträge: 7
Registriert: Montag 6. Mai 2019, 11:20

Code Fehler: global name "locale" is not defined

Hab das hier eingefügt was ja offensichtlich falsch ist, wie gesagt ich hab keine Ahnung, ich will doch nur dt. Wochentage

Code: Alles auswählen

now = localtime(time())
				locale.setlocale(locale.LC_TIME, 'de_DE.UTF-8')
				prime = datetime(now.tm_year, now.tm_mon, now.tm_mday, 20, 15)
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code: Alles auswählen

# -*- coding: utf-8 -*-
from enigma import eEPGCache, eServiceReference
from Components.Converter.Converter import Converter
from Components.Element import cached
from datetime import datetime, timedelta
from time import localtime, strftime, mktime, time
from Components.config import config

import locale
locale.setlocale(locale.LC_TIME, 'de_DE.UTF-8')


class CerxPrimetimeEvent(Converter, object):
	def __init__(self, type):
		Converter.__init__(self, type)
		self.epgcache = eEPGCache.getInstance()
		  			
	@cached
	def getText(self):
		entry = ''
		ref = self.source.service
		info = ref and self.source.info
		if info is None:
			return entry
		primeTimeEvent = self.source.getCurrentEvent()
		if primeTimeEvent:
			
			if not self.epgcache.startTimeQuery(eServiceReference(ref.toString()), primeTimeEvent.getBeginTime()):
				tomorrow = False
				actualtime = localtime(time())
				now = localtime(time())
				prime = datetime(now.tm_year, now.tm_mon, now.tm_mday, 20, 15)
				if time() > mktime(prime.timetuple()):
					tomorrow = True
					prime += timedelta(days=1)
				primeTime = int(mktime(prime.timetuple()))
				if not self.epgcache.startTimeQuery(eServiceReference(ref.toString()), primeTime):
					event = self.epgcache.getNextTimeEntry()
					if event and (event.getBeginTime() <= int(mktime(prime.timetuple()))):
						if tomorrow == False:
							entry = "%s - %s" % (strftime("%a %H:%M", localtime(event.getBeginTime())), event.getEventName()) 
						else:
							entry = "%s - %s" % (strftime("Morgen " + "%H:%M", localtime(event.getBeginTime())), event.getEventName())
		return entry
	text = property(getText)
	def changed(self, changedvalue):
		Converter.changed(self, changedvalue)
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@Cryptor: wenn Du etwas an einem Programm ändern willst, mußt Du programmieren lernen, oder jemanden beauftragen, der das für Dich macht. Das Forum ist für Leute gedacht, die Programmieren lernen wollen.

`locale` ist ein Modul und muß daher importiert werden.
Cryptor
User
Beiträge: 7
Registriert: Montag 6. Mai 2019, 11:20

Leider crasht jetzt die Box mit der .log Meldung wenn ich den Code so einfüge wie oben.
return _setlocale(category, locale)
Error: unsupported locale setting
Sirius3 hat geschrieben: Montag 6. Mai 2019, 15:26 @Cryptor: wenn Du etwas an einem Programm ändern willst, mußt Du programmieren lernen, oder jemanden beauftragen, der das für Dich macht. Das Forum ist für Leute gedacht, die Programmieren lernen wollen.

`locale` ist ein Modul und muß daher importiert werden.
Ja, ich weiß. Ich bin über 50, wenn ich 20 Jahre jünger wäre kein Thema, ich dachte das wäre einfacher zu bewerkstelligen, zumal ich doch sonst auch überall an der Enigma2 Box einen deutschen Wochentag habe.
Danke für Eure Mühe, ich frag dann wohl besser im passenden Forum mal nach
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Cryptor: Problematisch bei „copy & paste“-Programmierung ist das der Code damit in der Regel immer schlechter wird. Wenn man nur c&p macht, ohne die Sprache wirklich zu können, kann man zudem nicht einmal einschätzen wie schlecht die Vorlage bereits ist.

Von `object` muss nicht geerbt werden weil `CerxPrimetimeEvent` von `Converter` erbt, was von `Element` erbt, was seinerseits von `object` abgeleitet ist.

Die `changed()`-Methode zeugt auch davon das der Autor von der Klasse anscheinend so seine Probleme mit Objektorientierung hat. Die Methode ist genau so überflüssig wie von `object` zu erben, weil die nur die gleichnamige Methode der Basisklasse mit einem 1:1 durchgereichten Argument aufruft. Also genau das was auch passieren würde, wenn man `changed()` nicht überschreibt.

Die Bestimmung von `ref` und `info`, das ``and`` und damit die indirekte Prüfung ob `ref` `None` ist, finde ich ziemlich verwirrend. Zudem: Wenn `ref` `None` ist, `self.source.info` aber nicht, dann läuft der Code irgendwann später in eine Ausnahme, weil `ref.toString()` dann natürlich auf die Nase fallen wird. Es müssen also sowohl `ref` als auch `info` ungleich `None` sein, und nicht nur `info`. `ref` scheint auch als Name falsch zu sein, denn die Service-Referenz wird aus später erst aus diesem Objekt erstellt. Und das zwei mal. Das ist auch etwas was an dem Code negativ auffällt – das Sachen mehrfach berechnet werden statt nur einmal.

`actualtime` wird definiert aber nirgends verwendet. `now` wird exakt gleich definiert. Das `actual` wäre auch falsch, denn das hätte `current` heissen müssen.

Den Wert von `tomorrow` muss man nicht mit literalen `True` und `False` Werten festlegen, das ist genau der Wert der bei dem Vergleich heraus kommt ob die aktuelle Zeit schon grösser als 20:15 ist.

Ab da fängt auch diese völlig unsinnige Vermischung von `time` und `datetime` an. Mit dem `time`-Modul ein `time.struct_time` mit der aktuellen Zeit zu erstellen, um das dann teilweise in ein `datetime.datetime`-Objekt umzupacken ist unsinnig. Man kann auch gleich ein `datetime.datetime`-Objekt mit der aktuellen Zeit erstellen. Und dann kombiniert man dessen Datum mit der Zeit 20:15 um einen `primetime`-Wert zu erstellen. Und die beiden kann man dann direkt vergleichen, ohne da erst wieder ein `time.struct_time` und daraus dann wieder die Sekunden seit Epoch zu berechnen, um *die* dann zu vergleichen.

Ungetestet:

Code: Alles auswählen

# -*- coding: utf-8 -*-
from datetime import datetime as DateTime, time as Time, timedelta as TimeDelta
from functools import partial

from enigma import eEPGCache, eServiceReference
from Components.Converter.Converter import Converter
from Components.Element import cached


class CerxPrimetimeEvent(Converter):

    def __init__(self, type_):
        Converter.__init__(self, type_)
        self.epgcache = eEPGCache.getInstance()
                    
    @cached
    def getText(self):
        event = self.source.getCurrentEvent()
        if event and self.source.service and self.source.info:
            now = DateTime.now()
            primetime = DateTime.combine(now.date(), Time(20, 15))
            is_tomorrow = now > primetime
            if is_tomorrow:
                primetime += TimeDelta(days=1)
                assert now <= primetime
            
            query_cache = partial(
                self.epgcache.startTimeQuery,
                eServiceReference(self.source.service.toString())
            )
            if not (
                query_cache(event.getBeginTime())
                or query_cache(int(primetime.timestamp()))
            ):
                event = self.epgcache.getNextTimeEntry()
                if event:
                    event_begin = DateTime.fromtimestamp(event.getBeginTime())
                    if event_begin <= primetime:
                        return u'{:{} %H:%M} - {}'.format(
                            event_begin,
                            ('Morgen' if is_tomorrow else '%a'),
                            event.getEventName(),
                        )

        return ''
    
    text = property(getText)
Was die Darstellung des Tagesnamens angeht solltest Du nicht an einer globalen Einstellung wie `local.setlocale()` herum schrauben, sondern schauen wie Enigma das gelöst hat, denn ich vermute ja mal das man dort die Sprache der Bedienungsoberfläche irgendwo einstellen kann – unabhängig von der Sprache des Betriebssystems wahrscheinlich. Also wird das System auch irgendeine API zur Lokalisierung bereitstellen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Cryptor
User
Beiträge: 7
Registriert: Montag 6. Mai 2019, 11:20

Ich hab zwar kaum was verstanden (Kein Wunder als Noob. Ich bin mehr der Skinner) Danke dir aber trotzdem vielmals für die Erklärung. Für mich ist halt wichtig das er das anzeigt was ich möchte und es kein Crash gibt, das hab ich ja schon durch Try & Error immer hinbekommen. Nur jetzt happert es eben.
Da ich das nicht wirklich brauche, lohnt sich jetzt nicht wirklich Python für die paar Codeschnipsel zu lernen.
Sorry
Wegen dem Tagesnamen auf Deutsch hab ich mal einen angesprochen der auch Python kennt und zum team gehört das die Images für Enigma2 Boxen baut.
Ich hab deinen Code jetzt mal eingefügt. Nun kommt die Fehlermeldung:
Code Fehler: " datetime.datetime" object has no attribute "timestamp"
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Hm, dann ist das Python was die benutzen zu alt. Die Methode gibt es seit Python 3.3, also seit 2012. Enigma scheint auch noch Python 2 zu verwenden‽ Das bekommt schon seit geraumer Zeit nur noch Bugfixes und ab Ende dieses Jahres nicht einmal mehr das.

Du hast doch da Tagesnamen in dem Bildschirmfoto – kannst Du nicht einfach den Code suchen der diese Ausgaben macht und da nachsehen wie der die Umwandlung macht?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Cryptor
User
Beiträge: 7
Registriert: Montag 6. Mai 2019, 11:20

Das ist ja der gesamte Code der da nur diese Ausgabe unten im Bereich unter: "Primetime:" macht, das in gelber Schrift ist der gesamte Code.
OK, lößt sich nicht ändern. Vielen lieben Dank für eure Mühen
Benutzeravatar
__blackjack__
User
Beiträge: 13114
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Darüber steht doch aber auch der ”Mo”ntag, und der Code der das ausgibt, macht ja offenbar etwas anderes. Ist halt die Frage was.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Enigma benutzt ein übliches Internationalisierungspaket:

Code: Alles auswählen

event_begin = localtime(event.getBeginTime())
entry = "%s %s - %s" % (_(strftime("%a", event_begin)), strftime("%H:%M", event_begin), event.getEventName())
Antworten