Class: Maildir

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/maildir.rb

Defined Under Namespace

Modules: Keywords, Serializer, Subdirs Classes: Message, UniqueName

Constant Summary collapse

SUBDIRS =
[:tmp, :new, :cur].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, create = true) ⇒ Maildir

Create a new maildir at path. If create is true, will ensure that the required subdirectories exist.



12
13
14
15
16
17
# File 'lib/maildir.rb', line 12

def initialize(path, create = true)
  @path = File.expand_path(path)
  @path = File.join(@path, '/') # Ensure path has a trailing slash
  @path_regexp = /^#{Regexp.quote(@path)}/ # For parsing directory listings
  create_directories if create
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



8
9
10
# File 'lib/maildir.rb', line 8

def path
  @path
end

Instance Method Details

#<=>(maildir) ⇒ Object

Compare maildirs by their paths. If maildir is a different class, return nil. Otherwise, return 1, 0, or -1.



22
23
24
25
26
27
# File 'lib/maildir.rb', line 22

def <=>(maildir)
  # Return nil if comparing different classes
  return nil unless self.class === maildir

  self.path <=> maildir.path
end

#add(data) ⇒ Object

Writes data object out as a new message. Returns a Maildir::Message. See Maildir::Message.create for more.



79
80
81
# File 'lib/maildir.rb', line 79

def add(data)
  Maildir::Message.create(self, data)
end

#create_directoriesObject

Ensure subdirectories exist. This can safely be called multiple times, but must hit the disk. Avoid calling this if you’re certain the directories exist.



44
45
46
47
48
49
# File 'lib/maildir.rb', line 44

def create_directories
  SUBDIRS.each do |subdir|
    subdir_path = File.join(path, subdir.to_s)
    FileUtils.mkdir_p(subdir_path)
  end
end

#delete(key) ⇒ Object

Deletes the message for key by calling destroy() on the message.



100
101
102
# File 'lib/maildir.rb', line 100

def delete(key)
  get(key).destroy
end

#find(unique_name) ⇒ Object

Returns a message object for the given unique name. This allows retrieving messages where the flags may have changed, but obviously is slower than getting it by key.



91
92
93
94
95
96
97
# File 'lib/maildir.rb', line 91

def find(unique_name)
  get_dir_listing(:cur).each do |key|
    # NOTE: I used split(File::SEPARATOR) and split(':') here first,
    #       but when benchmarking it turned out this is 2 times faster.
    return get(key) if key.match(/cur\/(.*):.*$/)[1] == unique_name
  end
end

#get(key) ⇒ Object

Returns a message object for key



84
85
86
# File 'lib/maildir.rb', line 84

def get(key)
  Maildir::Message.new(self, key)
end

#get_stale_tmp(time = Time.now - 129600) ⇒ Object

Finds messages in the tmp folder that have not been modified since time. time defaults to 36 hours ago.



106
107
108
109
110
# File 'lib/maildir.rb', line 106

def get_stale_tmp(time = Time.now - 129600)
  list(:tmp).select do |message|
    (mtime = message.mtime) && mtime < time
  end
end

#inspectObject

Friendly inspect method



30
31
32
# File 'lib/maildir.rb', line 30

def inspect
  "#<#{self.class} path=#{@path}>"
end

#list(dir, options = {}) ⇒ Object

Returns an arry of messages from :new or :cur directory, sorted by key. If options is specified, returns only so many keys.

E.g.

maildir.list(:new) # => all new messages
maildir.list(:cur, :limit => 10) # => 10 oldest messages in cur


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/maildir.rb', line 57

def list(dir, options = {})
  unless SUBDIRS.include? dir.to_sym
    raise ArgumentError, "dir must be :new, :cur, or :tmp"
  end

  keys = get_dir_listing(dir)

  # Sort the keys (chronological order)
  # TODO: make sorting configurable
  keys.sort!

  # Apply the limit after sorting
  if limit = options[:limit]
    keys = keys[0,limit]
  end

  # Map keys to message objects
  keys.map{|key| get(key)}
end