Class: Redwood::IMAP
- Inherits:
-
Source
show all
- Defined in:
- lib/sup/imap.rb
Constant Summary
- SCAN_INTERVAL =
60
- RECOVERABLE_ERRORS =
upon these errors we'll try to rereconnect a few times
[ Errno::EPIPE, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError ]
Instance Attribute Summary (collapse)
Attributes inherited from Source
#cur_offset, #id, #uri
Class Method Summary
(collapse)
Instance Method Summary
(collapse)
Methods inherited from Source
#done?, #file_path, #is_source_for?, #reset!, #seek_to!, #to_s
Constructor Details
- (IMAP) initialize(uri, username, password, last_idate = nil, usual = true, archived = false, id = nil, labels = [])
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/sup/imap.rb', line 59
def initialize uri, username, password, last_idate=nil, usual=true, archived=false, id=nil, labels=[]
raise ArgumentError, "username and password must be specified" unless username && password
raise ArgumentError, "not an imap uri" unless uri =~ %r!imaps?://!
super uri, last_idate, usual, archived, id
@parsed_uri = URI(uri)
@username = username
@password = password
@imap = nil
@imap_state = {}
@ids = []
@last_scan = nil
@labels = ((labels || []) - LabelManager::RESERVED_LABELS).uniq.freeze
@say_id = nil
@mutex = Mutex.new
end
|
Instance Attribute Details
- (Object) password
Returns the value of attribute password
55
56
57
|
# File 'lib/sup/imap.rb', line 55
def password
@password
end
|
- (Object) username
Returns the value of attribute username
55
56
57
|
# File 'lib/sup/imap.rb', line 55
def username
@username
end
|
Class Method Details
+ (Object) suggest_labels_for(path)
77
78
79
|
# File 'lib/sup/imap.rb', line 77
def self.suggest_labels_for path
path =~ /([^\/]*inbox[^\/]*)/i ? [$1.downcase.intern] : []
end
|
Instance Method Details
is this necessary? TODO: remove maybe
93
|
# File 'lib/sup/imap.rb', line 93
def == o; o.is_a?(IMAP) && o.uri == self.uri && o.username == self.username; end
|
89
|
# File 'lib/sup/imap.rb', line 89
def check; end
|
136
137
138
139
|
# File 'lib/sup/imap.rb', line 136
def connect
return if @imap
safely { } end
|
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
# File 'lib/sup/imap.rb', line 164
def each
return unless start_offset
ids =
@mutex.synchronize do
unsynchronized_scan_mailbox
@ids
end
start = ids.index(cur_offset || start_offset) or raise OutOfSyncSourceError, "Unknown message id #{cur_offset || start_offset}."
start.upto(ids.length - 1) do |i|
id = ids[i]
state = @mutex.synchronize { @imap_state[id] } or next
self.cur_offset = id
labels = { :Flagged => :starred,
:Deleted => :deleted
}.inject(@labels) do |cur, (imap, sup)|
cur + (state[:flags].include?(imap) ? [sup] : [])
end
labels += [:unread] unless state[:flags].include?(:Seen)
yield id, labels
end
end
|
- (Object) each_raw_message_line(id)
103
104
105
|
# File 'lib/sup/imap.rb', line 103
def each_raw_message_line id
StringIO.new(raw_message(id)).each { |l| yield l }
end
|
- (Object) end_offset
197
198
199
200
|
# File 'lib/sup/imap.rb', line 197
def end_offset
unsynchronized_scan_mailbox
@ids.last + 1
end
|
129
130
131
132
133
|
# File 'lib/sup/imap.rb', line 129
def expunge
@imap.expunge
unsynchronized_scan_mailbox true
true
end
|
81
|
# File 'lib/sup/imap.rb', line 81
def host; @parsed_uri.host; end
|
95
96
97
|
# File 'lib/sup/imap.rb', line 95
def id
MBox:: StringIO.new((id))
end
|
- (Object) load_message(id)
99
100
101
|
# File 'lib/sup/imap.rb', line 99
def load_message id
RMail::Parser.read raw_message(id)
end
|
83
84
85
86
|
# File 'lib/sup/imap.rb', line 83
def mailbox
x = @parsed_uri.path[1..-1]
(x.nil? || x.empty?) ? 'INBOX' : CGI.unescape(x)
end
|
- (Object) mark_as_deleted(ids)
120
121
122
123
124
125
126
|
# File 'lib/sup/imap.rb', line 120
def mark_as_deleted ids
ids = [ids].flatten unsynchronized_scan_mailbox
imap_ids = ids.map { |i| @imap_state[i] && @imap_state[i][:id] }.compact
return if imap_ids.empty?
@imap.store imap_ids, "+FLAGS", [:Deleted]
end
|
- (Object) pct_done
203
|
# File 'lib/sup/imap.rb', line 203
def pct_done; 100.0 * (@ids.index(cur_offset) || 0).to_f / (@ids.length - 1).to_f; end
|
82
|
# File 'lib/sup/imap.rb', line 82
def port; @parsed_uri.port || (ssl? ? 993 : 143); end
|
107
108
109
110
111
|
# File 'lib/sup/imap.rb', line 107
def id
unsynchronized_scan_mailbox
, flags = get_imap_fields id, 'RFC822.HEADER'
.gsub(/\r\n/, "\n")
end
|
- (Object) raw_message(id)
114
115
116
117
|
# File 'lib/sup/imap.rb', line 114
def raw_message id
unsynchronized_scan_mailbox
get_imap_fields(id, 'RFC822').first.gsub(/\r\n/, "\n")
end
|
- (Object) scan_mailbox(force = false)
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/sup/imap.rb', line 142
def scan_mailbox force=false
return if !force && @last_scan && (Time.now - @last_scan) < SCAN_INTERVAL
last_id = safely do
@imap.examine mailbox
@imap.responses["EXISTS"].last
end
@last_scan = Time.now
@ids = [] if force
return if last_id == @ids.length
range = (@ids.length + 1) .. last_id
Redwood::log "fetching IMAP headers #{range}"
fetch(range, ['RFC822.SIZE', 'INTERNALDATE', 'FLAGS']).each do |v|
id = make_id v
@ids << id
@imap_state[id] = { :id => v.seqno, :flags => v.attr["FLAGS"] }
end
Redwood::log "done fetching IMAP headers"
end
|
- (Boolean) ssl?
87
|
# File 'lib/sup/imap.rb', line 87
def ssl?; @parsed_uri.scheme == 'imaps' end
|
- (Object) start_offset
191
192
193
194
|
# File 'lib/sup/imap.rb', line 191
def start_offset
unsynchronized_scan_mailbox
@ids.first
end
|