Revision 743
- Date:
- 2018/11/14 22:54:18
- Files:
-
- /utf8/core/lib/Contenido/Accessor.pm (Diff) (Checkout)
- /utf8/core/lib/Contenido/Email.pm (Diff) (Checkout)
- /utf8/core/lib/Contenido/Init.pm (Diff) (Checkout)
- /utf8/core/lib/Contenido/Keeper.pm (Diff) (Checkout)
- /utf8/core/lib/Contenido/Mail.pm (Diff) (Checkout)
- /utf8/core/lib/Contenido/State.pm.proto (Diff) (Checkout)
- /utf8/core/services/mail_process.pl (Diff) (Checkout)
- /utf8/core/sql/TOAST/mailqueue.sql (Diff) (Checkout)
Legend:
- Added
- Removed
- Modified
-
utf8/core/lib/Contenido/Accessor.pm
1 package Contenido::Accessor; 2 3 sub mk_accessors { 4 my ($class, @names) = @_; 5 6 foreach my $name (@names) { 7 no strict 'refs'; 8 *{"${class}::$name"} = sub { 9 my $self = shift; 10 if ( @_ ) { 11 return $self->{$name} = shift; 12 } else { 13 return $self->{$name}; 14 } 15 }; 16 } 17 } 18 19 1; -
utf8/core/lib/Contenido/Email.pm
3 3 use strict; 4 4 use base 'Contenido::Document'; 5 5 use Contenido::Globals; 6 use SQL::MailQueueTable; 6 7 7 8 sub extra_properties 8 9 { 9 10 10 return ( 11 11 { 'attr' => 'status', 12 12 'cases' => [ … … 20 20 { 'attr' => 'cc', 'type' => 'text', 'rusname' => 'Дополнительные получатели (по одному на строку)', rows => 10 }, 21 21 { 'attr' => 'body_text', 'type' => 'text', 'rusname' => 'Текст письма (txt)', 'rows' => 40 }, 22 22 { 'attr' => 'body_html', 'type' => 'wysiwyg', 'rusname' => 'Текст письма (html)', 'rows' => 40 }, 23 { 'attr' => 'error', 'type' => 'text', 'rusname' => 'Сообщение об ошибке', 'rows' => 5 }, 23 24 { 'attr' => 'pictures', 'type' => 'images', 'rusname' => 'Список иллюстраций', preview => ['400x400'], crop => ['870x450','85x85'] }, 24 25 ) 25 26 } -
utf8/core/lib/Contenido/Init.pm
33 33 use Contenido::Section; 34 34 use Contenido::Keeper; 35 35 use Contenido::Image; 36 use Contenido::Mail; 37 use Contenido::Email; 36 38 # Типы данных 37 39 use Contenido::Type::File; 38 40 … … 239 241 push (@{ $state->{'available_sections'} }, 'Contenido::Section'); 240 242 push (@{ $state->{'available_users'} }, 'Contenido::User'); 241 243 push (@{ $state->{'available_links'} }, 'Contenido::Link'); 244 if ( $state->email_enable ) { 245 push (@{ $state->{'available_documents'} }, 'Contenido::Email'); 246 } 242 247 243 248 return $LR; 244 249 } -
utf8/core/lib/Contenido/Keeper.pm
1 2 1 package Contenido::Keeper; 3 2 4 3 # ---------------------------------------------------------------------------- -
utf8/core/lib/Contenido/Mail.pm
1 1 package Contenido::Mail; 2 2 3 use strict; 4 use warnings; 5 3 6 use Net::SMTP; 4 7 use MIME::Lite; 5 8 use MIME::Base64; 6 9 use Data::Dumper; 10 11 use parent 'Contenido::Accessor'; 12 __PACKAGE__->mk_accessors(qw(enable mailer from login password server hello timeout ssl port)); 13 7 14 use Contenido::Globals; 15 use Contenido::Email; 8 16 9 17 sub new { 10 my ($proto) = @_; 18 my ($proto, $args) = @_; 11 19 my $class = ref($proto) || $proto; 20 $args //= {}; 12 21 my $self = {}; 22 bless $self, $class; 13 23 14 $self->{enable} = $state->{email_enable}; 15 if ( $self->{enable} ) { 16 $self->{mailer} = $state->{email_mailer}; 17 $self->{from} = $state->{email_from}; 18 $self->{login} = $state->{email_auth_login}; 19 $self->{password} = $state->{email_auth_password}; 20 if ( $self->{mailer} eq 'smtp' ) { 21 $self->{server} = $state->{email_smtp_server}; 22 $self->{hello} = $state->{email_smtp_hello}; 23 $self->{timeout} = $state->{email_smtp_timeout}; 24 $self->{ssl} = $state->{email_smtp_ssl}; 25 $self->{port} = $state->{email_smtp_port}; 24 $self->enable( $state->{email_enable} ); 25 if ( $self->enable ) { 26 $self->mailer( $state->{email_mailer} ); 27 $self->from( $state->{email_from} ); 28 $self->login( delete $args->{login} || $state->{email_auth_login} ); 29 $self->password( delete $args->{password} || $state->{email_auth_password} ); 30 if ( $self->mailer eq 'smtp' ) { 31 $self->server( $state->{email_smtp_server} ); 32 $self->hello( $state->{email_smtp_hello} ); 33 $self->timeout( $state->{email_smtp_timeout} ); 34 $self->ssl( $state->{email_smtp_ssl} ); 35 $self->port( $state->{email_smtp_port} ); 26 36 } 27 37 } 28 38 29 bless $self, $class; 39 warn Dumper $self; 30 40 return $self; 31 41 } 32 42 … … 35 45 my $self; 36 46 if ( ref $_[0] eq 'Contenido::Mail' ) { 37 47 $self = shift; 48 } elsif ( !ref $_[0] && $_[0] eq 'Contenido::Mail' ) { 49 my $class = shift; 50 $self = $class->new; 38 51 } else { 39 52 $self = Contenido::Mail->new; 40 53 } … … 52 65 $subject =~ s/\s//sgi; 53 66 $subject = '=?utf-8?B?'.$subject.'?='; 54 67 68 my $error; 55 69 my $emailfrom; 56 70 if ( $email->{from} ) { 57 71 my ($from, $efrom) = $email->{from} =~ /^(.*?)<(.*?)>/ ? ($1, $2) : $email->{from} =~ /<(.*?)>/ ? ('',$1) : ('',$email->{from}); … … 148 162 $mailer->dataend; 149 163 $mailer->quit; 150 164 } else { 151 warn "MAIL ERROR! Can't connect to Yandex SMTP\n"; 165 $error = "MAIL ERROR! Can't connect to SMTP"; 166 warn "$error\n"; 152 167 } 153 168 } 169 return $error; 154 170 } 155 171 156 172 173 sub add { 174 return unless @_; 175 my $self; 176 if ( ref $_[0] eq 'Contenido::Mail' ) { 177 $self = shift; 178 } elsif ( !ref $_[0] && $_[0] eq 'Contenido::Mail' ) { 179 my $class = shift; 180 $self = $class->new; 181 } else { 182 $self = Contenido::Mail->new; 183 } 184 185 my $opts = shift // {}; 186 187 my $email = delete $opts->{email} // return undef; 188 return unless ref $email && exists $email->{to} && $email->{subject} && $email->{body}; 189 190 my $que = Contenido::Email->new( $keeper ); 191 $que->status( 0 ); 192 $que->name( $email->{to} ); 193 $que->subject( $email->{subject} ); 194 $que->body_html( $email->{body} ); 195 if ( exists $email->{text} ) { 196 $que->body_text( $email->{text} ); 197 } 198 if ( exists $email->{cc} && ref $email->{cc} eq 'ARRAY' ) { 199 $que->cc( join("\n", @{$email->{cc}}) ); 200 } elsif ( exists $email->{cc} && $email->{cc} ) { 201 $que->cc( $email->{cc} ); 202 } 203 if ( exists $email->{date} && ref $email->{date} eq 'DateTime' ) { 204 $que->dtime( $email->{date}->ymd('-').' '.$email->{date}->hms ); 205 } elsif ( exists $email->{date} && $email->{date} ) { 206 my $dt; 207 eval{ $dt = Contenido::DateTime->new( postgres => $email->{date} ) }; 208 if ( ref $dt ) { 209 $que->dtime( $dt->ymd('-').' '.$dt->hms ); 210 } 211 } else { 212 my $now = Contenido::DateTime->new; 213 $que->dtime( $now->ymd('-').' '.$now->hms ); 214 } 215 if ( $que->store ) { 216 return $que; 217 } 218 return undef; 219 } 220 157 221 1; -
utf8/core/lib/Contenido/State.pm.proto
150 150 $self->{email_from} = '@EMAIL_FROM@'; 151 151 $self->{email_auth_login} = '@EMAIL_LOGIN@'; 152 152 $self->{email_auth_password} = '@EMAIL_PASSWORD@'; 153 warn "Password: ".$self->{email_auth_password}."\n"; 153 154 if ( $self->{email_mailer} eq 'smtp' ) { 154 155 $self->{email_smtp_server} = '@EMAIL_SMTP_SERVER@'; 155 156 $self->{email_smtp_hello} = '@EMAIL_SMTP_HELLO@'; -
utf8/core/services/mail_process.pl
1 #!/usr/bin/perl 2 3 use strict; 4 use warnings "all"; 5 use locale; 6 7 BEGIN { require 'inc.pl' }; 8 9 use Contenido::Globals; 10 use Contenido::Init; 11 use ErrorTee; 12 use PidFile; 13 use Data::Dumper; 14 15 # begin 16 Contenido::Init->init(); 17 18 my $keeper_module = $state->project.'::Keeper'; 19 $keeper = $keeper_module->new($state); 20 21 #PidFile->new($keeper, compat=>1); # db-based locking (run only on one host) 22 #PidFile->new($keeper, compat=>1, per_host=>1); # db-based locking (run on whole cluster) 23 24 ############################################ 25 # please use: 26 # $state->{log_dir} for logging 27 # $state->{tmp_dir} for temporary files 28 ########################################### 29 $keeper->t_connect() || die $keeper->error(); 30 my $ids = $keeper->TSQL->selectall_arrayref("SELECT id FROM mailqueue WHERE status = 0 and dtime <= CURRENT_TIMESTAMP ORDER BY ctime LIMIT 5"); 31 if ( ref $ids eq 'ARRAY' && @$ids ) { 32 $keeper->TSQL->do("UPDATE mailqueue SET status = 2 WHERE ID IN (".join(',', '?' x scalar @$ids).")", {}, map { $_->[0] } @$ids); 33 } 34 $keeper->t_finish(); 35 36 if ( @$ids ) { 37 my $sendmail = Contenido::Mail->new({password => 'g8$feds1'}); 38 foreach my $row ( @$ids ) { 39 my $mail = $keeper->get_document_by_id($row->[0], class => 'Contenido::Email'); 40 if ( ref $mail ) { 41 my $data = { 42 to => $mail->name, 43 subject => $mail->subject, 44 body => $mail->body_html, 45 }; 46 if ( $mail->cc ) { 47 $data->{cc} = [split /\n/, $mail->cc]; 48 } 49 if ( $mail->body_text ) { 50 $data->{text} = $mail->body_text; 51 } 52 if ( my $err = $sendmail->send({ email => $data }) ) { 53 $mail->status(3); 54 $mail->error( $err ); 55 } else { 56 $mail->status(2); 57 } 58 $mail->store; 59 } 60 } 61 } -
utf8/core/sql/TOAST/mailqueue.sql
15 15 subject text, 16 16 data text 17 17 ); 18 create index mailqueue_sections on mailqueue (sections); 18 create index mailqueue_actual on mailqueue (status, dtime) WHERE status = 0; 19 19 create index mailqueue_dtime on mailqueue (dtime);