Ruby 2.4

Net::IMAP

class Net::IMAP

父:ObjectIncluded模块:MonitorMixin,OpenSSL,OpenSSL :: SSL

Net :: IMAP实现Internet消息访问协议(IMAP)客户端功能。该协议在IMAP中进行了描述。

IMAP概述

IMAP客户端连接到服务器,然后使用authenticate()或login()进行身份验证。通过身份验证后,可以使用一系列命令。大多数使用邮箱,可以安排在分层名称空间中,并且每个邮箱都包含零个或多个邮件。这在服务器上如何实现是依赖于实现的; 在UNIX服务器上,它经常以目录层次结构中的邮箱格式实现为文件。

要处理邮箱内的邮件,客户端必须首先使用select()或(对于只读访问)examine()来选择该邮箱。一旦客户端成功选择了一个邮箱,它们就进入选定状态,并且该邮箱成为当前邮箱,邮件项目相关命令将隐式操作。

消息有两种标识符:消息序列号和UID。

消息序号将邮箱中的邮件数从1增加到邮箱中的邮件数。如果新消息在会话期间到达,它会收到一个等于邮箱新大小的序列号。如果从邮箱中删除邮件,则剩余的邮件会将其序列号“乱码”以填补空白。

另一方面,UID永久保证不会在同一个邮箱中标识另一个邮件,即使现有邮件已被删除。UID需要在邮箱内以升序(但不一定是顺序)顺序进行分配; 这意味着如果非IMAP客户端重新排列邮箱中邮件项目的顺序,则必须重新分配UID。因此,IMAP客户端无法重新排列消息订单。

使用示例

列出默认邮箱中所有最近消息的发件人和主题

imap = Net::IMAP.new('mail.example.com') imap.authenticate('LOGIN', 'joe_user', 'joes_password') imap.examine('INBOX') imap.search(["RECENT"]).each do |message_id| envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"] puts "#{envelope.from[0].name}: \t#{envelope.subject}" end

将所有邮件从2003年4月的“邮件/发送邮件”从“Mail / sent-apr03”

imap = Net::IMAP.new('mail.example.com') imap.authenticate('LOGIN', 'joe_user', 'joes_password') imap.select('Mail/sent-mail') if not imap.list('Mail/', 'sent-apr03') imap.create('Mail/sent-apr03') end imap.search(["BEFORE", "30-Apr-2003", "SINCE", "1-Apr-2003"]).each do |message_id| imap.copy(message_id, "Mail/sent-apr03") imap.store(message_id, "+FLAGS", [:Deleted]) end imap.expunge

线程安全

Net :: IMAP支持并发线程。例如,

imap = Net::IMAP.new("imap.foo.net", "imap2") imap.authenticate("cram-md5", "bar", "password") imap.select("inbox") fetch_thread = Thread.start { imap.fetch(1..-1, "UID") } search_result = imap.search(["BODY", "hello"]) fetch_result = fetch_thread.value imap.disconnect

该脚本同时调用FETCH命令和SEARCH命令。

错误

IMAP服务器可以发送三种不同类型的响应来指示失败:

NO

试图执行的命令无法成功完成。例如,用于登录的用户名/密码不正确; 所选邮箱不存在; 等等

BAD

来自客户端的请求并不遵循服务器对IMAP协议的理解。这包括尝试来自错误的客户端状态的命令; 例如,试图在没有选择当前邮箱的情况下执行SEARCH命令。它也可能表示发生了内部服务器故障(如磁盘崩溃)。

BYE

服务器正在说再见。这可以是正常注销序列的一部分,并且可以用作登录序列的一部分,以表明服务器(由于某种原因)不愿意接受您的连接。作为对任何其他命令的响应,它表明服务器正在关闭,或者服务器由于不活动而超时客户端连接。

这三个错误响应由错误Net :: IMAP :: NoResponseError,Net :: IMAP :: BadResponseError和Net :: IMAP :: ByeResponseError表示,所有这些都是Net :: IMAP :: ResponseError的子类。从本质上讲,所有涉及向服务器发送请求的方法都可能会产生这些错误之一。以下仅记录最相关的实例。

由于IMAP类使用套接字进行通信,因此其方法也易受使用套接字时可能发生的各种错误的影响。这些通常表示为Errno错误。例如,任何涉及向服务器发送请求和/或从其接收响应的方法都会在网络连接意外关闭时引发Errno :: EPIPE错误。请参阅套接字(7),ip(7),tcp(7),套接字(2),连接(2)以及关联的手册页。

最后,如果发现低级别数据的格式不正确(例如,在UTF-8和UTF-16之间转换时),则Net :: IMAP :: DataFormatError被抛出,并且Net :: IMAP :: ResponseParseError为如果服务器响应不可解析则抛出。

参考

IMAP

  • Crispin,“INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1”,

RFC 2060,December 1996.(注:由于RFC 3501已经过时)

LANGUAGE-TAGS

Alvestrand,H.,“用于识别语言的标签”,RFC 1766,1995年3月。

MD5

Myers,J.和M. Rose,“Content-MD5 Header Field”,RFC 1864,1995年10月。

MIME-IMB

Freed,N.和N.Borenstein,“MIME(多用途因特网邮件扩展)第一部分:Internet消息体的格式”,RFC 2045,1996年11月。

RFC-822

Crocker,D.,“ARPA因特网文本消息格式标准”,STD 11,RFC 822,特拉华大学,1982年8月。

RFC-2087

Myers,J。,“IMAP4 QUOTA扩展”,RFC 2087,1997年1月。

RFC-2086

Myers,J.,“IMAP4 ACL扩展”,RFC 2086,1997年1月。

RFC-2195

Klensin,J.,Catoe,R.和Krumviede,P.,“IMAP / POP AUTHorize Extension for Simple Challenge / Response”,RFC 2195,1997年9月。

SORT-THREAD-EXT

Crispin,M.,“INTERNET MESSAGE ACCESS PROTOCOL - SORT和THREAD Extensions”,Draft-ietf-imapext-sort,2003年5月。

OSSL

www.openssl.org

RSSL

savannah.gnu.org/projects/rubypki

UTF7

Goldsmith,D。和Davis,M.,“UTF-7:Unicode的邮件安全转换格式”,RFC 2152,1997年5月。

常量

ANSWERED

指示消息的标志已被回答。

Address

Net :: IMAP :: Address表示电子邮件地址。

领域:

name

从RFC-822邮箱返回短语。

route

返回RFC-822 route-addr的路由。

mailbox

