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
Returns the value of attribute pass.
-
#port ⇒ Object
Returns the value of attribute port.
-
#responses ⇒ Object
readonly
Returns the value of attribute responses.
-
#user ⇒ Object
Returns the value of attribute user.
Instance Method Summary collapse
-
#capability ⇒ Object
Returns the server’s capabilities.
-
#clear_log ⇒ 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
mailbox
in 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::Mailbox
objects. -
#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. -
#separator ⇒ Object
Returns the character that is used to separate nested mailbox names.
-
#server ⇒ Object
Attribute reader for the server domain name.
-
#server=(server_with_optional_port) ⇒ Object
Attribute writer for the server domain name; a port may be appended with a colon.
-
#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.
17 18 19 20 21 |
# File 'lib/imapcli/client.rb', line 17 def initialize(server_with_optional_port, user, pass) @port = 993 # default self.server, @user, @pass = server_with_optional_port, user, pass clear_log end |
Instance Attribute Details
#pass ⇒ Object
Returns the value of attribute pass.
8 9 10 |
# File 'lib/imapcli/client.rb', line 8 def pass @pass end |
#port ⇒ Object
Returns the value of attribute port.
8 9 10 |
# File 'lib/imapcli/client.rb', line 8 def port @port end |
#responses ⇒ Object (readonly)
Returns the value of attribute responses.
9 10 11 |
# File 'lib/imapcli/client.rb', line 9 def responses @responses end |
#user ⇒ Object
Returns the value of attribute user.
8 9 10 |
# File 'lib/imapcli/client.rb', line 8 def user @user end |
Instance Method Details
#capability ⇒ Object
Returns the server’s capabilities.
104 105 106 |
# File 'lib/imapcli/client.rb', line 104 def capability @capability ||= query_server { connection.capability } end |
#clear_log ⇒ Object
Clears the server response log
62 63 64 |
# File 'lib/imapcli/client.rb', line 62 def clear_log @log = [] end |
#collect_stats ⇒ Object
Collects stats for all mailboxes recursively.
164 165 166 |
# File 'lib/imapcli/client.rb', line 164 def collect_stats mailbox_root.collect_stats(self) end |
#connection ⇒ Object
Returns a connection to the server.
The value is cached.
74 75 76 |
# File 'lib/imapcli/client.rb', line 74 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.
185 186 187 |
# File 'lib/imapcli/client.rb', line 185 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’).
99 100 101 |
# File 'lib/imapcli/client.rb', line 99 def greeting query_server { connection.greeting.data.text.strip } end |
#last_response ⇒ Object
Returns the last response from the server
67 68 69 |
# File 'lib/imapcli/client.rb', line 67 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).
82 83 84 85 86 87 88 89 |
# File 'lib/imapcli/client.rb', line 82 def login raise('no connection to a server') unless connection begin response_ok? connection.login(@user, @pass) rescue Net::IMAP::NoResponseError => error log_error error end end |
#logout ⇒ Object
Logs out of the server.
92 93 94 95 |
# File 'lib/imapcli/client.rb', line 92 def logout # access instance variable to avoid creating a new connection @connection.logout if @connection end |
#mailbox_root ⇒ Object
Returns a tree of Imapcli::Mailbox
objects.
The value is cached.
178 179 180 |
# File 'lib/imapcli/client.rb', line 178 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.
171 172 173 |
# File 'lib/imapcli/client.rb', line 171 def mailboxes @mailboxes ||= query_server { @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.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/imapcli/client.rb', line 148 def (mailbox) # Could use the EXAMINE command to get the number of messages in a mailbox, # but we need to retrieve an array of message indexes anyway (to compute # the total mailbox size), so we can save one roundtrip to the server. # query_server { connection.examine(mailbox) } # total = connection.responses['EXISTS'][0] # unseen = query_server { connection.search('UNSEEN') }.length = (mailbox) if .length > 0 query_server { connection.fetch(, 'RFC822.SIZE').map { |f| f.attr['RFC822.SIZE'] } } else [] end end |
#messages(mailbox) ⇒ Object
Returns an array of message indexes for a mailbox.
The value is currently NOT cached.
133 134 135 136 |
# File 'lib/imapcli/client.rb', line 133 def (mailbox) query_server { connection.examine(mailbox) } query_server { 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.
120 121 122 123 124 125 126 127 128 |
# File 'lib/imapcli/client.rb', line 120 def quota if supports_quota @quota ||= begin info = query_server { @connection.getquotaroot('INBOX')[1] } percent = info.quota.to_i > 0 ? info.usage.to_i.fdiv(info.quota.to_i) * 100 : nil [ info.usage, info.quota, percent ] end end end |
#separator ⇒ Object
Returns the character that is used to separate nested mailbox names.
109 110 111 |
# File 'lib/imapcli/client.rb', line 109 def separator @separator ||= query_server { connection.list('', '')[0].delim } end |
#server ⇒ Object
Attribute reader for the server domain name
24 25 26 |
# File 'lib/imapcli/client.rb', line 24 def server @server end |
#server=(server_with_optional_port) ⇒ Object
Attribute writer for the server domain name; a port may be appended with a colon.
If no port is appended, the default port (993) will be used.
32 33 34 35 36 37 38 39 40 |
# File 'lib/imapcli/client.rb', line 32 def server=(server_with_optional_port) match = server_with_optional_port.match('^([^:]+):(\d+)$') if match @server = match[1] @port = match[2].to_i else @server = server_with_optional_port end 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.
46 47 48 |
# File 'lib/imapcli/client.rb', line 46 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])$' end |
#supports_quota ⇒ Object
Returns true if the server supports the IMAP QUOTA extension.
114 115 116 |
# File 'lib/imapcli/client.rb', line 114 def supports_quota capability.include? 'QUOTA' end |
#user_valid? ⇒ Boolean
Perform very basic sanity check on user name
52 53 54 |
# File 'lib/imapcli/client.rb', line 52 def user_valid? @user&.length > 0 end |
#valid? ⇒ Boolean
Returns true if both server and user name are valid.
57 58 59 |
# File 'lib/imapcli/client.rb', line 57 def valid? server_valid? && user_valid? end |