@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Differential - add ability to setup "create" addresses for revisions

Summary: Fixes T1476. The body of the email should be just the output of some diff command.

Test Plan:
git diff master > text.txt; ./bin/mail receive-test --to <configured-diff-create-address> < text.txt; a diff was successfully created...! email generated had a working link to the diff.

./bin/mail receive-test --to <configured-diff-create-address> < README.md; a diff was not created as expected...! email generated had a sensical error message, telling me that the mail body should have been generated via a diff command

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: johnny-bit, Korvin, epriestley

Maniphest Tasks: T1476

Differential Revision: https://secure.phabricator.com/D11574

+155 -2
+2
src/__phutil_library_map__.php
··· 322 322 'DifferentialCreateCommentConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateCommentConduitAPIMethod.php', 323 323 'DifferentialCreateDiffConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateDiffConduitAPIMethod.php', 324 324 'DifferentialCreateInlineConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateInlineConduitAPIMethod.php', 325 + 'DifferentialCreateMailReceiver' => 'applications/differential/mail/DifferentialCreateMailReceiver.php', 325 326 'DifferentialCreateRawDiffConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateRawDiffConduitAPIMethod.php', 326 327 'DifferentialCreateRevisionConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateRevisionConduitAPIMethod.php', 327 328 'DifferentialCustomField' => 'applications/differential/customfield/DifferentialCustomField.php', ··· 3421 3422 'DifferentialCreateCommentConduitAPIMethod' => 'DifferentialConduitAPIMethod', 3422 3423 'DifferentialCreateDiffConduitAPIMethod' => 'DifferentialConduitAPIMethod', 3423 3424 'DifferentialCreateInlineConduitAPIMethod' => 'DifferentialConduitAPIMethod', 3425 + 'DifferentialCreateMailReceiver' => 'PhabricatorMailReceiver', 3424 3426 'DifferentialCreateRawDiffConduitAPIMethod' => 'DifferentialConduitAPIMethod', 3425 3427 'DifferentialCreateRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod', 3426 3428 'DifferentialCustomField' => 'PhabricatorCustomField',
+16
src/applications/differential/application/PhabricatorDifferentialApplication.php
··· 162 162 return $status; 163 163 } 164 164 165 + public function supportsEmailIntegration() { 166 + return true; 167 + } 168 + 169 + public function getAppEmailBlurb() { 170 + return pht( 171 + 'Send email to these addresses to create revisions. The body of the '. 172 + 'message and / or one or more attachments should be the output of a '. 173 + '"diff" command. %s', 174 + phutil_tag( 175 + 'a', 176 + array( 177 + 'href' => $this->getInboundEmailSupportLink(),), 178 + pht('Learn More'))); 179 + } 180 + 165 181 protected function getCustomCapabilities() { 166 182 return array( 167 183 DifferentialDefaultViewCapability::CAPABILITY => array(
+3 -2
src/applications/differential/conduit/DifferentialConduitAPIMethod.php
··· 12 12 $uri = PhabricatorEnv::getProductionURI($uri); 13 13 14 14 return array( 15 - 'id' => $diff->getID(), 16 - 'uri' => $uri, 15 + 'id' => $diff->getID(), 16 + 'phid' => $diff->getPHID(), 17 + 'uri' => $uri, 17 18 ); 18 19 } 19 20
+123
src/applications/differential/mail/DifferentialCreateMailReceiver.php
··· 1 + <?php 2 + 3 + final class DifferentialCreateMailReceiver extends PhabricatorMailReceiver { 4 + 5 + public function isEnabled() { 6 + $app_class = 'PhabricatorDifferentialApplication'; 7 + return PhabricatorApplication::isClassInstalled($app_class); 8 + } 9 + 10 + public function canAcceptMail(PhabricatorMetaMTAReceivedMail $mail) { 11 + $differential_app = new PhabricatorDifferentialApplication(); 12 + return $this->canAcceptApplicationMail($differential_app, $mail); 13 + } 14 + 15 + protected function processReceivedMail( 16 + PhabricatorMetaMTAReceivedMail $mail, 17 + PhabricatorUser $sender) { 18 + 19 + $attachments = $mail->getAttachments(); 20 + $files = array(); 21 + $errors = array(); 22 + if ($attachments) { 23 + $files = id(new PhabricatorFileQuery()) 24 + ->setViewer($sender) 25 + ->withPHIDs($attachments) 26 + ->execute(); 27 + foreach ($files as $index => $file) { 28 + if ($file->getMimeType() != 'text/plain') { 29 + $errors[] = pht( 30 + 'Could not parse file %s; only files with mimetype text/plain '. 31 + 'can be parsed via email.', 32 + $file->getName()); 33 + unset($files[$index]); 34 + } 35 + } 36 + } 37 + 38 + $diffs = array(); 39 + foreach ($files as $file) { 40 + $call = new ConduitCall( 41 + 'differential.createrawdiff', 42 + array( 43 + 'diff' => $file->loadFileData(), 44 + )); 45 + $call->setUser($sender); 46 + try { 47 + $result = $call->execute(); 48 + $diffs[$file->getName()] = $result['uri']; 49 + } catch (Exception $e) { 50 + $errors[] = pht( 51 + 'Could not parse attachment %s; only attachments (and mail bodies) '. 52 + 'generated via "diff" commands can be parsed.', 53 + $file->getName()); 54 + } 55 + } 56 + 57 + $body = $mail->getCleanTextBody(); 58 + if ($body) { 59 + $call = new ConduitCall( 60 + 'differential.createrawdiff', 61 + array( 62 + 'diff' => $body,)); 63 + $call->setUser($sender); 64 + try { 65 + $result = $call->execute(); 66 + $diffs[pht('Mail Body')] = $result['uri']; 67 + } catch (Exception $e) { 68 + $errors[] = pht( 69 + 'Could not parse mail body; only mail bodies (and attachments) '. 70 + 'generated via "diff" commands can be parsed.'); 71 + } 72 + } 73 + 74 + $subject_prefix = 75 + PhabricatorEnv::getEnvConfig('metamta.differential.subject-prefix'); 76 + if (count($diffs)) { 77 + $subject = pht( 78 + 'You successfully created %d diff(s).', 79 + count($diffs)); 80 + } else { 81 + $subject = pht( 82 + 'Diff creation failed; see body for error(s).', 83 + count($errors)); 84 + } 85 + $body = new PhabricatorMetaMTAMailBody(); 86 + $body->addRawSection($subject); 87 + if (count($diffs)) { 88 + $text_body = ''; 89 + $html_body = array(); 90 + $body_label = pht('DIFF LINK(S)', count($diffs)); 91 + foreach ($diffs as $filename => $diff_uri) { 92 + $text_body .= $filename.': '.$diff_uri."\n"; 93 + $html_body[] = phutil_tag( 94 + 'a', 95 + array( 96 + 'href' => $diff_uri, 97 + ), 98 + $filename); 99 + $html_body[] = phutil_tag('br'); 100 + } 101 + $body->addTextSection($body_label, $text_body); 102 + $body->addHTMLSection($body_label, $html_body); 103 + } 104 + 105 + if (count($errors)) { 106 + $body_section = new PhabricatorMetaMTAMailSection(); 107 + $body_label = pht('ERROR(S)', count($errors)); 108 + foreach ($errors as $error) { 109 + $body_section->addFragment($error); 110 + } 111 + $body->addTextSection($body_label, $body_section); 112 + } 113 + 114 + id(new PhabricatorMetaMTAMail()) 115 + ->addTos(array($sender->getPHID())) 116 + ->setSubject($subject) 117 + ->setSubjectPrefix($subject_prefix) 118 + ->setFrom($sender->getPHID()) 119 + ->setBody($body->render()) 120 + ->saveAndSend(); 121 + } 122 + 123 + }
+11
src/infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php
··· 19 19 ), 20 20 'Task(s)' => array('Task', 'Tasks'), 21 21 22 + 'ERROR(S)' => array('ERROR', 'ERRORS'), 22 23 '%d Error(s)' => array('%d Error', '%d Errors'), 23 24 '%d Warning(s)' => array('%d Warning', '%d Warnings'), 24 25 '%d Auto-Fix(es)' => array('%d Auto-Fix', '%d Auto-Fixes'), ··· 30 31 '%d line(s)' => array('%d line', '%d lines'), 31 32 '%d path(s)' => array('%d path', '%d paths'), 32 33 '%d diff(s)' => array('%d diff', '%d diffs'), 34 + 35 + 'DIFF LINK(S)' => array('DIFF LINK', 'DIFF LINKS'), 36 + 'You successfully created %d diff(s).' => array( 37 + 'You successfully created %d diff.', 38 + 'You successfully created %d diffs.', 39 + ), 40 + 'Diff creation failed; see body for error(s).' => array( 41 + 'Diff creation failed; see body for error.', 42 + 'Diff creation failed; see body for errors.', 43 + ), 33 44 34 45 'There are %d raw fact(s) in storage.' => array( 35 46 'There is %d raw fact in storage.',