1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 16:52:41 +01:00

Maniphest - add support for !assign command

Summary:
also try to centralize some of the command parsing logic. note that differential is still an exception here. it uses a whitelist-style regex. i think long-term we should have this for every app but changing it seemed too big for this diff.

Fixes T3937.

Test Plan:
echo '!assign btrahan' | ./bin/mail receive-test --as xerxes --to T22 ; echo '!claim' | ./bin/mail receive-test --as xerxes --to T22

unit tests passed, though my new one is silly

Reviewers: epriestley

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T3937

Differential Revision: https://secure.phabricator.com/D7307
This commit is contained in:
Bob Trahan 2013-10-14 12:29:41 -07:00
parent 13178ec279
commit d0127f95e5
9 changed files with 120 additions and 56 deletions

View file

@ -69,7 +69,6 @@ final class ConpherenceReplyHandler extends PhabricatorMailReplyHandler {
->setParentMessageID($mail->getMessageID());
$body = $mail->getCleanTextBody();
$body = trim($body);
$file_phids = $mail->getAttachments();
$body = $this->enhanceBodyWithAttachments(
$body,

View file

@ -32,8 +32,8 @@ final class FileReplyHandler extends PhabricatorMailReplyHandler {
$actor = $this->getActor();
$file = $this->getMailReceiver();
$body = $mail->getCleanTextBody();
$body = trim($body);
$body_data = $mail->parseBody();
$body = $body_data['body'];
$body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
$content_source = PhabricatorContentSource::newForSource(
@ -42,19 +42,8 @@ final class FileReplyHandler extends PhabricatorMailReplyHandler {
'id' => $mail->getID(),
));
$lines = explode("\n", trim($body));
$first_line = head($lines);
$xactions = array();
$command = null;
$matches = null;
if (preg_match('/^!(\w+)/', $first_line, $matches)) {
$lines = array_slice($lines, 1);
$body = implode("\n", $lines);
$body = trim($body);
$command = $matches[1];
}
$command = $body_data['body'];
switch ($command) {
case 'unsubscribe':

View file

@ -37,8 +37,8 @@ final class LegalpadReplyHandler extends PhabricatorMailReplyHandler {
$actor = $this->getActor();
$document = $this->getMailReceiver();
$body = $mail->getCleanTextBody();
$body = trim($body);
$body_data = $mail->parseBody();
$body = $body_data['body'];
$body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
$content_source = PhabricatorContentSource::newForSource(
@ -47,19 +47,9 @@ final class LegalpadReplyHandler extends PhabricatorMailReplyHandler {
'id' => $mail->getID(),
));
$lines = explode("\n", trim($body));
$first_line = head($lines);
$xactions = array();
$command = null;
$matches = null;
if (preg_match('/^!(\w+)/', $first_line, $matches)) {
$lines = array_slice($lines, 1);
$body = implode("\n", $lines);
$body = trim($body);
$command = $matches[1];
}
$command = $body_data['command'];
switch ($command) {
case 'unsubscribe':

View file

@ -45,8 +45,8 @@ final class ManiphestReplyHandler extends PhabricatorMailReplyHandler {
$user = $this->getActor();
$body = $mail->getCleanTextBody();
$body = trim($body);
$body_data = $mail->parseBody();
$body = $body_data['body'];
$body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
$xactions = array();
@ -73,18 +73,9 @@ final class ManiphestReplyHandler extends PhabricatorMailReplyHandler {
$task->setPriority(ManiphestTaskPriority::getDefaultPriority());
} else {
$lines = explode("\n", trim($body));
$first_line = head($lines);
$command = null;
$matches = null;
if (preg_match('/^!(\w+)/', $first_line, $matches)) {
$lines = array_slice($lines, 1);
$body = implode("\n", $lines);
$body = trim($body);
$command = $matches[1];
}
$command = $body_data['command'];
$command_value = $body_data['command_value'];
$ttype = PhabricatorTransactions::TYPE_COMMENT;
$new_value = null;
@ -97,6 +88,23 @@ final class ManiphestReplyHandler extends PhabricatorMailReplyHandler {
$ttype = ManiphestTransaction::TYPE_OWNER;
$new_value = $user->getPHID();
break;
case 'assign':
$ttype = ManiphestTransaction::TYPE_OWNER;
if ($command_value) {
$assign_users = id(new PhabricatorPeopleQuery())
->setViewer($user)
->withUsernames(array($command_value))
->execute();
if ($assign_users) {
$assign_user = head($assign_users);
$new_value = $assign_user->getPHID();
}
}
// assign to the user by default
if (!$new_value) {
$new_value = $user->getPHID();
}
break;
case 'unsubscribe':
$is_unsub = true;
$ttype = ManiphestTransaction::TYPE_CCS;

View file

@ -2,8 +2,51 @@
final class PhabricatorMetaMTAEmailBodyParser {
/**
* Mails can have bodies such as
*
* !claim
*
* taking this task
*
* Or
*
* !assign epriestley
*
* please, take this task I took; its hard
*
* This function parses such an email body and returns a dictionary
* containing a clean body text (e.g. "taking this task"), a $command
* (e.g. !claim, !assign) and a $command_value (e.g. "epriestley" in the
* !assign example.)
*
* @return dict
*/
public function parseBody($body) {
$body = $this->stripTextBody($body);
$lines = explode("\n", trim($body));
$first_line = head($lines);
$command = null;
$command_value = null;
$matches = null;
if (preg_match('/^!(\w+)\s*(\S+)?/', $first_line, $matches)) {
$lines = array_slice($lines, 1);
$body = implode("\n", $lines);
$body = trim($body);
$command = $matches[1];
$command_value = idx($matches, 2);
}
return array(
'body' => $body,
'command' => $command,
'command_value' => $command_value);
}
public function stripTextBody($body) {
return $this->stripSignature($this->stripQuotedText($body));
return trim($this->stripSignature($this->stripQuotedText($body)));
}
private function stripQuotedText($body) {

View file

@ -12,6 +12,44 @@ final class PhabricatorMetaMTAEmailBodyParserTestCase
}
}
public function testEmailBodyCommandParsing() {
$bodies = $this->getEmailBodiesWithFullCommands();
foreach ($bodies as $body) {
$parser = new PhabricatorMetaMTAEmailBodyParser();
$body_data = $parser->parseBody($body);
$this->assertEqual('OKAY', $body_data['body']);
$this->assertEqual('whatevs', $body_data['command']);
$this->assertEqual('dude', $body_data['command_value']);
}
$bodies = $this->getEmailBodiesWithPartialCommands();
foreach ($bodies as $body) {
$parser = new PhabricatorMetaMTAEmailBodyParser();
$body_data = $parser->parseBody($body);
$this->assertEqual('OKAY', $body_data['body']);
$this->assertEqual('whatevs', $body_data['command']);
$this->assertEqual(null, $body_data['command_value']);
}
}
private function getEmailBodiesWithFullCommands() {
$bodies = $this->getEmailBodies();
$with_commands = array();
foreach ($bodies as $body) {
$with_commands[] = "!whatevs dude\n" . $body;
}
return $with_commands;
}
private function getEmailBodiesWithPartialCommands() {
$bodies = $this->getEmailBodies();
$with_commands = array();
foreach ($bodies as $body) {
$with_commands[] = "!whatevs\n" . $body;
}
return $with_commands;
}
private function getEmailBodies() {
$trailing_space = ' ';

View file

@ -307,7 +307,7 @@ EOBODY;
return $this->getSingleReplyHandlerPrefix($address);
}
final protected function enhanceBodyWithAttachments(
final protected function enhanceBodyWithAttachments(
$body,
array $attachments,
$format = '- {F%d, layout=link}') {

View file

@ -120,12 +120,17 @@ final class PhabricatorMetaMTAReceivedMail extends PhabricatorMetaMTADAO {
}
public function getCleanTextBody() {
$body = idx($this->bodies, 'text');
$body = $this->getRawTextBody();
$parser = new PhabricatorMetaMTAEmailBodyParser();
return $parser->stripTextBody($body);
}
public function parseBody() {
$body = $this->getRawTextBody();
$parser = new PhabricatorMetaMTAEmailBodyParser();
return $parser->parseBody($body);
}
public function getRawTextBody() {
return idx($this->bodies, 'text');
}

View file

@ -32,8 +32,8 @@ final class PasteReplyHandler extends PhabricatorMailReplyHandler {
$actor = $this->getActor();
$paste = $this->getMailReceiver();
$body = $mail->getCleanTextBody();
$body = trim($body);
$body_data = $mail->parseBody();
$body = $body_data['body'];
$body = $this->enhanceBodyWithAttachments($body, $mail->getAttachments());
$content_source = PhabricatorContentSource::newForSource(
@ -46,15 +46,7 @@ final class PasteReplyHandler extends PhabricatorMailReplyHandler {
$first_line = head($lines);
$xactions = array();
$command = null;
$matches = null;
if (preg_match('/^!(\w+)/', $first_line, $matches)) {
$lines = array_slice($lines, 1);
$body = implode("\n", $lines);
$body = trim($body);
$command = $matches[1];
}
$command = $body_data['command'];
switch ($command) {
case 'unsubscribe':