juks (juks) wrote in changelog,
juks
juks
changelog

[livejournal] r18653: LJSUP-8195 E-mail unsubscription

Committer: iaskarov
LJSUP-8195 E-mail unsubscription
U   trunk/bin/upgrading/proplists.dat
A   trunk/bin/worker/email-status
U   trunk/bin/worker/find-sendmail-problems
U   trunk/cgi-bin/LJ/DoSendEmail.pm
U   trunk/cgi-bin/LJ/SiteMessages.pm
U   trunk/cgi-bin/LJ/User/Email.pm
A   trunk/cgi-bin/LJ/User/EmailStatus.pm
U   trunk/htdocs/register.bml
Modified: trunk/bin/upgrading/proplists.dat
===================================================================
--- trunk/bin/upgrading/proplists.dat	2011-03-21 10:04:55 UTC (rev 18652)
+++ trunk/bin/upgrading/proplists.dat	2011-03-21 10:31:21 UTC (rev 18653)
@@ -1632,4 +1632,11 @@
   des: Counter of spam comments in this entry
   prettyname: Spam counter
   sortorder: 108
+  
+userproplist.email_faulty:
+  datatype: bool
+  des: True if user email was set as unconfirmed due to delivery related problems
+  cldversion: 8
+  prettyname: Email is faulty
 
+

Added: trunk/bin/worker/email-status
===================================================================
--- trunk/bin/worker/email-status	                        (rev 0)
+++ trunk/bin/worker/email-status	2011-03-21 10:31:21 UTC (rev 18653)
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+use strict;
+use lib "$ENV{LJHOME}/cgi-bin";
+use LJ::TryNBuy;
+use LJ::User::EmailStatus;
+
+require 'ljlib.pl';
+require 'ljprotocol.pl';
+require 'ljlang.pl';
+
+package LJ::NewWorker::TheSchwartz::EmailStatus;
+use base 'LJ::NewWorker::TheSchwartz';
+sub capabilities { qw/TheSchwartz::Worker::EmailStatus/ };
+
+__PACKAGE__->start;
+
+package TheSchwartz::Worker::EmailStatus;
+use base 'TheSchwartz::Worker';
+
+sub work {
+    my ($class, $job) = @_;
+    my $args = $job->arg;
+
+	warn "GOT A JOB";
+	
+	if(!$args->{email}) {
+		warn "TheSchwartz::Worker::EmailStatus: No Email";
+		
+		$job->completed;
+		return;
+	}
+	
+	LJ::User::EmailStatus->change_email_users_status(email => $args->{email}, disabled => $args->{disabled});
+		
+	$job->completed;
+    return;
+}
+
+1


Property changes on: trunk/bin/worker/email-status
___________________________________________________________________
Added: svn:executable
   + *

Modified: trunk/bin/worker/find-sendmail-problems
===================================================================
--- trunk/bin/worker/find-sendmail-problems	2011-03-21 10:04:55 UTC (rev 18652)
+++ trunk/bin/worker/find-sendmail-problems	2011-03-21 10:31:21 UTC (rev 18653)
@@ -1,4 +1,9 @@
 #!/usr/bin/perl
+
+#
+#	THIS CODE IS OBSOLETE NOW REPLACED BY email-status
+#
+
 use strict;
 
 use lib "$ENV{LJHOME}/cgi-bin";
