polo2ro / imapbox

Dump imap inbox to a local folder in a regular backupable format: html, json and attachements
MIT License
223 stars 47 forks source link

imaplib.error: command SEARCH illegal in state AUTH #31

Open llamafilm opened 4 years ago

llamafilm commented 4 years ago

Hello. First of all, thank you for this app, it's a great idea. I want to download my Gmail archive so that I can delete my Google account. I set remote_folder to ALL and it started downloading a few folders but it fails when it gets to the main one called [Gmail]. So then I set remote_folder=[Gmail] and it does the same thing. Do you know what is causing this?

$ python imapbox.py 
account1/[Gmail] (on imap.gmail.com)
MailboxClient: Could not select remote folder '[Gmail]'
Traceback (most recent call last):
  File "imapbox.py", line 105, in <module>
    main()
  File "imapbox.py", line 102, in main
    save_emails(account, options)
  File "/usr/home/elliott/imapbox-master/mailboxresource.py", line 123, in save_emails
    stats = mailbox.copy_emails(options['days'], options['local_folder'], options['wkhtmltopdf'])
  File "/usr/home/elliott/imapbox-master/mailboxresource.py", line 44, in copy_emails
    typ, data = self.mailbox.search(None, criterion)
  File "/usr/local/lib/python3.7/imaplib.py", line 723, in search
    typ, dat = self._simple_command(name, *criteria)
  File "/usr/local/lib/python3.7/imaplib.py", line 1196, in _simple_command
    return self._command_complete(name, self._command(name, *args))
  File "/usr/local/lib/python3.7/imaplib.py", line 944, in _command
    ', '.join(Commands[name])))
imaplib.error: command SEARCH illegal in state AUTH, only allowed in states SELECTED
jakeprice-me commented 2 years ago

I'm getting the same issue, wondering if there's a fix @polo2ro?

jakeprice-me commented 2 years ago

@llamafilm I've managed to get around this issue by just removing "[Gmail]" from the account array.

            if '"[Gmail]"' in folders: folders.remove('"[Gmail]"')

It fit's in below in the imapbox.py script:

    for account in options['accounts']:

        print('{}/{} (on {})'.format(account['name'], account['remote_folder'], account['host']))
        basedir = options['local_folder']

        if account['remote_folder'] == "__ALL__":
            folders = []
            for folder_entry in get_folder_fist(account):
                folders.append(folder_entry.decode().replace("/",".").split(' "." ')[1])
            # Remove gmail specific parent folder from array as causes script to fail:
            if '"[Gmail]"' in folders: folders.remove('"[Gmail]"')

From what I understand, it's a Gmail specific parent folder for Gmail specific folders, or something like that. The point is it doesn't, as far as I know, contain any emails itself, and so can be removed.

Will give it a bit more of a test this weekend and if all seems to be working I'll raise a PR.

That being said, perhaps there's a reason why it's failing - maybe because it contains no emails, but I've just focused on trying to work around it for now, as imapbox does exactly what I've been looking for otherwise.

polo2ro commented 2 years ago

I think i never tested this on gmail. Good thing you find a fix :+1:

jakeprice-me commented 2 years ago

PR's been created :+1: