AnyEvent-IMAP
view release on metacpan or search on metacpan
lib/AnyEvent/IMAP.pm view on Meta::CPAN
package AnyEvent::IMAP;
use strict;
use warnings;
use 5.010001;
our $VERSION = '0.04';
use parent qw(Object::Event);
use AnyEvent::Socket;
use AnyEvent::Handle;
use AnyEvent::TLS;
use Mail::IMAP::Util;
use Mouse;
has 'socket' => (is => 'ro');
has 'ssl' => (is => 'rw', isa => 'Bool');
has 'host' => (is => 'rw');
has 'port' => (is => 'rw');
has 'user' => (is => 'rw');
has 'pass' => (is => 'rw');
has id => (is => 'ro', default => sub { 1 });
sub connect {
my ($self) = @_;
if ($self->{socket}) {
$self->disconnect("reconnect requested");
}
my $cv = AE::cv();
$self->{accumulator} = [];
$self->{lineparts} = [];
$self->{socket} = AnyEvent::Handle->new(
connect => [$self->host, $self->port],
($self->ssl ? (tls => 'connect') : ()),
on_connect => sub {
my ($handle, $host, $port, $retry) = @_;
$self->{socket}->push_read(
line => "\r\n", sub {
my ($handle, $line) = @_;
if ($line =~ /^\*\s+OK/) {
$cv->send(1, $line);
$self->event('connect');
} else {
$cv->send(0, $line);
$self->event('connect_error');
}
},
);
},
on_starttls => sub {
$self->event('starttls');
},
on_eof => sub {
$self->disconnect("EOF from server $self->{host}: $self->{port}");
},
on_error => sub {
$self->disconnect("Error in connection to server $self->{host}: $self->{port}: $!");
},
on_drain => sub {
$self->event('buffer_empty');
},
on_read => sub {
$self->{socket}->push_read('regex' => qr{((?:^.+?\r\n)*)(NIC\d+)\s+([A-Z_]+)[^\r\n]+\r\n}, sub {
my ($handle, $res) = @_;
$self->event('recv', $res);
my $id = $2;
my $status = $3;
my $ok = $status eq 'OK' ? 1 : 0;
if (my $cv = delete $self->{cvmap}->{$id}) {
my @lines = split /\r\n/, $res;
pop @lines; # remove last line
if ($ok && (my $filter = delete $self->{filters}->{$id})) {
$res = $filter->(@lines)
} else {
$res = \@lines;
}
$cv->send($ok, $res);
}
});
},
);
return $cv;
}
sub login {
my $self = shift;
my $user = imap_string_quote($self->user);
my $pass = imap_string_quote($self->pass);
my ($id, $cv) = $self->send_cmd("LOGIN $user $pass");
return $cv;
}
sub disconnect {
my ($self, $reason) = @_;
lib/AnyEvent/IMAP.pm view on Meta::CPAN
sub select {
my ($self, $folder) = @_;
$folder = imap_string_quote($folder);
my ($id, $cv) = $self->send_cmd("SELECT $folder");
return $cv;
}
sub fetch {
my ($self, $query) = @_;
my ($id, $cv) = $self->send_cmd("FETCH $query", sub {
# in form: [ '*', ID, 'FETCH', [ tokens ]]
[map { +{@{$_->[3]}} } grep { $_->[2] eq 'FETCH' } map {imap_parse_tokens([$_])} @_]
});
return $cv;
}
sub expunge {
my ($self) = @_;
my ($id, $cv) = $self->send_cmd('EXPUNGE');
return $cv;
}
sub create_folder {
my ($self, $folder) = @_;
$folder = imap_string_quote($folder);
my ($id, $cv) = $self->send_cmd("CREATE $folder");
return $cv;
}
sub noop {
my ($self) = @_;
my ($id, $cv) = $self->send_cmd('NOOP');
return $cv;
}
# TODO:
# add_flags
# copy
# search('ALL')
# get_part_body
1;
__END__
=encoding utf8
=head1 NAME
AnyEvent::IMAP - IMAP client library for AnyEvent
=head1 SYNOPSIS
use AnyEvent::IMAP;
my $imap = AnyEvent::IMAP->new(
host => 'server',
user => "USERID",
pass => 'password',
port => 993,
ssl => 1,
);
$imap->reg_cb(
connect => sub {
$imap->login()->cb(sub {
my ($ok, $line) = shift->recv;
...
}
}
);
$imap->connect();
=head1 DESCRIPTION
AnyEvent::IMAP is IMAP client library for AnyEvent/Perl.
=head1 METHODS
And some methods are usable by L<Object::Event>.
=over 4
=item my $imap = AnyEvent::IMAP->new(%args);
Create a new instance with following attributes.
=over 4
=item host
=item user
=item pass
=item port
=item ssl
=back
=item my ($tag, $cv) = $imap->send_cmd($command[, $filter : CodeRef])
Send a $command to the server. You can filter the response by optional $filter.
$tag is a IMAP command tag.
$cv is a instance of L<AnyEvent::CondVar>. You can process the server response by following format.
my ($tag, $cv) = $imap->send_cmd('LOGIN');
$cv->cb(sub {
my ($ok, $res) = shift->recv;
...
});
First response value is $ok. It presents server status is OK or not in boolean value.
$res is a response value. You can filter it by $filter in argument.
=back
=head1 EVENTS
=over 4
=item connect
=item connect_error
=item disconnect
=item buffer_empty
=item send
=item recv
=back
=head1 AND Example code
is available in example/demo.pl
=head1 FAQ
=over 4
=item How can I decode UTF-7 folder names?
use L<Encode::IMAPUTF7>.
=back
=head1 AUTHOR
Tokuhiro Matsuno E<lt>tokuhirom AAJKLFJEF@ GMAIL COME<gt>
=head1 THANKS TO
( run in 0.788 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )