gurgitate-mail 1.9.1 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -87,10 +87,20 @@ module Gurgitate
87
87
  spooldir homedir
88
88
  spoolfile File.join(spooldir,"Maildir")
89
89
  maildir spoolfile
90
+ elsif style[0] == MH then
91
+ mh_profile_path = File.join(ENV["HOME"],".mh_profile")
92
+ if File.exists?(mh_profile_path) then
93
+ mh_profile = YAML.load(File.read(mh_profile_path))
94
+ maildir mh_profile["Path"]
95
+ else
96
+ maildir File.join(ENV["HOME"],"Mail")
97
+ end
98
+ spoolfile File.join(maildir,"inbox")
90
99
  else
91
100
  spooldir "/var/spool/mail"
92
101
  spoolfile File.join(spooldir, @passwd.name)
93
102
  end
103
+
94
104
  @folderstyle = style[0]
95
105
  else
96
106
  raise ArgumentError, "wrong number of arguments "+
@@ -7,6 +7,7 @@
7
7
 
8
8
  require "gurgitate/deliver/mbox"
9
9
  require "gurgitate/deliver/maildir"
10
+ require "gurgitate/deliver/mh"
10
11
 
11
12
  module Gurgitate
12
13
  module Deliver
@@ -38,7 +39,7 @@ module Gurgitate
38
39
  end
39
40
 
40
41
  begin
41
- [MBox,Maildir].each do |mod|
42
+ [MBox,Maildir,MH].each do |mod|
42
43
  if mod::check_mailbox(mailbox) then
43
44
  extend mod
44
45
  raise MailboxFound
