title: MailBox to csv using Python
body: <p>I have downloaded an archive of mails from my gmail account.  I am using the following python(2.7) code taken from a blog to convert the contents of the archive to csv.</p>
  
  <pre><code>import mailbox
  import csv
  writer = csv.writer(open(("clean_mail.csv", "wb"))
  for message in mailbox.mbox('archive.mbox'):
      writer.writerow([message['subject'], message['from'], message['date']])
  </code></pre>
  
  <p>I want to include the body of the mail(the actual messages) too...but couldn't figure out how.  I have not used python earlier, can someone help please?  I have used other SO options given but couldn't get through.</p>
  
  <p>To do the same task, I have used the following code too:  but get indentation error for line 60: return json_msg.  I have tried different indentation options but nothing improved.</p>
  
  <pre><code>import sys
  import mailbox
  import email
  import quopri
  import json
  import time
  from BeautifulSoup import BeautifulSoup
  from dateutil.parser import parse
  
  MBOX = 'Users/mymachine/client1/Takeout/Mail/archive.mbox'
  OUT_FILE = 'Users/mymachine/client1/Takeout/Mail/archive.mbox.json'
  
  def cleanContent(msg):
      msg = quopri.decodestring(msg)
      try:
          soup = BeautifulSoup(msg)
      except:
          return ''
      return ''.join(soup.findAll(text=True))
  # There's a lot of data to process, and the Pythonic way to do it is with a
  # generator. See http://wiki.python.org/moin/Generators.
  # Using a generator requires a trivial encoder to be passed to json for object
  # serialization.
  class Encoder(json.JSONEncoder):
      def default(self, o): return list(o)
  
  def gen_json_msgs(mb):
      while 1:
          msg = mb.next()
          if msg is None:
              break
              yield jsonifyMessage(msg)
  
  def jsonifyMessage(msg):
      json_msg = {'parts': []}
      for (k, v) in msg.items():
          json_msg[k] = v.decode('utf-8', 'ignore')
  
      for k in ['To', 'Cc', 'Bcc']:
              if not json_msg.get(k):
                  continue
      json_msg[k] = json_msg[k].replace('\n', '').replace('\t', '').replace('\r', '')\
      .replace(' ', '').decode('utf-8', 'ignore').split(',')
  
  for part in msg.walk():
      json_part = {}
      if part.get_content_maintype() == 'multipart':
          continue
  
  
      json_part['contentType'] = part.get_content_type()
      content = part.get_payload(decode=False).decode('utf-8', 'ignore')
      json_part['content'] = cleanContent(content)
  
      json_msg['parts'].append(json_part)
      then = parse(json_msg['Date'])
      millis = int(time.mktime(then.timetuple())*1000 + then.microsecond/1000)
      json_msg['Date'] = {'$date' : millis}
  
  return json_msg
  
  mbox = mailbox.UnixMailbox(open(MBOX, 'rb'), email.message_from_file)
  
  f = open(OUT_FILE, 'w')
  for msg in gen_json_msgs(mbox):
      if msg != None:
              f.write(json.dumps(msg, cls=Encoder) + '\n')
  f.close()
  </code></pre>