nil表示RFC-822组的结束。如果非零和主机为零,则返回RFC-822组名。否则,返回RFC-822本地部分。

host

nil表示RFC-822组语法。否则,返回RFC-822域名。

ContentDisposition

Net :: IMAP :: ContentDisposition表示Content-Disposition字段。

Fields:

dsp_type

返回处置类型。

param

返回表示Content-Disposition字段参数的散列。

ContinuationRequest

Net :: IMAP :: ContinuationRequest表示命令继续请求。

命令继续请求响应由“+”标记而不是标记指示。这种形式的响应表明服务器已准备好接受来自客户端的命令的继续。这个回应的其余部分是一行文字。

continue_req ::= "+" SPACE (resp_text / base64)

Fields:

data

返回数据(Net :: IMAP :: ResponseText)。

raw_data

返回原始数据字符串。

DATE_MONTH DELETED

指示消息的标志已被标记为删除。邮箱关闭或清除时会发生这种情况。

DRAFT

指示消息的标志只是草稿或正在进行中的版本。

Envelope

Net :: IMAP :: Envelope表示消息的信封结构。

Fields:

date

返回表示日期的字符串。

subject

返回表示主题的字符串。

from

返回表示from的Net :: IMAP :: Address数组。

sender

返回表示发件人的Net :: IMAP :: Address数组。

reply_to

返回表示答复的Net :: IMAP :: Address数组。

to

返回表示to的Net :: IMAP :: Address数组。

cc

返回表示cc的Net :: IMAP :: Address数组。

bcc

返回表示密件抄送的Net :: IMAP :: Address数组。

in_reply_to

返回一个表示in-reply-to的字符串。

message_id

返回表示消息ID的字符串。

FLAGGED

表示消息的标志已被标记为特别或紧急关注。

FetchData

Net :: IMAP :: FetchData表示FETCH响应的内容。

Fields:

seqno

返回消息序列号。(注意:即使对于UID命令响应,也不是唯一标识符。)

attr

返回一个散列。每个键都是数据项名称,每个值都是其值。

目前的数据项是:

BODY

没有扩展数据的BODYSTRUCTURE形式。

Net::IMAP::BodyTypeBasic, Net::IMAP::BodyTypeText, Net::IMAP::BodyTypeMessage, Net::IMAP::BodyTypeMultipart. ENVELOPE

描述消息信封结构的Net :: IMAP :: Envelope对象。

FLAGS

为此消息设置的标志符号数组。标志符号大写字符串#大写。

INTERNALDATE

表示消息内部日期的字符串。

RFC822

相当于BODY []。

RFC822.HEADER

Equivalent to BODY.PEEK.

RFC822.SIZE

表示消息的RFC-822大小的数字。

RFC822.TEXT

相当于BODY。

UID

表示消息唯一标识符的数字。

MARKED

指示邮箱已被服务器标记为“有趣”的标志; 这通常表示邮箱包含新邮件。

MailboxACLItem

Net :: IMAP :: MailboxACLItem表示来自GETACL的响应。

acl_data ::= "ACL" SPACE mailbox *(SPACE identifier SPACE rights) identifier ::= astring rights ::= astring

Fields:

user

对使用getacl命令指定的邮箱具有某些权限的登录名。

rights

指定用户对邮箱的访问权限。

MailboxList

Net :: IMAP :: MailboxList表示LIST响应的内容。

mailbox_list ::= "(" #("\Marked" / "\Noinferiors" / "\Noselect" / "\Unmarked" / flag_extension) ")" SPACE (<"> QUOTED_CHAR <"> / nil) SPACE mailbox

Fields:

attr

返回名称属性。每个名称属性都是由String#capitalize大写的符号,例如:Noselect(not:NoSelect)。

delim

返回层次结构分隔符。

name

返回邮箱名称。

MailboxQuota

Net :: IMAP :: MailboxQuota表示GETQUOTA响应的内容。该对象也可以是对GETQUOTAROOT的响应。在下面的语法规范中,与“#”构造一起使用的分隔符是单个空格(SPACE)。

quota_list ::= "(" #quota_resource ")" quota_resource ::= atom SPACE number SPACE number quota_response ::= "QUOTA" SPACE astring SPACE quota_list

Fields:

mailbox

带有关联配额的邮箱。

usage

邮箱的当前存储使用情况。

quota

对邮箱施加配额限制。

MailboxQuotaRoot

Net :: IMAP :: MailboxQuotaRoot表示GETQUOTAROOT响应的一部分。(GETQUOTAROOT也可以返回Net :: IMAP :: MailboxQuota。)

quotaroot_response ::= "QUOTAROOT" SPACE astring *(SPACE astring)

Fields:

mailbox

带有关联配额的邮箱。

quotaroots

影响指定邮箱配额的零个或多个quotaroots。

NOINFERIORS

指示邮箱上下文名称不能包含子项的标志。

NOSELECT

表示邮箱未被选中的标志。

RECENT

表示该消息为“最近”的标志,表示该会话是客户端已收到此消息通知的第一个会话。

ResponseCode

Net :: IMAP :: ResponseCode表示响应代码。

resp_text_code ::= "ALERT" / "PARSE" / "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" / "READ-ONLY" / "READ-WRITE" / "TRYCREATE" / "UIDVALIDITY" SPACE nz_number / "UNSEEN" SPACE nz_number / atom [SPACE 1*<any TEXT_CHAR except "]">]

Fields:

name

返回名称,例如“ALERT”,“PERMANENTFLAGS”或“UIDVALIDITY”。

data

返回数据(如果存在)。

ResponseText

Net :: IMAP :: ResponseText表示响应的文本。文本可能以响应代码为前缀。

resp_text ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text) ;; text SHOULD NOT begin with "[" or "="

Fields:

code

返回响应代码。请参阅((<Net :: IMAP :: ResponseCode>))。

text

返回文本。

SEEN

表示消息的标志已被看到。

StatusData

Net :: IMAP :: StatusData表示STATUS响应的内容。

Fields:

mailbox

返回邮箱名称。

attr

返回一个散列。每个密钥都是“消息”,“最近”,“下一个”,“无效”,“未使用”之一。每个值都是一个数字。

TaggedResponse

Net :: IMAP :: TaggedResponse表示标记的响应。

服务器完成结果响应指示操作的成功或失败。它使用与开始操作的客户端命令相同的标记进行标记。

response_tagged ::= tag SPACE resp_cond_state CRLF tag ::= 1*<any ATOM_CHAR except "+"> resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text

Fields:

tag

返回标签。

