Class: Redwood::IMAP
Constant Summary
collapse
- 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, #usual
Constructor Details
#initialize(uri, username, password, last_idate = nil, usual = true, archived = false, id = nil, labels = []) ⇒ IMAP
Returns a new instance of IMAP.
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/sup/imap.rb', line 56
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
Returns the value of attribute password.
52
53
54
|
# File 'lib/sup/imap.rb', line 52
def password
@password
end
|
Returns the value of attribute username.
52
53
54
|
# File 'lib/sup/imap.rb', line 52
def username
@username
end
|
Class Method Details
.suggest_labels_for(path) ⇒ Object
74
75
76
77
78
79
80
|
# File 'lib/sup/imap.rb', line 74
def self.suggest_labels_for path
if path =~ /inbox/i
[path.intern]
else
[]
end
end
|
Instance Method Details
is this necessary? TODO: remove maybe
94
|
# File 'lib/sup/imap.rb', line 94
def == o; o.is_a?(IMAP) && o.uri == self.uri && o.username == self.username; end
|
90
|
# File 'lib/sup/imap.rb', line 90
def check; end
|
121
122
123
124
|
# File 'lib/sup/imap.rb', line 121
def connect
return if @imap
safely { }
end
|
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
# File 'lib/sup/imap.rb', line 147
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
|
#each_raw_message_line(id) ⇒ Object
104
105
106
|
# File 'lib/sup/imap.rb', line 104
def each_raw_message_line id
StringIO.new(raw_message(id)).each { |l| yield l }
end
|
#end_offset ⇒ Object
180
181
182
183
|
# File 'lib/sup/imap.rb', line 180
def end_offset
unsynchronized_scan_mailbox
@ids.last
end
|
82
|
# File 'lib/sup/imap.rb', line 82
def host; @parsed_uri.host; end
|
96
97
98
|
# File 'lib/sup/imap.rb', line 96
def id
MBox:: StringIO.new((id))
end
|
#load_message(id) ⇒ Object
100
101
102
|
# File 'lib/sup/imap.rb', line 100
def load_message id
RMail::Parser.read raw_message(id)
end
|
84
85
86
87
|
# File 'lib/sup/imap.rb', line 84
def mailbox
x = @parsed_uri.path[1..-1]
(x.nil? || x.empty?) ? 'INBOX' : CGI.unescape(x)
end
|
186
|
# File 'lib/sup/imap.rb', line 186
def pct_done; 100.0 * (@ids.index(cur_offset) || 0).to_f / (@ids.length - 1).to_f; end
|
83
|
# File 'lib/sup/imap.rb', line 83
def port; @parsed_uri.port || (ssl? ? 993 : 143); end
|
108
109
110
111
112
|
# File 'lib/sup/imap.rb', line 108
def id
unsynchronized_scan_mailbox
, flags = get_imap_fields id, 'RFC822.HEADER'
.gsub(/\r\n/, "\n")
end
|
#raw_message(id) ⇒ Object
115
116
117
118
|
# File 'lib/sup/imap.rb', line 115
def raw_message id
unsynchronized_scan_mailbox
get_imap_fields(id, 'RFC822').first.gsub(/\r\n/, "\n")
end
|
#scan_mailbox ⇒ Object
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
# File 'lib/sup/imap.rb', line 127
def scan_mailbox
return if @last_scan && (Time.now - @last_scan) < SCAN_INTERVAL
last_id = safely do
@imap.examine mailbox
@imap.responses["EXISTS"].last
end
@last_scan = Time.now
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
end
|
#ssl? ⇒ Boolean
88
|
# File 'lib/sup/imap.rb', line 88
def ssl?; @parsed_uri.scheme == 'imaps' end
|
#start_offset ⇒ Object
174
175
176
177
|
# File 'lib/sup/imap.rb', line 174
def start_offset
unsynchronized_scan_mailbox
@ids.first
end
|