@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.

Add a rough `bin/mail volume` command for showing mail volume

Summary: Ref T7013. This might help us understand the problem better.

Test Plan:
```
$ ./bin/mail volume
+==============+============+
| User | Unfiltered |
+==============+============+
| admin | 136 |
| dog | 31 |
| epriestley | 24 |
| ducksey | 18 |
| saurus | 8 |
| example-list | 7 |
| squeakybirdo | 3 |
| nnn | 3 |
| facebooker | 2 |
+==============+============+

Mail sent in the last 30 days.
"Unfiltered" is raw volume before preferences were applied.
```

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T7013

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

+115 -12
+2
src/__phutil_library_map__.php
··· 2257 2257 'PhabricatorMailManagementSendTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php', 2258 2258 'PhabricatorMailManagementShowInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowInboundWorkflow.php', 2259 2259 'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php', 2260 + 'PhabricatorMailManagementVolumeWorkflow' => 'applications/metamta/management/PhabricatorMailManagementVolumeWorkflow.php', 2260 2261 'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php', 2261 2262 'PhabricatorMailReceiver' => 'applications/metamta/receiver/PhabricatorMailReceiver.php', 2262 2263 'PhabricatorMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php', ··· 6183 6184 'PhabricatorMailManagementSendTestWorkflow' => 'PhabricatorMailManagementWorkflow', 6184 6185 'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorMailManagementWorkflow', 6185 6186 'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorMailManagementWorkflow', 6187 + 'PhabricatorMailManagementVolumeWorkflow' => 'PhabricatorMailManagementWorkflow', 6186 6188 'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow', 6187 6189 'PhabricatorMailReceiver' => 'Phobject', 6188 6190 'PhabricatorMailReceiverTestCase' => 'PhabricatorTestCase',
+79
src/applications/metamta/management/PhabricatorMailManagementVolumeWorkflow.php
··· 1 + <?php 2 + 3 + final class PhabricatorMailManagementVolumeWorkflow 4 + extends PhabricatorMailManagementWorkflow { 5 + 6 + protected function didConstruct() { 7 + $this 8 + ->setName('volume') 9 + ->setSynopsis( 10 + pht('Show how much mail users have received in the last 30 days.')) 11 + ->setExamples( 12 + '**volume**') 13 + ->setArguments( 14 + array( 15 + )); 16 + } 17 + 18 + public function execute(PhutilArgumentParser $args) { 19 + $console = PhutilConsole::getConsole(); 20 + $viewer = $this->getViewer(); 21 + 22 + $since = (PhabricatorTime::getNow() - phutil_units('30 days in seconds')); 23 + $until = PhabricatorTime::getNow(); 24 + 25 + $mails = id(new PhabricatorMetaMTAMailQuery()) 26 + ->setViewer($viewer) 27 + ->withDateCreatedBetween($since, $until) 28 + ->execute(); 29 + 30 + $unfiltered = array(); 31 + 32 + foreach ($mails as $mail) { 33 + $unfiltered_actors = mpull($mail->loadAllActors(), 'getPHID'); 34 + foreach ($unfiltered_actors as $phid) { 35 + if (empty($unfiltered[$phid])) { 36 + $unfiltered[$phid] = 0; 37 + } 38 + $unfiltered[$phid]++; 39 + } 40 + } 41 + 42 + arsort($unfiltered); 43 + 44 + $table = id(new PhutilConsoleTable()) 45 + ->setBorders(true) 46 + ->addColumn( 47 + 'user', 48 + array( 49 + 'title' => pht('User'), 50 + )) 51 + ->addColumn( 52 + 'unfiltered', 53 + array( 54 + 'title' => pht('Unfiltered'), 55 + )); 56 + 57 + $handles = $viewer->loadHandles(array_keys($unfiltered)); 58 + $names = mpull(iterator_to_array($handles), 'getName', 'getPHID'); 59 + 60 + foreach ($unfiltered as $phid => $count) { 61 + $table->addRow( 62 + array( 63 + 'user' => idx($names, $phid), 64 + 'unfiltered' => $count, 65 + )); 66 + } 67 + 68 + $table->draw(); 69 + 70 + echo "\n"; 71 + echo pht('Mail sent in the last 30 days.')."\n"; 72 + echo pht( 73 + '"Unfiltered" is raw volume before preferences were applied.')."\n"; 74 + echo "\n"; 75 + 76 + return 0; 77 + } 78 + 79 + }
+34 -12
src/applications/metamta/query/PhabricatorMetaMTAMailQuery.php
··· 7 7 private $phids; 8 8 private $actorPHIDs; 9 9 private $recipientPHIDs; 10 + private $createdMin; 11 + private $createdMax; 10 12 11 13 public function withIDs(array $ids) { 12 14 $this->ids = $ids; ··· 28 30 return $this; 29 31 } 30 32 33 + public function withDateCreatedBetween($min, $max) { 34 + $this->createdMin = $min; 35 + $this->createdMax = $max; 36 + return $this; 37 + } 38 + 31 39 protected function loadPage() { 32 40 return $this->loadStandardPage($this->newResultObject()); 33 41 } 34 42 35 - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 36 - $where = array(); 43 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 44 + $where = parent::buildWhereClauseParts($conn); 37 45 38 46 if ($this->ids !== null) { 39 47 $where[] = qsprintf( 40 - $conn_r, 48 + $conn, 41 49 'mail.id IN (%Ld)', 42 50 $this->ids); 43 51 } 44 52 45 53 if ($this->phids !== null) { 46 54 $where[] = qsprintf( 47 - $conn_r, 55 + $conn, 48 56 'mail.phid IN (%Ls)', 49 57 $this->phids); 50 58 } 51 59 52 60 if ($this->actorPHIDs !== null) { 53 61 $where[] = qsprintf( 54 - $conn_r, 62 + $conn, 55 63 'mail.actorPHID IN (%Ls)', 56 64 $this->actorPHIDs); 57 65 } 58 66 59 67 if ($this->recipientPHIDs !== null) { 60 68 $where[] = qsprintf( 61 - $conn_r, 69 + $conn, 62 70 'recipient.dst IN (%Ls)', 63 71 $this->recipientPHIDs); 64 72 } 65 73 66 74 if ($this->actorPHIDs === null && $this->recipientPHIDs === null) { 67 75 $viewer = $this->getViewer(); 76 + if (!$viewer->isOmnipotent()) { 77 + $where[] = qsprintf( 78 + $conn, 79 + 'edge.dst = %s OR actorPHID = %s', 80 + $viewer->getPHID(), 81 + $viewer->getPHID()); 82 + } 83 + } 84 + 85 + if ($this->createdMin !== null) { 68 86 $where[] = qsprintf( 69 - $conn_r, 70 - 'edge.dst = %s OR actorPHID = %s', 71 - $viewer->getPHID(), 72 - $viewer->getPHID()); 87 + $conn, 88 + 'mail.dateCreated >= %d', 89 + $this->createdMin); 73 90 } 74 91 75 - $where[] = $this->buildPagingClause($conn_r); 92 + if ($this->createdMax !== null) { 93 + $where[] = qsprintf( 94 + $conn, 95 + 'mail.dateCreated <= %d', 96 + $this->createdMax); 97 + } 76 98 77 - return $this->formatWhereClause($where); 99 + return $where; 78 100 } 79 101 80 102 protected function buildJoinClause(AphrontDatabaseConnection $conn) {