svn: SVNROOT/ commit-email.php

[email protected] (Gwynne Raskind) Tue, 21 Jul 09 11:47:57 +0000
Newsgroups php.cvs,svn.migration
Message-ID <[email protected]>
--a67f1bdd2d4d4d223bedeb466037030f3a34e22d
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

gwynne		Tue, 21 Jul 2009 11:47:57 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=284485

Log:
- fix bjori's newlines once and for all, I hope- a bit more reorganization of the code- use easier-to-read-and-understand heredocs- allow a slightly longer subject- give the diff attachment a more useful name- don't use inconsistent tabbing anymore- a couple extra comments


Changed paths:
	U   SVNROOT/commit-email.php
Modified: SVNROOT/commit-email.php
===================================================================
--- SVNROOT/commit-email.php	2009-07-21 11:36:18 UTC (rev 284484)
+++ SVNROOT/commit-email.php	2009-07-21 11:47:57 UTC (rev 284485)
@@ -146,72 +146,89 @@
                     ($diffs_length > 8192 ? NULL : $commit_info['diffs']));

 // -----------------------------------------------------------------------------------------------------------------------------
-// Build e-mail
-$boundary = sha1("{$commit_info['author']}{$commit_info['date']}");
-$messageid = "{$commit_info['author']}-{$commit_info['date']}-{$REV}-" . mt_rand();
-$subject = "svn: " . ($parent_path === '' ? '/' : $parent_path);
-
-foreach ($commit_info['changed_paths'] as $changed_path) {
-    $changed_path = trim(strstr($changed_path, ' '));
-    if (substr($changed_path, -1) !== '/') {
-        $subject .= ' ' . substr($changed_path, strlen($parent_path));
-    }
-}
-$subject = substr($subject, 0, 950); // Max SMTP line length = 998. Some slop in this value.
-
-$fullname = "=?utf-8?q?" . imap_8bit(str_replace(array('?', ' '), array('=3F', '_'), $commit_info['author_name'])) . "?=";
-
-$msg_headers = "From: {$fullname} <{$commit_info['author']}@php.net>\r\n" .
-               "To: " . implode(', ', $emails_to) . "\r\n" .
-               "Message-ID: <svn{$messageid}@svn.php.net>\r\n" .
-               "Date: " . date(DATE_RFC822, $commit_info['date']) . "\r\n" .
-               "Subject: {$subject}\r\n" .
-               "MIME-Version: 1.0\r\n" .
-               "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\r\n";
-
+// Process bugs
 $bugs_body = '';
 if (isset($bug_list) && count($bug_list) > 0) {
-    $bugs_body = count($bug_list) > 1 ? "Bugs: " : "Bug: ";
+    $bugs_body = count($bug_list) > 1 ? "\nBugs: " : "\nBug: ";
     foreach ($bug_list as $n => $bug) {
         if (isset($bug['error'])) {
             $status = '(error getting bug information)';
         } else {
             $status = "({$bug['status']}) {$bug['short_desc']}";
         }
-        $bugs_body .= "{$bug['url']} {$status}\r\n      ";
+        $bugs_body .= "{$bug['url']} {$status}\n      ";
     }
 }

-$msg_body = "--{$boundary}\r\n" .
-            "Content-Type: text/plain; charset=\"utf-8\"\r\n" .
-            "Content-Transfer-Encoding: 8bit\r\n" .
-            "\r\n" .
-            "{$commit_info['author']}\t\t" . date(DATE_RFC2822, $commit_info['date']) . "\r\n" .
-            "\r\n" .
-            "Revision: http://svn.php.net/viewvc?view=revision&revision={$REV}\r\n" .
-            "\r\n" .
-            "Log:\r\n" .
-            "{$commit_info['log_message']}\r\n" .
-            "{$bugs_body}\r\n" .
-            "\r\n" .
-            "Changed paths:\r\n" .
-            "\t" . implode("\r\n\t", $commit_info['changed_paths']) . "\r\n" .
-            str_replace("\n", "\r\n", $diffs_string);
+// -----------------------------------------------------------------------------------------------------------------------------
+// Process changed paths
+$paths_list = $parent_path === '' ? '/' : $parent_path;
+foreach ($commit_info['changed_paths'] as $changed_path) {
+    $changed_path = trim(strstr($changed_path, ' '));
+    if (substr($changed_path, -1) !== '/') {
+        $paths_list .= ' ' . substr($changed_path, strlen($parent_path));
+    }
+}

