Python Newbie - Message Box

  • Hi, eines vorweg: ich bin absoluter Neuling in Python und habe mir kleine Aufgabe gestellt.


    Ich möchte das imap-Plugin (enigma2-plugin-extensions-emailclient_3.999+git5231+74706cd-r2_mips32el.ipk) so gestalten, dass bei Eingang einer neuen Nachricht ein eigener Screen geöffnet wird und man bei Klick darauf in den Posteingang des Accounts geleitet wird.


    Nach meinen dürftigen Vorstellungen wird eine neue Nachricht hier mittels einer Messagebox dargestellt:


    Python
    Notifications.AddNotification(MessageBox, message, type=MessageBox.TYPE_INFO, timeout=config.plugins.emailimap.timeout.value)

    Kann man sich nun einen eigenen Screen basteln und diesen dann bei Eingang aufrufen?
    Und für später eine Taste definieren, welche auf den Posteingang des Accounts leitet?


    schon mal herzlichen Dank für Newbie-Schelten :winking_face:

  • Bei Notifications gibt es die Möglichkeit callbacks zu machen. Da wird dann die entsprechende Aktion ausgeführt. Gibt aif github sicher Beispiele dafür.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • Merci für die Antwort.
    Ich bin wirklich noch ganz am Anfang und versuche die Einzelheiten zu verstehen.


    Ich habe die notification.py gefunden und dort gibt es die Funktion (?):

    Python
    def AddNotificationWithCallback(fnc, screen, *args, **kwargs):
    __AddNotification(fnc, screen, None, *args, **kwargs)


    Kann ich das dann so anwenden:


    Python
    Notifications.AddNotificationWithCallback(MessageBox, message, type=MessageBox.TYPE_INFO, timeout=config.plugins.emailimap.timeout.value)

    Aber welchen Screen kann ich dann nehmen und was bedeutet hier "args, kwargs"?
    Vielleicht muss ich noch mehr über die Grundlagen lesen, aber ich wollte am praktischen Beispiel beginnen.


    sg

  • Du musst dir die Definition von AddNotificationWithCallback anschauen:
    fnc: hier gibst du die Callback-Function an
    screen: Screen, der angezeigt werden soll. Bei dir MessageBox
    *args: das ist eine undefinierte Menge von Argumenten (args), die mitgegeben werden können. Die haben alle kein keyword
    **kwargs: das gleiche, aber mit keyword (kw). Also key, value Paare.


    Hier ein Beispiel, wie ich das im fstabEditor gemacht habe:

    Code
    Notifications.AddNotificationWithCallback(runRemountCommand, MessageBox, _("rootfs is mounted readonly. This is usually caused by a corrupted fstab. Do you want to remount now to be able to fix this?"), MessageBox.TYPE_YESNO, 5, windowTitle="fstabEditor", domain="fstabEditor")


    Wie du siehst, hab ich 3 args und 2 kwargs. Warum das? Schauen wir uns an, was MessageBox für Parameter kennt:

    Python
    def __init__(self, session, text, type = TYPE_YESNO, timeout = -1, close_on_any_key = False, default = True, enable_input = True, msgBoxID = None, windowTitle = None, additionalActionMap=None, title = _("Message"))


    self und session können wir mal ignorieren.
    text: Was soll angezeigt werden? Mein erster Parameter oben.
    type: mein zweiter Parameter. Dieser könnte sogar weggelassen werden, da TYPE_YESNO default ist
    timeout: ich will ein timeout von 5 Sekunden, was ich als drittes migebe. Ohne bliebe der Screen dauerhaft, bis der User klickt
    Die nächsten 4 Parameter lasse ich auf default und gebe sie deshalb nicht mit.
    windowTitle: den Titel gebe ich wieder mit. Da ich die drei vorherigen Parameter als default übernommen habe, muss ich nun ein keyword angeben. Sonst würde der Wert bei close_on_any_key angewendet. Das ist also mein erstes kwargs.
    Die letzten zwei Parameter lasse ich wieder unverändert


    Zusätzlich habe ich noch eine Domain für die Notification mitgegeben.


    Die wird hier verwendet als zweites Argument:
    [code]def __AddNotification(fnc, screen, id, *args, **kwargs)[\code]


    __AddNotification wird von AddNotificationWithCallback aufgerufen.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

    2 Mal editiert, zuletzt von dre ()

  • Abend - vielen Dank bisher.
    Ich habe jetzt mal folgendes probiert:


    Das headers kommt wohl von (self, headers)? Damit bekomme ich ein Popup mit Auswahl ja/nein und mit der Anzeige des Email-Headers .
    Drücke ich nun ja oder nein bekomme ich einen BuntScreen.
    Auf weiterer Recherche bin auf Definition der keys und der Actionmap gestoßen - bin ich hier auf den richtigen Weg?


    Ziel ist es mit "ja" zum entsprechenden EmailAccount zu gelangen.

  • Schau, was ich oben geschrieben habe: erster Parameter ist die callback-Function. Die wird nach dem Schliessen der MessageBox (egal ob ja oder nein) aufgerufen.


    Jetzt musst du dir eine Function bauen, die die Antwort auswertet und bei Ja die Mailbox öffnet.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • ...uff. Ich glaube ich bin noch weit weg von Python ;).
    Der erste Parameter zeigt also auf eine Funktion (def) welche in einer Klasse liegt? Was beim Schließen der MessageBox passiert ist ja eigentlich nicht bedeutend.


    Die Klasse in der die Email-Übersicht definiert wird, heißt im Plugin "class ScreenMailView(Screen):"


    und darunter die weiteren Funktionen.
    Kann ich das abkupfern oder auf eine Funktion aus einer anderen Klasse verweisen und wie bringe ich der MessageBox bei dass wenn ich "ja" klicke es die Funktion ausführen soll.


    Sorry nochmal für die Anfängerfragen, aber irgendwie möchte ich es verstehen, was da so treibe.

  • Die callback-Function ist in der gleichen Klasse. Kann natürlich theoretisch auch in einer anderen sein, macht aber wenig Sinn. Wichtig ist, dass die Function einen Parameter für die Antwort aus der MessageBox hat. Ich nenne diesen jeweils answer, da DMM das auch so macht.


    Den obigen Screen kannst du mit

    Code
    self.session.open(ScreenMailView, account, message, uid, flags)

    aufrufen. Dein Problem wird dann aber sein, dass account, message, uid und flags nicht bekannt sind. Daher musst du vor dem Aufruf der Notification das machen:

    Code
    self.account = account
    self.message = message
    self.uid = uid
    self.flags = flags


    Damit sind die Variablen in der ganzen Klasse bekannt. Entsprechend musst du beim Aufruf des Screens self. vorne dran machen.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • Hi nochmal.
    Ich habe mir nochmal den fstabEditor angesehen und folgendes getestet:

    Leider bekomme ich damit die Meldung: "Kann Header nicht lesen".


    Die Variablen self.account = account etc. hatte ich eingefügt, wusste aber nicht in welche Klasse und mit welcher Einrückung.

  • Also die Zuweisungen musst du natürlich schon dort machen, wo die Variable headers bekannt ist (also in _onHeaderList) resp. du hast ja dort im loop drin die message - genau genommen deren Header). Damit kannst du dir uid und flags setzen. account müsste in der class ja bereits vorhanden sein (oben wird ja self._name bei der Zuweisung verwendet). Nur bei message ist halt die Frage, woher du die kriegst.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • Bin ich damit auf der richtigen Fährte?

  • Ja und Nein. Also die Variablen, die du zuweisst, die müssen schon bekannt sein. Das oben wird zu einem Greenscreen führen. Und in message steht der Text für die MessageBox drin. Das wird kaum dem Gesuchten entsprechen.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • HI.
    Ich schreibe mal, wie es bisher verstanden habe.


    Die callback-Funktion heißt bei mir "showEmail".
    Durch Aufruf der Messagebox wird auf diese verwiesen und es soll der Screen "ScreenMailView" geöffnet werden. Dadurch bekomme ich die Fehlermeldung "kann Header nicht lesen".


    Die Variable "message" taucht im Aufruf der Messagebox und der Funktion "showEmail" auf. In der Messagebox ist sie korrekt, da dort definiert:

    Code
    message = _("New mail arrived for account %s:\n\n") %self._name

    In der callback-Funktion ist der Aufruf "message" wohl verkehrt


    In der Klasse "ScreenMailView" werden auch folgende Variablen definiert, ich weiß aber nicht was hier "self" bewirkt.

    Muss jetzt in der Callback-Funktion auf die Variablen aus der Klasse "ScreenMailView" zurückgeriffen werden und was verhindert, dass die Messagebox die headers nicht findet.


    danke für deine Geduld

  • Nein, du rufst ja ScreenMailView auf. Und die Zuweisung von message an self._email kann nur klappen, wenn du message auch beim Aufruf mitgegeben hast. Wie oben geschrieben macht self die Variable in der ganzen Class verfügbar.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • Hmm..., okay.
    D.h. es passt eigentlich, funktioniert aber nicht ;).


    Wie gesagt, ich bekomme bei Anzeige der MessageBox immer den Fehler "kann header nicht lesen", auch wird keine ja-nein Auswahl mehr angeboten.
    Irgendwie drehe ich mich im Kreis.

  • ich seh grad noch was:

    Also callback-Func mit self.showEmail und dann bei def showEmail natürlich auch noch ein self rein.

    Gruss
    Dre


    Boxen (im Einsatz): DM920, DM900, DMOne
    Developer Project Merlin - we are OpenSource

  • Edit:
    hier stand nichts hilfreiches :winking_face:


    Nur die Erkenntnis, dass bisherige Versuche wohl nicht zum Ziel führen werden.


    1. die nötigen Parameter zum Aufruf von ScreenMailView sind in der Function _onHeaderList wohl nicht zu erlangen
    Hier mal der echte Aufruf aus der aktuellen deb-Version:
    https://github.com/opendreambo…client/src/plugin.py#L267


    2. werden in der Function _onHeaderList ja alle neuen Mails durchlaufen
    Da macht es ja keinen Sinn, sich eine Mail direkt anzeigen zu lassen, wenn z.B. 3 neue Mails gemeldet wurden.

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

    6 Mal editiert, zuletzt von Sven H ()

  • @matthis
    Versuch mal das hier:
    Dann öffnet sich vermutlich die Mailliste zum Account mit den neuen Mails.
    Dort kannst du dann die Mails ja bestimmt zum Öffnen auswählen.
    Ich tippe mal, du möchtest einfach eine Möglichkeit, nach der Info zu neuen Mails direkt ins Plugin zu kommen :winking_face:


    Ich nutze dieses Plugin nicht, wodurch es noch etwas schwieriger ist, den Code zu verstehen :winking_face:

    Gruß Sven (aka Dreamy)


    DM920 mit unstable OE2.5 DP
    One mit unstable OE2.6 DP

    3 Mal editiert, zuletzt von Sven H ()

  • @Sven H
    Morgen.
    Yup, direkt in das Plugin bzw. in den Account zu gelangen wäre schon ein guter Schritt.


    Mit deinem Code bekomme ich folgenden Crashlog:


    Code
    File "/usr/lib/enigma2/python/Plugins/Extensions/EmailClient/plugin.py", line 592, in showEmail
    self.session.open(EmailScreen, self._account)
    AttributeError: CheckMail instance has no attribute 'session'