class IMAPGet
Constants
- DEFAULT_BATCH_SIZE
- DEFAULT_DELIMITER
- DEFAULT_LOG_LEVEL
- DEFAULT_STRATEGY
- FETCH_ATTR
- VERSION
Attributes
batch_size[RW]
excl[R]
imap[R]
incl[R]
log_level[RW]
strategy[R]
Public Class Methods
new(options)
click to toggle source
# File lib/imapget.rb 48 def initialize(options) 49 @batch_size = options.fetch(:batch_size, DEFAULT_BATCH_SIZE) 50 @log_level = options.fetch(:log_level, DEFAULT_LOG_LEVEL) 51 52 @imap = Net::IMAP.new(options[:host], options) 53 @imap.starttls(options[:starttls]) if options[:starttls] 54 55 authenticate(options) 56 inclexcl(options) 57 end
Public Instance Methods
delete!(name, uids) { || ... }
click to toggle source
# File lib/imapget.rb 141 def delete!(name, uids) 142 return if uids.empty? 143 144 log "#{name}: #{uids.size}" 145 146 yield if block_given? 147 148 imap.select(name) 149 150 imap.store(uids, '+FLAGS', [Net::IMAP::DELETED]).size.tap { |count| 151 log "#{count} DELETED!" 152 } 153 end
dupes(name, quiet = false)
click to toggle source
# File lib/imapget.rb 125 def dupes(name, quiet = false) 126 imap.examine(name) 127 128 hash = Hash.zipkey { |h, k| h[k] = [] } 129 130 1.step(size(name), step = batch_size) { |i| 131 fetch_batch([[i, step]]) { |mail| 132 hash[mail.attr['RFC822']] << mail.attr['UID'] unless deleted?(mail) 133 } 134 } 135 136 hash.flat_map { |_, uids| uids.drop(1) if uids.size > 1 }.tap { |dupes| 137 dupes.compact!; log "#{name}: #{dupes.size}" unless quiet 138 } 139 end
each() { |mailbox| ... }
click to toggle source
# File lib/imapget.rb 78 def each 79 mailboxes.each { |mailbox| yield mailbox if include?(mailbox) } 80 end
exclude?(mailbox)
click to toggle source
# File lib/imapget.rb 86 def exclude?(mailbox) 87 name = case mailbox 88 when String then mailbox 89 when Net::IMAP::MailboxList then mailbox.name 90 else raise TypeError, "MailboxList or String expected, got #{mailbox.class}" 91 end 92 93 _excl = excl && name =~ excl 94 _incl = incl && name =~ incl 95 96 case strategy 97 when :include then _excl || !_incl 98 when :exclude then _excl && !_incl 99 end 100 end
get(dir)
click to toggle source
# File lib/imapget.rb 102 def get(dir) 103 each { |mailbox| get_name(name = mailbox.name, 104 File.join(dir, Net::IMAP.decode_utf7(name))) } 105 end
Also aliased as: download
get_name(name, dir)
click to toggle source
# File lib/imapget.rb 109 def get_name(name, dir) 110 log "#{'=' * 10} #{name} #{'=' * 10}" 111 112 imap.examine(name) 113 114 imap.uid_search("SINCE #{mtime(dir)}").each_slice(batch_size) { |batch| 115 fetch_batch(batch) { |mail| fetch(mail, dir, name) } 116 } 117 end
Also aliased as: download_name
inclexcl(options)
click to toggle source
# File lib/imapget.rb 59 def inclexcl(options) 60 delim = Regexp.escape(options.fetch(:delim, DEFAULT_DELIMITER)) 61 62 %w[include exclude].each { |key| 63 instance_variable_set("@#{key[0, 4]}", case value = options[key.to_sym] 64 when String then Regexp.new(value) 65 when Array then Regexp.new(value.map { |v| 66 "\\A#{Regexp.escape(Net::IMAP.encode_utf7(v))}(?:#{delim}|\\z)" 67 }.join('|')) 68 end) 69 } 70 71 @strategy = options.fetch(:strategy, DEFAULT_STRATEGY).to_sym 72 end
include?(mailbox)
click to toggle source
# File lib/imapget.rb 82 def include?(mailbox) 83 !exclude?(mailbox) 84 end
mailboxes()
click to toggle source
# File lib/imapget.rb 74 def mailboxes 75 @mailboxes ||= imap.list('', '*').sort_by(&:name) 76 end
size(name, attr = 'MESSAGES')
click to toggle source
# File lib/imapget.rb 121 def size(name, attr = 'MESSAGES') 122 imap.status(name, [attr]).values.first 123 end
uniq!(name, &block)
click to toggle source
# File lib/imapget.rb 155 def uniq!(name, &block) 156 delete!(name, dupes(name, true), &block) 157 end
Private Instance Methods
authenticate(options)
click to toggle source
# File lib/imapget.rb 161 def authenticate(options) 162 if auth = options.fetch(:auth) { 163 imap.capability.grep(/\AAUTH=(.*)/) { $1 }.first 164 } 165 imap.authenticate(auth, options[:user], options[:password]) 166 else 167 imap.login(options[:user], options[:password]) 168 end 169 end
deleted?(mail)
click to toggle source
# File lib/imapget.rb 203 def deleted?(mail) 204 mail.attr['FLAGS'].include?(Net::IMAP::DELETED) 205 end
fetch(mail, dir, name)
click to toggle source
# File lib/imapget.rb 183 def fetch(mail, dir, name) 184 uid = mail.attr['UID'].to_s 185 file = File.join(dir, uid) 186 exists = File.exist?(file) 187 188 if deleted?(mail) 189 if exists 190 info "#{dir}: #{name} <- #{uid}" 191 File.unlink(file) 192 end 193 else 194 date = mail.attr['INTERNALDATE'] 195 196 unless exists && date && File.mtime(file) >= Time.parse(date) 197 info "#{dir}: #{name} -> #{uid}" 198 File.write(file, mail.attr['RFC822']) 199 end 200 end 201 end
fetch_batch(batch, fetch_attr = FETCH_ATTR, &block)
click to toggle source
# File lib/imapget.rb 171 def fetch_batch(batch, fetch_attr = FETCH_ATTR, &block) 172 case set = batch.first 173 when Array 174 batch = set.first .. (set.first + set.last - 1) 175 when Range 176 batch = set.first .. (set.last - 1) if set.exclude_end? 177 end if batch.size == 1 178 179 mails = imap.uid_fetch(batch, fetch_attr) 180 mails.each(&block) if mails 181 end
info(msg)
click to toggle source
# File lib/imapget.rb 216 def info(msg) 217 log(msg, 2) 218 end
log(msg, level = 1)
click to toggle source
# File lib/imapget.rb 212 def log(msg, level = 1) 213 warn msg if log_level >= level 214 end
mtime(dir)
click to toggle source
# File lib/imapget.rb 207 def mtime(dir) 208 Net::IMAP.format_date((File.directory?(dir) ? 209 File.mtime(dir) : (FileUtils.mkdir_p(dir); Time.at(0))).utc) 210 end