+// -----------------------------------------------------------------------------------------------------------------------------
+// Build e-mail
+$boundary = sha1("{$commit_info['author']}{$commit_info['date']}");
+$messageid = "{$commit_info['author']}-{$commit_info['date']}-{$REV}-" . mt_rand();
+$subject = substr("svn: {$paths_list}", 0, 970); // Max SMTP line length = 998. Some slop in this value.
+$email_date = date(DATE_RFC2822, $commit_info['date']);
+$fullname = "=?utf-8?q?" . imap_8bit(str_replace(array('?', ' '), array('=3F', '_'), $commit_info['author_name'])) . "?=";
+$email_list = implode(', ', $emails_to);
+$readable_path_list = "    " . implode("\n    ", $commit_info['changed_paths']);
+$nspaces = str_repeat(" ", max(1, 72 - strlen($commit_info['author']) - strlen($email_date)));
+
+$msg_body = <<<MIMEBODY
+From: {$fullname} <{$commit_info['author']}@php.net>
+To: {$email_list}
+Message-ID: <svn{$messageid}@svn.php.net>
+Date: {$email_date}
+Subject: {$subject}
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="{$boundary}"
+
+--{$boundary}
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+{$commit_info['author']}{$nspaces}{$email_date}
+
+Revision: http://svn.php.net/viewvc?view=revision&revision={$REV}
+
+Log:
+{$commit_info['log_message']}
+{$bugs_body}
+Changed paths:
+{$readable_path_list}
+
+{$diffs_string}
+--{$boundary}
+MIMEBODY;
+
 if ($diffs_string === NULL) {
-    $msg_body .=
-        "--{$boundary}\r\n" .
-        "Content-Type: text/x-diff; encoding=\"utf-8\"\r\n" .
-        "Content-Disposition: attachment; filename=\"{$boundary}.txt\"\r\n" .
-        "Content-Transfer-Encoding: base64\r\n" .
-        "\r\n" .
-        wordwrap(base64_encode($commit_info['diffs']), 80, "\r\n", TRUE) . "\r\n";
+    $diff_data = wordwrap(base64_encode($commit_info['diffs']), 80, "\n", TRUE);
+    $msg_body .= <<<MIMEBODY
+
+Content-Type: text/x-diff; encoding="utf-8"
+Content-Disposition: attachment; filename="svn-diffs-{$REV}.txt"
+Content-Transfer-Encoding: base64
+
+{$diff_data}
+--{$boundary}
+MIMEBODY;
 }

-$msg_body .= "\r\n--{$boundary}--";
+// The -- at the end finishes off the MIME body.
+$msg_body .= "--";
+// Yes, I really DID mean to do two str_replace()s instead of using array()
+// parameters. This absolutely ensures that the replacements will be done in the
+// correct order.
+$msg_body = str_replace(PHP_EOL, "\r\n", $msg_body);
+$msg_body = str_replace("\r\n.\r\n", "\r\n..\r\n", $msg_body);

-$complete_email = $msg_headers . "\r\n" . str_replace("\r\n.\r\n", "\r\n..\r\n", $msg_body);
-
 // -----------------------------------------------------------------------------------------------------------------------------
 // Send e-mail
 if ($is_DEBUG) {
@@ -223,19 +240,23 @@
     fail("Couldn't connect to SMTP server {$smtp_server}. Errno: {$errno}.\n");
 }

-fwrite($socket,
-    "EHLO localhost\r\n" .
-    "MAIL FROM:<[email protected]> BODY=8BITMIME\r\n");
-foreach ($emails_to as $send_addr) {
-    fwrite($socket, "RCPT TO:<{$send_addr}>\r\n");
-}
-fwrite($socket,
-    "DATA\r\n" .
-    $complete_email . "\r\n" .
-    ".\r\n" .
-    "QUIT\r\n");
+$rcpt_commands = "RCPT TO:<" . implode(">\r\nRCPT TO:<", $emails_to) . ">";
+fwrite($socket, <<<SMTP
+EHLO localhost\r
+MAIL FROM:<[email protected]> BODY=8BITMIME\r
+{$rcpt_commands}\r
+DATA\r
+{$msg_body}\r
+.\r
+QUIT\r

+SMTP
+      );
+
 if (!$is_DEBUG) {
+    // For the record, I don't bother parsing errors here because the local MTA
+    // pretty much never errors out directly. Instead the errors come from the
+    // upstream MTAs (such as on lists), which I can't access from here anyway.
     $discard = stream_get_contents($socket);
 }
 fclose($socket);

--a67f1bdd2d4d4d223bedeb466037030f3a34e22d--