name

返回名称,“OK”,“NO”或“BAD”之一。

data

返回数据。请参阅((<Net :: IMAP :: ResponseText>))。

raw_data

返回原始数据字符串。

ThreadMember

Net :: IMAP :: ThreadMember表示由#thread返回的线程节点。

Fields:

seqno

此消息的序列号。

children

用于邮件项目的Net :: IMAP :: ThreadMember对象的数组,它们是线程中的子项。

UNMARKED

指示邮箱不包含新邮件的标志。

UntaggedResponse

Net :: IMAP :: UntaggedResponse表示无标记的响应。

由服务器传输到客户端的数据以及不表示命令完成的状态响应以标记“*”作为前缀,并称为未标记的响应。

response_data ::= "*" SPACE (resp_cond_state / resp_cond_bye / mailbox_data / message_data / capability_data)

Fields:

name

返回名称,例如“FLAGS”,“LIST”或“FETCH”。

data

返回数据,如标志符号数组,一个((<Net :: IMAP :: MailboxList>))对象。

raw_data

返回原始数据字符串。

属性

client_threadRW

接收异常的线程。

greetingR

返回来自服务器的初始问候响应。

response_handlersR

返回所有响应处理程序。

responsesR

返回未标记的响应。例如:

imap.select("inbox") p imap.responses["EXISTS"][-1] #=> 2 p imap.responses["UIDVALIDITY"][-1] #=> 968263756

公共类方法

add_authenticator(auth_type,authenticator)显示源文件

为#authenticate添加一个验证器。auth_type是此验证器支持的验证类型(例如“LOGIN”)。该authenticator对象定义了一个process()方法来处理与服务器的身份验证。有关示例,请参阅Net :: IMAP :: LoginAuthenticator,Net :: IMAP :: CramMD5Authenticator和Net :: IMAP :: DigestMD5Authenticator。

如果auth_type引用现有的身份验证器,它将被新的替换。

# File lib/net/imap.rb, line 294 def self.add_authenticator(auth_type, authenticator) @@authenticators[auth_type] = authenticator end

debug() Show source

返回调试模式。

# File lib/net/imap.rb, line 264 def self.debug return @@debug end

debug=(val) Show source

设置调试模式。

# File lib/net/imap.rb, line 269 def self.debug=(val) return @@debug = val end

decode_utf7(s) Show source

将字符串从修改的UTF-7格式解码为UTF-8。

UTF-7是Unicode UTF7的7位编码。IMAP使用稍微修改后的版本来编码包含非ASCII字符的邮箱名称; 请参阅IMAP第5.1.3节。

网:: IMAP并不会自动编码和邮箱名称和UTF-7进行解码。

# File lib/net/imap.rb, line 991 def self.decode_utf7(s) return s.gsub(/&([^-]+)?-/n) { if $1 ($1.tr(",", "/") + "===").unpack("m")[0].encode(Encoding::UTF_8, Encoding::UTF_16BE) else "&" end } end

default_imap_port()

别名为:default_port

default_imaps_port()

别名为:default_tls_port

default_port() Show source

IMAP连接的默认端口,端口143

# File lib/net/imap.rb, line 299 def self.default_port return PORT end

另外别名为:default_imap_port

default_ssl_port()

别名为:default_tls_port

default_tls_port() Show source

IMAPS连接的默认端口,端口993

# File lib/net/imap.rb, line 304 def self.default_tls_port return SSL_PORT end

另外别名为:default_imaps_port,default_ssl_port

encode_utf7(s) Show source

将UTF-8格式的字符串编码为修改后的UTF-7。

# File lib/net/imap.rb, line 1002 def self.encode_utf7(s) return s.gsub(/(&)|[^\x20-\x7e]+/) { if $1 "&-" else base64 = [$&.encode(Encoding::UTF_16BE)].pack("m0") "&" + base64.delete("=").tr("/", ",") + "-" end }.force_encoding("ASCII-8BIT") end

format_date(time) Show source

格式化time为IMAP风格的日期。

# File lib/net/imap.rb, line 1014 def self.format_date(time) return time.strftime('%d-%b-%Y') end

format_datetime(time) Show source

格式化time为IMAP风格的日期时间。

# File lib/net/imap.rb, line 1019 def self.format_datetime(time) return time.strftime('%d-%b-%Y %H:%M %z') end

max_flag_count() Show source

返回实现为符号的最大标志数。

# File lib/net/imap.rb, line 274 def self.max_flag_count return @@max_flag_count end

max_flag_count=(count) Show source

将实际标记的最大数量设置为符号。

# File lib/net/imap.rb, line 279 def self.max_flag_count=(count) @@max_flag_count = count end

Net::IMAP.new(host, options = {}) Show source

创建一个新的Net :: IMAP对象并将其连接到指定的对象host

options 是一个选项散列,其中的每个键都是一个符号。

可用的选项是:

port

端口号(imap的缺省值是143,imaps的缺省值是993)

ssl

如果选项为真,那么将尝试使用SSL(现在称为TLS)连接到服务器。为此,需要安装OpenSSL OSSL和Ruby OpenSSL RSSL扩展。如果options是一个散列,它将作为参数传递给OpenSSL :: SSL :: SSLContext#set_params。

最常见的错误是:

Errno::ECONNREFUSED

连接拒绝host或介入防火墙。

Errno::ETIMEDOUT

连接超时(可能是由于数据包被干扰防火墙丢弃)。

Errno::ENETUNREACH

没有通往该网络的路线。

SocketError

主机名未知或其他套接字错误。

Net::IMAP::ByeResponseError

连接到主机是成功的,但它立即说再见。

调用超类方法MonitorMixin.new

# File lib/net/imap.rb, line 1061 def initialize(host, port_or_options = {}, usessl = false, certs = nil, verify = true) super() @host = host begin options = port_or_options.to_hash rescue NoMethodError # for backward compatibility options = {} options[:port] = port_or_options if usessl options[:ssl] = create_ssl_params(certs, verify) end end @port = options[:port] || (options[:ssl] ? SSL_PORT : PORT) @tag_prefix = "RUBY" @tagno = 0 @parser = ResponseParser.new @sock = TCPSocket.open(@host, @port) begin if options[:ssl] start_tls_session(options[:ssl]) @usessl = true else @usessl = false end @responses = Hash.new([].freeze) @tagged_responses = {} @response_handlers = [] @tagged_response_arrival = new_cond @continuation_request_arrival = new_cond @idle_done_cond = nil @logout_command_tag = nil @debug_output_bol = true @exception = nil @greeting = get_response if @greeting.nil? raise Error, "connection closed" end if @greeting.name == "BYE" raise ByeResponseError, @greeting end @client_thread = Thread.current @receiver_thread = Thread.start { begin receive_responses rescue Exception end } @receiver_thread_terminating = false rescue Exception @sock.close raise end end

