Class: Imapcli::Client
- Inherits:
-
Object
- Object
- Imapcli::Client
- Defined in:
- lib/imapcli/client.rb
Overview
Wrapper for Net::IMAP
Instance Attribute Summary collapse
-
#pass ⇒ Object
rubocop:disable Metrics/ClassLength.
-
#port ⇒ Object
rubocop:disable Metrics/ClassLength.
-
#server ⇒ Object
Attribute reader for the server domain name.
-
#user ⇒ Object
rubocop:disable Metrics/ClassLength.
Instance Method Summary collapse
-
#capability ⇒ Object
Returns the server’s capabilities.
-
#clear_responses ⇒ Object
Clears the server response log.
-
#collect_stats ⇒ Object
Collects stats for all mailboxes recursively.
-
#connection ⇒ Object
Returns a connection to the server.
-
#find_mailbox(mailbox) ⇒ Object
Attempts to locate a given
mailboxin themailbox_root. -
#greeting ⇒ Object
Returns the server’s greeting (which may reveal the server software name such as ‘Dovecot’).
-
#initialize(server_with_optional_port, user, pass) ⇒ Client
constructor
Initializs the Client class.
-
#last_response ⇒ Object
Returns the last response from the server.
-
#login ⇒ Object
Logs in to the server.
-
#logout ⇒ Object
Logs out of the server.
-
#mailbox_root ⇒ Object
Returns a tree of
Imapcli::Mailboxobjects. -
#mailboxes ⇒ Object
Gets a list of Net::IMAP::MailboxList items, one for each mailbox.
-
#message_sizes(mailbox) ⇒ Object
Examines a mailbox and returns statistics about the messages in it.
-
#messages(mailbox) ⇒ Object
Returns an array of message indexes for a mailbox.
-
#quota ⇒ Object
If the server
supports_quota, returns an array containing the current usage (in kiB), the total quota (in kiB), and the percent usage. -
#responses ⇒ Object
Returns the IMAP server response log.
-
#separator ⇒ Object
Returns the character that is used to separate nested mailbox names.
-
#server_valid? ⇒ Boolean
Perform basic sanity check on server name.
-
#supports_quota ⇒ Object
Returns true if the server supports the IMAP QUOTA extension.
-
#user_valid? ⇒ Boolean
Perform very basic sanity check on user name.
-
#valid? ⇒ Boolean
Returns true if both server and user name are valid.
Constructor Details
#initialize(server_with_optional_port, user, pass) ⇒ Client
Initializs the Client class.
server_with_optional_port is the server’s domain name; the port may be added following a colon. Default port is 993. user is the user (account) name to log into the server. pass is the password to log into the server.
16 17 18 19 20 21 22 |
# File 'lib/imapcli/client.rb', line 16 def initialize(server_with_optional_port, user, pass) @port = 993 # default self.server = server_with_optional_port @user = user @pass = pass clear_responses end |
Instance Attribute Details
#pass ⇒ Object
rubocop:disable Metrics/ClassLength
8 9 10 |
# File 'lib/imapcli/client.rb', line 8 def pass @pass end |
#port ⇒ Object
rubocop:disable Metrics/ClassLength
8 9 10 |
# File 'lib/imapcli/client.rb', line 8 def port @port end |
#server ⇒ Object
Attribute reader for the server domain name
25 26 27 |
# File 'lib/imapcli/client.rb', line 25 def server @server end |
#user ⇒ Object
rubocop:disable Metrics/ClassLength
8 9 10 |
# File 'lib/imapcli/client.rb', line 8 def user @user end |
Instance Method Details
#capability ⇒ Object
Returns the server’s capabilities.
109 110 111 |
# File 'lib/imapcli/client.rb', line 109 def capability @capability ||= query_server('capability') { connection.capability } end |
#clear_responses ⇒ Object
Clears the server response log
61 62 63 |
# File 'lib/imapcli/client.rb', line 61 def clear_responses @log = [] end |
#collect_stats ⇒ Object
Collects stats for all mailboxes recursively.
169 170 171 |
# File 'lib/imapcli/client.rb', line 169 def collect_stats mailbox_root.collect_stats(self) end |
#connection ⇒ Object
Returns a connection to the server.
The value is cached.
78 79 80 |
# File 'lib/imapcli/client.rb', line 78 def connection @connection ||= Net::IMAP.new(@server, @port, true) end |
#find_mailbox(mailbox) ⇒ Object
Attempts to locate a given mailbox in the mailbox_root.
Returns nil if the mailbox is not found.
190 191 192 |
# File 'lib/imapcli/client.rb', line 190 def find_mailbox(mailbox) mailbox_root.find_sub_mailbox(mailbox, separator) end |
#greeting ⇒ Object
Returns the server’s greeting (which may reveal the server software name such as ‘Dovecot’).
104 105 106 |
# File 'lib/imapcli/client.rb', line 104 def greeting query_server('greeting') { connection.greeting.data.text.strip } end |
#last_response ⇒ Object
Returns the last response from the server
71 72 73 |
# File 'lib/imapcli/client.rb', line 71 def last_response @log.last end |
#login ⇒ Object
Logs in to the server.
Returns true if login was successful, false if not (e..g, invalid credentials).
86 87 88 89 90 91 92 93 94 |
# File 'lib/imapcli/client.rb', line 86 def login raise('no connection to a server') unless connection begin response_ok? connection.login(@user, @pass) rescue Net::IMAP::NoResponseError => e log_error e end end |
#logout ⇒ Object
Logs out of the server.
97 98 99 100 |
# File 'lib/imapcli/client.rb', line 97 def logout # access instance variable to avoid creating a new connection @connection&.logout end |
#mailbox_root ⇒ Object
Returns a tree of Imapcli::Mailbox objects.
The value is cached.
183 184 185 |
# File 'lib/imapcli/client.rb', line 183 def mailbox_root @mailbox_root ||= Mailbox.new(mailboxes) end |
#mailboxes ⇒ Object
Gets a list of Net::IMAP::MailboxList items, one for each mailbox.
The value is cached.
176 177 178 |
# File 'lib/imapcli/client.rb', line 176 def mailboxes @mailboxes ||= query_server('list') { @connection.list('', '*') } end |
#message_sizes(mailbox) ⇒ Object
Examines a mailbox and returns statistics about the messages in it.
Returns an array with the following keys:
-
:count: Total count of messages.
-
:size: Total size of all messages in bytes.
-
:min: Size of the smallest message.
-
:q1: First quartile of message sizes.
-
:median: Median of message sizes.
-
:q3: Third quartile of messages sizes.
-
:max: Size of largest message.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/imapcli/client.rb', line 153 def (mailbox) = (mailbox) if .empty? [] else query_server('fetch(...)') do .each_slice(1000).map do || connection.fetch(, 'RFC822.SIZE').map do |f| f.attr['RFC822.SIZE'] end end.flatten end end end |
#messages(mailbox) ⇒ Object
Returns an array of message indexes for a mailbox.
The value is currently NOT cached.
138 139 140 141 |
# File 'lib/imapcli/client.rb', line 138 def (mailbox) query_server("examine('#{mailbox}')") { connection.examine(mailbox) } query_server("search('ALL')") { connection.search('ALL') } end |
#quota ⇒ Object
If the server supports_quota, returns an array containing the current usage (in kiB), the total quota (in kiB), and the percent usage.
125 126 127 128 129 130 131 132 133 |
# File 'lib/imapcli/client.rb', line 125 def quota return unless supports_quota @quota ||= begin info = query_server("getquotaroot('INBOX')") { @connection.getquotaroot('INBOX')[1] } percent = info.quota.to_i.positive? ? info.usage.to_i.fdiv(info.quota.to_i) * 100 : nil [info.usage, info.quota, percent] end end |
#responses ⇒ Object
Returns the IMAP server response log
66 67 68 |
# File 'lib/imapcli/client.rb', line 66 def responses @log end |
#separator ⇒ Object
Returns the character that is used to separate nested mailbox names.
114 115 116 |
# File 'lib/imapcli/client.rb', line 114 def separator @separator ||= query_server("list('')") { connection.list('', '')[0].delim } end |
#server_valid? ⇒ Boolean
Perform basic sanity check on server name
Note that a propery regex for an FQDN is hard to achieve. See stackoverflow.com/a/106223/270712 and elsewhere.
45 46 47 |
# File 'lib/imapcli/client.rb', line 45 def server_valid? @server.match? '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$' # rubocop:disable Layout/LineLength end |
#supports_quota ⇒ Object
Returns true if the server supports the IMAP QUOTA extension.
119 120 121 |
# File 'lib/imapcli/client.rb', line 119 def supports_quota capability.include? 'QUOTA' end |
#user_valid? ⇒ Boolean
Perform very basic sanity check on user name
51 52 53 |
# File 'lib/imapcli/client.rb', line 51 def user_valid? @user&.length&.> 0 end |
#valid? ⇒ Boolean
Returns true if both server and user name are valid.
56 57 58 |
# File 'lib/imapcli/client.rb', line 56 def valid? server_valid? && user_valid? end |