Now processes broken addresses through the web site.
authorStéphane Jacob <sj@m4x.org>
Sun, 11 Oct 2009 10:59:52 +0000 (12:59 +0200)
committerStéphane Jacob <sj@m4x.org>
Sun, 18 Oct 2009 17:09:42 +0000 (19:09 +0200)
bin/emails.broken.helper.php [deleted file]
bin/emails.broken.php [deleted file]
modules/email.php
templates/admin/index.tpl
templates/emails/broken_addr.tpl [new file with mode: 0644]

diff --git a/bin/emails.broken.helper.php b/bin/emails.broken.helper.php
deleted file mode 100755 (executable)
index 2e7f08c..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/php5 -q
-<?php
-/***************************************************************************
- *  Copyright (C) 2003-2009 Polytechnique.org                              *
- *  http://opensource.polytechnique.org/                                   *
- *                                                                         *
- *  This program is free software; you can redistribute it and/or modify   *
- *  it under the terms of the GNU General Public License as published by   *
- *  the Free Software Foundation; either version 2 of the License, or      *
- *  (at your option) any later version.                                    *
- *                                                                         *
- *  This program is distributed in the hope that it will be useful,        *
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
- *  GNU General Public License for more details.                           *
- *                                                                         *
- *  You should have received a copy of the GNU General Public License      *
- *  along with this program; if not, write to the Free Software            *
- *  Foundation, Inc.,                                                      *
- *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************/
-
-ini_set('include_path', '.:../include:/usr/share/php');
-
-require_once('connect.db.inc.php');
-require_once('emails.inc.php');
-
-$opts = getopt('o:');
-if (($opts['o'] && $opts['o'] == '-') || empty($opts['o'])) {
-    printf("Usage: emails.broken.helper.php -o <file>\n");
-    exit(1);
-} else {
-    $output = $opts['o'];
-}
-
-$input_fd = fopen("php://stdin", "r");
-$output_fd = fopen($output, "a");
-
-while ($_email = fgets($input_fd)) {
-    $_email = trim($_email);
-    $email = valide_email($_email);
-    if (empty($email) || $email=='@') {
-        printf(">> %s: invalid email\n", $_email);
-        continue;
-    }
-
-    $sel = XDB::query(
-            "SELECT  e1.uid, e1.panne != 0 AS panne, count(e2.uid) AS nb_mails, u.nom, u.prenom, u.promo, a.alias
-               FROM  emails        AS e1
-          LEFT JOIN  emails        AS e2 ON (e1.uid = e2.uid AND FIND_IN_SET('active', e2.flags) AND e1.email != e2.email)
-         INNER JOIN  auth_user_md5 AS u  ON (e1.uid = u.user_id)
-         INNER JOIN  aliases       AS a  ON (u.user_id = a.id AND FIND_IN_SET('bestalias',a.flags))
-              WHERE  e1.email = {?}
-           GROUP BY  e1.uid", $email);
-    if ($sel->numRows() > 0) {
-        fwrite($output_fd, $email . "\n");
-    } else {
-        printf(">> %s: email not in the database\n", $_email);
-    }
-}
-
-fclose($input_fd);
-fclose($output_fd);
-
-// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
-?>
diff --git a/bin/emails.broken.php b/bin/emails.broken.php
deleted file mode 100755 (executable)
index ef9cb39..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/php5 -q
-<?php
-/***************************************************************************
- *  Copyright (C) 2003-2009 Polytechnique.org                              *
- *  http://opensource.polytechnique.org/                                   *
- *                                                                         *
- *  This program is free software; you can redistribute it and/or modify   *
- *  it under the terms of the GNU General Public License as published by   *
- *  the Free Software Foundation; either version 2 of the License, or      *
- *  (at your option) any later version.                                    *
- *                                                                         *
- *  This program is distributed in the hope that it will be useful,        *
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
- *  GNU General Public License for more details.                           *
- *                                                                         *
- *  You should have received a copy of the GNU General Public License      *
- *  along with this program; if not, write to the Free Software            *
- *  Foundation, Inc.,                                                      *
- *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************/
-
-ini_set('include_path', '.:../include:/usr/share/php');
-
-require_once('connect.db.inc.php');
-require_once('emails.inc.php');
-require_once('plmailer.php');
-
-$opts = getopt('i:o:');
-if (($opts['i'] && $opts['i'] == '-') || empty($opts['i'])) {
-    $file = 'php://stdin';
-} else {
-    $file = $opts['i'];
-}
-if (($opts['o'] && $opts['o'] == '-') || empty($opts['o'])) {
-    $output = 'php://stdout';
-} else {
-    $output = $opts['o'];
-}
-
-$emails = explode("\n", file_get_contents($file));
-$list   = array();
-
-foreach ($emails as $_email) {
-    $email = valide_email($_email);
-    if (empty($email) || $email=='@') {
-        continue;
-    }
-
-    $sel = XDB::query(
-            "SELECT  e1.uid, e1.panne != 0 AS panne, count(e2.uid) AS nb_mails, u.nom, u.prenom, u.promo, a.alias
-               FROM  emails        AS e1
-          LEFT JOIN  emails        AS e2 ON (e1.uid = e2.uid AND FIND_IN_SET('active', e2.flags) AND e1.email != e2.email)
-         INNER JOIN  auth_user_md5 AS u  ON (e1.uid = u.user_id)
-         INNER JOIN  aliases       AS a  ON (u.user_id = a.id AND FIND_IN_SET('bestalias',a.flags))
-              WHERE  e1.email = {?}
-           GROUP BY  e1.uid", $email);
-    if ($x = $sel->fetchOneAssoc()) {
-        if (!$x['panne']) {
-            XDB::execute("UPDATE emails
-                             SET panne=NOW(), last=NOW(),
-                                 panne_level = 1
-                           WHERE email = {?}",
-                          $email);
-        } else {
-            XDB::execute("UPDATE emails
-                             SET last = CURDATE(),
-                                 panne_level = panne_level + 1
-                           WHERE email = {?}
-                                 AND DATE_ADD(last, INTERVAL 7 DAY) < CURDATE()", $email);
-        }
-
-        if (empty($x['nb_mails'])) {
-            echo "$email : seule adresse active de {$x['prenom']} {$x['nom']}\n";
-        } else {
-            $mail = new PlMailer('emails/broken.mail.tpl');
-            $mail->addTo("\"{$x['prenom']} {$x['nom']}\" <{$x['alias']}@" . $globals->mail->domain . '>');
-            $mail->assign('x', $x);
-            $mail->assign('email', $email);
-            $mail->send();
-            echo "$email : mail envoyé\n";
-        }
-
-        if (!isset($list[$x['alias']])) {
-            $list[$x['alias']] = array($email);
-        } else {
-            $list[$x['alias']][] = $email;
-        }
-    } else {
-        echo "$email : cette adresse n'est pas dans la base\n";
-    }
-}
-
-XDB::execute("UPDATE emails
-                 SET panne_level = panne_level - 1
-               WHERE flags = 'active' AND panne_level > 1
-                     AND last != CURDATE()");
-XDB::execute("UPDATE emails
-                 SET panne_level = 0
-               WHERE flags = 'active' AND panne_level = 1
-                     AND DATE_ADD(last, INTERVAL 1 YEAR) < CURDATE()");
-
-$csv = "nom;prenom;promo;alias;bounce;nbmails\n";
-foreach ($list as $alias=>$mails) {
-    $sel = Xdb::query(
-            "SELECT u.user_id, count(e.email) AS nb_mails, u.nom, u.prenom, u.promo
-               FROM aliases       AS a
-         INNER JOIN auth_user_md5 AS u ON a.id = u.user_id
-         LEFT JOIN emails         AS e ON (e.uid = u.user_id AND FIND_IN_SET('active', e.flags) AND e.panne = 0)
-              WHERE a.alias = {?}
-           GROUP BY u.user_id", $alias);
-    if ($x = $sel->fetchOneAssoc()) {
-        $csv .= $x['nom'].';'.$x['prenom'].';' .$x['promo'].';'.$alias.';' . join(',', $mails) . ';'.$x['nb_mails']."\n";
-    }
-}
-
-$fo = fopen($output, 'w+');
-fwrite($fo, $csv);
-fclose($fo);
-
-// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
-?>
index 489a364..73d44ee 100644 (file)
@@ -41,6 +41,7 @@ class EmailModule extends PLModule
             'admin/emails/duplicated' => $this->make_hook('duplicated',  AUTH_MDP,    'admin'),
             'admin/emails/watch'      => $this->make_hook('duplicated',  AUTH_MDP,    'admin'),
             'admin/emails/lost'       => $this->make_hook('lost',        AUTH_MDP,    'admin'),
+            'admin/emails/broken'     => $this->make_hook('broken_addr', AUTH_MDP,    'admin'),
         );
     }
 
@@ -790,6 +791,7 @@ L'équipe d'administration <support@" . $globals->mail->domain . '>';
             $page->assign('doublon', $props);
         }
     }
+
     function handler_lost(&$page, $action = 'list', $email = null)
     {
         $page->changeTpl('emails/lost.tpl');
@@ -802,6 +804,140 @@ L'équipe d'administration <support@" . $globals->mail->domain . '>';
                     u.deces = 0 AND u.perms IN ('user', 'admin', 'disabled')
           ORDER BY  u.promo DESC, u.nom, u.prenom"));
     }
+
+    function handler_broken_addr(&$page)
+    {
+        require_once 'emails.inc.php';
+        $page->changeTpl('emails/broken_addr.tpl');
+
+        if (Env::has('sort_broken')) {
+            S::assert_xsrf_token();
+
+            $list = trim(Env::v('list'));
+            if ($list == '') {
+                $page->trigError('La liste est vide.');
+            } else {
+                $valid_emails = array();
+                $invalid_emails = array();
+                $broken_list = explode("\n", $list);
+                sort($broken_list);
+                foreach ($broken_list as $orig_email) {
+                    $email = valide_email(trim($orig_email));
+                    if (empty($email) || $email == '@') {
+                        $invalid_emails[] = "$orig_email: invalid email";
+                    } else {
+                        $res = XDB::query('SELECT  COUNT(*)
+                                             FROM  emails
+                                            WHERE  email = {?}', $email);
+                        if ($res->fetchOneCell() > 0) {
+                            $valid_emails[] = $email;
+                        } else {
+                            $invalid_emails[] = "$orig_email: no such redirection";
+                        }
+                    }
+                }
+
+                $page->assign('valid_emails', $valid_emails);
+                $page->assign('invalid_emails', $invalid_emails);
+            }
+        }
+
+        if (Env::has('process_broken')) {
+            S::assert_xsrf_token();
+
+            $list = trim(Env::v('list'));
+            if ($list == '') {
+                $page->trigError('La liste est vide.');
+            } else {
+                global $platal;
+
+                $broken_user_list = array();
+                $broken_list = explode("\n", $list);
+                sort($broken_list);
+                foreach ($broken_list as $orig_email) {
+                    $email = valide_email(trim($orig_email));
+                    if (empty($email) || $email == '@') {
+                        continue;
+                    }
+
+                    $sel = XDB::query(
+                        "SELECT  e1.uid, e1.panne != 0 AS panne, count(e2.uid) AS nb_mails,
+                                 u.nom, u.prenom, u.promo, a.alias
+                           FROM  emails        AS e1
+                      LEFT JOIN  emails        AS e2 ON (e1.uid = e2.uid AND FIND_IN_SET('active', e2.flags)
+                                                         AND e1.email != e2.email)
+                     INNER JOIN  auth_user_md5 AS u  ON (e1.uid = u.user_id)
+                     INNER JOIN  aliases       AS a  ON (u.user_id = a.id AND FIND_IN_SET('bestalias', a.flags))
+                          WHERE  e1.email = {?}
+                       GROUP BY  e1.uid", $email);
+
+                    if ($x = $sel->fetchOneAssoc()) {
+                        if (!$x['panne']) {
+                            XDB::execute('UPDATE  emails
+                                             SET  panne=NOW(), last=NOW(), panne_level = 1
+                                           WHERE  email = {?}',
+                                          $email);
+                        } else {
+                            XDB::execute('UPDATE  emails
+                                             SET  last = CURDATE(), panne_level = panne_level + 1
+                                           WHERE  email = {?}
+                                                  AND DATE_ADD(last, INTERVAL 14 DAY) < CURDATE()',
+                                         $email);
+                        }
+
+                        if (!empty($x['nb_mails'])) {
+                            $mail = new PlMailer('emails/broken.mail.tpl');
+                            $mail->addTo("\"{$x['prenom']} {$x['nom']}\" <{$x['alias']}@"
+                                         . $globals->mail->domain . '>');
+                            $mail->assign('x', $x);
+                            $mail->assign('email', $email);
+                            $mail->send();
+                        }
+
+                        if (!isset($broken_user_list[$x['alias']])) {
+                            $broken_user_list[$x['alias']] = array($email);
+                        } else {
+                            $broken_user_list[$x['alias']][] = $email;
+                        }
+                    }
+                }
+
+                XDB::execute("UPDATE  emails
+                                 SET  panne_level = panne_level - 1
+                               WHERE  flags = 'active' AND panne_level > 1
+                                      AND DATE_ADD(last, INTERVAL 1 MONTH) < CURDATE()");
+                XDB::execute("UPDATE  emails
+                                 SET  panne_level = 0
+                               WHERE  flags = 'active' AND panne_level = 1
+                                      AND DATE_ADD(last, INTERVAL 1 YEAR) < CURDATE()");
+
+                // Output the list of users with recently broken addresses,
+                // along with the count of valid redirections.
+                header('Content-Type: text/x-csv; charset=utf-8;');
+                header('Cache-Control: no-cache');
+
+                $csv = fopen('php://output', 'w');
+                fputcsv($csv, array('nom', 'prenom', 'alias', 'bounce', 'nbmails'), ';');
+                foreach ($broken_user_list as $alias => $mails) {
+                    $sel = Xdb::query(
+                        "SELECT  u.user_id, count(e.email) AS nb_mails, u.nom, u.prenom, u.promo
+                           FROM  aliases       AS a
+                     INNER JOIN  auth_user_md5 AS u ON a.id = u.user_id
+                      LEFT JOIN  emails        AS e ON (e.uid = u.user_id
+                                                        AND FIND_IN_SET('active', e.flags) AND e.panne = 0)
+                          WHERE  a.alias = {?}
+                       GROUP BY  u.user_id", $alias);
+
+                    if ($x = $sel->fetchOneAssoc()) {
+                        fputcsv($csv, array($x['nom'], $x['prenom'], $x['promo'], $alias,
+                                            join(',', $mails), $x['nb_mails']), ';');
+                    }
+                }
+                fclose($csv);
+                exit;
+            }
+        }
+    }
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
index 0dd9434..06b3972 100644 (file)
@@ -58,6 +58,8 @@
       <a href="admin/emails/lost">Perdus de vue</a>
       &nbsp;&nbsp;|&nbsp;&nbsp;
       <a href="admin/emails/watch">Surveillés</a>
+      &nbsp;&nbsp;|&nbsp;&nbsp;
+      <a href="admin/emails/broken">Pattes cassées</a>
     </td>
   </tr>
   <tr class="pair">
diff --git a/templates/emails/broken_addr.tpl b/templates/emails/broken_addr.tpl
new file mode 100644 (file)
index 0000000..3fa83fa
--- /dev/null
@@ -0,0 +1,36 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2009 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+<h1>Pattes cassées</h1>
+
+<form method="post" action="{$platal->ns}admin/emails/broken" enctype="multipart/form-data">
+  {xsrf_token_field}
+  <textarea name="list" cols="60" rows="30">{if $valid_emails || $invalid_emails}{foreach from=$valid_emails item=email}{$email}{/foreach}
+
+{foreach from=$invalid_emails item=email}{$email}{/foreach}{/if}</textarea><br />
+  <input type="submit" name="sort_broken"
+         value="Trie et supprime les doublons de la liste d'adresses" /><br />
+  <input type="submit" name="process_broken"
+         value="Traite les adresses en panne et met à jour la BDD" />
+</form>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}