[Solved] Creating Folders on IMAP account and filter on them

Talk about add-ons and extension development.
Post Reply
T4ng10r
Posts: 17
Joined: April 30th, 2016, 4:34 am

[Solved] Creating Folders on IMAP account and filter on them

Post by T4ng10r »

Hi,
I create folder when specific mails arrive. However - I want to create filter for this specific mail and as action send it to newly created folder.
When I scan incommingServer for newly created folder -I can't find it, as its not synchronized and not existing.

How can I wait or add some callback/listener for this folder creation? I've tried AddFolderListener, but without success.

Code: Select all

//create Subfolder
var someListener = {
  OnItemAdded: function(aParentItem, aItem) {
     Application.console.log("OnItemAdded ?");
   },
  OnItemRemoved: function (aParentItem, aItem) {
     Application.console.log("OnItemRemoved ?");
   },
  OnItemPropertyChanged: function (aItem, aProperty, aOldValue, aNewValue) {
     Application.console.log("OnItemPropertyChanged ");
   },
  OnItemIntPropertyChanged: function (aItem, aProperty, aOldValue, aNewValue) {
     Application.console.log("OnItemIntPropertyChanged?");
   },
  OnItemBoolPropertyChanged: function (aItem, aProperty, aOldValue, aNewValue) {
     Application.console.log("OnItemBoolPropertyChanged ?");
   },
  OnItemUnicharPropertyChanged: function (aItem, aProperty, aOldValue, aNewValue) {
     Application.console.log("OnItemUnicharPropertyChanged ?");
   },
  OnItemPropertyFlagChanged: function (aItem, aProperty, aOldFlag, aNewFlag) {
     Application.console.log("OnItemPropertyFlagChanged ?");
   },
  OnItemEvent: function (aItem, aEvent) {
     Application.console.log("OnItemEvent ?");
   }
}

Application.console.log("Creating subfolder '" +folder_name+"'");
notAssignFolder.createSubfolder(folder_name, null);
notAssignFolder.updateFolder(null);
notAssignFolder.AddFolderListener(someListener);
Trigerring this script ends in TH crash.

To conclude - I want to create folder, wait enough time for IMAP account to create it and TH update his internals. Then create filter with action - move to newly created folder.
Currently I don't know HOW TO receive VALID and existing nsIMsgFolder object pointing to newly created folder.
Last edited by T4ng10r on May 31st, 2016, 11:41 am, edited 3 times in total.
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Creating Folders on IMAP account and filter on them

Post by morat »

Here is how to get the nsIMsgFolder object.

Code: Select all

function folderListener() {
  this.OnItemAdded = function(aParentItem, aItem) {
    Application.console.log("OnItemAdded aParentItem: " + aParentItem);
    try {
      var folder = aParentItem.QueryInterface(Components.interfaces.nsIMsgFolder);
      Application.console.log("OnItemAdded aParentItem folder: " + folder.URI);
    } catch(e) {}
    try {
      var msgHdr = aParentItem.QueryInterface(Components.interfaces.nsIMsgDBHdr);
      Application.console.log("OnItemAdded aParentItem msgHdr: " + msgHdr.mime2DecodedSubject);
    } catch(e) {}
    Application.console.log("OnItemAdded aItem: " + aItem);
    try {
      var folder = aItem.QueryInterface(Components.interfaces.nsIMsgFolder);
      Application.console.log("OnItemAdded aItem folder: " + folder.URI);
    } catch(e) {}
    try {
      var msgHdr = aItem.QueryInterface(Components.interfaces.nsIMsgDBHdr);
      Application.console.log("OnItemAdded aItem msgHdr: " + msgHdr.mime2DecodedSubject);
    } catch(e) {}
    mailSession.RemoveFolderListener(listener);
  };
  this.OnItemRemoved = function(aParentItem, aItem) {};
  this.OnItemPropertyChanged = function(aItem, aProperty, aOldValue, aNewValue) {};
  this.OnItemIntPropertyChanged = function(aItem, aProperty, aOldValue, aNewValue) {};
  this.OnItemBoolPropertyChanged = function(aItem, aProperty, aOldValue, aNewValue) {};
  this.OnItemUnicharPropertyChanged = function(aItem, aProperty, aOldValue, aNewValue) {};
  this.OnItemPropertyFlagChanged = function(aItem, aProperty, aOldFlag, aNewFlag) {};
  this.OnItemEvent = function(aItem, aEvent) {};
}
var mailSession = Components.classes["@mozilla.org/messenger/services/session;1"].
  getService(Components.interfaces.nsIMsgMailSession);