@@ -0,0 +1,137 @@
1
+ #!/opt/bin/ruby -w
2
+
3
+ require "yaml"
4
+
5
+ #------------------------------------------------------------------------
6
+ # Delivers a message to an mbox (also includes mbox detector)
7
+ #------------------------------------------------------------------------
8
+
9
+ module Gurgitate
10
+ module Deliver
11
+ module MH
12
+ # Checks to see if +mailbox+ is an mbox mailbox
13
+ # mailbox::
14
+ # A string containing the path of the mailbox to save
15
+ # the message to. If it is of the form "=mailbox", it
16
+ # saves the message to +Maildir+/+mailbox+. Otherwise,
17
+ # it simply saves the message to the file +mailbox+.
18
+ def self::check_mailbox(mailbox)
19
+ begin
20
+ # Rather annoyingly, pretty well any directory can
21
+ # be a MH mailbox, but this just checks to make sure
22
+ # it's not actually a Maildir by mistake.
23
+ #
24
+ # I could put in a check for the path given in
25
+ # $HOME/.mh_profile, but Claws-Mail uses MH mailboxes and
26
+ # disregards $HOME/.mh_profile.
27
+ if File.stat(mailbox).directory? and
28
+ not ( File.exists?(File.join(mailbox, "cur")) or
29
+ File.exists?(File.join(mailbox, "tmp")) or
30
+ File.exists?(File.join(mailbox, "new"))) then
31
+ return MH
32
+ end
33
+ rescue Errno::ENOENT
34
+ return nil
35
+ end
36
+ end
37
+
38
+ # Delivers the message to +mailbox+
39
+ # mailbox::
40
+ # A string containing the path of the mailbox to save
41
+ # the message to. If it is of the form "=mailbox", it
42
+ # saves the message to +Maildir+/+mailbox+. Otherwise,
43
+ # it simply saves the message to the file +mailbox+.
44
+ def deliver_message(mailbox)
45
+ if ! File.exists? mailbox then
46
+ Dir.mkdir(mailbox)
47
+ end
48
+
49
+ if File.exists? mailbox and not File.directory? mailbox then
50
+ raise SystemError, "not a directory"
51
+ end
52
+
53
+ new_msgnum = next_message(mailbox) do |filehandle|
54
+ filehandle.print self.to_s
55
+ end
56
+
57
+ update_sequences(mailbox, new_msgnum)
58
+ end
59
+
60
+ private
61
+
62
+ def update_sequences(mailbox, msgnum)
63
+ sequences = File.join(mailbox, ".mh_sequences")
64
+ lockfile = sequences + ".lock" # how quaint
65
+ loop do
66
+ begin
67
+ File.open(lockfile,
68
+ File::WRONLY |
69
+ File::CREAT |
70
+ File::EXCL ) do |lock|
71
+ File.open(sequences,
72
+ File::RDWR | File::CREAT) do |seq|
73
+
74
+ seq.flock(File::LOCK_EX)
75
+ metadata = YAML.load(seq.read) || Hash.new
76
+
77
+ metadata["unseen"] = update_unseen \
78
+ metadata["unseen"], msgnum
79
+
80
+ seq.rewind
81
+ metadata.each do |key, val|
82
+ seq.puts "#{key}: #{val}"
83
+ end
84
+ seq.truncate seq.tell
85
+ seq.flock(File::LOCK_UN)
86
+ end
87
+ end
88
+
89
+ File.unlink(lockfile)
90
+ break
91
+ rescue Errno::EEXIST
92
+ # some other process is doing something, so wait a few
93
+ # milliseconds until it's done
94
+ sleep(0.01)
95
+ end
96
+ end
97
+ end
98
+
99
+ def update_unseen unseen, msgnum
100
+ prevmsg = msgnum - 1
101
+ if unseen
102
+ unseenstring = unseen.to_s
103
+
104
+ if unseenstring =~ /-#{prevmsg}/ then
105
+ return unseenstring.sub(/\b#{prevmsg}\b/, msgnum.to_s)
106
+ end
107
+
108
+ if unseenstring.match(/\b#{prevmsg}\b/) then
109
+ return "#{unseenstring}-#{msgnum}"
110
+ end
111
+
112
+ return "#{unseenstring} #{msgnum}"
113
+ else
114
+ return msgnum
115
+ end
116
+ end
117
+
118
+ def next_message(mailbox)
119
+ next_msgnum = Dir.open(mailbox).map { |ent| ent.to_i }.max + 1
120
+ loop do
121
+ begin
122
+ File.open(File.join(mailbox, next_msgnum.to_s),
123
+ File::WRONLY |
124
+ File::CREAT |
125
+ File::EXCL ) do |filehandle|
126
+ yield filehandle
127
+ end
128
+ break
129
+ rescue Errno::EEXIST
130
+ next_msgnum += 1
131
+ end
132
+ end
133
+ return next_msgnum
134
+ end
135
+ end
136
+ end
137
+ end
@@ -31,13 +31,17 @@ class GurgitateTest < Test::Unit::TestCase
31
31
  @spoolfile = File.join(testdir, "default")
32
32
  end
33
33
 
34
- def maildirmake mailbox # per the command
34
+ def maildirmake mailbox # per the UNIX command
35
35
  FileUtils.mkdir mailbox
36
36
  %w/cur tmp new/.each do |subdir|
37
37
  FileUtils.mkdir File.join(mailbox, subdir)
38
38
  end
39
39
  end
40
40
 
41
+ def mhdirmake mailbox # per "maildirmake"
42
+ FileUtils.mkdir mailbox
43
+ end
44
+
41
45
  def teardown
42
46
  FileUtils.rmtree @testdir
43
47
  end
@@ -73,4 +73,21 @@ class TC_Deliver < Test::Unit::TestCase
73
73
  assert File.exists?(contents[0])
74
74
  assert_equal File.read(contents[0]), @deliver_test.to_s
75
75
  end
76
+
77
+ def test_basic_delivery_mh
78
+ @deliver_test.folderstyle = Gurgitate::Deliver::MH
79
+ assert_nothing_raised do
80
+ @deliver_test.save(@spoolfile)
81
+ end
82
+
83
+ assert File.exists?(@spoolfile)
84
+ assert File.directory?(@spoolfile)
85
+
86
+ mess = File.join(@spoolfile,"1")
87
+ seq = File.join(@spoolfile,".mh_sequences")
88
+ assert File.exists?(mess)
89
+ assert File.exists?(seq)
90
+ assert_equal File.read(mess), @deliver_test.to_s
91
+ assert_equal File.read(seq), "unseen: 1\n"
92
+ end
76
93
  end
@@ -4,8 +4,8 @@ require 'stringio'
4
4
  require 'fileutils'
5
5
  require 'pathname'
6
6
  require 'irb'
7
- require "./gurgitate-mail"
8
7
  require "test/gurgitate-test"
8
+ require "gurgitate-mail"
9
9
 
10
10
  class TC_Delivery < GurgitateTest
11
11
  #************************************************************************
@@ -4,8 +4,8 @@ require 'stringio'
4
4
  require 'fileutils'
5
5
  require 'pathname'
6
6
  require 'irb'
7
- require "./gurgitate-mail"
8
7
  require "test/gurgitate-test"
8
+ require "gurgitate-mail"
9
9
 
10
10
  class TC_Gurgitate_delivery < GurgitateTest
11
11
  #************************************************************************
@@ -46,6 +46,23 @@ class TC_Gurgitate_delivery < GurgitateTest
46
46
  setup
47
47
  end
48
48
 
49
+ def test_detect_mhdir
50
+ mhdirmake @spoolfile
51
+
52
+ assert_nothing_raised do
53
+ @gurgitate.process { nil }
54
+ end
55
+
56
+ assert File.exists?(@spoolfile)
57
+ assert File.directory?(@spoolfile)
58
+ assert File.exists?(File.join(@spoolfile,"1"))
59
+ assert File.exists?(File.join(@spoolfile,".mh_sequences"))
60
+ FileUtils.rmtree @spoolfile
61
+ teardown
62
+ test_detect_mbox
63
+ setup
64
+ end
65
+
49
66
  def test_save_folders
50
67
  assert_nothing_raised do
51
68
  @gurgitate.process do
@@ -83,6 +100,31 @@ class TC_Gurgitate_delivery < GurgitateTest
83
100
  assert_equal 1, Dir[File.join(@folders, "test", "new", "*")].length
84
101
  end
85
102
 
103
+ def test_save_guess_mh
104
+ mhdirmake File.join(@folders,"test")
105
+
106
+ assert File.exists?(File.join(@folders, "test"))
107
+ assert File.stat(File.join(@folders, "test")).directory?
108
+
109
+ assert_equal 0, Dir[File.join(@folders, "test", "*")].length
110
+
111
+ assert_nothing_raised do
112
+ @gurgitate.process do
113
+ save "=test"
114
+ break
115
+ end
116
+ end
117
+
118
+ assert File.exists?(File.join(@folders, "test"))
119
+ assert File.stat(File.join(@folders, "test")).directory?
120
+ assert File.exists?(File.join(@folders, "test", "1"))
121
+ assert File.stat(File.join(@folders, "test","1")).file?
122
+ assert File.exists?(File.join(@folders, "test", ".mh_sequences"))
123
+ assert File.stat(File.join(@folders, "test", ".mh_sequences")).file?
124
+ assert_equal "unseen: 1\n",
125
+ File.read(File.join(@folders, "test", ".mh_sequences"))
126
+ end
127
+
86
128
  def test_save_maildir_collision
87
129
  maildirmake File.join(@folders,"test")
88
130
 
@@ -109,6 +151,33 @@ class TC_Gurgitate_delivery < GurgitateTest
109
151
  assert_equal 2, Dir[File.join(@folders, "test", "new", "*")].length
110
152
  end
111
153
 
154
+ def test_save_mh_collision
155
+ mhdirmake File.join(@folders,"test")
156
+
157
+ assert File.exists?(File.join(@folders, "test"))
158
+ assert File.stat(File.join(@folders, "test")).directory?
159
+ assert_equal 0, Dir[File.join(@folders, "test", "*")].length
160
+
161
+ assert_nothing_raised do
162
+ @gurgitate.process do
163
+ save "=test"
164
+ save "=test"
165
+ break
166
+ end
167
+ end
168
+
169
+ assert File.exists?(File.join(@folders, "test"))
170
+ assert File.stat(File.join(@folders, "test")).directory?
171
+ assert File.exists?(File.join(@folders, "test", "1"))
172
+ assert File.stat(File.join(@folders, "test","1")).file?
173
+ assert File.exists?(File.join(@folders, "test", "2"))
174
+ assert File.stat(File.join(@folders, "test","2")).file?
175
+ assert File.exists?(File.join(@folders, "test", ".mh_sequences"))
176
+ assert File.stat(File.join(@folders, "test", ".mh_sequences")).file?
177
+ assert_equal "unseen: 1-2\n",
178
+ File.read(File.join(@folders, "test", ".mh_sequences"))
179
+ end
180
+
112
181
  def test_save_create_maildir
113
182
  maildirmake @spoolfile
114
183
 
@@ -129,6 +198,26 @@ class TC_Gurgitate_delivery < GurgitateTest
129
198
  assert_equal 1, Dir[File.join(@spoolfile, ".test", "new", "*")].length
130
199
  end
131
200
 
201
+ def test_save_create_mh
202
+ maildirmake @spoolfile
203
+
204
+ assert_nothing_raised do
205
+ @gurgitate.process do
206
+ @folderstyle = Gurgitate::Deliver::MH
207
+ @maildir = @spoolfile
208
+ save "=test"
209
+ break
210
+ end
211
+ end
212
+
213
+ assert File.exists?(File.join(@spoolfile, "test"))
214
+ assert File.stat(File.join(@spoolfile, "test")).directory?
215
+ assert File.exists?(File.join(@spoolfile, "test", ".mh_sequences"))
216
+ assert File.stat(File.join(@spoolfile, "test",".mh_sequences")).file?
217
+ assert File.exists?(File.join(@spoolfile, "test", "1"))
218
+ assert File.stat(File.join(@spoolfile, "test", "1")).file?
219
+ end
220
+
132
221
  def test_save_bad_filename
133
222
  assert_nothing_raised do
134
223
  @gurgitate.process do
@@ -209,4 +298,3 @@ class TC_Gurgitate_delivery < GurgitateTest
209
298
  assert_equal("Subject: test", mess.header("Subject"), "Subject header wrong")
210
299
  end
211
300
  end
212
-
@@ -4,6 +4,11 @@
4
4
  #
5
5
  #------------------------------------------------------------------------
6
6
 
7
+ builddir = File.join(File.dirname(__FILE__),"..")
8
+ unless $:[0] == builddir
9
+ $:.unshift builddir
10
+ end
11
+
7
12
  require 'test/unit'
8
13
  require 'test/unit/ui/console/testrunner'
9
14
  require 'stringio'
@@ -11,12 +16,9 @@ require 'stringio'
11
16
  class TC_Header < Test::Unit::TestCase
12
17
 
13
18
  def setup
14
- require './gurgitate-mail'
19
+ require 'gurgitate-mail'
15
20
  end
16
21
 
17
- # def teardown
18
- # end
19
-
20
22
  def test_simple_header
21
23
  h=Gurgitate::Header.new("From: fromheader@example.com")
22
24
  assert_equal(h.name,"From", "Simple header name is From")
@@ -40,6 +40,7 @@ EOF
40
40
  assert_equal(1,h["From"].length)
41
41
  assert_equal("From",h["From"][0].name)
42
42
  assert_equal("fromheader@example.com",h["From"][0].contents)
43
+ assert_equal nil, h["To"]
43
44
  end
44
45
 
45
46
  def test_changing_headers
@@ -1,10 +1,16 @@
1
+ builddir = File.join(File.dirname(__FILE__),"..")
2
+ unless $:[0] == builddir
3
+ $:.unshift builddir
4
+ end
5
+
1
6
  require 'test/unit'
2
7
  require 'test/unit/ui/console/testrunner'
3
8
  require 'stringio'
4
9
  require 'fileutils'
5
10
  require 'pathname'
6
11
  require 'irb'
7
- require "./gurgitate-mail"
12
+ require "gurgitate-mail"
13
+ require "test/gurgitate-test"
8
14
 
9
15
  class TC_Process < GurgitateTest
10
16
  #************************************************************************
@@ -1,10 +1,19 @@
1
1
  #/opt/bin/ruby -w
2
2
 
3
+ builddir = File.join(File.dirname(__FILE__),"..")
4
+ unless $:[0] == builddir
5
+ $:.unshift builddir
6
+ end
7
+
3
8
  require 'test/unit'
4
9
  require 'test/unit/ui/console/testrunner'
5
10
  require 'stringio'
6
11
 
7
12
  class TC_Writing < Test::Unit::TestCase
13
+ def setup
14
+ require 'gurgitate-mail'
15
+ end
16
+
8
17
  def test_null_message
9
18
  assert_nothing_raised do
10
19
  Gurgitate::Mailmessage.new
@@ -102,7 +111,7 @@ class TC_Writing < Test::Unit::TestCase
102
111
  assert_equal "sender@test", mess.from
103
112
  assert_equal "recipient@test", mess.to
104
113
  assert_equal "This is a test", mess.body
105
- assert_equal "From: from@test", mess.headers["From"].to_s
106
- assert_equal "To: to@test", mess.headers["To"].to_s
114
+ assert_equal "From: from@test", (mess.headers["From"]).to_s
115
+ assert_equal "To: to@test", (mess.headers["To"]).to_s
107
116
  end
108
117
  end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
2
+ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: gurgitate-mail
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.9.1
7
- date: 2007-12-27 00:00:00 +09:00
6
+ version: 1.10.0
7
+ date: 2008-01-30 00:00:00 +09:00
8
8
  summary: gurgitate-mail is a mail filter (and a mail-delivery agent)
9
9
  require_paths:
10
10
  - lib
@@ -30,23 +30,24 @@ authors:
30
30
  - Dave Brown
31
31
  files:
32
32
  - lib/gurgitate-mail.rb
33
+ - lib/gurgitate/deliver.rb
33
34
  - lib/gurgitate/headers.rb
35
+ - lib/gurgitate/header.rb
34
36
  - lib/gurgitate/mailmessage.rb
35
37
  - lib/gurgitate/deliver/maildir.rb
36
38
  - lib/gurgitate/deliver/mbox.rb
37
- - lib/gurgitate/deliver.rb
38
- - lib/gurgitate/header.rb
39
+ - lib/gurgitate/deliver/mh.rb
40
+ - test/gurgitate-test.rb
41
+ - test/runtests.rb
39
42
  - test/test_configuration.rb
40
- - test/test_headers.rb
41
- - test/test_gurgitate_delivery.rb
43
+ - test/test_deliver.rb
42
44
  - test/test_delivery.rb
45
+ - test/test_header.rb
43
46
  - test/test_process.rb
44
- - test/runtests.rb
45
- - test/gurgitate-test.rb
46
- - test/test_deliver.rb
47
47
  - test/test_rules.rb
48
48
  - test/test_writing.rb
49
- - test/test_header.rb
49
+ - test/test_gurgitate_delivery.rb
50
+ - test/test_headers.rb
50
51
  test_files:
51
52
  - test/runtests.rb
52
53
  rdoc_options: []