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:
parent
13178ec279
commit
d0127f95e5
9 changed files with 120 additions and 56 deletions
|
@ -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,
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 = ' ';
|
||||
|
||||
|
|
|
@ -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}') {
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -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':
|
||||
|
|
Loading…
Reference in a new issue