AxKit2
view release on metacpan or search on metacpan
plugins/demo/webmail view on Meta::CPAN
#!/usr/bin/perl -w
use Digest::SHA1 qw(sha1_hex);
use AxKit2::Utils qw(xml_escape);
use Net::IMAP::Simple::NB;
use Matts::Message::Parser;
use Scalar::Util qw(weaken isweak);
use Data::Pageset;
use Time::Piece qw(gmtime);
use Text::Wrap qw(wrap);
use File::Temp qw(tempfile);
my %imap_cache;
my %password_cache;
sub conf_IMAP_Server;
sub conf_IMAP_Port;
sub register {
my $self = shift;
$self->register_hook('xmlresponse' => 'main_response');
$self->register_hook('xmlresponse' => 'main_response_cont');
$self->register_hook('xmlresponse' => 'auth_response');
$self->register_hook('xmlresponse' => 'auth_response_cont');
}
sub main_response {
my ($self, $input) = @_;
my $client = $self->client;
my $headers = $client->headers_in;
$client->notes('mail_response', DECLINED);
my $cookie = $headers->cookie('mail_session');
# No cookie, skip to auth
return DECLINED unless $cookie;
# Cookie invalid/expired, skip to auth
my $login = eval { decookie($cookie) };
if ($@) {
$self->log(LOGINFO, $@);
$client->notes('cookie_failure', $@);
return DECLINED;
}
my $server = shift @{ $imap_cache{$login} || [] };
if ($server) {
my $bref = $server->read(1);
if (!defined $bref) {
# connection went away, login again
return $self->imap_login($input, $client, $headers, $login, $password_cache{$login}) if $password_cache{$login};
return DECLINED; # if password isn't currently stored for some reason
}
}
else {
return $self->imap_login($input, $client, $headers, $login, $password_cache{$login}) if $password_cache{$login};
return DECLINED; # if password isn't currently stored for some reason
}
push @{ $imap_cache{$login} }, $server;
$self->display_page($input, $client, $headers, $login);
# Everything IMAP happens as a continuation
return CONTINUATION;
plugins/demo/webmail view on Meta::CPAN
my $relative = $full_uri;
$relative =~ s/^\///;
my $output = '<webmail><uri>' . xml_escape($relative) . '</uri>' .
'<base-uri>http://' . xml_escape($headers->header('Host') . $client->config->path) . '/</base-uri>' .
'<user>'. xml_escape($login) . '</user>';
print "Full URI: $full_uri\n";
if ($full_uri =~ /\/folder\/([^\/]+)(\/([^\/]*))?/) {
my $folder = $1;
my $msg = $3;
print "URI parsed to: $folder, $msg\n";
if ($msg) {
return $self->display_email($input, $client, $headers, $login, $output, $folder, $msg);
}
else {
return $self->display_folder_list($input, $client, $headers, $login, $output, $folder);
}
}
elsif ($full_uri =~ /\/folders$/) {
return $self->display_all_folders($input, $client, $headers, $login, $output);
}
else {
return $self->display_main_page($input, $client, $headers, $login, \$output);
}
}
sub display_main_page {
my ($self, $input, $client, $headers, $login, $output) = @_;
$$output .= '</webmail>';
print "Output: $$output\n";
$input->dom($$output);
my $out = $input->transform(TAL($client->config->docroot . '/main.tal'));
$out->output();
$client->notes('mail_response', DONE);
return $client->finish_continuation;
}
sub display_all_folders {
my ($self, $input, $client, $headers, $login, $output) = @_;
# get imap connection and delete it from the valid pool.
my $imap = shift @{ $imap_cache{$login} || [] }
|| die "Should never get here without a valid IMAP connection";
print "All Folders Using IMAP Server: $imap\n";
# Get folders
$imap->mailboxes(sub {
my @boxes = @_;
$output .= '<mailboxes>';
my $start = "INBOX";
my $sub;
$sub = sub {
weaken($sub) unless isweak($sub);
my $num_msgs = shift;
print "Got $start ($num_msgs)\n";
$output .= '<mailbox><name>' . xml_escape($start) . '</name>' .
'<count>' . xml_escape($num_msgs) . '</count>' .
'</mailbox>';
if (@boxes) {
$start = shift @boxes;
$imap->select($start, $sub);
}
else {
$output .= '</mailboxes>';
return $self->finish_output(\$output, $input, $client, 'folders.xsl');
}
};
$imap->select($start, $sub);
});
return CONTINUATION;
}
sub display_folder_list {
my ($self, $input, $client, $headers, $login, $output, $folder) = @_;
# get imap connection and delete it from the valid pool.
my $imap = shift @{ $imap_cache{$login} || [] }
|| die "Should never get here without a valid IMAP connection";
print "Folder $folder list Using IMAP Server: $imap\n";
$imap->select($folder, sub {
my $num_in_selected = shift;
if (!$num_in_selected) {
# folder didn't exist probably
$output .= '<error>' . xml_escape($Net::IMAP::Simple::errstr) . '</error>';
return $self->finish_output(\$output, $input, $client);
}
my $pageset = Data::Pageset->new({
total_entries => $num_in_selected,
entries_per_page => 50,
mode => 'slide',
pages_per_set => 10,
});
$output .= pageset_xml($pageset, $headers);
my $current = $pageset->first;
my $last = $pageset->last;
$output .= '<contents folder="' . xml_escape($folder) . '">';
my $sub;
$sub = sub {
weaken($sub) unless isweak($sub);
my $headers = shift;
if ($headers) {
my ($from) = grep {/^From:/i} @$headers;
my ($subj) = grep {/^Subject:/i} @$headers;
my ($recvd) = grep {/^Received:/i} @$headers;
my ($date) = grep {/^Date:/i} @$headers;
s/^.*?:\s*// for ($from, $subj, $recvd, $date);
local $/="\r\n";
chomp($from, $subj);
my $parsed_recvd_time;
my $time;
if ($recvd =~ /(\d{1,2} [a-z]{3} \d{4} \d\d:\d\d:\d\d)/i) {
#print "parsing recieved header date: $1\n";
$time = Time::Piece->strptime($1, '%d %b %Y %H:%M:%S');
}
elsif ($date =~ /(\d{1,2} [a-z]{3} \d{4} \d\d:\d\d:\d\d)/i) {
#print "parsing Date header date: $1\n";
$time = Time::Piece->strptime($1, '%d %b %Y %H:%M:%S');
}
else {
$time = gmtime;
}
my $today = gmtime;
my $today_midnight = $today - ($today->hour * 60 * 60 + $today->min * 60 + $today->sec);
my $yesterday = $today_midnight - (60 * 60 * 24);
my $output_date;
if ($time >= $today_midnight) {
$output_date = "Today";
}
elsif ($time >= $yesterday) {
$output_date = "Yesterday";
}
else {
$output_date = join(' ', $time->day_of_month, $time->fullmonth, $time->year);
}
print "got mail: $subj ($output_date)\n";
$output .= "<mail id='$current'>" .
'<from>' . xml_escape($from) . '</from>' .
'<subject>' . xml_escape($subj) . '</subject>' .
'<received_at><date>' . xml_escape($output_date) . '</date>' .
'<time>' . xml_escape($time->hms) . '</time>' .
'</received_at>' .
'</mail>';
}
else {
$self->log(LOGDEBUG, "Unable to get headers for $login/$folder::$current");
}
if ($current >= $last) {
$output .= '</contents>';
return $self->finish_output(\$output, $input, $client, 'contents.xsl');
}
else {
$current++;
$imap->top($current, $sub);
}
};
$imap->top($current, $sub);
});
( run in 0.631 second using v1.01-cache-2.11-cpan-39bf76dae61 )