- Timestamp:
- 01/11/2015 11:00:02 AM (10 years ago)
- 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 1 1 <?php 2 2 3 namespace Dotorg\Slack TracHooks\Comments;3 namespace Dotorg\Slack\Trac; 4 4 5 function process_message( $lines ) { 6 $lines = array_map( 'rtrim', $lines ); 5 class 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 ); 7 35 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 } 21 40 } 22 41 } 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; 24 122 } 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; 30 136 } 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 ) ); 65 169 } 66 170 } 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 line77 }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' );86 171 } 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.