公共实例方法

add_response_handler(handler = Proc.new) Show source

添加一个响应处理程序。例如,要检测服务器何时发送新的EXISTS响应(通常表示将新邮件添加到邮箱中),请在选择邮箱后添加以下处理程序:

imap.add_response_handler { |resp| if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS" puts "Mailbox now has #{resp.data} messages" end }

# File lib/net/imap.rb, line 898 def add_response_handler(handler = Proc.new) @response_handlers.push(handler) end

append(mailbox, message, flags = nil, date_time = nil) Show source

发送一个APPEND命令来追加message到。的末尾mailbox。可选flags参数是最初传递给新消息的标志数组。可选date_time参数指定分配给新消息的创建时间; 它默认为当前时间。例如:

imap.append("inbox", "Subject: hello From: shugo@ruby-lang.org To: shugo@ruby-lang.org hello world ".gsub(/\n/, "\r\n"), [:Seen], Time.now)

如果邮箱不存在(它不会自动创建),或者如果flags,date_time或message参数包含错误,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 691 def append(mailbox, message, flags = nil, date_time = nil) args = [] if flags args.push(flags) end args.push(date_time) if date_time args.push(Literal.new(message)) send_command("APPEND", mailbox, *args) end

authenticate(auth_type, *args) Show source

发送一个AUTHENTICATE命令来认证客户端。该auth_type参数是一个表示要使用的认证机制的字符串。目前Net :: IMAP支持认证机制:

LOGIN:: login using cleartext user and password. CRAM-MD5:: login with cleartext user and encrypted password (see [RFC-2195] for a full description). This mechanism requires that the server have the user's password stored in clear-text password.

对于这两种机制,应该有两个args:用户名和(明文)密码。服务器可能不支持这些机制中的一种或另一种; 检查能力()的形式为“AUTH = LOGIN”或“AUTH = CRAM-MD5”的能力。

身份验证使用适当的身份验证器对象完成:有关插入自己的身份验证器的更多信息,请参阅@@ authenticators。

例如:

imap.authenticate('LOGIN', user, password)

如果身份验证失败,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 409 def authenticate(auth_type, *args) auth_type = auth_type.upcase unless @@authenticators.has_key?(auth_type) raise ArgumentError, format('unknown auth type - "%s"', auth_type) end authenticator = @@authenticators[auth_type].new(*args) send_command("AUTHENTICATE", auth_type) do |resp| if resp.instance_of?(ContinuationRequest) data = authenticator.process(resp.data.text.unpack("m")[0]) s = [data].pack("m0") send_string_data(s) put_string(CRLF) end end end

capability() Show source

发送CAPABILITY命令,并返回服务器支持的一组功能。每个功能都是一个字符串。请参阅IMAP以获取可能的功能列表。

请注意,Net :: IMAP类不会根据服务器的功能修改其行为; 在使用服务器之前,要确保服务器支持某种功能,这取决于该类的用户。

# File lib/net/imap.rb, line 351 def capability synchronize do send_command("CAPABILITY") return @responses.delete("CAPABILITY")[-1] end end

check() Show source

发送CHECK命令以请求当前所选邮箱的检查点。这将执行特定于实施的内务管理; 例如,协调邮箱的内存和磁盘状态。

# File lib/net/imap.rb, line 705 def check send_command("CHECK") end

close() Show source

发送CLOSE命令关闭当前选定的邮箱。CLOSE命令将从邮箱中永久删除所有设置了“已删除”标志的邮件。

# File lib/net/imap.rb, line 712 def close send_command("CLOSE") end

copy(set, mailbox) Show source

发送COPY命令将指定的消息复制到指定目标的末尾mailbox。该set参数是一个数字,一个数字数组或一个Range对象。该号码是消息序号。

# File lib/net/imap.rb, line 845 def copy(set, mailbox) copy_internal("COPY", set, mailbox) end

create(mailbox) Show source

发送一个CREATE命令来创建一个新的mailbox

如果无法创建具有该名称的邮箱,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 472 def create(mailbox) send_command("CREATE", mailbox) end

delete(mailbox) Show source

发送DELETE命令以删除mailbox

如果具有该名称的邮箱无法删除,或者因为它不存在或者因为客户端没有删除它的权限,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 481 def delete(mailbox) send_command("DELETE", mailbox) end

disconnect() Show source

断开与服务器的连接。

# File lib/net/imap.rb, line 315 def disconnect begin begin # try to call SSL::SSLSocket#io. @sock.io.shutdown rescue NoMethodError # @sock is not an SSL::SSLSocket. @sock.shutdown end rescue Errno::ENOTCONN # ignore `Errno::ENOTCONN: Socket is not connected' on some platforms. rescue Exception => e @receiver_thread.raise(e) end @receiver_thread.join synchronize do @sock.close end raise e if e end

disconnected?() Show source

如果与服务器断开连接,则返回true。

# File lib/net/imap.rb, line 337 def disconnected? return @sock.closed? end

examine(mailbox) Show source

发送一个EXAMINE命令来选择一个,mailbox以便mailbox可以访问该消息。与select()的行为相同,只是所选内容mailbox被标识为只读。

如果邮箱不存在或出于某种原因不可检查,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 461 def examine(mailbox) synchronize do @responses.clear send_command("EXAMINE", mailbox) end end

expunge() Show source

发送EXPUNGE命令,从当前选定的邮箱中永久删除所有设置了“已删除”标志的邮件。

# File lib/net/imap.rb, line 718 def expunge synchronize do send_command("EXPUNGE") return @responses.delete("EXPUNGE") end end

fetch(set, attr) Show source

发送FETCH命令以检索与邮箱中的邮件相关的数据。

set参数是两个数字之间的数字或范围,或者是这些数字的数组。该数字是一个消息序列号,其中-1表示用于范围表示法(如100 ..- 1)的'*'被解释为'100:*'。请注意,根据exclude_end?协议规范,Range对象的属性将被忽略,并且范围的内容与范围端点的顺序无关,因此1 ... 5,5..1和5 ... 1全部等于1 ..5。

attr是要提取的属性列表; 有关有效属性的列表,请参阅Net :: IMAP :: FetchData的文档。

如果没有匹配的消息,则返回值是一个Net :: IMAP :: FetchData或nil(而不是空数组)的数组。

例如:

p imap.fetch(6..8, "UID") #=> [#<Net::IMAP::FetchData seqno=6, attr={"UID"=>98}>, \\ #<Net::IMAP::FetchData seqno=7, attr={"UID"=>99}>, \\ #<Net::IMAP::FetchData seqno=8, attr={"UID"=>100}>] p imap.fetch(6, "BODY[HEADER.FIELDS (SUBJECT)]") #=> [#<Net::IMAP::FetchData seqno=6, attr={"BODY[HEADER.FIELDS (SUBJECT)]"=>"Subject: test\r\n\r\n"}>] data = imap.uid_fetch(98, ["RFC822.SIZE", "INTERNALDATE"])[0] p data.seqno #=> 6 p data.attr["RFC822.SIZE"] #=> 611 p data.attr["INTERNALDATE"] #=> "12-Oct-2000 22:40:59 +0900" p data.attr["UID"] #=> 98

# File lib/net/imap.rb, line 809 def fetch(set, attr) return fetch_internal("FETCH", set, attr) end

getacl(mailbox) Show source

发送GETACL命令以及指定的mailbox。如果此邮箱存在,则会返回一个包含Net :: IMAP :: MailboxACLItem对象的数组。

# File lib/net/imap.rb, line 631 def getacl(mailbox) synchronize do send_command("GETACL", mailbox) return @responses.delete("ACL")[-1] end end

getquota(mailbox) Show source

与指定一起发送GETQUOTA命令mailbox。如果此邮箱存在,则返回包含Net :: IMAP :: MailboxQuota对象的数组。此命令通常仅适用于服务器管理员。

# File lib/net/imap.rb, line 595 def getquota(mailbox) synchronize do send_command("GETQUOTA", mailbox) return @responses.delete("QUOTA") end end

getquotaroot(mailbox) Show source

发送GETQUOTAROOT命令以及指定的命令mailbox。该命令通常对管理员和用户都可用。如果此邮箱存在,它将返回一个包含Net :: IMAP :: MailboxQuotaRoot和Net :: IMAP :: MailboxQuota类型对象的数组。

# File lib/net/imap.rb, line 581 def getquotaroot(mailbox) synchronize do send_command("GETQUOTAROOT", mailbox) result = [] result.concat(@responses.delete("QUOTAROOT")) result.concat(@responses.delete("QUOTA")) return result end end

idle(timeout = nil, &response_handler) Show source

发送IDLE命令,等待新消息或已删除消息的通知。在IDLE期间从服务器收到响应。

Use idle_done() to leave IDLE.

如果timeout给出,则此方法在timeout秒过后返回。timeout可以用于保持活力。例如,以下代码每60秒检查一次连接。

loop do imap.idle(60) do |res| ... end end

# File lib/net/imap.rb, line 944 def idle(timeout = nil, &response_handler) raise LocalJumpError, "no block given" unless response_handler response = nil synchronize do tag = Thread.current[:net_imap_tag] = generate_tag put_string("#{tag} IDLE#{CRLF}") begin add_response_handler(response_handler) @idle_done_cond = new_cond @idle_done_cond.wait(timeout) @idle_done_cond = nil if @receiver_thread_terminating raise Net::IMAP::Error, "connection closed" end ensure unless @receiver_thread_terminating remove_response_handler(response_handler) put_string("DONE#{CRLF}") response = get_tagged_response(tag, "IDLE") end end end return response end

idle_done() Show source

留下 IDLE.

# File lib/net/imap.rb, line 974 def idle_done synchronize do if @idle_done_cond.nil? raise Net::IMAP::Error, "not during IDLE" end @idle_done_cond.signal end end

list(refname, mailbox) Show source

发送LIST命令,并从客户端可用的全部名称集中返回名称的子集。refname提供上下文(例如,基于目录的邮箱层次结构中的基本目录)。mailbox在该上下文中指定邮箱或(通过通配符)邮箱。两个通配符可用于mailbox:'*',它匹配包括层次结构定界符在内的所有字符(例如,在UNIX托管的基于目录的邮箱层次结构上的'/'); 和'%',它匹配层次分隔符的所有字符。

如果refname为空,mailbox则直接用于确定要匹配哪些邮箱。如果mailbox为空,refname则返回根名称和层次分隔符。

返回值是一个数组Net::IMAP::MailboxList。例如:

imap.create("foo/bar") imap.create("foo/baz") p imap.list("", "foo/%") #=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\ #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\ #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]

# File lib/net/imap.rb, line 538 def list(refname, mailbox) synchronize do send_command("LIST", refname, mailbox) return @responses.delete("LIST") end end

登录(用户,密码)显示源

Sends a LOGIN command to identify the client and carries the plaintext password authenticating this user. Note that, unlike calling authenticate() with an auth_type of “LOGIN”, login() does not use the login authenticator.

如果身份验证失败,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 432 def login(user, password) send_command("LOGIN", user, password) end

注销()显示源

发送LOGOUT命令以通知服务器客户端已完成连接。

# File lib/net/imap.rb, line 365 def logout send_command("LOGOUT") end

lsub(refname,mailbox)显示源文件

发送LSUB命令,并返回用户声明为“活动”或“订阅”的一组名称中的名称子集,refname并将mailbox其解释为list()。返回值是一个数组Net::IMAP::MailboxList

# File lib/net/imap.rb, line 643 def lsub(refname, mailbox) synchronize do send_command("LSUB", refname, mailbox) return @responses.delete("LSUB") end end

移动(设置,邮箱)显示源

发送MOVE命令将指定的消息移动到指定目标的末尾mailbox。该set参数是一个数字,一个数字数组或一个Range对象。该号码是消息序号。RFC-6851中描述了IMAP MOVE扩展。

# File lib/net/imap.rb, line 859 def move(set, mailbox) copy_internal("MOVE", set, mailbox) end

noop()显示源代码

向服务器发送NOOP命令。它什么也没做。

# File lib/net/imap.rb, line 359 def noop send_command("NOOP") end

remove_response_handler(处理程序)显示源

删除响应处理程序。

# File lib/net/imap.rb, line 903 def remove_response_handler(handler) @response_handlers.delete(handler) end

重命名(邮箱,新名称)显示源

发送重命名命令来改变名称mailboxnewname

如果具有名称的邮箱因任何原因mailbox无法重命名,则会引发Net :: IMAP :: NoResponseError newname; 例如,因为mailbox不存在,或者因为已经有一个名称为邮箱newname

# File lib/net/imap.rb, line 492 def rename(mailbox, newname) send_command("RENAME", mailbox, newname) end

搜索(键,字符集=零)显示源

发送 SEARCH 命令在邮箱中搜索符合给定搜索条件的邮件,并返回邮件序列号。keys可以是保存整个搜索字符串的字符串,也可以是搜索关键字和参数的单维数组。以下是一些常见的搜索标准; 有关完整列表,请参阅IMAP第6.4.4节。

<message set>

一组消息序列号。','表示间隔,':'表示范围。例如,'2,10:12,15'表示“2,10,11,12,15”。

BEFORE <date>

严格在<date>之前包含内部日期的消息。日期参数的格式类似于2002年8月8日。

BODY <string>

在其正文中包含<string>的消息。

CC <string>

在CC字段中包含<string>的消息。

FROM <string>

在其FROM字段中包含<string>的消息。

NEW

消息与最近,但不是看到,标志设置。

NOT <search-key>

否定以下搜索键。

OR <search-key> <search-key>

“或”两个搜索键在一起。

ON <date>

内部日期完全等于<date>的消息,其格式类似于2002年8月8日。

SINCE <date>

内部日期在<日期>之后或之后的消息。

SUBJECT <string>

在主题中包含<string>的消息。

TO <string>

带有<string>的消息在其TO域中。

例如:

p imap.search(["SUBJECT", "hello", "NOT", "NEW"]) #=> [1, 6, 7, 8]

# File lib/net/imap.rb, line 765 def search(keys, charset = nil) return search_internal("SEARCH", keys, charset) end

选择(邮箱)显示源

发送一个SELECT命令来选择一个,mailbox以便mailbox可以访问该消息。

选择邮箱后,您可以从@response-1中检索该邮箱中的邮件数量,并从@response-1中检索最近邮件的数量。请注意,如果在会话期间新消息到达,这些值可能会更改; 有关检测此事件的方法,请参阅add_response_handler()。

如果邮箱不存在或出于某种原因不可选,则会引发Net :: IMAP :: NoResponseError。

# File lib/net/imap.rb, line 448 def select(mailbox) synchronize do @responses.clear send_command("SELECT", mailbox) end end

setacl(邮箱,用户,权限)显示源

发送SETACL命令mailboxuser并且该rights用户将在该邮箱中拥有该命令。如果rights为零,则该用户将被剥夺该邮箱的任何权利。IMAP ACL命令在RFC-2086中进行了描述。

# File lib/net/imap.rb, line 620 def setacl(mailbox, user, rights) if rights.nil? send_command("SETACL", mailbox, user, "") else send_command("SETACL", mailbox, user, rights) end end

setquota(邮箱,配额)显示源

发送SETQUOTA命令以及指定的mailboxquota。如果quota是零,那么quota将取消设置该邮箱。通常需要以服务器管理员身份登录才能正常工作。RFC-2087中描述了IMAP配额命令。

# File lib/net/imap.rb, line 607 def setquota(mailbox, quota) if quota.nil? data = '()' else data = '(STORAGE ' + quota.to_s + ')' end send_command("SETQUOTA", mailbox, RawData.new(data)) end

排序(sort_keys,search_keys,charset)显示源文件

发送一个SORT命令对邮箱中的邮件进行分类。返回一组消息序列号。例如:

p imap.sort(["FROM"], ["ALL"], "US-ASCII") #=> [1, 2, 3, 5, 6, 7, 8, 4, 9] p imap.sort(["DATE"], ["SUBJECT", "hello"], "US-ASCII") #=> [6, 7, 8, 1]

有关更多详细信息,请参见SORT-THREAD-EXT。

# File lib/net/imap.rb, line 877 def sort(sort_keys, search_keys, charset) return sort_internal("SORT", sort_keys, search_keys, charset) end

starttls(options = {},verify = true)显示源文件

发送STARTTLS命令以启动TLS会话。

# File lib/net/imap.rb, line 370 def starttls(options = {}, verify = true) send_command("STARTTLS") do |resp| if resp.kind_of?(TaggedResponse) && resp.name == "OK" begin # for backward compatibility certs = options.to_str options = create_ssl_params(certs, verify) rescue NoMethodError end start_tls_session(options) end end end

status(mailbox, attr) Show source

发送一个STATUS命令,并返回指示的状态mailboxattr是其状态将被请求的一个或多个属性的列表。支持的属性包括:

MESSAGES:: the number of messages in the mailbox. RECENT:: the number of recent messages in the mailbox. UNSEEN:: the number of unseen messages in the mailbox.

返回值是属性的散列值。例如:

p imap.status("inbox", ["MESSAGES", "RECENT"]) #=> {"RECENT"=>0, "MESSAGES"=>44}

如果mailbox无法返回状态值,则会引发Net :: IMAP :: NoResponseError ; 例如,因为它不存在。

# File lib/net/imap.rb, line 666 def status(mailbox, attr) synchronize do send_command("STATUS", mailbox, attr) return @responses.delete("STATUS")[-1].attr end end

存储(set,attr,flags)显示源文件

发送STORE命令来更改与邮箱中的邮件相关的数据,特别是其标志。该set参数是一个数字,一个数字数组或一个Range对象。每个号码都是一个消息序号。attr是要存储的数据项目的名称:'FLAGS'将用提供的标记替换消息的标记列表,'+ FLAGS'将添加提供的标记,'-FLAGS'将删除它们。flags是一个标志列表。

返回值是Net :: IMAP :: FetchData的数组。例如:

p imap.store(6..8, "+FLAGS", [:Deleted]) #=> [#<Net::IMAP::FetchData seqno=6, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\ #<Net::IMAP::FetchData seqno=7, attr={"FLAGS"=>[:Seen, :Deleted]}>, \\ #<Net::IMAP::FetchData seqno=8, attr={"FLAGS"=>[:Seen, :Deleted]}>]

# File lib/net/imap.rb, line 832 def store(set, attr, flags) return store_internal("STORE", set, attr, flags) end

subscribe(mailbox) Show source

发送SUBSCRIBE命令,将指定的mailbox名称添加到由lsub()返回的服务器的“活动”或“订阅”邮箱集。

如果mailbox无法订阅,则会引发Net :: IMAP :: NoResponseError ; 例如,因为它不存在。

# File lib/net/imap.rb, line 502 def subscribe(mailbox) send_command("SUBSCRIBE", mailbox) end

线程(算法,search_keys,字符集)显示源文件

与search()类似,但以线程格式返回消息序列号,作为Net :: IMAP :: ThreadMember树。支持的算法是:

ORDEREDSUBJECT

根据主题分为单层线程,按日期排序。

REFERENCES

根据哪个消息是对其的回复确定的父/子关系拆分为线程。

与search()不同,它charset是一个必需的参数。US-ASCII和UTF-8是样本值。

有关更多详细信息,请参见SORT-THREAD-EXT。

# File lib/net/imap.rb, line 920 def thread(algorithm, search_keys, charset) return thread_internal("THREAD", algorithm, search_keys, charset) end

uid_copy(set,mailbox)显示源文件

与copy()类似,但set包含唯一标识符。

# File lib/net/imap.rb, line 850 def uid_copy(set, mailbox) copy_internal("UID COPY", set, mailbox) end

uid_fetch(set, attr) Show source

与fetch()类似,但set包含唯一标识符。

# File lib/net/imap.rb, line 814 def uid_fetch(set, attr) return fetch_internal("UID FETCH", set, attr) end

uid_move(set, mailbox) Show source

与move()类似,但set包含唯一标识符。

# File lib/net/imap.rb, line 864 def uid_move(set, mailbox) copy_internal("UID MOVE", set, mailbox) end

uid_search(keys, charset = nil) Show source

与搜索()类似,但返回唯一标识符。

# File lib/net/imap.rb, line 770 def uid_search(keys, charset = nil) return search_internal("UID SEARCH", keys, charset) end

uid_sort(sort_keys, search_keys, charset) Show source

与sort()类似,但返回一个唯一标识符数组。

# File lib/net/imap.rb, line 882 def uid_sort(sort_keys, search_keys, charset) return sort_internal("UID SORT", sort_keys, search_keys, charset) end

uid_store(set, attr, flags) Show source

与store()类似,但set包含唯一标识符。

# File lib/net/imap.rb, line 837 def uid_store(set, attr, flags) return store_internal("UID STORE", set, attr, flags) end

uid_thread(algorithm, search_keys, charset) Show source

与thread()类似,但返回唯一标识符而不是消息序列号。

# File lib/net/imap.rb, line 926 def uid_thread(algorithm, search_keys, charset) return thread_internal("UID THREAD", algorithm, search_keys, charset) end

unsubscribe(mailbox) Show source

发送UNSUBSCRIBE命令以mailbox从服务器的“活动”或“订阅”邮箱组中删除指定的名称。

如果mailbox无法取消订阅,则会引发Net :: IMAP :: NoResponseError ; 例如,因为客户当前没有订阅它。

# File lib/net/imap.rb, line 512 def unsubscribe(mailbox) send_command("UNSUBSCRIBE", mailbox) end

xlist(refname, mailbox) Show source

发送XLIST命令,并从客户端可用的全部名称集中返回一个名称的子集。refname提供上下文(例如,基于目录的邮箱层次结构中的基本目录)。mailbox在该上下文中指定邮箱或(通过通配符)邮箱。两个通配符可用于mailbox:'*',它匹配包括层次结构定界符在内的所有字符(例如,在UNIX托管的基于目录的邮箱层次结构上的'/'); 和'%',它匹配层次分隔符的所有字符。

如果refname为空,mailbox则直接用于确定要匹配哪些邮箱。如果mailbox为空,refname则返回根名称和层次分隔符。

XLIST命令与LIST命令相似,只不过返回的标志引用了文件夹/邮箱的功能,例如:已发送

返回值是一个数组Net::IMAP::MailboxList。例如:

imap.create("foo/bar") imap.create("foo/baz") p imap.xlist("", "foo/%") #=> [#<Net::IMAP::MailboxList attr=[:Noselect], delim="/", name="foo/">, \\ #<Net::IMAP::MailboxList attr=[:Noinferiors, :Marked], delim="/", name="foo/bar">, \\ #<Net::IMAP::MailboxList attr=[:Noinferiors], delim="/", name="foo/baz">]

# File lib/net/imap.rb, line 570 def xlist(refname, mailbox) synchronize do send_command("XLIST", refname, mailbox) return @responses.delete("XLIST") end end

私有实例方法

copy_internal(cmd, set, mailbox) Show source

# File lib/net/imap.rb, line 1414 def copy_internal(cmd, set, mailbox) send_command(cmd, MessageSet.new(set), mailbox) end

create_ssl_params(certs = nil, verify = true) Show source

# File lib/net/imap.rb, line 1453 def create_ssl_params(certs = nil, verify = true) params = {} if certs if File.file?(certs) params[:ca_file] = certs elsif File.directory?(certs) params[:ca_path] = certs end end if verify params[:verify_mode] = VERIFY_PEER else params[:verify_mode] = VERIFY_NONE end return params end

fetch_internal(cmd, set, attr) Show source

# File lib/net/imap.rb, line 1386 def fetch_internal(cmd, set, attr) case attr when String then attr = RawData.new(attr) when Array then attr = attr.map { |arg| arg.is_a?(String) ? RawData.new(arg) : arg } end synchronize do @responses.delete("FETCH") send_command(cmd, MessageSet.new(set), attr) return @responses.delete("FETCH") end end

generate_tag() Show source

# File lib/net/imap.rb, line 1256 def generate_tag @tagno += 1 return format("%s%04d", @tag_prefix, @tagno) end

get_response() Show source

# File lib/net/imap.rb, line 1201 def get_response buff = String.new while true s = @sock.gets(CRLF) break unless s buff.concat(s) if /\{(\d+)\}\r\n/n =~ s s = @sock.read($1.to_i) buff.concat(s) else break end end return nil if buff.length == 0 if @@debug $stderr.print(buff.gsub(/^/n, "S: ")) end return @parser.parse(buff) end

get_tagged_response(tag, cmd) Show source

# File lib/net/imap.rb, line 1185 def get_tagged_response(tag, cmd) until @tagged_responses.key?(tag) raise @exception if @exception @tagged_response_arrival.wait end resp = @tagged_responses.delete(tag) case resp.name when /\A(?:NO)\z/ni raise NoResponseError, resp when /\A(?:BAD)\z/ni raise BadResponseError, resp else return resp end end

normalize_searching_criteria(keys) Show source

# File lib/net/imap.rb, line 1442 def normalize_searching_criteria(keys) keys.collect! do |i| case i when -1, Range, Array MessageSet.new(i) else i end end end

put_string(str) Show source

# File lib/net/imap.rb, line 1261 def put_string(str) @sock.print(str) if @@debug if @debug_output_bol $stderr.print("C: ") end $stderr.print(str.gsub(/\n(?!\z)/n, "\nC: ")) if /\r\n\z/n.match(str) @debug_output_bol = true else @debug_output_bol = false end end end

receive_responses() Show source

# File lib/net/imap.rb, line 1119 def receive_responses connection_closed = false until connection_closed synchronize do @exception = nil end begin resp = get_response rescue Exception => e synchronize do @sock.close @exception = e end break end unless resp synchronize do @exception = EOFError.new("end of file reached") end break end begin synchronize do case resp when TaggedResponse @tagged_responses[resp.tag] = resp @tagged_response_arrival.broadcast if resp.tag == @logout_command_tag return end when UntaggedResponse record_response(resp.name, resp.data) if resp.data.instance_of?(ResponseText) && (code = resp.data.code) record_response(code.name, code.data) end if resp.name == "BYE" && @logout_command_tag.nil? @sock.close @exception = ByeResponseError.new(resp) connection_closed = true end when ContinuationRequest @continuation_request_arrival.signal end @response_handlers.each do |handler| handler.call(resp) end end rescue Exception => e @exception = e synchronize do @tagged_response_arrival.broadcast @continuation_request_arrival.broadcast end end end synchronize do @receiver_thread_terminating = true @tagged_response_arrival.broadcast @continuation_request_arrival.broadcast if @idle_done_cond @idle_done_cond.signal end end end

record_response(name, data) Show source

# File lib/net/imap.rb, line 1221 def record_response(name, data) unless @responses.has_key?(name) @responses[name] = [] end @responses[name].push(data) end

search_internal(cmd, keys, charset) Show source

# File lib/net/imap.rb, line 1370 def search_internal(cmd, keys, charset) if keys.instance_of?(String) keys = [RawData.new(keys)] else normalize_searching_criteria(keys) end synchronize do if charset send_command(cmd, "CHARSET", charset, *keys) else send_command(cmd, *keys) end return @responses.delete("SEARCH")[-1] end end

send_command(cmd, *args, &block) Show source

# File lib/net/imap.rb, line 1228 def send_command(cmd, *args, &block) synchronize do args.each do |i| validate_data(i) end tag = generate_tag put_string(tag + " " + cmd) args.each do |i| put_string(" ") send_data(i) end put_string(CRLF) if cmd == "LOGOUT" @logout_command_tag = tag end if block add_response_handler(block) end begin return get_tagged_response(tag, cmd) ensure if block remove_response_handler(block) end end end end

send_data(data) Show source

# File lib/net/imap.rb, line 1293 def send_data(data) case data when nil put_string("NIL") when String send_string_data(data) when Integer send_number_data(data) when Array send_list_data(data) when Time send_time_data(data) when Symbol send_symbol_data(data) else data.send_data(self) end end

send_list_data(list) Show source

# File lib/net/imap.rb, line 1342 def send_list_data(list) put_string("(") first = true list.each do |i| if first first = false else put_string(" ") end send_data(i) end put_string(")") end

send_literal(str) Show source

# File lib/net/imap.rb, line 1331 def send_literal(str) put_string("{" + str.bytesize.to_s + "}" + CRLF) @continuation_request_arrival.wait raise @exception if @exception put_string(str) end

send_number_data(num) Show source

# File lib/net/imap.rb, line 1338 def send_number_data(num) put_string(num.to_s) end

send_quoted_string(str) Show source

# File lib/net/imap.rb, line 1327 def send_quoted_string(str) put_string('"' + str.gsub(/["\]/n, "\\\\\\&") + '"') end

send_string_data(str) Show source

# File lib/net/imap.rb, line 1312 def send_string_data(str) case str when "" put_string('""') when /[\x80-\xff\r\n]/n # literal send_literal(str) when /[(){ \x00-\x1f\x7f%*"\]/n # quoted string send_quoted_string(str) else put_string(str) end end

send_symbol_data(symbol) Show source

# File lib/net/imap.rb, line 1366 def send_symbol_data(symbol) put_string("\\" + symbol.to_s) end

send_time_data(time) Show source

# File lib/net/imap.rb, line 1358 def send_time_data(time) t = time.dup.gmtime s = format('"%2d-%3s-%4d %02d:%02d:%02d +0000"', t.day, DATE_MONTH[t.month - 1], t.year, t.hour, t.min, t.sec) put_string(s) end

sort_internal(cmd, sort_keys, search_keys, charset) Show source

# File lib/net/imap.rb, line 1418 def sort_internal(cmd, sort_keys, search_keys, charset) if search_keys.instance_of?(String) search_keys = [RawData.new(search_keys)] else normalize_searching_criteria(search_keys) end normalize_searching_criteria(search_keys) synchronize do send_command(cmd, sort_keys, charset, *search_keys) return @responses.delete("SORT")[-1] end end

start_tls_session(params = {}) Show source

# File lib/net/imap.rb, line 1470 def start_tls_session(params = {}) unless defined?(OpenSSL::SSL) raise "SSL extension not installed" end if @sock.kind_of?(OpenSSL::SSL::SSLSocket) raise RuntimeError, "already using SSL" end begin params = params.to_hash rescue NoMethodError params = {} end context = SSLContext.new context.set_params(params) if defined?(VerifyCallbackProc) context.verify_callback = VerifyCallbackProc end @sock = SSLSocket.new(@sock, context) @sock.sync_close = true @sock.connect if context.verify_mode != VERIFY_NONE @sock.post_connection_check(@host) end end

store_internal(cmd, set, attr, flags) Show source

# File lib/net/imap.rb, line 1403 def store_internal(cmd, set, attr, flags) if attr.instance_of?(String) attr = RawData.new(attr) end synchronize do @responses.delete("FETCH") send_command(cmd, MessageSet.new(set), attr, flags) return @responses.delete("FETCH") end end

thread_internal(cmd, algorithm, search_keys, charset) Show source

# File lib/net/imap.rb, line 1431 def thread_internal(cmd, algorithm, search_keys, charset) if search_keys.instance_of?(String) search_keys = [RawData.new(search_keys)] else normalize_searching_criteria(search_keys) end normalize_searching_criteria(search_keys) send_command(cmd, algorithm, charset, *search_keys) return @responses.delete("THREAD")[-1] end

validate_data(data) Show source

# File lib/net/imap.rb, line 1276 def validate_data(data) case data when nil when String when Integer NumValidator.ensure_number(data) when Array data.each do |i| validate_data(i) end when Time when Symbol else data.validate end end