class RIMS::MailFolder

Constants

MessageStruct

Attributes

mbox_id[R]
read_only[R]
read_only?[R]

Public Class Methods

new(mbox_id, mail_store, read_only: false) click to toggle source
# File lib/rims/mail_store.rb, line 375
def initialize(mbox_id, mail_store, read_only: false)
  @mbox_id = mbox_id
  @mail_store = mail_store
  @read_only = read_only

  # late loding
  @cnum = nil
  @msg_list = nil
  @uid_map = nil
end
parse_msg_seq(msg_seq_desc, last_number) click to toggle source
# File lib/rims/mail_store.rb, line 541
def self.parse_msg_seq(msg_seq_desc, last_number)
  case (msg_seq_desc)
  when /\A (\d+|\*) \z/x
    msg_seq_pair = [ $&, $& ]
  when /\A (\d+|\*):(\d+|\*) \z/x
    msg_seq_pair = [ $1, $2 ]
  else
    raise MessageSetSyntaxError, "invalid message sequence format: #{msg_seq_desc}"
  end

  msg_seq_pair.map!{|num|
    case (num)
    when '*'
      last_number
    else
      n = num.to_i
      if (n < 1) then
        raise MessageSetSyntaxError, "out of range of message sequence number: #{msg_seq_desc}"
      end
      n
    end
  }

  Range.new(msg_seq_pair[0], msg_seq_pair[1])
end
parse_msg_set(msg_set_desc, last_number) click to toggle source
# File lib/rims/mail_store.rb, line 567
def self.parse_msg_set(msg_set_desc, last_number)
  msg_set = [].to_set
  msg_set_desc.split(/,/).each do |msg_seq_desc|
    msg_range = parse_msg_seq(msg_seq_desc, last_number)
    msg_range.step do |n|
      msg_set << n
    end
  end

  msg_set
end

Public Instance Methods

[](msg_idx) click to toggle source
# File lib/rims/mail_store.rb, line 430
def [](msg_idx)
  @msg_list[msg_idx]
end
alive?() click to toggle source
# File lib/rims/mail_store.rb, line 388
def alive?
  ! @mail_store.mbox_name(@mbox_id).nil?
end
attach(server_response_channel) click to toggle source
# File lib/rims/mail_store.rb, line 396
def attach(server_response_channel)
  @pub, @sub = server_response_channel.make_pub_sub_pair(@mbox_id)
  self
end
close(&block) click to toggle source
# File lib/rims/mail_store.rb, line 505
def close(&block)
  unless (@read_only) then
    expunge_mbox(&block)
    @mail_store.each_msg_uid(@mbox_id) do |msg_id|
      if (@mail_store.msg_flag(@mbox_id, msg_id, 'recent')) then
        @mail_store.set_msg_flag(@mbox_id, msg_id, 'recent', false)
      end
    end
  end
  @cnum = nil
  @msg_list = nil
  @uid_map = nil
  self
end
detach() click to toggle source
# File lib/rims/mail_store.rb, line 520
def detach
  @mail_store = nil
  @pub.detach
  @sub.detach
  self
end
each_msg() { |msg| ... } click to toggle source
# File lib/rims/mail_store.rb, line 434
def each_msg
  return enum_for(:each_msg) unless block_given?
  for msg in @msg_list
    yield(msg)
  end
  self
end
expunge_mbox() { |num| ... } click to toggle source
# File lib/rims/mail_store.rb, line 475
def expunge_mbox
  if (@mail_store.mbox_flag_num(@mbox_id, 'deleted') > 0) then
    if (block_given?) then
      uid2num = {}
      for msg in @msg_list
        uid2num[msg.uid] = msg.num
      end

      msg_num_list = []
      @mail_store.expunge_mbox(@mbox_id) do |uid|
        num = uid2num[uid] or raise "internal error: not found a message: #{@mbox_id},#{uid}"
        msg_num_list << num
      end

      # to prevent to decrement message sequence numbers that
      # appear in a set of successive expunge responses, expunge
      # command should early return an expunge response of larger
      # message sequence number.
      msg_num_list.sort!
      msg_num_list.reverse_each do |num|
        yield(num)
      end
    else
      @mail_store.expunge_mbox(@mbox_id)
    end
  end

  self
end
msg_find_all(msg_set, uid: false) click to toggle source
# File lib/rims/mail_store.rb, line 442
def msg_find_all(msg_set, uid: false)
  if (msg_set.size < @msg_list.length) then
    if (uid) then
      msg_set.inject([]) {|msg_list, id|
        if (msg = @uid_map[id]) then
          msg_list << msg
        end
        msg_list
      }
    else
      msg_set.inject([]) {|msg_list, num|
        if (1 <= num && num <= @msg_list.length) then
          msg_list << @msg_list[num - 1]
        end
        msg_list
      }
    end
  else
    if (uid) then
      @msg_list.find_all{|msg|
        msg_set.include? msg.uid
      }
    else
      @msg_list.find_all{|msg|
        msg_set.include? msg.num
      }
    end
  end
end
parse_msg_set(msg_set_desc, uid: false) click to toggle source
# File lib/rims/mail_store.rb, line 527
def parse_msg_set(msg_set_desc, uid: false)
  if (@msg_list.empty?) then
    last_number = 0
  else
    if (uid) then
      last_number = @msg_list[-1].uid
    else
      last_number = @msg_list[-1].num
    end
  end

  self.class.parse_msg_set(msg_set_desc, last_number)
end
reload() click to toggle source
# File lib/rims/mail_store.rb, line 407
def reload
  @cnum = @mail_store.cnum

  msg_id_list = @mail_store.each_msg_uid(@mbox_id).to_a
  msg_id_list.sort!

  @msg_list = Array.new(msg_id_list.length)
  @uid_map = {}

  msg_id_list.each_with_index do |id, i|
    num = i.succ
    msg = MessageStruct.new(id, num)
    @msg_list[i] = msg
    @uid_map[id] = msg
  end

  self
end
should_be_alive() click to toggle source
# File lib/rims/mail_store.rb, line 392
def should_be_alive
  alive? or raise "deleted folder: #{@mbox_id}"
end
updated?() click to toggle source
# File lib/rims/mail_store.rb, line 426
def updated?
  @mail_store.cnum != @cnum
end