From 167907a8ff0e9a87fc83612d48cdf09b3218b362 Mon Sep 17 00:00:00 2001 From: Ben Walton Date: Wed, 6 May 2009 22:32:50 -0400 Subject: [PATCH] Add store_message to IMAP, mbox and Maildir sources. With this method, each of the named source types is now capable of acting as a destination for sent mail. Signed-off-by: Ben Walton --- lib/sup/imap.rb | 8 ++++++++ lib/sup/maildir.rb | 36 +++++++++++++++++++++++++++++++++++- lib/sup/mbox/loader.rb | 9 +++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/sup/imap.rb b/lib/sup/imap.rb index 7508c2c..6c04d88 100644 --- a/lib/sup/imap.rb +++ b/lib/sup/imap.rb @@ -111,6 +111,14 @@ class IMAP < Source end synchronized :raw_header + def store_message date, from_email, &block + message = StringIO.new + yield message + message.string.gsub! /\n/, "\r\n" + + safely { @imap.append mailbox, message.string, [:Seen], Time.now } + end + def raw_message id unsynchronized_scan_mailbox get_imap_fields(id, 'RFC822').first.gsub(/\r\n/, "\n") diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb index a9ae05c..c6577c1 100644 --- a/lib/sup/maildir.rb +++ b/lib/sup/maildir.rb @@ -10,6 +10,7 @@ module Redwood class Maildir < Source SCAN_INTERVAL = 30 # seconds + MYHOSTNAME = Socket.gethostname ## remind me never to use inheritance again. yaml_properties :uri, :cur_offset, :usual, :archived, :id, :labels, :mtimes @@ -44,7 +45,35 @@ class Maildir < Source start = @ids.index(cur_offset || start_offset) or raise OutOfSyncSourceError, "Unknown message id #{cur_offset || start_offset}." # couldn't find the most recent email end - + + def store_message date, from_email, &block + stored = false + new_fn = new_maildir_basefn + ':2,S' + Dir.chdir(@dir) do |d| + tmp_path = File.join(@dir, 'tmp', new_fn) + new_path = File.join(@dir, 'new', new_fn) + begin + sleep 2 if File.stat(tmp_path) + + File.stat(tmp_path) + rescue Errno::ENOENT #this is what we want. + begin + File.open(tmp_path, 'w') do |f| + yield f #provide a writable interface for the caller + f.fsync + end + + File.link tmp_path, new_path + stored = true + ensure + File.unlink tmp_path if File.exists? tmp_path + end + end #rescue Errno... + end #Dir.chdir + + stored + end + def each_raw_message_line id scan_mailbox with_file_for(id) do |f| @@ -167,6 +196,11 @@ private sprintf("%d%07d", stat.mtime, stat.size % 10000000).to_i end + def new_maildir_basefn + Kernel::srand() + "#{Time.now.to_i.to_s}.#{$$}#{Kernel.rand(1000000)}.#{MYHOSTNAME}" + end + def with_file_for id fn = @ids_to_fns[id] or raise OutOfSyncSourceError, "No such id: #{id.inspect}." begin diff --git a/lib/sup/mbox/loader.rb b/lib/sup/mbox/loader.rb index ebb2aed..ff41d51 100644 --- a/lib/sup/mbox/loader.rb +++ b/lib/sup/mbox/loader.rb @@ -109,6 +109,15 @@ class Loader < Source ret end + def store_message date, from_email, &block + need_blank = File.exists?(@filename) && !File.zero?(@filename) + File.open(@filename, "a") do |f| + f.puts if need_blank + f.puts "From #{from_email} #{date}" + yield f + end + end + ## apparently it's a million times faster to call this directly if ## we're just moving messages around on disk, than reading things ## into memory with raw_message. -- 2.43.0