var listener = new folderListener();
var notifyFlags = Components.interfaces.nsIFolderListener.all;
mailSession.AddFolderListener(listener, notifyFlags);
var uri = "imap://username%40gmail.com@imap.gmail.com/[Gmail]";
var folder = MailUtils.getFolderForURI(uri);
folder.createSubfolder("Example", msgWindow);
BTW,

Are you using FiltaQuilla?

http://addons.mozilla.org/thunderbird/a ... ltaquilla/
http://mesquilla.com/extensions/filtaquilla/
Last edited by morat on May 31st, 2016, 11:09 am, edited 2 times in total.
T4ng10r
Posts: 17
Joined: April 30th, 2016, 4:34 am

Re: Creating Folders on IMAP account and filter on them

Post by T4ng10r »

Thank you morat.
You were faster by 15 minutes with your mail. I found this solution in code of other extension.

PS. I've tried to use FiltaQuilla, but didn't find any good use for it. It don't filter msg body which was my main interest.
T4ng10r
Posts: 17
Joined: April 30th, 2016, 4:34 am

Re: [Solved] Creating Folders on IMAP account and filter on

Post by T4ng10r »

Morat, this solution isn't fully working.
Simple snippet

Code: Select all

        var newFolder = getMsgFolderFromUri(newFolderURI, null)
        if (!newFolder.filePath.exists()) {
          var alertTxt = "Subfolder '" + newFolderName + "' doesn't exists yet";
          slideAlert(alertTxt, "FoderCreateCompleted ");
          return;
        }
falls when activated inside onItemAdded and in onItemEvent - unless FolderLoaded event for newly created folder appears.
However - I can't trigger FolderLoaded. getMsgFolderFromUri(newFolderURI) returns false. parentFolder.updateFolder() doesn't help - it triggers FolderLoaded but for parentFolder.
Even iterating subfolders in parent Folder during onItemAdded and onItemEvent processing can't find this folder.

So problem is partially solved. Until I manually click on new folder - getMsgFolderFromUri() return false.
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Creating Folders on IMAP account and filter on them

Post by morat »

I don't understand what you're trying to do.

This code shows false for a empty folder that never contained a message.

Code: Select all

var uri = "imap://username%40gmail.com@imap.gmail.com/[Gmail]/Example";
var folder = MailUtils.getFolderForURI(uri);
alert(folder.filePath.exists());
The folder exists in memory. The developers didn't bother to create a zero byte file on folder creation.
T4ng10r
Posts: 17
Joined: April 30th, 2016, 4:34 am

Re: Creating Folders on IMAP account and filter on them

Post by T4ng10r »

What I need:
First - click on specific message. (in future maybe create filter detecting messages starting new topic and executing below steps)
Second - create folder for unprocessed topics (like Not Assing)
Third - create filter to move all messaged from given topic to newly created folder

First and second are done.
Creating filter - not.
When I add filter where action is move to folder and as folder I use URI - TH refuse to enable this filter due to lack of destination folder.
Currently I create folder with above script and with second script create filter and execute it.

I spent whole day trying each event to find WHY getFolderForURI returns not existing folder. New folder is created, I see that ii appear on folder view pane. But from JS POV i can't access it in the same script.
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: Creating Folders on IMAP account and filter on them

Post by morat »

T4ng10r wrote:from JS POV i can't access it
I can move selected messages from the inbox to a newly created folder.

Code: Select all

