class Maildir::Message

Constants

COLON

COLON seperates the unique name from the info

FLAG_NAMES
INFO

The default info, to which flags are appended

Attributes

dir[R]
info[R]
unique_name[R]

Public Class Methods

create(maildir, data) click to toggle source

Create a new message in maildir with data. The message is first written to the tmp dir, then moved to new. This is a shortcut for:

message = Maildir::Message.new(maildir)
message.write(data)
# File lib/maildir/message.rb, line 14
def self.create(maildir, data)
  message = self.new(maildir)
  message.write(data)
  message
end
new(maildir, key=nil) click to toggle source

Create a new, unwritten message or instantiate an existing message. If key is nil, create a new message:

Message.new(maildir) # => a new, unwritten message

If key is not nil, instantiate a message object for the message at key.

Message.new(maildir, key) # => an existing message
# File lib/maildir/message.rb, line 41
def initialize(maildir, key=nil)
  @maildir = maildir
  if key.nil?
    @dir = :tmp
    @unique_name = Maildir::UniqueName.create
  else
    parse_key(key)
  end

  unless Maildir::SUBDIRS.include? dir
    raise ArgumentError, "State must be in #{Maildir::SUBDIRS.inspect}"
  end
end
serializer() click to toggle source

DEPRECATED: Get the serializer. @see Maildir.serializer

# File lib/maildir/message.rb, line 22
def self.serializer
  Maildir.serializer
end
serializer=(serializer) click to toggle source

DEPRECATED: Set the serializer. @see Maildir.serializer=

# File lib/maildir/message.rb, line 28
def self.serializer=(serializer)
  Maildir.serializer = serializer
end

Public Instance Methods

<=>(message) click to toggle source

Compares messages by their paths. If message is a different class, return nil. Otherwise, return 1, 0, or -1.

# File lib/maildir/message.rb, line 58
def <=>(message)
  # Return nil if comparing different classes
  return nil unless self.class === message

  self.path <=> message.path
end
add_flag(flag) click to toggle source

Adds a flag to a message. Returns the message's key if successful, false otherwise.

# File lib/maildir/message.rb, line 133
def add_flag(flag)
  self.flags = (flags << flag.upcase)
end
atime() click to toggle source

Returns the message's atime, or false if the file doesn't exist.

# File lib/maildir/message.rb, line 174
def atime
  guard { File.atime(path) }
end
data() click to toggle source

Returns the message's data from disk. If the path doesn't exist, freeze's the object and raises Errno:ENOENT

# File lib/maildir/message.rb, line 163
def data
  guard(true) { serializer.load(path) }
end
destroy() click to toggle source

Deletes the message path and freezes the message object. Returns 1 if the file was destroyed, false if the file was missings.

# File lib/maildir/message.rb, line 185
def destroy
  freeze
  guard { File.delete(path) }
end
filename() click to toggle source

Returns the filename of the message

# File lib/maildir/message.rb, line 147
def filename
  [unique_name, info].compact.join(COLON)
end
flags() click to toggle source

Returns an array of single letter flags applied to the message

# File lib/maildir/message.rb, line 121
def flags
  @info.to_s.sub(INFO,'').split(//)
end
flags=(*flags) click to toggle source

Sets the flags on a message. Returns the message's key if successful, false otherwise.

# File lib/maildir/message.rb, line 127
def flags=(*flags)
  self.info = INFO + sort_flags(flags.flatten.join(''))
end
info=(info) click to toggle source

Set info on a message. Returns the message's key if successful, false otherwise.

# File lib/maildir/message.rb, line 97
def info=(info)
  raise "Can only set info on cur messages" unless :cur == @dir
  rename(:cur, info)
end
inspect() click to toggle source

Friendly inspect method

# File lib/maildir/message.rb, line 66
def inspect
  "#<#{self.class} key=#{key} maildir=#{@maildir.inspect}>"
end
key() click to toggle source

Returns the key to identify the message

# File lib/maildir/message.rb, line 152
def key
  File.join(dir.to_s, filename)
end
mtime() click to toggle source

Returns the message's mtime, or false if the file doesn't exist.

# File lib/maildir/message.rb, line 179
def mtime
  guard { File.mtime(path) }
end
path() click to toggle source

Returns the full path to the message

# File lib/maildir/message.rb, line 157
def path
  File.join(@maildir.path, key)
end
process() click to toggle source

Move a message from new to cur, add info. Returns the message's key

# File lib/maildir/message.rb, line 91
def process
  rename(:cur, INFO)
end
remove_flag(flags) click to toggle source

Removes flags from a message. Returns the message's key if successful, false otherwise.

flags

String or Array

# File lib/maildir/message.rb, line 141
def remove_flag(flags)
  return self.flags if flags.blank?
  self.flags = self.flags.reject { |f| f =~ /[#{Array(flags).join}]/ }
end
serializer() click to toggle source

Helper to get serializer.

# File lib/maildir/message.rb, line 71
def serializer
  @maildir.serializer
end
utime(atime, mtime) click to toggle source

Updates the modification and access time. Returns 1 if successful, false otherwise.

# File lib/maildir/message.rb, line 169
def utime(atime, mtime)
  guard { File.utime(atime, mtime, path) }
end
write(data) click to toggle source

Writes data to disk. Can only be called on messages instantiated without a key (which haven't been written to disk). After successfully writing to disk, rename the message to the new dir

Returns the message's key

# File lib/maildir/message.rb, line 80
def write(data)
  raise "Can only write to messages in tmp" unless :tmp == @dir

  # Write out contents to tmp
  serializer.dump(data, path)

  rename(:new)
end

Protected Instance Methods

guard(reraise = false) { || ... } click to toggle source

Guard access to the file system by rescuing Errno::ENOENT, which happens if the file is missing. When blocks fails and reraise is false, returns false, otherwise reraises Errno::ENOENT

# File lib/maildir/message.rb, line 195
def guard(reraise = false, &block)
  begin
    yield
  rescue Errno::ENOENT
    if @old_key
      # Restore ourselves to the old state
      parse_key(@old_key)
    end

    # Don't allow further modifications
    freeze

    reraise ? raise : false
  end
end
old_path() click to toggle source
# File lib/maildir/message.rb, line 223
def old_path
  File.join(@maildir.path, @old_key)
end
parse_key(key) click to toggle source

Sets dir, #unique_name, and info based on the key

# File lib/maildir/message.rb, line 212
def parse_key(key)
  @dir, filename = key.split(File::SEPARATOR)
  @dir = @dir.to_sym
  @unique_name, @info = filename.split(COLON)
end
rename(new_dir, new_info=nil) click to toggle source

Renames the message. Returns the new key if successful, false otherwise.

# File lib/maildir/message.rb, line 228
def rename(new_dir, new_info=nil)
  # Save the old key so we can revert to the old state
  @old_key = key

  # Set the new state
  @dir = new_dir
  @info = new_info if new_info

  guard do
    File.rename(old_path, path) unless old_path == path
    @old_key = nil # So guard() doesn't reset to a bad state
    return key
  end
end
sort_flags(flags) click to toggle source

Ensure the flags are uppercase and sorted

# File lib/maildir/message.rb, line 219
def sort_flags(flags)
  flags.split('').map{|f| f.upcase}.sort!.uniq.join('')
end