AttachmentExtractor wird zu "AttachmentExtractor Continued" für Thunderbird 60 und neuer

    Wenn du mit TB68 testen willst, es gibt jetzt release candidates:

    https://ftp.mozilla.org/pub/th…ndidates/68.0-candidates/

    Danke, ich verfolge die Newgroup in der das geschrieben wurde und habe dort auch Deine Beiträge gesehen ;-)


    Momentan teste ich primär mit dem 68er RC, aber auch mit der 69er-Beta. Das erspart mir hoffentlich, dass ich Dinge "programmiere", die anschließend nicht mehr zu gebrauchen sind. Dabei ist mir auch schon aufgefallen, dass ab dem 69er dann die Toolbar-Menu-Buttons folgendes im XUL benötigen: is="toolbar-menu-button", was aber auch im 68er schon drin stehen darf ohne Probleme zu machen.

  • Ich versuche mich gerade einzulesen.


    Kannst du kurz erklären, was konzeptionell der Unterschied zwischen aeMessenger.saveAttachmentToFolder und aewindow.messenger.saveAttachmentToFile ist, und warum der erstere ein file Objekt zurückgibt und das originale file Objekt des Attachments überschreibt?


    aeMessenger.saveAttachmentToFolder ist die Funktion, die am Ende die problematische startupUrl Funktion aufruft, richtig?


    Trennen beide Funktionen auch das Attachment ab (also löschen es aus der Mail?) . Wo passiert das?


    Danke und viele Grüße

    John

    der Unterschied zwischen aeMessenger.saveAttachmentToFolder und aewindow.messenger.saveAttachmentToFile

    aeMessenger.saveAttachmentToFolder ist die "eigene" Routine des Attachments, die scheinbar aus dem C++ abgeleitet wurde. Dies wird momentan wohl nur noch gebraucht, wenn man bestimmte Attachments aus dem Objekt/Array raus nehmen möchte (aufgrund der Dateigröße), oder wenn man das Datum der zu speichernden Attachments mit dem Empfangsdatum der jeweiligen E-Mail machen will (also letztlich das Datum in den Meta-Daten der resultierenden Datei auf der Festplatte).


    aewindow.messenger.saveAttachmentToFile ist der Aufruf von Thunderbirds eigener Detach-Routine. Ich konnte für diese Routine bereits erreichen, dass (optional) nicht mehr bei jeder E-Mail gefragt wird, ob die Dateien tatsächlich gelöscht werden sollen.


    aeMessenger.saveAttachmentToFolder ist die Funktion, die am Ende die problematische startupUrl Funktion aufruft, richtig?

    Das ist richtig.


    Trennen beide Funktionen auch das Attachment ab (also löschen es aus der Mail?) . Wo passiert das?

    Die "eigenen" Routinen des Add-ons verstehe ich leider oftmals auch noch nicht richtig. In obigem Code habe ich comments drin, wo ae-eigener Code und wo Thunderbirds Code beginnt bzw. aufgerufen wird.

    Übrigens wird der Begriff bzw. die Variablen "...detach" eigentlich verwirrend verwendet. Detach kann mit oder ohne Löschen sein... Und Detach kann auch ohne Speichern sein, so dass nur gelöscht wird oder dass die Attachments gar nicht angefasst werden, sondern nur die Mail selbst manipuliert wird. Im JS-Code sind zwei Variablen entscheidend/hilfreich für mich:


    .detachMode (aus den allgemeinen Einstellungen)

    • kann 0, 1 oder 2 sein (im manuellen Modus)
      kann 1 oder 2 sein (im Automatik-Modus)
      0 = Löschen mit Thunderbirds Routinen
      1 = Löschen mit AE-Routinen
      2 = nur Abtrennen mit AE-Routinen
    • Ich habe diese Option quasi inaktiviert, indem ich sie an 2 initialen Stellen einfach mit "0" überschreibe. Somit wird immer mit Thunderbirds eigenen Routinen gelöscht. Zusätzlich habe ich dazu eine neue Option eingeführt, die festlegt ob für das Löschen jeweils pro E-Mail eine Rückfrage erfolgen soll: .detachWithoutConfirmation
      Das funktioniert bei meinem Tests absolut einwandfrei.

    Es wäre denkbar, dass meine obigen Maßnahmen momentan zu Folge-Fehlern in der Logik der Funktionen führen, wenn es nun um folgendes geht:


    isExtractEnabled (aus den erweiterten Einstellungen)

    In den erweiterten Einstellungen kann man das Speichern der Attachments ganz deaktivieren oder zwischen Thunderbird- und AE-Abtrennfunktion wählen. Diese Option überschneidet sich mit der vorherigen Option, die ich ja letztlich zur Zeit ausgeblendet und überschrieben habe.

  • Also sollte ich eher veruchen über die TB funktionen Attachment Größe und Datum zu erhalten, damit die alte Funktion gelöscht und die Einstellungen vereinfacht werden können. Richtig?

    Das wäre bestimmt die beste Lösung, denke ich.


    Wenn Dir oder jemand anderem übrigens auf GitLab etwas auffällt, was ich anders machen sollte, dann gebt mir Rückmeldung. Es ist das absolut erste mal, dass ich diese Wochen mit Git / GitLab arbeite. Es ist nicht gerade leicht sich in die Logik der Berechtigungen und der anderen Dinge rein zu denken. Nebenbei verwende ich gleichzeitig auch das erste Mal einen Code-Editor (Visual Studio Code), nachdem ich Jahre lang mit UltraEdit lokal bei mir gearbeitet hatte... Ohne Suchmaschine und Youtube wäre ich wohl verloren :/.

  • Überall wo du Zugriff auf aewindow.currentTask hast, kannst du via aewindow.currentTask.getMessageHeader() auf die Header Daten der Email zugreifen (https://developer.mozilla.org/…ce/nsIMsgDBHdr#Attributes)


    In AEMessage.prototype.saveAtt kannst du direkt als erstes, also hier

    https://gitlab.com/Thunderbird…ent/aec_js_window.js#L885


    mal folgendes einfügen


    console.log(aewindow.currentTask.getMessageHeader().subject + " : " + aewindow.currentTask.getMessageHeader().dateInSeconds)


    und bekommst für jede Mail den gesuchten Timestamp.


    Hilft das?

  • Um an die Attachment Größe zu kommen, hab ich das hier als Vorlage genommen.: https://searchfox.org/comm-cen…ontent/msgHdrView.js#1806


    Bei meinen Tests hat das funktioniert, aber es gibt noch offene Fragen.


    Zunächst habe ich eine weitere Methode von AEMessage definiert:


    und hier eingefügt:

    https://gitlab.com/Thunderbird…ent/aec_js_window.js#L883


    Aufgerufen hab ich diese Funktion dann zwischen Zeile 897 und 898, also hier:

    https://gitlab.com/Thunderbird…ent/aec_js_window.js#L898


    mit dieser Zeile:

    this.getAttSize(attachment.url, attachment.isExternalAttachment).then(function(size) { console.log("Size: " + size); });


    Das ist jetzt erstmal nur zum Testen, ob du damit für die verschiedenen Attachment Typen an die richtige Größe kommst.


    1. Die Methode die ich als Vorlage benutzt habe, kennt isLinkAttachment, dein AddOn scheint das nicht zu kennen, hab es daher per default auf false gesetzt. Sagt dir isLinkAttachment was?


    2. Durch fetch() ist die neue getAttSize Methode async, daher auch der Aufruf mit .then(). Kennst du async/await und Promises? Im Prinzip gabelt sich der Programmablauf durch this.getAttSize() auf, der Aufruf wird in den Hintergrund geschoben und sofort die nächste Zeile (899) abgearbeitet. Irgendwann ist die async Funktion im Hintergrund fertig und führt dann die im then() angegebene Funktion aus. Ähnlich wie ein setTimeout, nur das der Callback nicht nach einer bestimmten Zeit ausgeführt wird, sondern wenn eine andere Funktion fertig ist.


    Wenn du damit die richtigen Größen bekommst, und du sicher bist, dass du dann nur noch die Thunderbird eigenen Funktionen und z.B. nicht mehr saveAttachmentToFolder benutzen willst, dann wäre es glaube ich gut, den ganzen Kram dann wirklich zu entfernen (neuer branch im gitlab) und in der reduzierten Version dann echte async Funktionen zu benutzen - oder alles nach dem Aufruf von getAttSize in den .then() zu stopfen, aber das wird so unleserlich...


    Erstmal is wichtig, bekommst du den Zeitstempel (mein vorletzter Post) und die Größe und könntest somit den alten Kram rauswerfen?

    Puhh, das ist schon Mal super von dir. Ich werde bestimmt 2-3 Tage brauchen, um mir das anzuschauen.


    Ich habe relativ wenig Ahnung vom Programmieren, habe aber schon von den Promises gehört. Selbst die Prototypes verstehe ich nicht wirklich und nutze den Code halt so wie er ist.


    Bis Morgen werde ich die Menüs wohl fertig überarbeitet und die Favoriten final eingebaut haben. Dann gehe ich an Deine Vorschläge.


    Danke

    N'Abend!


    Ich habe jetzt vor meiner weiteren Arbeit wieder ein neues Tag in GitLab erstellt, in dem es eine Menge geänderten Code gibt. Die Änderungen sollten allerdings nicht für die hier besprochenen Probleme relevant sein.


    1.) Deine Hilfen zu Zeitstempel der Mail und Größe der Attachments funktionieren (für den console.log).


    2.) isLinkAttachment ist vermutlich true, wenn es sich um einen Anhang handelt, der nicht als MIME-Part mit der Mail gesendet wurde - also letztlich quasi extern verlinkt ist?


    Wenn ich am Wochenende (trotz, oder gerade wegen, Rufbereitschaft) genügend Zeit habe, werde ich versuchen, Deinen Code dann auch in den Funktionen umzusetzen / zu nutzen.

  • Wenn du übers Wochenende zunächst erstmal den alten Code rauswirfst, könnte ich am Montag den grundlegenden Umbau hin zu async function machen (den du für fetch() zwingend brauchst). Das ist nicht sehr viel, aber es zu erklären würde länger dauern, als es zu machen.

    Wenn du übers Wochenende zunächst erstmal den alten Code rauswirfst, könnte ich am Montag den grundlegenden Umbau hin zu async function machen (den du für fetch() zwingend brauchst). Das ist nicht sehr viel, aber es zu erklären würde länger dauern, als es zu machen.


    Dann mache ich Morgen einen neuen Branch auf, in dem ich den alten Code raus werfe und melde mich bis Montag wieder.

    Okay,


    jobisoft

    ich denke der Code ist für Deinen "Umbau" ausreichend vorbereitet. Alle alten (internen) Routinen habe ich entfernt, soweit diese nicht mehr innerhalb des Codes verwendet werden.


    Der Code mit aktuellem Stand hat neben den von uns besprochenen Problemen (Zeitstempel, Mindestgröße und der von Dir "gewünschte" async-Umbau) noch ein kleines weiteres Problem, das ich anschließend angehen würde: Für das Erstellen einer Report-Datei (in den erweiterten Einstellungen des Add-ons) verschluckt sich der Code noch an den theoretisch möglichen CSS-Dateien. Solange man auf CSS komplett verzichtet, funktioniert das Erstellen der Report-Dateien. Sobald aber eine CSS-Datei im Report verlinkt oder direkt eingebunden werden soll, schlägt es fehl.


    Ich habe zur Unterscheidung einen Branch "dev-stable-68" erstellt, in dem der momentan funktionierende Code drin ist.


    Du kannst nun bitte im Branch "dev-next-68" den async-Umbau etc. vornehmen - Danke!

  • GitLab has some strange limitations. I cannot create a merge request for your dev-next-68 branch. Only into your master. Even though I commited my changes into the dev-next-68 branch of my fork.


    Could you make your dev-next-68 branch the default branch (if that is possible with GitLab)?

    Ich habe mir Deine Änderungen in Deinem Repository gerade mal angesehen.


    Ist der Grund für Deinen Wunsch nach async gerade an der von Dir umgesetzten Stelle die Performance? Ist das der zeitliche Haupt-Flaschenhals, der bei großen Datenmengen ausbremst? Was soll ich dann mit dem Timeout dort machen? Wenn ich die Folgen richtig verstehe, müsste ich per await / then (oder was auch immer) dafür sorgen, dass es nicht zu Problemen durch async kommt, oder?

  • Also ich komme mit gitlab nicht klar. Ich habe meinen Fork gelöscht, neu geforked, die Änderungen neu gemacht und kann jetzt trotzdem nur auf deinen master mergen. Hier ist jetzt einfach die "neue" Datei am Stück, kannst du die bei dir einfach selbst committen?


    aec_js_window.js.txt


    Wenn ich merge requests erstellen will, kann ich nur lokale MR erstellen, dein Repo kann ich garnicht auswählen. Manchmal taucht eine vorgegebene Option "merge in ThunderbirdMailDE/attachmentextractor master", wo ich aber nix änder kann. Sehr sehr komisch. Musst du mir irgendwie eine merge berechtigung geben?


    Zu deiner Frage: Es geht nicht um Performance. Es geht darum, dass fetch() async ist und wir das jetzt benutzen müssen, um an die size zu kommen. Async ist die Zukunft, weil das multiple threads nutzen kann. Async ist also auf jeden Fall gut (deswegen ist fetch() asyny). Man muss keine Callbacks mehr definieren (so wie jetzt bei setTimeout, z.B.), die geschachtelt echt widerlich werden. Mit async/await kann man async code schreiben wie früher sequentiellen code.


    Das Problem, man kann sync code nicht einfach so in async code umwandeln. Die Funktion saveAtt() muss auf jeden Fall async werden, damit wir darin await getSize() machen können. Jetzt muss man in der call sequence nach oben gehen und eigentlich jeden Aufruf in der Hierarchie überprüfen und gucken, wo man den Übergang von sync zu async machen kann. setTimerouts sind super, die erzeugen ja quasi bereits parallelen async code und daher kann man da ganz prima den Übergang machen.


    Problematisch ist der Aufruf von saveAtt(0) (ich hab gerade ein Kleinkind aufm Schoß, daher keine Zeilennummern). Wenn ich das so lasse wie jetzt bei mir committet, ändert sich der Execution flow: Anstatt saveAtt(0) auszuführen, wird es als Hintergrund-Task geplant und dann direkt weiter gemacht, ohne auf das Ausführen von saveAtt(0) zu warten. Das muss ich mir noch genauer Angucken. Kannst du einfach mal ausprobieren, ob es funzt?

    Musst du mir irgendwie eine merge berechtigung geben?

    Das kann sein, ich schaue mal .... sieht eigentlich in den Einstellungen so aus, als könnte jeder (was so aber nicht explizit da steht) einen Merge Request machen. Nur das Approval muss ich als Maintainer bzw. Owner selbst machen. Eigentlich müsste es also gehen. Ich schaue mir später die ganzen Einstellungen noch mal in Ruhe durch.


    Deine Datei habe ich zum Testen schon kopiert ich werde diese dann quasi selbst commiten und pushen. Dabei habe ich schon einen Logik-Fehler bei


    Code
    if (sizeToSmall) {
    return;

    gefunden. Dort muss es wohl korrekt


    Code
    if (sizeToSmall) {
    return aewindow.currentMessage.saveAtt_cleanUp(attachmentindex, true);

    heißen. Sonst bleibt der ganze Prozess einfach stehen.