|
package SL::IMAPClient;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use utf8;
|
|
|
|
use IO::Socket::INET;
|
|
use IO::Socket::SSL;
|
|
use Mail::IMAPClient;
|
|
use Email::MIME;
|
|
use File::MimeInfo::Magic;
|
|
use Encode qw(encode decode);
|
|
use Encode::IMAPUTF7;
|
|
use SL::Locale;
|
|
|
|
use SL::SessionFile;
|
|
use SL::Locale::String qw(t8);
|
|
use SL::DB::EmailImport;
|
|
use SL::DB::EmailJournal;
|
|
use SL::DB::EmailJournalAttachment;
|
|
|
|
use SL::DB::Order;
|
|
|
|
sub new {
|
|
my ($class, %params) = @_;
|
|
my $config = $::lx_office_conf{imap_client} || {};
|
|
my $server_locale = Locale->new($::lx_office_conf{server}->{language});
|
|
my %record_type_to_folder = (
|
|
sales_quotation => $server_locale->text('Sales Quotations'),
|
|
sales_order => $server_locale->text('Sales Orders'),
|
|
);
|
|
my %record_folder_to_type = reverse %record_type_to_folder;
|
|
my $self = bless {
|
|
enabled => $config->{enabled},
|
|
hostname => $config->{hostname},
|
|
port => $config->{port},
|
|
ssl => $config->{ssl},
|
|
username => $config->{username},
|
|
password => $config->{password},
|
|
base_folder => $config->{base_folder} || 'INBOX',
|
|
record_type_to_folder => \%record_type_to_folder,
|
|
record_folder_to_type => \%record_folder_to_type,
|
|
%params,
|
|
}, $class;
|
|
return unless $self->{enabled};
|
|
$self->_create_imap_client();
|
|
return $self;
|
|
}
|
|
|
|
sub DESTROY {
|
|
my ($self) = @_;
|
|
if ($self->{imap_client}) {
|
|
$self->{imap_client}->logout();
|
|
}
|
|
}
|
|
|
|
sub store_email_in_email_folder {
|
|
my ($self, $email_string, $folder_path) = @_;
|
|
$folder_path ||= $self->{base_folder};
|
|
|
|
my $folder_string = $self->get_folder_string_from_path($folder_path);
|
|
$self->{imap_client}->append_string($folder_string, $email_string)
|
|
or die "Could not store email in folder '$folder_string': "
|
|
. $self->{imap_client}->LastError() . "\n";
|
|
}
|
|
|
|
sub update_emails_from_folder {
|
|
my ($self, $folder_path, $params) = @_;
|
|
$folder_path ||= $self->{base_folder};
|
|
|
|
my $folder_string = $self->get_folder_string_from_path($folder_path);
|
|
my $email_import =
|
|
_update_emails_from_folder_strings($self, $folder_path, [$folder_string], $params);
|
|
|
|
return $email_import;
|
|
}
|
|
|
|
sub update_emails_from_subfolders {
|
|
my ($self, $base_folder_path, $params) = @_;
|
|
$base_folder_path ||= $self->{base_folder};
|
|
my $base_folder_string = $self->get_folder_string_from_path($base_folder_path);
|
|
|
|
my @subfolder_strings = $self->{imap_client}->folders($base_folder_string)
|
|
or die "Could not get subfolders via IMAP: $@\n";
|
|
@subfolder_strings = grep { $_ ne $base_folder_string } @subfolder_strings;
|
|
|
|
my $email_import =
|
|
_update_emails_from_folder_strings($self, $base_folder_path, \@subfolder_strings, $params);
|
|
|
|
return $email_import;
|
|
}
|
|
|
|
sub _update_emails_from_folder_strings {
|
|
my ($self, $base_folder_path, $folder_strings, $params) = @_;
|
|
|
|
my $dbh = SL::DB->client->dbh;
|
|
|
|
my $email_import;
|
|
SL::DB->client->with_transaction(sub {
|
|
foreach my $folder_string (@$folder_strings) {
|
|
$self->{imap_client}->select($folder_string)
|
|
or die "Could not select IMAP folder '$folder_string': $@\n";
|
|
|
|
my $folder_uidvalidity = $self->{imap_client}->uidvalidity($folder_string)
|
|
or die "Could not get UIDVALIDITY for folder '$folder_string': $@\n";
|
|
|
|
my $msg_uids = $self->{imap_client}->messages
|
|
or die "Could not get messages via IMAP: $@\n";
|
|
|
|
my $query = <<SQL;
|
|
SELECT uid
|
|
FROM email_imports ei
|
|
LEFT JOIN email_journal ej
|
|
ON ej.email_import_id = ei.id
|
|
WHERE ei.host_name = ?
|
|
AND ei.user_name = ?
|
|
AND ej.folder = ?
|
|
AND ej.folder_uidvalidity = ?
|
|
SQL
|
|
|
|
my $existing_uids = $dbh->selectall_hashref($query, 'uid', undef,
|
|
$self->{hostname}, $self->{username}, $folder_string, $folder_uidvalidity);
|
|
|
|
my @new_msg_uids = grep { !$existing_uids->{$_} } @$msg_uids;
|
|
|
|
next unless @new_msg_uids;
|
|
|
|
$email_import ||= $self->_create_email_import($base_folder_path)->save();
|
|
|
|
foreach my $new_uid (@new_msg_uids) {
|
|
my $new_email_string = $self->{imap_client}->message_string($new_uid);
|
|
my $email = Email::MIME->new($new_email_string);
|
|
my $email_journal = $self->_create_email_journal(
|
|
$email, $email_import, $new_uid, $folder_string, $folder_uidvalidity, $params->{email_journal}
|
|
);
|
|
$email_journal->save();
|
|
}
|
|
}
|
|
});
|
|
|
|
return $email_import;
|
|
}
|
|
|
|
sub _create_email_import {
|
|
my ($self, $folder_path) = @_;
|
|
my $email_import = SL::DB:: |