Skip to main content

Raymii.org Raymii.org Logo

Quis custodiet ipsos custodes?
Home | About | All pages | Cluster Status | RSS Feed

Ruby script to upload or convert a Maildir Inbox to an IMAP server

Published: 01-01-2013 | Author: Thibaut Colar | Text only version of this article


❗ This post is over eleven years old. It may no longer be up to date. Opinions may have changed.

Note: The original page is often offline, so therefore the script is mirrored here. Credits to the original author: wiki.colar.net/ruby script to upload convert a maildir inbox to an imap_server

I decided to change email server for several reasons, anyway, long story short I was using postfix(qmail before that) and decided to switch to citadel, which is much easier to deal with (simple config).

Recently I removed all Google Ads from this site due to their invasive tracking, as well as Google Analytics. Please, if you found this content useful, consider a small donation using any of the options below:

I'm developing an open source monitoring app called Leaf Node Monitoring, for windows, linux & android. Go check it out!

Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.

You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $100 credit for 60 days.

Anyway, Citadel use it's own format for emails (Berkeley DB), so you can't just copy over the existing emails stored in Maildir format (8 years worth !), but since Citadel provides an IMAP server, all I need is a tool that can copy/upload The IMAP folder(s) content to an IMAP server.

I thought that would already exist, easy to find, but did not seem to find one. I found one made in PERL, but as usual Perl / CPAN failed me completely :(

I found another one that was really bare bone but usable here: http://www.robsayers.com/computing/MaildirToImap.html

It's quite compact and easy to use, tanks to ruby, but it was kinda hard coded to copy just the Inbox folder ... in my case I had many subfolders (Sent, archives and so on) that I wanted to copy as well, so I modified it a little to make it "parameterizable", so i could run it against other sub folders of my choice.

Usage

  • Prerequisite: You need a ruby install (apt-get install ruby)
  • Save the script (scroll down) to your machine (MaildirToImap.rb)
  • Edit the script ans set the variables IMAP HOST, IMAP USER, and IMAP_PASS to correct values.
  • Use the script with 2 params(absolute directory of a Maildir Inbox, IMAP box name), see examples:

Example: Copy the Inbox

ruby MaildirToImap.rb /home/tcolar/Maildir/cur/ INBOX

Example: Copy an Inbox sub-folder (ex: 'Sent')

ruby MaildirToImap.rb /home/tcolar/Maildir/.Sent/cur/ INBOX/Sent

Repeat for all the sub-folders you want to copy.

It takes about 0.5 seconds per email (on a local server), so if you have many emails it can take a while.

The script:

# Thibaut Colar
# http://wiki.colar.net/
# "Upload" a local Maildir folder onto an IMAP server
# Inspired by: http://www.robsayers.com/computing/MaildirToImap.html
# WARNING: Come with no warranties of any kind whatsoever, use at your own risk !
#
# Use, Example: ruby MaildirToImap.rb /home/tcolar/Maildir/cur INBOX
# Example(sub-box): ruby MaildirToImap.rb /home/tcolar/Maildir/.Sent/cur/ INBOX/Sent

#vars - set accordingly
IMAP_HOST = 'localhost'
IMAP_USER = 'me'
IMAP_PASS = 'my_password'
TEST_MODE = 0 # Set to 0 to actually do it

# program
require 'net/imap'

def upload_dir(imap, mail_dir, imap_dir)
        imap.examine(imap_dir)
        msgs = Dir.entries(mail_dir).each do |f|
        if !File.directory?(f) then
                print "Will add ", mail_dir, f, "t to: ", imap_dir, "n"
                if TEST_MODE == 0 then
                        imap.append(imap_dir,File.open(mail_dir+f).read,[:Seen])
                end
        end
        end
end

# Main
if ARGV.length < 2 then
        print "Expecting 2 params: - maildir directory (usually ends with /cur) - IMAP dirn"
        exit
end

mail_dir=ARGV[0]
imap_dir=ARGV[1]
imap = Net::IMAP.new(IMAP_HOST)
imap.authenticate('LOGIN', IMAP_USER, IMAP_PASS)
begin
        imap.create(imap_dir)
rescue
        print "Failed creating: ", imap_dir, ", that's probably OKn"
end
upload_dir(imap, mail_dir, imap_dir)
Tags: email , imap , nopriv , ruby , software