Solution for my "INFINITE FOLDER CREATION DETECTED"

Robert Wolf r.wolf.debian at atlas.cz
Wed Aug 8 06:45:30 UTC 2012



Hallo,

I have updated offlineimap to 6.5.4 and I have found the documentation about 
required nametrans on local repository too. I have created the local nametrans 
but now I get "INFINITE FOLDER CREATION DETECTED" error.

In my case, I want to synchronize from different external IMAP servers to my 
own IMAP server (to have only one passwort for all accounts and better speed). 
I want every account to be stored as 
INBOX.[remote-account-email-address].FOLDERS on my local IMAP server. I use 
courier IMAP with "." as folder separator.

One account to synchronize is Gmail. In Gmail I get emails from some other POP 
servers, e.g. from atlas.cz. The Gmail get-pop3-emails feature creates 
automatically folder with the name of email address, e.g. 
r.wolf.debian at atlas.cz. On Gmail IMAP I can see folders INBOX, [Gmail], Sent, 
Queue, Trash and r.wolf.debian at atlas.cz. These folders should be created on my 
IMAP, but I have to replace "." (and "[" and "]") with some other string - I 
have choosed to make "escape" sequences for special characters - I will 
replaces special characters with some other characters tr/[]./()-/ and enclose 
between "_", e.g. "[" will be "_(_".

Gmail uses "/" as folder separator, and my Courier uses ".". Offlineimap can 
automatically replace "/" separator to "." separator, but I have to replace all 
"." in the folder name (as in r.wolf.debian at atlas.cz) to escape sequence. This 
works find and offlineimap creates gmail's folder "r.wolf.debian at atlas.cz" of 
account some-gmail-address at gmail-com as 
"INBOX.some-gmail-address at gmail-com.r_-_wolf_-_debian@atlas_-_cz" during first 
run - the folder name of gmail is translated to 
"INBOX.some-gmail-address at gmail-com."+foldername (where 
"some-gmail-address at gmail-com" is manually entered alias, where should be 
created the other folders)


I have written both (remote and local) nametrans functions, but there is some
problem because of how offlineimap works. Here are the offlineimap config and
the important functions:

*** .offlineimaprc ***
==================================================
[general]
accounts=some-email-address at gmail.com
ui = TTY.TTYUI
pythonfile=~/.offlineimap.py

[Account some-email-address at gmail.com]
localrepository = local-some-email-address at gmail.com
remoterepository = some-email-address at gmail.com

[Repository local-some-email-address at gmail.com]
type = IMAP
ssl = yes
remotehost = localhost
remoteuser = wolf
nametrans = lambda foldername: local2ext(foldername)
folderfilter = lambda foldername: filterlocalfolders(foldername,'some-email-address at gmail-com')

[Repository some-email-address at gmail.com]
type = IMAP
ssl = yes
remotehost = imap.gmail.com
remoteuser = some-email-address
nametrans = lambda foldername: ext2local(foldername,'some-email-address at gmail-com')
folderfilter = lambda foldername: disablegmailfolders(foldername)
==================================================

*** .offlineimap.py ***
==================================================
### encode escape sequences in folder names
def replacechars(foldername):
    ### escape sequence is "_C_", so encode "_" too
    foldername = re.sub(r'_',r'___',foldername);
    foldername = re.sub(r'\[',r'_(_',foldername);
    foldername = re.sub(r'\]',r'_)_',foldername);
    foldername = re.sub(r'\.',r'_-_',foldername);
    return(foldername)

### decode escape sequences in folder names
def restorechars(foldername):
    foldername = re.sub(r'___',r'_',foldername);
    foldername = re.sub(r'_\(_',r'[',foldername);
    foldername = re.sub(r'_\)_',r']',foldername);
    foldername = re.sub(r'_-_',r'.',foldername);
    return(foldername)

### convert external folder name to local (add "INBOX.{ext-account-name}.")
def ext2local(foldername,accountname):
    return(re.sub('^', 'INBOX.' + accountname + '.', replacechars(foldername)))

### convert local folder name to external (remove "INBOX.{ext-account-name}.")
def local2ext(foldername):
    return(re.sub(r'^INBOX\.[^.]+.',r'', restorechars(foldername)))

### filter out gmail's all mail folder
def disablegmailfolders(foldername):
    return(foldername not in ['[Gmail]/All Mail'])

### process only local folders for specified account
def filterlocalfolders(foldername,account):
    fb = "INBOX."+account
    return(fb == foldername[0:len(fb)])
==================================================


As I have written, the first offlineimap run has created from remote folder
"r.wolf.debian at atlas.cz" local folder
"INBOX.some-email-address at gmail-com.r_-_wolf_-_debian@atlas_-_cz". During
second run offlineimap reports following error: 

ERROR: INFINITE FOLDER CREATION DETECTED! Folder 'INBOX.some-email-address at gmail-com.r_-_wolf_-_debian@atlas_-_cz' (repository 'local-some-email-address at gmail.com') would be created as folder 'r/wolf/debian at atlas/cz' (repository 'some-email-address at gmail.com'). The latter becomes 'INBOX.some-email-address at gmail-com.r.wolf.debian@atlas.cz' in return, leading to infinite folder creation cycles.



The function restorechars() restores sequence "_-_" back to ".", but
offlineimap uses "." as folder separator and want to create new folders.

If I disable the code for restore the "." from "_-_" in restorechars(), the
offlineimap reports following error - this is clear, it will keep the sequence
in the name and creates new folder.


ERROR: INFINITE FOLDER CREATION DETECTED! Folder 'INBOX.some-gmail-address at gmail-com.r_-_wolf_-_debian@atlas_-_cz' (repository 'local-some-gmail-address at gmail.com') would be created as folder 'r_-_wolf_-_debian at atlas_-_cz' (repository 'some-email-address at gmail.com'). The latter becomes 'INBOX.some-email-address at gmail-com.r___-___wolf___-___debian@atlas___-___cz' in return, leading to infinite folder creation cycles.




I have not yet read the code of offlineimap, but it looks like offlineimap
runs first nametrans code and the it try to replace folder separators of IMAP
servers.

For remote gmail repository offlineimap makes:
foldername -> nametrans(foldername) -> replace "/" with "." in foldername

For local repositore offlineimap makes the same:
foldername -> nametrans(foldername) -> replace "." with "/" in foldername

But in the local repository I need, that offlineimap replaces first the folder
separator "." to "/" and then nametrans() can replace sequence "_-_" to "."
and these "." are not evaluated as local folder separators.


Or I can do everything in the nametrans - replace the "." (folder 
separators of local IMAP) to "/" (remote IMAP folder separator) first and then 
the sequence "_-_" to single "." (as part of foldername), but I need to tell 
offlineimap, that it should not replace folder separators, somehow define the 
same folder separator or undefine folder separator. But the folder separator of 
IMAP is detected and if I could set it to some other character, then 
offlineimap will work probably incorrectly (because of using incorrect folder 
separator).



Do you have any idea how can I solve this problem?

Do you think the offline imap should for do for remote repositories first the
nametrans and then replace the folder separators, but for local repositories
should do offlineimap first replace folder separator and then make nametrans?

Thank you for your idea and help.


Regards,

Robert Wolf



More information about the OfflineIMAP-project mailing list