Question

I'm trying to get my emails to work from commandline with mutt. I have been trying to follow these two guides: http://blog.developwithpassion.com/2013/05/02/getting-up-and-running-with-a-sane-mutt-setup/ and http://stevelosh.com/blog/2012/10/the-homely-mutt/#configuring-offlineimap

To do this there are 4 main steps: 1. setup offlineimap to download and keep synced your emails 2. setup mutt (the email user interface) 3. setup notmuch (to be able to search your emails) 4. setup msmtp (to be able to send emails)

Note that I am using Macbook Pro running the OS X 10.9.2. I am stuck at step 1 because I am getting an error with offlineimap! I am able to run offlineimap for a long time, i.e. it will sync all of the emails (36197 of them!) and then right at the end it spits out the following error:

ERROR: getfolder() asked for a nonexisting folder 'Drafts'.

Folder Deleted Items [acc: gloriphobia]:

Establishing connection to imap.gmail.com:993

Account sync gloriphobia:

 *** Finished account 'gloriphobia' in 137:16

ERROR: Exceptions occurred during the run!

ERROR: command: UID => socket error: <class 'socket.error'> - [Errno 54] Connection reset by peer


Traceback:

  File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/folder/IMAP.py", line 219, in getmessage
'(BODY.PEEK[])')

  File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/imaplib2.py", line 1167, in uid

    return self._simple_command('UID', command, *args, **kw)

  File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/imaplib2.py", line 1615, in _simple_command
return self._command_complete(self._command(name, *args), kw)

  File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/imaplib2.py", line 1378, in _command_complete
typ, dat = rqb.get_response('command: %s => %%s' % rqb.name)

 File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/imaplib2.py", line 176, in get_response
raise typ(exc_fmt % str(val))


ERROR: getfolder() asked for a nonexisting folder 'Drafts'.


Traceback:

  File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/accounts.py", line 241, in syncrunner
self.sync()

  File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/accounts.py", line 320, in sync
localfolder = self.get_local_folder(remotefolder)

  File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/accounts.py", line 269, in get_local_folder
replace(self.remoterepos.getsep(), self.localrepos.getsep()))

  File "/usr/local/Cellar/offline-imap/6.5.5/libexec/offlineimap/repository/Maildir.py", line 134, in getfolder
OfflineImapError.ERROR.FOLDER)

My .offlineimaprc is:

[general]
accounts = gloriphobia
ui = TTYUI
pythonfile=~/Development/MuttMailPython/offline.py
fsync = False

[Account gloriphobia]
localrepository = gloriphobia_local
remoterepository = gloriphobia_remote
status_backend = sqlite
postsynchook = notmuch new

[Repository gloriphobia_local]
type = Maildir
localfolders = ~/.mail/Test
nametrans = get_remote_name

[Repository gloriphobia_remote]
maxconnections = 1
type = Gmail
cert_fingerprint = 89091347184d41768bfc0da9fad94bfe882dd358
remoteuser = myemailaddress
remotepasseval = get_keychain_pass(account="myemailaddress",server="imap.gmail.com")
realdelete = no
nametrans = get_local_name
folderfilter = is_included

My python file, the one that is called offline.py is:

#!/usr/bin/python
import subprocess
import re    

class NameMapping:
  def __init__(self, local_name, remote_name):
    self.local_name = local_name
    self.remote_name = remote_name    

class LocalName:
  def __init__(self, folder):
    self.folder = folder    

  def matches(self, mapping):
    return mapping.remote_name == self.folder    

  def mapped_folder_name(self, mapping):
    return mapping.local_name    

class RemoteName:
  def __init__(self, folder):
    self.folder = folder    

  def matches(self, mapping):
    return mapping.local_name == self.folder    

  def mapped_folder_name(self, mapping):
    return mapping.remote_name    

def get_keychain_pass(account=None, server=None):
  params = {
      'security': '/usr/bin/security',
      'command': 'find-internet-password',
      'account': account,
      'server': server,
      'keychain': '/Users/mec07/Library/Keychains/login.keychain',
  }
  command = "sudo -u mec07 %(security)s -v %(command)s -g -a %(account)s -s %(server)s %(keychain)s" % params
  output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
  outtext = [l for l in output.splitlines()
             if l.startswith('password: ')][0]    

  return re.match(r'password: "(.*)"', outtext).group(1)    

def is_included(folder):
  result = True    

  for pattern in exclusion_patterns:
    result = result and (re.search(pattern, folder) == None)    

  return result    

exclusion_patterns = [
  "efax",
  "earth_class_mail",
  "eventbrite",
  "gotomeeting",
  "moshi_monsters",
  "peepcode",
  "raini_fowl",
  "stuart_know",
  "training.*2008",
  "training.*2009",
  "training.*2010",
  "training.*2011",
  "training.*2012",
  "training.*nbdn",
  "training.*nothin_but_bdd",
  "unblock_us",
  "web_hosting",
  "webinars",
  "Gmail.*Important"
]    

name_mappings = [
  NameMapping('inbox', '[Gmail]/Inbox'),
  NameMapping('starred', '[Gmail]/Starred'),
  NameMapping('important', '[Gmail]/Important'),
  NameMapping('sent', '[Gmail]/Sent Mail'),
  NameMapping('drafts', '[Gmail]/Drafts'),
  NameMapping('archive', '[Gmail]/All Mail'),
  NameMapping('spam', '[Gmail]/Spam'),
  NameMapping('flagged', '[Gmail]/Starred'),
  NameMapping('trash',   '[Gmail]/Trash'),
  NameMapping('deleted', '[Gmail]/Deleted Items'),
  NameMapping('Mum', '[Gmail]/Jana'),
  NameMapping('Maggie', '[Gmail]/Maggie'),
  NameMapping('papers', '[Gmail]/Scholar Alert'),
  NameMapping('sent items', '[Gmail]/Sent Items'),
  NameMapping('sent messages', '[Gmail]/Sent Messages')
]    



def find_name_mapping(name):
  default_mapping = NameMapping(name.folder, name.folder)    

  for mapping in name_mappings:
    if (name.matches(mapping)):
      return mapping    

  return default_mapping    

def get_name_mapping(name):
  mapping = find_name_mapping(name)
  return name.mapped_folder_name(mapping)    

def get_remote_name(local_folder_name):
  name = RemoteName(local_folder_name)
  return get_name_mapping(name)    

def get_local_name(remote_folder_name):
  name = LocalName(remote_folder_name)
  return get_name_mapping(name)    

Thanks in advance for your help!

Was it helpful?

Solution

Add:

folderfilter = lambda folder: folder not in ['Drafts,]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top