Perl - IMAP 使用 X-GM-RAW 搜索 unicode 字符串

Perl - IMAP search unicode string with X-GM-RAW

我正在使用 PerlMail::IMAPClient 模块来搜索电子邮件并从 Gmail 服务器获取它们,但遇到了问题在 X-GM-RAW 中使用 unicode 字符串。

当我发送命令时:

SEARCH CHARSET UTF-8 X-GM-RAW "Новости"

它不起作用:(

但是

SEARCH CHARSET UTF-8 X-GM-RAW "News"

工作没有问题,returns 消息 ID 列表

我的 perl 脚本如下所示:

#!/usr/bin/env perl

use utf8::all;
use strict;
use warnings;
use feature 'say';
use Mail::IMAPClient;

my $imap = Mail::IMAPClient->new(
    Server   => 'imap.gmail.com',
    User     => 'username@gmail.com',
    Password => 'secr3t',
    Ssl      => 1,
    Uid      => 0,
    Debug    => 1
);

$imap->select('[Gmail]/All Mail');
my $news = $imap->search('CHARSET UTF-8 X-GM-RAW "Новости"');
print "@$news"; # print message ids

调试消息:

Started at Wed Apr 15 00:25:43 2015
Using Mail::IMAPClient version 3.35 on perl 5.020002
Connecting with IO::Socket::SSL PeerAddr imap.gmail.com PeerPort 993 Proto tcp Timeout 600 Debug 1
Connected to imap.gmail.com
Read:   * OK Gimap ready for requests from 178.47.31.152 e1mb42229459lab
Sending: 1 LOGIN username@gmail.com secr3t
Sent 43 bytes
Read:   * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT
    1 OK username@gmail.com authenticated (Success)
Sending: 2 SELECT "[Gmail]/All Mail"
Sent 29 bytes
Read:   * FLAGS (\Answered \Flagged \Draft \Deleted \Seen $label3 $Phishing $Forwarded $MDNSent Old $NotJunk NotJunk NonJunk $NotPhishing Junk)
    * OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $label3 $Phishing $Forwarded $MDNSent Old $NotJunk NotJunk NonJunk $NotPhishing Junk \*)] Flags permitted.
    * OK [UIDVALIDITY 596378645] UIDs valid.
    * 36992 EXISTS
    * 0 RECENT
    * OK [UIDNEXT 99973] Predicted next UID.
    * OK [HIGHESTMODSEQ 3390697]
    2 OK [READ-WRITE] [Gmail]/All Mail selected. (Success)
Sending: 3 SEARCH CHARSET UTF-8 X-GM-RAW "Новости"
Sent 41 bytes
...

而且不停... 直到我用 Ctrl+C

杀了他

如果你已经解决了这个问题,请帮忙!)

谢谢!

发送

0 ENABLE UTF8=ACCEPT

首先。 enable 命令启用特定的服务器功能,在这种情况下,相关功能是在带引号的字符串(“Новости”)中使用 UTF-8 的能力。如果您想阅读更多内容,则适用 RFC 5161 和 6855,但这并不是真正必要的。

所有 IMAP 服务器都允许您在文字 ({14}CRLFНовости) 或非同步文字 ({14+}CRLFНовости) 中使用 UTF8,但是带引号的字符串要方便得多,而且 gmail 确实支持 enable.

找到方法 Quote,它按照你说的做:

returns its argument as a correctly quoted string or a literal string.

并添加了带有 no utf8 pragma 的块以切换回将源文本视为当前词法范围中的文字字节。

#!/usr/bin/env perl

use utf8;
use strict;
use warnings;
use feature 'say';
use Mail::IMAPClient;

my $imap = Mail::IMAPClient->new(
    Server   => 'imap.gmail.com',
    User     => 'username@gmail.com',
    Password => 'secr3t',
    Ssl      => 1,
    Uid      => 0,
    Debug    => 1
);

$imap->select('[Gmail]/All Mail');

my $newsid_ref;
{
    no utf8;
    my $string = $imap->Quote("Новости");
    $newsid_ref = $imap->search('CHARSET UTF-8 X-GM-RAW ' . $string);
}
say for @$newsid_ref;

现在脚本可以正常工作了。