gurgitate-mail 1.9.1 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []