Making WordPress.org


Ignore:
Timestamp:
01/11/2015 11:00:02 AM (10 years ago)
Author:
nacin
Message:

Update Slack libraries.

Location:
sites/trunk/svn.wordpress.org/includes/slack-trac-hooks/trac
Files:
1 added
1 moved

Legend:

Unmodified
Added
Removed
  • sites/trunk/svn.wordpress.org/includes/slack-trac-hooks/trac/comment-handler.php

    r1080 r1121  
    11<?php
    22
    3 namespace Dotorg\SlackTracHooks\Comments;
     3namespace Dotorg\Slack\Trac;
    44
    5 function process_message( $lines ) {
    6     $lines = array_map( 'rtrim', $lines );
     5class Comment_Handler {
     6
     7    function __construct( Dotorg\Slack\Send $send, array $email_message ) {
     8        $this->send  = $send;
     9        $this->lines = $email_message;
     10    }
     11
     12    function run() {
     13        $this->process_message();
     14
     15        // Don't post auto-comments for commits.
     16        if ( false !== strpos( $this->comment, '#!CommitTicketReference' ) ) {
     17            return;
     18        }
     19
     20        $this->generate_payload();
     21        $this->send->send( $trac->get_firehose_channel() );
     22    }
     23
     24    function process_message() {
     25        $lines = array_map( 'rtrim', $this->lines );
     26       
     27        // Trim off headers.
     28        while ( '' !== current( $lines ) ) {
     29            $line = array_shift( $lines );
     30            if ( 0 === strpos( $line, 'X-Trac-Ticket-URL:' ) ) {
     31                // X-Trac-Ticket-URL: https://core.trac.wordpress.org/ticket/12345#comment:1
     32                list( , $comment_url ) = explode( ': ', $line );
     33                list( $ticket_url, $comment_id ) = explode( '#comment:', $comment_url );
     34                list( $trac_url, $ticket_id ) = explode( '/ticket/', $ticket_url );
    735   
    8     // Trim off headers.
    9     while ( '' !== current( $lines ) ) {
    10         array_shift( $lines );
    11     }
    12     // Remove empty line between headers and body.
    13     array_shift( $lines );
    14    
    15     $title = '';
    16     while ( 0 !== strpos( current( $lines ), '------' ) ) {
    17         if ( '' !== $title ) {
    18             $last = substr( $title, -1 );
    19             if ( $last !== '-' && $last !== '_' ) {
    20                 $title .= ' ';
     36                $trac = Dotorg\Slack\Trac::get( $trac_url );
     37                if ( ! $trac ) {
     38                    return false;
     39                }
    2140            }
    2241        }
    23         $title .= array_shift( $lines );
     42
     43        // Remove empty line between headers and body.
     44        array_shift( $lines );
     45       
     46        $title = '';
     47        while ( 0 !== strpos( current( $lines ), '------' ) ) {
     48            if ( '' !== $title ) {
     49                $last = substr( $title, -1 );
     50                if ( $last !== '-' && $last !== '_' ) {
     51                    $title .= ' ';
     52                }
     53            }
     54            $title .= array_shift( $lines );
     55        }
     56        $title = substr( $title, strpos( $title, ': ' ) + 2 );
     57
     58        // Remove up to top of ticket properties table.
     59        while ( 0 !== strpos( current( $lines ), '------' ) ) {
     60            array_shift( $lines );
     61        }
     62        // Remove top border of table.
     63        array_shift( $lines );
     64        // Remove ticket properties table.
     65        while ( 0 !== strpos( current( $lines ), '------' ) ) {
     66            array_shift( $lines );
     67        }
     68        // Remove bottom border of table.
     69        array_shift( $lines );
     70       
     71        // Remove empty line if present. (It is when it's a comment without changes.)
     72        if ( current( $lines ) === '' ) {
     73            array_shift( $lines );
     74        }
     75       
     76        // Remove Trac email footer.
     77        while ( end( $lines ) !== '--' ) {
     78            array_pop( $lines );
     79        }
     80        // Remove -- which starts footer.
     81        array_pop( $lines );
     82        // Remove empty line before footer.
     83        array_pop( $lines );
     84       
     85        preg_match( '/^(Comment|Changes) \(by (.*)\):$/', array_shift( $lines ), $matches );
     86        $has_changes = $matches[1] === 'Changes';
     87        $author = $matches[2];
     88
     89        // Remove blank line after 'Comment|Changes (by author):'
     90        array_shift( $lines );
     91       
     92        $changes = $comment = array();
     93        if ( $has_changes ) {
     94            while ( '' !== current( $lines ) ) {
     95                $changes[] = preg_replace( '~^ \* (.*?):  ~', '_*$1:*_ ', array_shift( $lines ) );
     96            }
     97        }
     98       
     99        // Remove blank lines (should be two if it had changes).
     100        while ( '' === current( $lines ) ) {
     101            array_shift( $lines );
     102        }
     103       
     104        // Next line should start with 'Comment' if there is one.
     105        if ( $has_changes && 0 === strpos( current( $lines ), 'Comment' ) ) {
     106            array_shift( $lines ); // Remove 'Comment'
     107            array_shift( $lines ); // Remove blank line
     108        }
     109
     110        // Everything left is the comment. Remove leading space.
     111        $comment = array_map( 'ltrim', $lines );
     112
     113        $this->trac    = $trac;
     114        $this->title   = $title;
     115        $this->author  = $author;
     116        $this->comment = $comment;
     117        $this->changes = $changes;
     118        $this->ticket_id   = $ticket_id;
     119        $this->ticket_url  = $ticket_url;
     120        $this->comment_id  = $comment_id;
     121        $this->comment_url = $comment_url;
    24122    }
    25     $title = substr( $title, strpos( $title, ': ' ) + 2 );
    26    
    27     // Remove up to top of ticket properties table.
    28     while ( 0 !== strpos( current( $lines ), '------' ) ) {
    29         array_shift( $lines );
     123
     124    function format_comment_for_slack() {
     125        // Link 'Replying to [comment:1 user]:'
     126        $ticket_url = $this->ticket_url;
     127        $comment = preg_replace_callback( '/Replying to \[comment:(\d+) (.*)\]/m',
     128            function ( $matches ) use ( $ticket_url ) {
     129                $comment_url = $ticket_url . '#comment:' . $matches[1];
     130                $text = 'Replying to ' . $matches[2];
     131                return "<$comment_url|$text>";
     132            }, $this->comment );
     133
     134        $comment = Trac::format_for_slack( $comment );
     135        return $comment;
    30136    }
    31     // Remove top border of table.
    32     array_shift( $lines );
    33     // Remove ticket properties table.
    34     while ( 0 !== strpos( current( $lines ), '------' ) ) {
    35         array_shift( $lines );
    36     }
    37     // Remove bottom border of table.
    38     array_shift( $lines );
    39    
    40     // Remove empty line if present. (It is when it's a comment without changes.)
    41     if ( current( $lines ) === '' ) {
    42         array_shift( $lines );
    43     }
    44    
    45     // Remove Trac email footer.
    46     while ( end( $lines ) !== '--' ) {
    47         array_pop( $lines );
    48     }
    49     // Remove -- which starts footer.
    50     array_pop( $lines );
    51     // Remove empty line before footer.
    52     array_pop( $lines );
    53    
    54     preg_match( '/^(Comment|Changes) \(by (.*)\):$/', array_shift( $lines ), $matches );
    55     $has_changes = $matches[1] === 'Changes';
    56     $author = $matches[2];
    57    
    58     // Remove blank line after 'Comment|Changes (by author):'
    59     array_shift( $lines );
    60    
    61     $changes = $comment = array();
    62     if ( $has_changes ) {
    63         while ( '' !== current( $lines ) ) {
    64             $changes[] = preg_replace( '~^ \* (.*?):  ~', '_*$1:*_ ', array_shift( $lines ) );
     137
     138    function generate_payload() {
     139        $this->send->set_icon( $this->trac->get_icon() );
     140        $this->send->set_username( $this->trac->get_ticket_username() );
     141           
     142        $comment         = $this->format_comment_for_slack();
     143        $main_attachment = $this->changes ? $this->changes : $comment;
     144        $fallback        = trim( $pretext, '*' ) . "\n" . $main_attachment;
     145        $pretext         = sprintf( '*%s updated <%s|#%s %s>*', $this->author, $this->comment_url, $this->ticket_id, $this->title );
     146
     147        $attachment = array(
     148            'pretext'   => $pretext,
     149            'fallback'  => $fallback,
     150            'text'      => $main_attachment,
     151            'mrkdwn_in' => array( 'pretext', 'fallback', 'text' ),
     152        );
     153
     154        // Ensure the comment uses a darker gray color, even when alone.   
     155        if ( ! $this->changes ) {
     156            $attachment['color'] = '#999';
     157        }
     158
     159        $this->send->add_attachment( $attachment );
     160
     161        // If we have both changes and a comment, append the comment.
     162        if ( $this->changes && $comment ) {
     163            $this->send->add_attachment( array(
     164                'fallback'  => $comment,
     165                'text'      => $comment,
     166                'mrkdwn_in' => array( 'fallback', 'text' ),
     167                'color'     => '#999',
     168            ) );
    65169        }
    66170    }
    67    
    68     // Remove blank lines (should be two if it had changes).
    69     while ( '' === current( $lines ) ) {
    70         array_shift( $lines );
    71     }
    72    
    73     // Next line should start with 'Comment' if there is one.
    74     if ( $has_changes && 0 === strpos( current( $lines ), 'Comment' ) ) {
    75         array_shift( $lines ); // Remove 'Comment'
    76         array_shift( $lines ); // Remove blank line
    77     }
    78    
    79     // Everything left is the comment. Remove leading space.
    80     $comment = array_map( 'ltrim', $lines );
    81    
    82     $changes = implode( "\n", $changes );
    83     $comment = implode( "\n", $comment );
    84 
    85     return compact( 'author', 'title', 'changes', 'comment' );
    86171}
    87 
    88 function format_comment( $comment, $ticket_url ) {
    89     // Link 'Replying to [comment:1 user]:'
    90     $comment = preg_replace_callback( '/^Replying to \[comment:(\d+) (.*)\]/m',
    91         function ( $matches ) use ( $ticket_url ) {
    92             $comment_url = $ticket_url . '#comment:' . $matches[1];
    93             $text = 'Replying to ' . $matches[2];
    94             return "<$comment_url|$text>";
    95         }, $comment );
    96 
    97     // Replace {{{ and }}} with ``` or `
    98     $comment = trim( str_replace(
    99         array( "\n{{{\n", "\n}}}\n", '{{{', '}}}' ),
    100         array( "\n```\n", "\n```\n", '`',   '`' ),
    101         "\n$comment\n"
    102     ), "\n" );
    103 
    104     return $comment;
    105 }
    106 
    107 function send( $slack_hook, $args ) {
    108     // Don't post auto-comments for commits.
    109     if ( false !== strpos( $args['comment'], '#!CommitTicketReference' ) ) {
    110         return;
    111     }
    112 
    113     $trac_class = '\\Dotorg\\SlackTracHooks\\' . $args['trac'] . '_Trac';
    114     $trac = new $trac_class;
    115 
    116        
    117     $args['comment'] = format_comment( $args['comment'], $args['ticket_url'] );
    118     $main_attachment = $args['changes'] ? $args['changes'] : $args['comment'];
    119 
    120     $pretext = sprintf( '*%s updated <%s|#%s %s>*', $args['author'], $args['comment_url'], $args['ticket'], $args['title'] );
    121     $fallback = trim( $pretext, '*' ) . "\n" . $main_attachment;
    122 
    123     $payload = array(
    124         'channel'     => $trac->get_firehose_channel(),
    125         'icon_emoji'  => $trac->get_emoji(),
    126         'username'    => $trac->get_ticket_username(),
    127         'attachments' => array(
    128             array(
    129                 'pretext'   => $pretext,
    130                 'fallback'  => $fallback,
    131                 'text'      => $main_attachment,
    132                 'mrkdwn_in' => array( 'pretext', 'fallback', 'text' ),
    133             ),
    134         ),
    135     );
    136 
    137     // If we have both changes and a comment, append the comment.
    138     // Ensure the comment uses a darker gray color, even when alone.   
    139     if ( $args['changes'] && $args['comment'] ) {
    140         $payload['attachments'][] = array(
    141             'fallback'  => $args['comment'],
    142             'text'      => $args['comment'],
    143             'mrkdwn_in' => array( 'fallback', 'text' ),
    144             'color'     => '#999',
    145         );
    146     } elseif ( ! $args['changes'] ) {
    147         $payload['attachments'][0]['color'] = '#999';
    148     }
    149    
    150     $payload = json_encode( $payload );
    151    
    152     $context = stream_context_create( array(
    153         'http' => array(
    154             'method'  => 'POST',
    155             'header'  => 'Content-Type: application/x-www-form-urlencoded' . PHP_EOL,
    156             'content' => http_build_query( compact( 'payload' ) ),
    157         ),
    158     ) );
    159    
    160     file_get_contents( $slack_hook, false, $context );
    161 }
    162 
Note: See TracChangeset for help on using the changeset viewer.