function copyListener(aFolder) {
  this.OnStartCopy = function() {};
  this.OnProgress = function(aProgress, aProgressMax) {};
  this.SetMessageKey = function(aKey) {};
  this.GetMessageId = function(aMessageId) {};
  this.OnStopCopy = function(aStatus) {
    if (Components.isSuccessCode(aStatus)) {
      aFolder.updateFolder(msgWindow);
      gFolderTreeView.selectFolder(aFolder);
    }
  };
}
function folderListener() {
  this.OnItemAdded = function(aParentItem, aItem) {
    try {
      var destFolder = aItem.QueryInterface(Components.interfaces.nsIMsgFolder);
      var sourceFolder = GetFirstSelectedMsgFolder();
      var msgHdrs = gFolderDisplay.selectedMessages;
      var mutableArray = Components.classes["@mozilla.org/array;1"].
        createInstance(Components.interfaces.nsIMutableArray);
      for (var i = 0; i < msgHdrs.length; i++) {
        var msgHdr = msgHdrs[i];
        mutableArray.appendElement(msgHdr, false /*weak*/);
      }
      var cs = Components.classes["@mozilla.org/messenger/messagecopyservice;1"].
        getService(Components.interfaces.nsIMsgCopyService);
      cs.CopyMessages(sourceFolder, mutableArray, destFolder,
        true /*isMove*/, new copyListener(destFolder), msgWindow, true /*allowUndo*/);
    } catch(e) {}
    mailSession.RemoveFolderListener(listener);
  };
  this.OnItemRemoved = function(aParentItem, aItem) {};
  this.OnItemPropertyChanged = function(aItem, aProperty, aOldValue, aNewValue) {};
  this.OnItemIntPropertyChanged = function(aItem, aProperty, aOldValue, aNewValue) {};
  this.OnItemBoolPropertyChanged = function(aItem, aProperty, aOldValue, aNewValue) {};
  this.OnItemUnicharPropertyChanged = function(aItem, aProperty, aOldValue, aNewValue) {};
  this.OnItemPropertyFlagChanged = function(aItem, aProperty, aOldFlag, aNewFlag) {};
  this.OnItemEvent = function(aItem, aEvent) {};
}
var mailSession = Components.classes["@mozilla.org/messenger/services/session;1"].
  getService(Components.interfaces.nsIMsgMailSession);
var listener = new folderListener();
var notifyFlags = Components.interfaces.nsIFolderListener.all;
mailSession.AddFolderListener(listener, notifyFlags);
var uri = "imap://username%40gmail.com@imap.gmail.com/[Gmail]";
var folder = MailUtils.getFolderForURI(uri);
folder.createSubfolder("Example", msgWindow);
I'm not familiar with filter creation, so I'm not much help to you.
Last edited by morat on June 1st, 2016, 8:31 am, edited 1 time in total.
T4ng10r
Posts: 17
Joined: April 30th, 2016, 4:34 am

Re: Creating Folders on IMAP account and filter on them

Post by T4ng10r »

Morat, help me understand.
Inside folderListener - OnItemAdded when I test destFolder.filePath.exists() - result is always FALSE and I used to break processing, as folder wasn't ready.
However, when I removed this test and called straight

Code: Select all

destFolder.updateFolder(msgWindow);
gFolderTreeView.selectFolder(dest);
It works...
HOW?

Beside this rhetorical question, Morat, thank you very much for your help =D> . This problem was puzzling me for month or so. ](*,)
morat
Posts: 6421
Joined: February 3rd, 2009, 6:29 pm

Re: [Solved] Creating Folders on IMAP account and filter on

Post by morat »

Thunderbird doesn't create a zero byte mbox file when creating a folder. That's why the folder.filePath.exists() method is false.

* select [Gmail] folder
* create Example subfolder
* open Command Prompt window
* change directory to ImapMail\imap.gmail.com\[Gmail].sbd in profile
* display files

e.g.

cd /d C:\ThunderbirdPortable\Data\profile\ImapMail\imap.gmail.com\[Gmail].sbd
dir

I see the "Example.msf" mail summary file, but not the "Example" mbox file. The "Example" mbox file is created when I move a message to the Example subfolder. If I remove the message from the Example subfolder and compact, then the "Example" mbox file now has zero bytes.
Post Reply