init III
This commit is contained in:
166
Perl OTRS/Kernel/cpan-lib/Sisimai/Mail/Maildir.pm
Normal file
166
Perl OTRS/Kernel/cpan-lib/Sisimai/Mail/Maildir.pm
Normal file
@@ -0,0 +1,166 @@
|
||||
package Sisimai::Mail::Maildir;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Accessor::Lite;
|
||||
use IO::Dir;
|
||||
use IO::File;
|
||||
|
||||
my $roaccessors = [
|
||||
'dir', # [String] Path to Maildir/
|
||||
];
|
||||
my $rwaccessors = [
|
||||
'path', # [String] Path to each file
|
||||
'file', # [String] Each file name of a mail in the Maildir/
|
||||
'inodes', # [Array] i-node List of files in the Maildir/
|
||||
'handle', # [IO::Dir] Directory handle
|
||||
];
|
||||
Class::Accessor::Lite->mk_accessors(@$rwaccessors);
|
||||
Class::Accessor::Lite->mk_ro_accessors(@$roaccessors);
|
||||
|
||||
sub new {
|
||||
# Constructor of Sisimai::Mail::Maildir
|
||||
# @param [String] argv1 Path to Maildir/
|
||||
# @return [Sisimai::Mail::Maildir,Undef] Object or Undef if the argument is
|
||||
# not a directory or does not exist
|
||||
my $class = shift;
|
||||
my $argv1 = shift // return undef;
|
||||
return undef unless -d $argv1;
|
||||
|
||||
my $param = {
|
||||
'dir' => $argv1,
|
||||
'file' => undef,
|
||||
'path' => undef,
|
||||
'inodes' => {},
|
||||
'handle' => IO::Dir->new($argv1),
|
||||
};
|
||||
return bless($param, __PACKAGE__);
|
||||
}
|
||||
|
||||
sub read {
|
||||
# Maildir reader, works as a iterator.
|
||||
# @return [String] Contents of file in Maildir/
|
||||
my $self = shift;
|
||||
return undef unless defined $self->{'dir'};
|
||||
return undef unless -d $self->{'dir'};
|
||||
|
||||
my $seekhandle = $self->{'handle'};
|
||||
my $filehandle = undef;
|
||||
my $readbuffer = '';
|
||||
my $emailindir = '';
|
||||
my $emailinode = undef;
|
||||
|
||||
eval {
|
||||
$seekhandle = IO::Dir->new($self->{'dir'}) unless $seekhandle;
|
||||
|
||||
while( my $r = $seekhandle->read ) {
|
||||
# Read each file in the directory
|
||||
next if( $r eq '.' || $r eq '..' );
|
||||
|
||||
$emailindir = $self->{'dir'}.'/'.$r;
|
||||
$emailindir =~ y{/}{}s;
|
||||
next unless -f $emailindir;
|
||||
next unless -s $emailindir;
|
||||
next unless -r $emailindir;
|
||||
|
||||
# Get inode number of the file
|
||||
$self->{'path'} = $emailindir;
|
||||
$emailinode = $^O eq 'MSWin32' ? $emailindir : [stat $emailindir]->[1];
|
||||
next if exists $self->{'inodes'}->{ $emailinode };
|
||||
|
||||
$filehandle = IO::File->new($emailindir, 'r');
|
||||
$readbuffer = do { local $/; <$filehandle> };
|
||||
$filehandle->close;
|
||||
|
||||
$self->{'inodes'}->{ $emailinode } = 1;
|
||||
$self->{'file'} = $r;
|
||||
|
||||
last;
|
||||
}
|
||||
};
|
||||
return $readbuffer;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Mail::Maildir - Mailbox reader
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Mail::Maildir;
|
||||
my $maildir = Sisimai::Mail::Maildir->new('/home/neko/Maildir/new');
|
||||
while( my $r = $maildir->read ) {
|
||||
print $r; # print contents of the mail in the Maildir/
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Mail::Maildir is a reader for getting contents of each email in the
|
||||
Maildir/ directory.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<new(I<path to Maildir/>)>>
|
||||
|
||||
C<new()> is a constructor of Sisimai::Mail::Maildir
|
||||
|
||||
my $maildir = Sisimai::Mail::Maildir->new('/home/neko/Maildir/new');
|
||||
|
||||
=head1 INSTANCE METHODS
|
||||
|
||||
=head2 C<B<dir()>>
|
||||
|
||||
C<dir()> returns the path to Maildir/
|
||||
|
||||
print $maildir->dir; # /home/neko/Maildir/new/
|
||||
|
||||
=head2 C<B<path()>>
|
||||
|
||||
C<path()> returns the path to each email in Maildir/
|
||||
|
||||
print $maildir->path; # /home/neko/Maildir/new/1.eml
|
||||
|
||||
=head2 C<B<file()>>
|
||||
|
||||
C<file()> returns current file name of the Maildir.
|
||||
|
||||
print $maildir->file;
|
||||
|
||||
=head2 C<B<inodes()>>
|
||||
|
||||
C<inodes()> returns i-node list of each email in Maildir.
|
||||
|
||||
print for @{ $maildir->inodes };
|
||||
|
||||
=head2 C<B<handle()>>
|
||||
|
||||
C<handle()> returns file handle object (IO::Dir) of the Maildir.
|
||||
|
||||
$maildir->handle->close;
|
||||
|
||||
=head2 C<B<read()>>
|
||||
|
||||
C<read()> works as a iterator for reading each email in the Maildir.
|
||||
|
||||
my $maildir = Sisimai::Mail->new('/home/neko/Maildir/new');
|
||||
while( my $r = $mailbox->read ) {
|
||||
print $r; # print each email in /home/neko/Maildir/new
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
163
Perl OTRS/Kernel/cpan-lib/Sisimai/Mail/Mbox.pm
Normal file
163
Perl OTRS/Kernel/cpan-lib/Sisimai/Mail/Mbox.pm
Normal file
@@ -0,0 +1,163 @@
|
||||
package Sisimai::Mail::Mbox;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Accessor::Lite;
|
||||
use File::Basename qw(basename dirname);
|
||||
use IO::File;
|
||||
|
||||
my $roaccessors = [
|
||||
'dir', # [String] Directory name of the mbox
|
||||
'file', # [String] File name of the mbox
|
||||
'path', # [String] Path to mbox
|
||||
'size', # [Integer] File size of the mbox
|
||||
];
|
||||
my $rwaccessors = [
|
||||
'offset', # [Integer] Offset position for seeking
|
||||
'handle', # [IO::File] File handle
|
||||
];
|
||||
Class::Accessor::Lite->mk_accessors(@$rwaccessors);
|
||||
Class::Accessor::Lite->mk_ro_accessors(@$roaccessors);
|
||||
|
||||
sub new {
|
||||
# Constructor of Sisimai::Mail::Mbox
|
||||
# @param [String] argv1 Path to mbox
|
||||
# @return [Sisimai::Mail::Mbox] Object or Undef if the argument is not
|
||||
# a file or does not exist
|
||||
my $class = shift;
|
||||
my $argv1 = shift // return undef;
|
||||
my $param = { 'offset' => 0 };
|
||||
return undef unless -f $argv1;
|
||||
|
||||
$param->{'dir'} = File::Basename::dirname $argv1;
|
||||
$param->{'path'} = $argv1;
|
||||
$param->{'size'} = -s $argv1;
|
||||
$param->{'file'} = File::Basename::basename $argv1;
|
||||
$param->{'handle'} = ref $argv1 ? $argv1 : IO::File->new($argv1, 'r');
|
||||
binmode $param->{'handle'};
|
||||
|
||||
return bless($param, __PACKAGE__);
|
||||
}
|
||||
|
||||
sub read {
|
||||
# Mbox reader, works as a iterator.
|
||||
# @return [String] Contents of mbox
|
||||
my $self = shift;
|
||||
|
||||
my $seekoffset = $self->{'offset'} // 0;
|
||||
my $filehandle = $self->{'handle'};
|
||||
my $readbuffer = '';
|
||||
|
||||
return undef unless defined $self->{'path'};
|
||||
unless( ref $self->{'path'} ) {
|
||||
# "path" is not IO::File object
|
||||
return undef unless -f $self->{'path'};
|
||||
return undef unless -T $self->{'path'};
|
||||
}
|
||||
return undef unless $self->{'offset'} < $self->{'size'};
|
||||
|
||||
eval {
|
||||
$seekoffset = 0 if $seekoffset < 0;
|
||||
seek($filehandle, $seekoffset, 0);
|
||||
|
||||
while( my $r = <$filehandle> ) {
|
||||
# Read the UNIX mbox file from 'From ' to the next 'From '
|
||||
last if( $readbuffer && substr($r, 0, 5) eq 'From ' );
|
||||
$readbuffer .= $r;
|
||||
}
|
||||
$seekoffset += length $readbuffer;
|
||||
$self->{'offset'} = $seekoffset;
|
||||
$filehandle->close unless $seekoffset < $self->{'size'};
|
||||
};
|
||||
return $readbuffer;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Mail::Mbox - Mailbox reader
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Mail::Mbox;
|
||||
my $mailbox = Sisimai::Mail::Mbox->new('/var/spool/mail/root');
|
||||
while( my $r = $mailbox->read ) {
|
||||
print $r; # print contents of each mail in mbox
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Mail::Mbox is a mailbox file (UNIX mbox) reader.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<new(I<path to mbox>)>>
|
||||
|
||||
C<new()> is a constructor of Sisimai::Mail::Mbox
|
||||
|
||||
my $mailbox = Sisimai::Mail::Mbox->new('/var/mail/root');
|
||||
|
||||
=head1 INSTANCE METHODS
|
||||
|
||||
=head2 C<B<dir()>>
|
||||
|
||||
C<dir()> returns the directory name of mbox
|
||||
|
||||
print $mailbox->dir; # /var/mail
|
||||
|
||||
=head2 C<B<path()>>
|
||||
|
||||
C<path()> returns the path to mbox.
|
||||
|
||||
print $mailbox->path; # /var/mail/root
|
||||
|
||||
=head2 C<B<file()>>
|
||||
|
||||
C<file()> returns a file name of the mbox.
|
||||
|
||||
print $mailbox->file; # root
|
||||
|
||||
=head2 C<B<size()>>
|
||||
|
||||
C<size()> returns the file size of the mbox.
|
||||
|
||||
print $mailbox->size; # 94515
|
||||
|
||||
=head2 C<B<offset()>>
|
||||
|
||||
C<offset()> returns offset position for seeking the mbox. The value of "offset"
|
||||
is bytes which have already read.
|
||||
|
||||
print $mailbox->offset; # 0
|
||||
|
||||
=head2 C<B<handle()>>
|
||||
|
||||
C<handle()> returns file handle object (IO::File) of the mbox.
|
||||
|
||||
$mailbox->handle->close;
|
||||
|
||||
=head2 C<B<read()>>
|
||||
|
||||
C<read()> works as a iterator for reading each email in the mbox.
|
||||
|
||||
my $mailbox = Sisimai::Mail->new('/var/mail/neko');
|
||||
while( my $r = $mailbox->read ) {
|
||||
print $r; # print each email in /var/mail/neko
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
129
Perl OTRS/Kernel/cpan-lib/Sisimai/Mail/Memory.pm
Normal file
129
Perl OTRS/Kernel/cpan-lib/Sisimai/Mail/Memory.pm
Normal file
@@ -0,0 +1,129 @@
|
||||
package Sisimai::Mail::Memory;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Accessor::Lite;
|
||||
|
||||
my $roaccessors = [
|
||||
'size', # [Integer] data size
|
||||
];
|
||||
my $rwaccessors = [
|
||||
'data', # [Array] entire bounce mail message
|
||||
'offset', # [Integer] Index of "data"
|
||||
];
|
||||
Class::Accessor::Lite->mk_accessors(@$rwaccessors);
|
||||
Class::Accessor::Lite->mk_ro_accessors(@$roaccessors);
|
||||
|
||||
sub new {
|
||||
# Constructor of Sisimai::Mail::Memory
|
||||
# @param [String] argv1 Entire email string
|
||||
# @return [Sisimai::Mail::Memory] Object or Undef if the argument is not
|
||||
# valid email text
|
||||
my $class = shift;
|
||||
my $argv1 = shift // return undef;
|
||||
my $first = substr($$argv1, 0, 5) || '';
|
||||
my $param = {
|
||||
'data' => [],
|
||||
'size' => length $$argv1 || 0,
|
||||
'offset' => 0,
|
||||
};
|
||||
|
||||
return undef unless $param->{'size'};
|
||||
if( $first eq 'From ') {
|
||||
# UNIX mbox
|
||||
$param->{'data'} = [split(/^From /m, $$argv1)];
|
||||
shift @{ $param->{'data'} };
|
||||
map { $_ = 'From '.$_ } @{ $param->{'data'} };
|
||||
|
||||
} else {
|
||||
$param->{'data'} = [$$argv1];
|
||||
}
|
||||
return bless($param, __PACKAGE__);
|
||||
}
|
||||
|
||||
sub read {
|
||||
# Memory reader, works as a iterator.
|
||||
# @return [String] Contents of a bounce mail
|
||||
my $self = shift;
|
||||
return undef unless scalar @{ $self->{'data'} };
|
||||
|
||||
$self->{'offset'} += 1;
|
||||
return shift @{ $self->{'data'} };
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Mail::Memory - Mailbox reader
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Mail::Memory;
|
||||
my $mailtxt = 'From Mailer-Daemon ...';
|
||||
my $mailobj = Sisimai::Mail::Memory->new(\$mailtxt);
|
||||
while( my $r = $mailobj->read ) {
|
||||
print $r; # print contents of each mail in the mailbox or Maildir/
|
||||
}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Mail::Memory is a class for reading a mailbox, files in Maildir/, or
|
||||
JSON string from variable.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<new(I<\$scalar>)>>
|
||||
|
||||
C<new()> is a constructor of Sisimai::Mail::Memory
|
||||
|
||||
my $mailtxt = 'From Mailer-Daemon ...';
|
||||
my $mailobj = Sisimai::Mail::Memory->new(\$mailtxt);
|
||||
|
||||
=head1 INSTANCE METHODS
|
||||
|
||||
=head2 C<B<size()>>
|
||||
|
||||
C<size()> returns a memory size of the mailbox or JSON string.
|
||||
|
||||
print $mailobj->size; # 94515
|
||||
|
||||
=head2 C<B<data()>>
|
||||
|
||||
C<data()> returns an array reference to each email message or JSON string
|
||||
|
||||
print scalar @{ $mailobj->data }; # 17
|
||||
|
||||
=head2 C<B<offset()>>
|
||||
|
||||
C<offset()> returns an offset position for seeking "data". The value of "offset"
|
||||
is an index number which have already read.
|
||||
|
||||
print $mailobj->offset; # 0
|
||||
|
||||
=head2 C<B<read()>>
|
||||
|
||||
C<read()> works as a iterator for reading each email in the mailbox.
|
||||
|
||||
my $mailtxt = 'From Mailer-Daemon ...';
|
||||
my $mailobj = Sisimai::Mail->new(\$mailtxt);
|
||||
while( my $r = $mailobj->read ) {
|
||||
print $r; # print each email in the first argument of new().
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
|
||||
138
Perl OTRS/Kernel/cpan-lib/Sisimai/Mail/STDIN.pm
Normal file
138
Perl OTRS/Kernel/cpan-lib/Sisimai/Mail/STDIN.pm
Normal file
@@ -0,0 +1,138 @@
|
||||
package Sisimai::Mail::STDIN;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Accessor::Lite;
|
||||
use IO::Handle;
|
||||
|
||||
my $roaccessors = [
|
||||
'path', # [String] Path to mbox
|
||||
'name', # [String] File name of the mbox
|
||||
'size', # [Integer] File size of the mbox
|
||||
];
|
||||
my $rwaccessors = [
|
||||
'offset', # [Integer] Offset position for seeking
|
||||
'handle', # [IO::File] File handle
|
||||
];
|
||||
Class::Accessor::Lite->mk_accessors(@$rwaccessors);
|
||||
Class::Accessor::Lite->mk_ro_accessors(@$roaccessors);
|
||||
|
||||
sub new {
|
||||
# Constructor of Sisimai::Mail::STDIN
|
||||
# @return [Sisimai::Mail::STDIN] Object
|
||||
my $class = shift;
|
||||
my $param = {
|
||||
'path' => '<STDIN>',
|
||||
'name' => '<STDIN>',
|
||||
'size' => undef,
|
||||
'offset' => 0,
|
||||
'handle' => IO::Handle->new->fdopen(fileno(STDIN), 'r'),
|
||||
};
|
||||
return bless($param, __PACKAGE__);
|
||||
}
|
||||
|
||||
sub read {
|
||||
# Mbox reader, works as a iterator.
|
||||
# @return [String] Contents of mbox
|
||||
my $self = shift;
|
||||
return undef unless -T $self->{'handle'};
|
||||
|
||||
my $readhandle = $self->{'handle'};
|
||||
my $readbuffer = '';
|
||||
eval {
|
||||
$readhandle = $self->{'handle'}->fdopen(fileno(STDIN), 'r') unless eof $readhandle;
|
||||
|
||||
while( my $r = <$readhandle> ) {
|
||||
# Read an email from the mailbox file
|
||||
last if( $readbuffer && substr($r, 0, 5) eq 'From ' );
|
||||
$readbuffer .= $r;
|
||||
}
|
||||
};
|
||||
return $readbuffer;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Mail::STDIN - Mailbox reader
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Mail::STDIN;
|
||||
my $mailbox = Sisimai::Mail::STDIN->new();
|
||||
while( my $r = $mailbox->read ) {
|
||||
print $r; # print data read from STDIN
|
||||
}
|
||||
$mailbox->close;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Mail::STDIN read email data from STDIN.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<new()>>
|
||||
|
||||
C<new()> is a constructor of Sisimai::Mail::STDIN
|
||||
|
||||
my $mailbox = Sisimai::Mail::STDIN->new();
|
||||
|
||||
=head1 INSTANCE METHODS
|
||||
|
||||
=head2 C<B<path()>>
|
||||
|
||||
C<path()> returns "<STDIN>"
|
||||
|
||||
print $mailbox->path; # "<STDIN>"
|
||||
|
||||
=head2 C<B<name()>>
|
||||
|
||||
C<name()> returns "<STDIN>"
|
||||
|
||||
print $mailbox->name; # "<STDIN>"
|
||||
|
||||
=head2 C<B<size()>>
|
||||
|
||||
C<size()> returns "undef"
|
||||
|
||||
print $mailbox->size; # undef
|
||||
|
||||
=head2 C<B<offset()>>
|
||||
|
||||
C<offset()> returns offset position for seeking the mbox. The value of "offset"
|
||||
is bytes which have already read.
|
||||
|
||||
print $mailbox->offset; # 0
|
||||
|
||||
=head2 C<B<handle()>>
|
||||
|
||||
C<handle()> returns file handle object (IO::Handle) of the mbox.
|
||||
|
||||
$mailbox->handle->close;
|
||||
|
||||
=head2 C<B<read()>>
|
||||
|
||||
C<read()> works as a iterator for reading each email in the mbox.
|
||||
|
||||
my $mailbox = Sisimai::Mail->new();
|
||||
while( my $r = $mailbox->read ) {
|
||||
print $r; # print data read from STDIN
|
||||
}
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
|
||||
Reference in New Issue
Block a user