@@ -12,6 +17,8 @@
 use LJ::User::Email;
 
 sub work {
+	return 0;
+
     my $emails = LJ::User::Email->get_marked_with_uids();
     foreach my $email (keys %$emails) {
         my $complete = 1; # reset this in case of any error with one of user for this email

Modified: trunk/cgi-bin/LJ/DoSendEmail.pm
===================================================================
--- trunk/cgi-bin/LJ/DoSendEmail.pm	2011-03-21 10:04:55 UTC (rev 18652)
+++ trunk/cgi-bin/LJ/DoSendEmail.pm	2011-03-21 10:31:21 UTC (rev 18653)
@@ -123,7 +123,8 @@
                                                 );
     unless ($smtp) {
         $class->error("Connection failed to domain '$host', MXes: [@ex]");
-        LJ::User::Email->mark(0, $rcpt, $class->error);
+        LJ::User::EmailStatus->handle_code(0, email => $rcpt);
+        #LJ::User::Email->mark(0, $rcpt, $class->error);
         return CONNECTION_FAILED;
     }
 
@@ -177,7 +178,7 @@
         $class->error("Permanent failure during $failed_phase phase to [$rcpt]: $details \n");
 
         ## log error
-        LJ::User::Email->mark(5, $rcpts, $err_msg);
+        LJ::User::EmailStatus->handle_code(5, email => $rcpt);
 
         ## handle other errors
         if ($failed_phase eq "TO"){
@@ -195,7 +196,7 @@
 
 
     ## flush errors if they are.
-    LJ::User::Email->mark(undef, $rcpt, "OK");
+    LJ::User::EmailStatus->handle_code(0, email => $rcpt);
 
     ##
     return OK;

Modified: trunk/cgi-bin/LJ/SiteMessages.pm
===================================================================
--- trunk/cgi-bin/LJ/SiteMessages.pm	2011-03-21 10:04:55 UTC (rev 18652)
+++ trunk/cgi-bin/LJ/SiteMessages.pm	2011-03-21 10:31:21 UTC (rev 18653)
@@ -14,6 +14,7 @@
     TryNBuy     => 256,
     AlreadyTryNBuy => 512,
     NeverTryNBuy   => 1024,
+    EmailFaulty    => 2048,
 };
 
 sub get_user_class {
@@ -24,6 +25,7 @@
     my $already_tb = LJ::TryNBuy->already_used($u);
     $add += AccountMask->{AlreadyTryNBuy} if $already_tb;
     $add += AccountMask->{NeverTryNBuy} unless $u->get_cap('trynbuy') or $already_tb;
+    $add += AccountMask->{EmailFaulty} if $u->prop('email_faulty');
 
     return $add + AccountMask->{Permanent} if $u->in_class('perm');
     return $add + AccountMask->{Sponsored} if $u->in_class('sponsored');

Modified: trunk/cgi-bin/LJ/User/Email.pm
===================================================================
--- trunk/cgi-bin/LJ/User/Email.pm	2011-03-21 10:04:55 UTC (rev 18652)
+++ trunk/cgi-bin/LJ/User/Email.pm	2011-03-21 10:31:21 UTC (rev 18653)
@@ -1,6 +1,10 @@
 package LJ::User::Email;
 use strict;
 
+#
+#   THIS PACKAGE IS OBSOLETE DO NOT USE
+#
+
 # status_code:
 #   undef   - OK: forget about problems with this address
 #   0       - cannot connect to MX-host or email domain.
@@ -12,6 +16,7 @@
     my $emails      = shift;    # One email if scalar or list of emails if array ref.
     my $message     = shift;
 
+    return;
     return if $LJ::DISABLED{'revoke_validation_on_errors'};
 
     if ('ARRAY' eq ref $emails) {

Added: trunk/cgi-bin/LJ/User/EmailStatus.pm
===================================================================
--- trunk/cgi-bin/LJ/User/EmailStatus.pm	                        (rev 0)
+++ trunk/cgi-bin/LJ/User/EmailStatus.pm	2011-03-21 10:31:21 UTC (rev 18653)
@@ -0,0 +1,166 @@
+package LJ::User::EmailStatus;
+use strict;
+
+my $max_error_count     = 3;                    # After this amount of smtp errors, occured within the faulty_period, the email status will be changed
+my $cache_time          = 86400;                # Memcached storage time
+my $faulty_period       = 86400 * 7;            # Minimal period, within the max_error_count should occur to cause the email status change
+my $max_faulty_period   = 86400 * 30;           # Maximal statistics storage time for the email
+
+#
+#   Handles SMTP code for some recipient email
+#
+sub handle_code {
+    my ($class, %params) = @_;
+    
+    return if $LJ::DISABLED{'revoke_validation_on_errors'};
+
+    die ('No Smtp Code')    if (!defined $params{code});
+    die ('No Email')        if (!$params{email});
+    die ('Invalid Email')   if (length($params{email}) > 50);
+    
+    my $cache_key = $class->get_cache_key($params{email});
+    
+    my $dbh;
+    my $data = undef; #'LJ::MemCache::get($cache_key);
+    
+    unless (defined $data) {
+        $dbh = LJ::get_db_writer() or die ('Failed to get db connection');
+        $data = $dbh->selectrow_hashref("SELECT * FROM email_status WHERE email = ?",
+                    undef,
+                    $params{email}
+                );    
+    }
+    
+    # If this email is disabled - we perfom no actions
+    return if ($data->{disabled});
+
+    # Address error count is increasing
+    if ($params{code} == 5) {
+        $dbh = LJ::get_db_writer() or die ('Failed to get db connection') if(!$dbh);
+             
+        if (!$data->{error_count} || time() - $data->{last_error_time} > $max_faulty_period) {
+            $data->{error_count}        = 1;
+            $data->{first_error_time}   = time();
+            $data->{last_error_time}    = time();
+
+            $dbh->do("REPLACE INTO email_status (email, error_count, first_error_time, last_error_time) VALUES (?, ?, ?, ?)",
+                        undef,
+                        $params{email}, $data->{error_count}, $data->{first_error_time}, $data->{last_error_time}
+                    );
+        } else {
+            $data->{error_count} ++;
+            $data->{last_error_time}  = time();
+
+            # Should put down this email if it is too faulty within minimum period of time
+            if ($data->{error_count} >= $max_error_count && ($data->{last_error_time} - $data->{first_error_time} > $faulty_period)) {
+                $data->{disabled}         = 1;
+                $class->process_disabled_status(%params, disabled => 1);
+            }
+
+            $dbh->do("UPDATE email_status SET error_count = ?, last_error_time = ?, disabled = ? WHERE email = ?",
+                        undef,
+                        $data->{error_count}, time(), $data->{disabled}, $params{email}
+                    ) or die('Failed to update record');
+        }
+        
+        LJ::MemCache::set($cache_key, $data, $cache_time);
+    # Address became OK, being faulty before
+    } elsif ($data->{error_count}) {
+        $dbh = LJ::get_db_writer() or die ('Failed to get db connection') if(!$dbh);
+             
+        $dbh->do("DELETE FROM email_status WHERE email = ?",
+                            undef,
+                            $params{email}
+                        );
+
+        $data->{error_count} = 0;
+        
+        LJ::MemCache::set($cache_key, $data, $cache_time);
+    }
+}
+
+#
+#   Change email status (active/not active)
+#
+sub process_disabled_status {
+    my ($class, %params) = @_;
+
+    die ('No Email') if (!$params{email});
+
+    my $sclient = LJ::theschwartz();
+    unless ($sclient) {
+        die "LJ::User::EmailStatus: Could not get TheSchwartz client";
+    }
+
+    # Set up the job
+    my $status_job = TheSchwartz::Job->new(
+        funcname  => "TheSchwartz::Worker::EmailStatus",
+        arg       => {  
+                        email       => $params{email},
+                        disabled    => $params{disabled}
+                     }
+    );
+
+    $sclient->insert($status_job);
+}
+
+#
+#   Change email users status
+#
+sub change_email_users_status {
+    my ($class, %params) = @_;
+
+    die ('No Email') if (!$params{email});
+    
+    my $is_disabled = $params{disabled} ? 1 : undef;
+    
+    LJ::MemCache::delete($class->get_cache_key($params{email})) if(!$params{disabled});
+   
+    my $dbh = LJ::get_db_writer() or die ('Failed to get db connection');
+    
+    unless ($is_disabled) {
+        $dbh->do("DELETE FROM email_status WHERE email = ?",
+                            undef,
+                            $params{email}
+                        );
+    }
+    
+    my @users;
+
+    unless ( $params{user} ) {
+        my $ids = $dbh->selectcol_arrayref("SELECT userid FROM email WHERE email = '" . $params{email} . "'");
+        my $users = LJ::load_userids(@$ids);
+        @users = values %$users;      
+    } else {
+        @users = ($params{user});
+    }
+ 
+    for my $user (@users) {
+       $user->set_prop('email_faulty', $is_disabled);
+       LJ::update_user($user, { 'status' => $is_disabled ? 'T' : 'A' } );
+    }
+}
+
+#
+#   Get Cache key
+#
+sub get_cache_key {
+    my ($class, $email) = @_;
+    
+    return 'email_status_' . $email;
+}
+
+#
+#   Drop the old outdated database entries
+#
+sub cleanup {
+    my $dbh = LJ::get_db_writer() or die ('Failed to get db connection');
+    
+    $dbh->do("DELETE FROM email_status WHERE unix_timestamp() - first_error_time > ?",
+                undef,
+                $max_faulty_period
+             );  
+}
+
+1;
+

Modified: trunk/htdocs/register.bml
===================================================================
--- trunk/htdocs/register.bml	2011-03-21 10:04:55 UTC (rev 18652)
+++ trunk/htdocs/register.bml	2011-03-21 10:31:21 UTC (rev 18653)
@@ -8,6 +8,7 @@
 
  use strict;
  use vars qw(%POST %GET $title);
+ use LJ::User::EmailStatus;
 
  LJ::set_active_crumb('register');
 
@@ -105,7 +106,9 @@
         }
      }
 
-     LJ::update_user($u, { status => 'A' });
+     LJ::User::EmailStatus->change_email_users_status(email => $u->email_raw, user => $u);
+     #LJ::update_user($u, { status => 'A' });
+     
      $u->update_email_alias;
      LJ::run_hook('email_verified', $u);
 

Tags: bml, dat, juks, livejournal, pm
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments