maildir 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg/*
2
+ benchmarks/scratch.rb
data/Rakefile CHANGED
@@ -22,3 +22,8 @@ begin
22
22
  rescue LoadError
23
23
  puts "Jeweler not available. Install it with: sudo gem install jeweler"
24
24
  end
25
+
26
+ desc "Run benchmarks"
27
+ task :bench do
28
+ load File.join(File.dirname(__FILE__), "benchmarks", "runner")
29
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/benchmarks/runner CHANGED
@@ -1,4 +1,30 @@
1
1
  #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+ require 'maildir'
4
+ require 'benchmark'
2
5
 
3
- $: << File.join(File.dirname(__FILE__), '..', 'lib')
4
- require 'maildir'
6
+ maildir_path = ENV['MAILDIR'] || "./tmp"
7
+ maildir = Maildir.new(maildir_path)
8
+
9
+ n = 300
10
+ message = "Write #{n} messages:"
11
+ tms = Benchmark.bmbm(message.size) do |x|
12
+ x.report(message) { n.times { maildir.add_message("") } }
13
+ end
14
+
15
+ puts "#{n/tms.first.real} messages per second"
16
+
17
+
18
+ message = "List new:"
19
+ tms = Benchmark.bm(message.size) do |x|
20
+ x.report(message) { n.times { maildir.list_keys(:new)} }
21
+ end
22
+
23
+ # require 'ruby-prof'
24
+ # result = RubyProf.profile do
25
+ # n.times { maildir.list_keys(:new) }
26
+ # end
27
+ #
28
+ # # Print a graph profile to text
29
+ # printer = RubyProf::GraphPrinter.new(result)
30
+ # printer.print(STDOUT, 0)
data/lib/maildir.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'fileutils'
1
2
  class Maildir
2
3
 
3
4
  SUBDIRS = [:tmp, :new, :cur].freeze
@@ -43,10 +44,10 @@ class Maildir
43
44
  get_dir_listing(new_or_cur)
44
45
  end
45
46
 
46
- # Writes IO object out as a new message. See Maildir::Message.create for
47
- # more.
48
- def add_message(io)
49
- Maildir::Message.create(self, io)
47
+ # Writes string_or_io object out as a new message. See
48
+ # Maildir::Message.create for more.
49
+ def add_message(string_or_io)
50
+ Maildir::Message.create(self, string_or_io)
50
51
  end
51
52
 
52
53
  def get_message(key)
@@ -57,8 +58,12 @@ class Maildir
57
58
  def get_dir_listing(new_or_cur)
58
59
  search_path = File.join(self.path, new_or_cur.to_s, '*')
59
60
  results = Dir.glob(search_path)
61
+
60
62
  # Remove the maildir's path from the beginning of the message path
61
- results.map!{|message_path| message_path.sub!(self.path, '')}
63
+ @dir_listing_regexp ||= /^#{Regexp.quote(self.path)}/
64
+ results.each do |message_path|
65
+ message_path.sub!(@dir_listing_regexp, "")
66
+ end
62
67
  end
63
68
  end
64
69
 
@@ -5,24 +5,27 @@ class Maildir::Message
5
5
  INFO = "2,"
6
6
 
7
7
  class << self
8
- # Create a new message in maildir with the contents of io. The message is
9
- # first written to the tmp dir, then moved to new. This is a shortcut for:
8
+ # Create a new message in maildir with the contents of string_or_io.
9
+ # The message is first written to the tmp dir, then moved to new. This is
10
+ # a shortcut for:
10
11
  # message = Maildir::Message.new(maildir)
11
- # message.write(io)
12
- def create(maildir, io)
12
+ # message.write(string_or_io)
13
+ def create(maildir, string_or_io)
13
14
  message = self.new(maildir)
14
- message.write(io)
15
+ message.write(string_or_io)
15
16
  message
16
17
  end
17
18
  end
18
19
 
19
20
  attr_reader :dir, :unique_name, :info, :old_key
20
21
 
21
- # Create a new, unwritten message:
22
- # Message.new(maildir)
22
+ # Create a new, unwritten message or instantiate an existing message.
23
+ # If key is nil, create a new message:
24
+ # Message.new(maildir) # => a new, unwritten message
23
25
  #
24
- # Instantiate an existing message:
25
- # Message.new(maildir, key)
26
+ # If +key+ is not nil, instantiate a message object for the message at
27
+ # +key+.
28
+ # Message.new(maildir, key) # => an existing message
26
29
  def initialize(maildir, key=nil)
27
30
  @maildir = maildir
28
31
  if key.nil?
@@ -31,33 +34,44 @@ class Maildir::Message
31
34
  parse_key(key)
32
35
  end
33
36
 
34
- raise ArgumentError, "State must be in #{Maildir::SUBDIRS.inspect}" unless Maildir::SUBDIRS.include? dir
37
+ unless Maildir::SUBDIRS.include? dir
38
+ raise ArgumentError, "State must be in #{Maildir::SUBDIRS.inspect}"
39
+ end
35
40
 
36
41
  if :tmp == dir
37
42
  @unique_name = Maildir::UniqueName.create
38
43
  end
39
44
  end
40
45
 
41
- # Writes io to disk. Can only be called on messages instantiated without a
42
- # key (which haven't been written to disk). If the io object has a 'read'
43
- # method, calls io.read. Otherwise, calls io.to_s.
44
- def write(io)
46
+ # Writes string_or_io to disk. Can only be called on messages
47
+ # instantiated without a key (which haven't been written to disk). If the
48
+ # +string_or_io+ object has a 'read' method, calls string_or_io.read.
49
+ # Otherwise, calls string_or_io.to_s.
50
+ #
51
+ # Returns the message's key
52
+ def write(string_or_io)
45
53
  raise "Can only write to messages in tmp" unless :tmp == @dir
46
54
  # Write out contents to tmp
47
55
  File.open(path, 'w') do |file|
48
- file.puts io.respond_to?(:read) ? io.read : io.to_s
56
+ if string_or_io.respond_to?(:read)
57
+ file.puts string_or_io.read
58
+ else
59
+ file.puts string_or_io.to_s
60
+ end
49
61
  end
50
62
 
51
63
  # Rename to new
52
64
  rename(:new)
53
-
54
65
  end
55
66
 
56
- # Move a message from new to cur, add info
67
+ # Move a message from new to cur, add info.
68
+ # Returns the message's key
57
69
  def process
58
70
  rename(:cur, INFO)
59
71
  end
60
72
 
73
+ # Set info on a message.
74
+ # Returns the message's key
61
75
  def info=(info)
62
76
  raise "Can only set info on cur messages" unless :cur == @dir
63
77
  rename(:cur, info)
@@ -68,6 +82,8 @@ class Maildir::Message
68
82
  @info.sub(INFO,'').split('')
69
83
  end
70
84
 
85
+ # Sets the flags on a message.
86
+ # Returns the message's key
71
87
  def flags=(*flags)
72
88
  self.info = INFO + sort_flags(flags.flatten.join(''))
73
89
  end
@@ -96,22 +112,29 @@ class Maildir::Message
96
112
  File.join(@maildir.path, key)
97
113
  end
98
114
 
99
- def old_path
100
- File.join(@maildir.path, old_key)
115
+ # Deletes the message path and freezes the message object
116
+ def destroy
117
+ File.delete(path)
118
+ freeze
101
119
  end
102
120
 
103
121
  protected
104
- # Sets dir, unique_name, and info based in key
122
+ # Sets dir, unique_name, and info based on the key
105
123
  def parse_key(key)
106
124
  @dir, filename = key.split(File::SEPARATOR)
107
125
  @dir = @dir.to_sym
108
126
  @unique_name, @info = filename.split(COLON)
109
127
  end
110
128
 
129
+ # Ensure the flags are uppercase and sorted
111
130
  def sort_flags(flags)
112
131
  flags.split('').map{|f| f.upcase}.sort!.uniq.join('')
113
132
  end
114
133
 
134
+ def old_path
135
+ File.join(@maildir.path, old_key)
136
+ end
137
+
115
138
  def rename(new_dir, new_info=nil)
116
139
  # Safe the old key so we can revert to the old state
117
140
  @old_key = key
@@ -122,6 +145,7 @@ class Maildir::Message
122
145
 
123
146
  begin
124
147
  File.rename(old_path, path) unless old_path == path
148
+ return key
125
149
  rescue Errno::ENOENT
126
150
  # Restore ourselves to the old state
127
151
  parse_key(@old_key)
data/maildir.gemspec ADDED
@@ -0,0 +1,61 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{maildir}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Aaron Suggs"]
12
+ s.date = %q{2010-01-05}
13
+ s.description = %q{A ruby library for reading and writing arbitrary messages in DJB's maildir format}
14
+ s.email = %q{aaron@ktheory.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "NOTES.txt",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "benchmarks/runner",
27
+ "lib/maildir.rb",
28
+ "lib/maildir/message.rb",
29
+ "lib/maildir/unique_name.rb",
30
+ "maildir.gemspec",
31
+ "test/test_helper.rb",
32
+ "test/test_maildir.rb",
33
+ "test/test_message.rb",
34
+ "test/test_unique_name.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/ktheory/maildir}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.5}
40
+ s.summary = %q{Read & write messages in the maildir format}
41
+ s.test_files = [
42
+ "test/test_helper.rb",
43
+ "test/test_maildir.rb",
44
+ "test/test_message.rb",
45
+ "test/test_unique_name.rb"
46
+ ]
47
+
48
+ if s.respond_to? :specification_version then
49
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
50
+ s.specification_version = 3
51
+
52
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
53
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
59
+ end
60
+ end
61
+
data/test/test_maildir.rb CHANGED
@@ -33,6 +33,17 @@ class TestMaildir < Test::Unit::TestCase
33
33
  assert_equal temp_maildir.path, new_maildir.path
34
34
  assert_equal temp_maildir, new_maildir
35
35
  end
36
+
37
+ context "with a message" do
38
+ setup do
39
+ @key = temp_maildir.add_message("").key
40
+ end
41
+
42
+ should "list the message in it's keys" do
43
+ keys = temp_maildir.list_keys(:new)
44
+ assert_equal keys, [@key]
45
+ end
46
+ end
36
47
  end
37
48
 
38
49
  end
data/test/test_message.rb CHANGED
@@ -147,6 +147,15 @@ class TestMessage < Test::Unit::TestCase
147
147
  assert_match /#{path_suffix}$/, @message.path
148
148
  end
149
149
  end
150
+ context "when destroyed" do
151
+ setup { @message.destroy }
152
+ should "be frozen" do
153
+ assert @message.frozen?, "Message is not frozen"
154
+ end
155
+ should "have a nonexistant path" do
156
+ assert !File.exists?(@message.path), "Message path exists"
157
+ end
158
+ end
150
159
  end
151
160
  end
152
161
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maildir
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Suggs
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-05 00:00:00 -05:00
12
+ date: 2010-01-05 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,7 @@ extra_rdoc_files:
32
32
  - LICENSE
33
33
  - README.rdoc
34
34
  files:
35
+ - .gitignore
35
36
  - LICENSE
36
37
  - NOTES.txt
37
38
  - README.rdoc
@@ -41,6 +42,7 @@ files:
41
42
  - lib/maildir.rb
42
43
  - lib/maildir/message.rb
43
44
  - lib/maildir/unique_name.rb
45
+ - maildir.gemspec
44
46
  - test/test_helper.rb
45
47
  - test/test_maildir.rb
46
48
  - test/test_message.rb