Class: EyeMap::Folder

Inherits:
Object
  • Object
show all
Defined in:
lib/eyemap/folder.rb

Direct Known Subclasses

Courier, Dovecot

Defined Under Namespace

Classes: Courier, Dovecot

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(folder_name, driver, delimiter, properties = { }) ⇒ Folder

Constructor. Inheriting drivers must implement this interface.



12
13
14
15
16
17
18
# File 'lib/eyemap/folder.rb', line 12

def initialize(folder_name, driver, delimiter, properties={ })
    @driver = driver
    @folder_name = (folder_name and folder_name.length > 0) ? folder_name : "INBOX"
    @folder_name.freeze
    @delimiter = delimiter
    @properties = properties || Hash.new
end

Instance Attribute Details

#delimiterObject (readonly)

Returns the value of attribute delimiter.



6
7
8
# File 'lib/eyemap/folder.rb', line 6

def delimiter
  @delimiter
end

#driverObject (readonly)

Returns the value of attribute driver.



5
6
7
# File 'lib/eyemap/folder.rb', line 5

def driver
  @driver
end

#folder_nameObject (readonly)

Returns the value of attribute folder_name.



4
5
6
# File 'lib/eyemap/folder.rb', line 4

def folder_name
  @folder_name
end

#propertiesObject (readonly)

Returns the value of attribute properties.



3
4
5
# File 'lib/eyemap/folder.rb', line 3

def properties
  @properties
end

Instance Method Details

#add_message(message_text) ⇒ Object

Add a new message to this folder.

Our message in this case is just a block of text. This does not use a message object.



206
207
208
209
# File 'lib/eyemap/folder.rb', line 206

def add_message(message_text)
    @driver.conn.append(@folder_name, message_text.gsub(/[^\r]\n/, "\r\n"),
                        [], Time.now)
end

#create(folder_name) ⇒ Object

Creates a new folder underneath this one with the name specified.

It will prepend the current folder information and the delimiter to the folder name passed.



186
187
188
189
190
# File 'lib/eyemap/folder.rb', line 186

def create(folder_name)
    new_folder = @folder_name + @delimiter + folder_name
    @driver.conn.create(new_folder)
    self.class.new(new_folder, @driver, @delimiter)
end

#deleteObject

Delete this folder.



196
197
198
# File 'lib/eyemap/folder.rb', line 196

def delete
    @driver.conn.delete(@folder_name)
end

#expungeObject

Permanently deletes all messages marked with the :Deleted flag



174
175
176
177
# File 'lib/eyemap/folder.rb', line 174

def expunge
    @driver.conn.examine(@folder_name)
    @driver.conn.expunge()
end

#find_message(message_id) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/eyemap/folder.rb', line 88

def find_message(message_id)
    @driver.conn.examine(@folder_name)

    if ! message_id.kind_of? Numeric
        raise EyeMap::Exception::BadCall.new("Message ID must be numeric")
    end

    messages = @driver.conn.fetch(message_id, "UID")
    uid = nil

    uid = messages[0].attr["UID"] if messages[0]

    return @driver[:message_class].new(uid, @folder_name, @driver) if uid

    return nil
end

#find_messages(message_ids = nil) ⇒ Object

Search through a range of message ids (or an array of them).

pass ‘nil’ to search for all messages (the default)



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/eyemap/folder.rb', line 111

def find_messages(message_ids=nil)
    # this next line of code would be great for AOP
    @driver.conn.examine(@folder_name)
    messages = []

    if message_ids.kind_of? Range
        query = "#{message_ids.first}:#{message_ids.last}"
    elsif message_ids.kind_of? Array
        query = message_ids.join(",")
    elsif ! message_ids
        query = "ALL"
    elsif message_ids.kind_of? Numeric
        return [find_message(message_ids)]
    else
        raise EyeMap::Exception::BadCall.new("Invalid query parameters")
    end

    @driver.conn.uid_search([query]).each do |uid|
        messages.push(@driver[:message_class].
                      new(uid, @folder_name, @driver))
    end

    return messages

end

#folder(folder_name) ⇒ Object

Get a specific folder underneath this one.



24
25
26
27
28
# File 'lib/eyemap/folder.rb', line 24

def folder(folder_name)
    self.class.new(@folder_name + @delimiter + folder_name,
                   @driver,
                   @delimiter)
end

#folder_treeObject

Returns all the folders below this folder in a series of ::Folder objects.



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/eyemap/folder.rb', line 63

def folder_tree
    skel = { :folder => nil, :children => [] }
    retval = []
    subfolders.each do |sub|
        folder = skel.dup
        folder[:folder] = sub
        folder[:children] = folder[:folder].folder_tree
        retval.push(folder)
    end

    return retval
end

#paginate_headers(page, num_per_page = 10) ⇒ Object

Get a list of valid messages for the current folder, that contain the number of items per page and reflect the current “page” for that inbox: page = (num_per_page * 10) - 9 -> (num_per_page * 10). The reason for this is that IMAP message id’s start with 1.



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/eyemap/folder.rb', line 144

def paginate_headers(page, num_per_page=10)
    @driver.conn.examine(@folder_name)
    uids = @driver.conn.uid_search(["ALL"])

    # get out now if we don't have any messages.
    unless uids and uids.length > 0
        return []
    end

    # for our query, the high and low mid's, respective to the array.
    low_mid  = (page * num_per_page) - (num_per_page - 1)
    high_mid = page * num_per_page

    # no messages this high
    if uids[low_mid].nil?
        return []
    end

    if uids[high_mid].nil?
        high_mid = -1
    end

    return uids[low_mid..high_mid]

end

#recentObject



80
81
82
# File 'lib/eyemap/folder.rb', line 80

def recent
    @driver.conn.status(@folder_name, ["RECENT"])["RECENT"]
end

#short_nameObject

return the ‘short name’ of the folder - the name of the folder without anything “lower” than the delimiter (including the delimiter itself).



34
35
36
# File 'lib/eyemap/folder.rb', line 34

def short_name
    return @folder_name.sub(/.*?([^#{@delimiter}]+)$/, '\1')
end

#subfoldersObject

Get the list of subfolders for this folder.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/eyemap/folder.rb', line 42

def subfolders
    list = @driver.conn.list(@folder_name, "%")

    retval = []

    if list
        list.each do |f|
            retval.push(@driver[:folder_class].
                        new(f.name, @driver, f.delim,
                            # deep copy
                            Marshal.load(Marshal.dump(f.attr))))
        end
    end

    return retval
end

#totalObject



76
77
78
# File 'lib/eyemap/folder.rb', line 76

def total
    @driver.conn.status(@folder_name, ["MESSAGES"])["MESSAGES"]
end

#unseenObject



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

def unseen
    @driver.conn.status(@folder_name, ["UNSEEN"])["UNSEEN"]
end