Class: Imapcli::Mailbox

Inherits:
Object
  • Object
show all
Defined in:
lib/imapcli/mailbox.rb

Overview

In IMAP speak, a mailbox is what one would commonly call a ‘folder’

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mailbox_list_items = nil, options = {}) ⇒ Mailbox

Creates a new root Mailbox object and optionally adds sub mailboxes from an array of Net::IMAP::MailboxList items.



11
12
13
14
15
16
# File 'lib/imapcli/mailbox.rb', line 11

def initialize(mailbox_list_items = nil, options = {})
  @level = 0
  @children = {}
  @options = options
  add_mailbox_list(mailbox_list_items) if mailbox_list_items
end

Instance Attribute Details

#imap_mailbox_listObject (readonly)

Returns the value of attribute imap_mailbox_list.



7
8
9
# File 'lib/imapcli/mailbox.rb', line 7

def imap_mailbox_list
  @imap_mailbox_list
end

#levelObject

Returns the value of attribute level.



7
8
9
# File 'lib/imapcli/mailbox.rb', line 7

def level
  @level
end

#nameObject

Returns the value of attribute name.



7
8
9
# File 'lib/imapcli/mailbox.rb', line 7

def name
  @name
end

#optionsObject

rubocop:disable Metrics/ClassLength



6
7
8
# File 'lib/imapcli/mailbox.rb', line 6

def options
  @options
end

#statsObject (readonly)

Returns the value of attribute stats.



7
8
9
# File 'lib/imapcli/mailbox.rb', line 7

def stats
  @stats
end

Class Method Details

.consolidate(list) ⇒ Object

Consolidates a list of mailboxes: If a mailbox is a sub-mailbox of another one, the mailbox is removed from the list.

Parameters:

  • list (Array)

    of mailboxes



140
141
142
143
144
# File 'lib/imapcli/mailbox.rb', line 140

def self.consolidate(list)
  list.reject do |mailbox|
    list.any? { |parent| parent.contains? mailbox }
  end.uniq
end

Instance Method Details

#[](mailbox) ⇒ Object



18
19
20
# File 'lib/imapcli/mailbox.rb', line 18

def [](mailbox)
  @children[mailbox]
end

#add_mailbox(imap_mailbox_list) ⇒ Object

Adds a sub mailbox designated by the name of a Net::IMAP::MailboxList.



71
72
73
74
75
# File 'lib/imapcli/mailbox.rb', line 71

def add_mailbox(imap_mailbox_list)
  return unless imap_mailbox_list&.name&.length&.> 0

  recursive_add(0, imap_mailbox_list, imap_mailbox_list.name)
end

#add_mailbox_list(array_of_mailbox_list_items) ⇒ Object

Add a list of mailboxes as returned by Net::IMAP#list.



66
67
68
# File 'lib/imapcli/mailbox.rb', line 66

def add_mailbox_list(array_of_mailbox_list_items)
  array_of_mailbox_list_items.sort_by { |m| m.name.downcase }.each { |i| add_mailbox i }
end

#childrenObject



61
62
63
# File 'lib/imapcli/mailbox.rb', line 61

def children
  @children.values
end

#children?Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/imapcli/mailbox.rb', line 57

def children?
  !@children.empty?
end

#collect_stats(client, max_level = nil) {|@stats| ... } ⇒ Object

Collects statistics for this mailbox and the subordinate mailboxes up to a given level.

If level is nil, all sub mailboxes are analyzed as well.

If a block is given, it is called with the Imapcli::Stats object for this mailbox.

Yields:



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/imapcli/mailbox.rb', line 109

def collect_stats(client, max_level = nil, &block)
  return if @stats

  @stats = Stats.new(client.message_sizes(full_name)) if full_name # proceed only if this is a mailbox of its own
  yield @stats if block_given?
  return unless max_level.nil? || level < max_level

  @children.each_value do |child|
    child.collect_stats(client, max_level, &block)
  end
end

#contains?(other_mailbox) ⇒ Boolean

Returns true if this mailbox contains a given other mailbox.

Returns:

  • (Boolean)


78
79
80
81
82
# File 'lib/imapcli/mailbox.rb', line 78

def contains?(other_mailbox)
  @children.values.any? do |child|
    child == other_mailbox || child.contains?(other_mailbox)
  end
end

#count(max_level = nil) ⇒ Object

Counts all sub mailboxes recursively.

The result includes the current mailbox.



35
36
37
38
39
40
41
42
# File 'lib/imapcli/mailbox.rb', line 35

def count(max_level = nil)
  sum = 1
  return unless max_level.nil? || level < max_level

  @children.values.inject(sum) do |count, child|
    count + child.count(max_level)
  end
end

#find_sub_mailbox(relative_name, delimiter) ⇒ Object

Attempts to locate and retrieve a sub mailbox.

Returns nil of none exists with the given name. Name must be relative to the current mailbox.



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/imapcli/mailbox.rb', line 88

def find_sub_mailbox(relative_name, delimiter) # rubocop:disable Metrics/MethodLength
  if relative_name
    sub_mailbox_name, subs_subs = relative_name.split(delimiter, 2)
    key = normalize_key(sub_mailbox_name, level)
    if (sub_mailbox = @children[key])
      sub_mailbox.find_sub_mailbox(subs_subs, delimiter)
    else # rubocop:disable Style/EmptyElse
      nil # no matching sub mailbox found, stop searching the tree
    end
  else
    self
  end
end

#full_nameObject



53
54
55
# File 'lib/imapcli/mailbox.rb', line 53

def full_name
  imap_mailbox_list&.name
end

#imap_mailbox?Boolean

Determines if this mailbox represents a dedicated IMAP mailbox with an associated Net::IMAP::MailboxList structure.

Returns:

  • (Boolean)


24
25
26
# File 'lib/imapcli/mailbox.rb', line 24

def imap_mailbox?
  !imap_mailbox_list.nil?
end

#max_levelObject

Determines the maximum level in the mailbox tree



45
46
47
48
49
50
51
# File 'lib/imapcli/mailbox.rb', line 45

def max_level
  if children?
    @children.values.map(&:max_level).max
  else
    level
  end
end

#root?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/imapcli/mailbox.rb', line 28

def root?
  name.respond_to?(:empty?) ? !!name.empty? : !name
end

#to_list(max_level = nil) ⇒ Object

Converts the mailbox tree to a flat list.

Mailbox objects that do not represent IMAP mailboxes (such as the root mailbox) are not included.



125
126
127
128
129
130
131
132
133
134
# File 'lib/imapcli/mailbox.rb', line 125

def to_list(max_level = nil)
  me = imap_mailbox? ? [self] : []
  if max_level.nil? || level < max_level
    @children.values.inject(me) do |ary, child|
      ary + child.to_list(max_level)
    end.sort_by(&:full_name)
  else
    me
  end
end