Skip to content

Commit

Permalink
Add diff report
Browse files Browse the repository at this point in the history
Signed-off-by: Florent Poinsaut <[email protected]>
  • Loading branch information
FlorentPoinsaut committed Nov 3, 2022
1 parent 1344da6 commit 67f299c
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 23 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"license": "MIT",
"require": {
"nikic/iter": "^2.2",
"symfony/serializer": "^5.4"
"symfony/serializer": "^5.4",
"swaggest/json-diff": "^3.9"
},
"require-dev": {
"phpunit/phpunit": "^9",
Expand Down
45 changes: 44 additions & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 0 additions & 7 deletions lib/Command/ListShares.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ public function configure() {

$this->setName('sharing:list')
->setDescription('List who has access to shares by owner')
->addOption(
'output',
'o',
InputOption::VALUE_OPTIONAL,
'Output format (json or csv, default is json)',
'json'
)
->addOption(
'output',
'o',
Expand Down
12 changes: 11 additions & 1 deletion lib/Command/SendShares.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public function configure() {

$this->setName('sharing:send')
->setDescription('Send list who has access to shares by owner')
->addOption(
'diff',
'd',
InputOption::VALUE_NONE,
'Create a differential report in json format from the last available report'
)
->addOption(
'recipients',
'r',
Expand All @@ -75,6 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->checkAllRequiredOptionsAreNotEmpty($input);

[$user, $path, $token, $filter] = $this->getOptions($input);
$diff = $input->getOption('diff');
$recipients = $input->getOption('recipients');
$targetPath = $input->getOption('target-path');

Expand All @@ -91,9 +98,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$token
);

if ($diff) {
$this->reportSender->diff($recipient, $targetPath);
}

$this->reportSender->sendReport($recipient, $dateTime);
}

return 0;
}

Expand Down
134 changes: 121 additions & 13 deletions lib/Service/ReportSender.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,40 @@

namespace OCA\ShareListing\Service;

use Icewind\SMB\Exception\NotFoundException;
use iter;
use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchOrder;
use OC\Files\Search\SearchQuery;
use OCA\ShareListing\Service\SharesList;
use OCP\Defaults;
use OCP\Files\FileInfo;
use OCP\Files\Folder;
use OCP\Files\InvalidDirectoryException;
use OCP\Files\IRootFolder;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOrder;
use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\L10N\IFactory;
use OCP\Mail\IMailer;
use OCP\Util;
use Psr\Log\LoggerInterface;
use Swaggest\JsonDiff\JsonDiff;

class ReportSender {
public const ACTIVITY_LIMIT = 20;
class ReportSender
{
protected const REPORT_NAME = ' - Shares report.';

/** @var string */
private $appName;
/** @var Iconfig */
private $config;
/** @var ?array */
protected $diffReport = null;

private $mailer;
private $userManager;
Expand Down Expand Up @@ -115,22 +128,27 @@ public function createReport(
$formats = ['json', 'csv'];
$formatedDateTime = $dateTime->format('YmdHi');
foreach ($formats as $key => $format) {
$fileName = $formatedDateTime . ' - Shares report.' . $format;
$fileName = $formatedDateTime . self::REPORT_NAME . $format;
if (!array_key_exists($fileName, $this->reports)) {
if ($key === array_key_first($formats)) {
$shares = iter\toArray($this->sharesList->getFormattedShares($userId, $filter, $path, $token));
}
$reportFile = $folder->newFile($fileName);
$reportFile->putContent($this->sharesList->getSerializedShares($shares, $format));
$this->reports[$reportFile->getName()] = $this->url->linkToRouteAbsolute(
'files.View.showFile',
['fileid' => $reportFile->getId()]
);
$data = $this->sharesList->getSerializedShares($shares, $format);
$reportFile->putContent($data);
$this->reports[$reportFile->getName()] = [
'url' => $this->url->linkToRouteAbsolute(
'files.View.showFile',
['fileid' => $reportFile->getId()]
),
'data' => $data
];
}
}
}

public function sendReport(string $recipient, \DateTimeImmutable $dateTime) {
public function sendReport(string $recipient, \DateTimeImmutable $dateTime)
{
$defaultLanguage = $this->config->getSystemValue('default_language', 'en');
$userLanguages = $this->config->getUserValue($recipient, 'core', 'lang');
$language = (!empty($userLanguages)) ? $userLanguages : $defaultLanguage;
Expand All @@ -146,12 +164,21 @@ public function sendReport(string $recipient, \DateTimeImmutable $dateTime) {
$template->addHeader();
$template->addBodyText('You can find the list of shares reports generated on ' . $formatedDateTime . ':');

foreach ($this->reports as $name => $url) {
foreach ($this->reports as $name => $value) {
$template->addBodyListItem(
'<a href="' . $url . '">' . $name . '</a>',
'<a href="' . $value['url'] . '">' . $name . '</a>',
'',
'',
$name . ': ' . $url
$name . ': ' . $value['url']
);
}
if ($this->diffReport !== null) {
$template->addBodyText('You can also find the differential between this report and the previous one:');
$template->addBodyListItem(
'<a href="' . $this->diffReport['url'] . '">' . $this->diffReport['fileName'] . '</a>',
'',
'',
$this->diffReport['fileName'] . ': ' . $this->diffReport['url']
);
}

Expand All @@ -170,7 +197,8 @@ public function sendReport(string $recipient, \DateTimeImmutable $dateTime) {
}
}

protected function getEmailAdressFromUserId(string $userId): ?string {
protected function getEmailAdressFromUserId(string $userId): ?string
{
$user = $this->userManager->get($userId);
if ($user === null) {
$this->logger->warning(
Expand All @@ -191,4 +219,84 @@ protected function getEmailAdressFromUserId(string $userId): ?string {

return $email;
}

public function diff(
string $userId,
string $dir
) {
$userFolder = $this->root->getUserFolder($userId);

if ($userFolder->nodeExists($dir)) {
/** @var Folder $folder */
$folder = $userFolder->get($dir);
if ($folder->getType() !== FileInfo::TYPE_FOLDER) {
throw new InvalidDirectoryException('Invalid directory, "' . $dir . '" not a folder');
}
} else {
throw new InvalidDirectoryException('Invalid directory, "' . $dir . '" does not exist');
}

$search = $userFolder->search(
new SearchQuery(
new SearchBinaryOperator(
ISearchBinaryOperator::OPERATOR_OR,
[
new SearchComparison(
ISearchComparison::COMPARE_LIKE,
'name',
'%' . self::REPORT_NAME . 'json'
)
]
),
1,
1,
[new SearchOrder(ISearchOrder::DIRECTION_DESCENDING, 'mtime')]
)
);

if (empty($search)) {
throw new NotFoundException('No previous report found on this folder.');
}

$previousFile = $search[0];
$previousFilename = $previousFile->getName();
$previousDateTime = substr($previousFilename, 0, 12);
$previousContent = json_decode($previousFile->getContent());
$previousContentWithId = [];
foreach ($previousContent as $value) {
$previousContentWithId[$value->id] = $value;
}

$newFilename = array_keys($this->reports)[0];
$newDateTime = substr($newFilename, 0, 12);
$newContent = json_decode(array_values($this->reports)[0]['data']);
$newContentWithId = [];
foreach ($newContent as $value) {
$newContentWithId[$value->id] = $value;
}

$jsonDiff = new JsonDiff(
$previousContentWithId,
$newContentWithId,
JsonDiff::REARRANGE_ARRAYS + JsonDiff::COLLECT_MODIFIED_DIFF
);

$reportFilename = $previousDateTime . ' - ' . $newDateTime . ' - Shares report diff.json';
$reportFile = $folder->newFile($reportFilename);
$res = [
'added' => $jsonDiff->getAdded(),
'removed' => $jsonDiff->getRemoved(),
'modified' => $jsonDiff->getModifiedDiff()
];

$reportFile->putContent(json_encode($res, JSON_PRETTY_PRINT));

$this->diffReport = [
'url' => $this->url->linkToRouteAbsolute(
'files.View.showFile',
['fileid' => $reportFile->getId()]
),
'fileName' => $reportFilename
];
}
}

0 comments on commit 67f299c

Please sign in to comment.