Skip to content

Commit

Permalink
Respect quota + add background job
Browse files Browse the repository at this point in the history
Fix #930

Signed-off-by: Carl Schwan <[email protected]>
  • Loading branch information
CarlSchwan committed Nov 19, 2021
1 parent bee91f4 commit b887742
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 28 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Group folders can be configured on the command line (cli) using the `occ` comman

- `occ groupfolders:create <name>` &rarr; create a group folder
- `occ groupfolders:delete <folder_id> [-f|--force]` &rarr; delete a group folder and all its contents
- `occ groupfolders:expire` &rarr; trigger file version expiration (see [Nextcloud docs](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/file_versioning.html) for details)
- `occ groupfolders:expire` &rarr; trigger file version and trashbin expiration (see [Nextcloud docs for versionning](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/file_versioning.html) and [Nextcloud docs for the trash bin](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/trashbin_configuration.html) for details)
- `occ groupfolders:group <folder_id> <group_id> [-d|--delete] [write|share|delete]` &rarr; assign groups and their rights to a group folder
- `occ groupfolders:list` &rarr; list configured group folders
- `occ groupfolders:permissions` &rarr; configure advanced permissions (see below for details)
Expand Down
10 changes: 5 additions & 5 deletions composer.lock

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

12 changes: 8 additions & 4 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent;
use OCA\Files_Trashbin\Expiration;
use OCA\GroupFolders\ACL\ACLManagerFactory;
use OCA\GroupFolders\ACL\RuleManager;
use OCA\GroupFolders\ACL\UserMapping\IUserMappingManager;
Expand Down Expand Up @@ -87,7 +88,8 @@ public function register(IRegistrationContext $context): void {
$c->get(TrashManager::class),
$c->get('GroupAppFolder'),
$c->get(MountProvider::class),
$c->get(ACLManagerFactory::class)
$c->get(ACLManagerFactory::class),
$c->getServer()->getRootFolder(),
$c->get(VersionsBackend::class)
);
});
Expand All @@ -103,9 +105,9 @@ public function register(IRegistrationContext $context): void {
$context->registerService(ExpireGroupVersions::class, function (IAppContainer $c) {
if (interface_exists('OCA\Files_Versions\Versions\IVersionBackend')) {
return new ExpireGroupVersions(
$c->get(GroupVersionsExpireManager::class)
$c->get(GroupVersionsExpireManager::class),
$c->get(TrashBackend::class)
$c->get(TrashBackend::class),
$c->get(Expiration::class)
);
}
return new ExpireGroupVersionsPlaceholder();
Expand All @@ -114,7 +116,9 @@ public function register(IRegistrationContext $context): void {
$context->registerService(\OCA\GroupFolders\BackgroundJob\ExpireGroupVersions::class, function (IAppContainer $c) {
if (interface_exists('OCA\Files_Versions\Versions\IVersionBackend')) {
return new \OCA\GroupFolders\BackgroundJob\ExpireGroupVersions(
$c->get(GroupVersionsExpireManager::class)
$c->get(GroupVersionsExpireManager::class),
$c->get(TrashBackend::class),
$c->get(Expiration::class)
);
}
return new \OCA\GroupFolders\BackgroundJob\ExpireGroupVersionsPlaceholder();
Expand Down
17 changes: 16 additions & 1 deletion lib/BackgroundJob/ExpireGroupVersions.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,35 @@
namespace OCA\GroupFolders\BackgroundJob;

use OCA\GroupFolders\Versions\GroupVersionsExpireManager;
use OCA\Files_Trashbin\Expiration;

class ExpireGroupVersions extends \OC\BackgroundJob\TimedJob {
const ITEMS_PER_SESSION = 1000;

/** @var GroupVersionsExpireManager */
private $expireManager;

public function __construct(GroupVersionsExpireManager $expireManager) {
/** @var TrashBackend */
private $trashBackend;

/** @var Expiration */
private $expiration;

public function __construct(
GroupVersionsExpireManager $expireManager,
TrashBackend $trashBackend,
Expiration $expiration
) {
// Run once per hour
$this->setInterval(60 * 60);

$this->expireManager = $expireManager;
$this->trashBackend = $trashBackend;
$this->expiration = $expiration;
}

protected function run($argument) {
$this->expireManager->expireAll();
$this->trashBackend->expire($this->expiration);
}
}
14 changes: 12 additions & 2 deletions lib/Command/ExpireGroupVersions.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,24 @@
use Symfony\Component\Console\Output\OutputInterface;

class ExpireGroupVersions extends Base {
/** @var GroupVersionsExpireManager */
private $expireManager;

/** @var TrashBackend */
private $trashBackend;

public function __construct(GroupVersionsExpireManager $expireManager, TrashBackend $trashBackend) {
/** @var Expiration */
private $expiration;

public function __construct(
GroupVersionsExpireManager $expireManager,
TrashBackend $trashBackend,
Expiration $expiration
) {
parent::__construct();
$this->expireManager = $expireManager;
$this->trashBackend = $trashBackend;
$this->expiration = $expiration;
}

protected function configure() {
Expand All @@ -62,7 +72,7 @@ protected function execute(InputInterface $input, OutputInterface $output) {
});


list($count, $size) = $this->trashBackend->expire(\OC::$server->get(Expiration::class));
list($count, $size) = $this->trashBackend->expire($this->expiration);
$output->writeln("<info>Removed $count expired trashbin items</info>");

$this->expireManager->expireAll();
Expand Down
4 changes: 2 additions & 2 deletions lib/Folder/FolderManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private function joinQueryWithFileCache(IQueryBuilder $query, int $rootStorageId
/**
* @return (array|bool|int|mixed)[][]
*
* @psalm-return array<int, array{id: int, mount_point: mixed, groups: array<empty, empty>|array<array-key, int>, quota: int, size: int|mixed, acl: bool, manage: mixed}>
* @psalm-return array<int, array{id: int, mount_point: mixed, groups: array<empty, empty>|array<array-key, int>, quota: int, size: int, acl: bool, manage: mixed}>
* @throws Exception
*/
public function getAllFoldersWithSize(int $rootStorageId): array {
Expand All @@ -142,7 +142,7 @@ public function getAllFoldersWithSize(int $rootStorageId): array {
'mount_point' => $row['mount_point'],
'groups' => $applicableMap[$id] ?? [],
'quota' => (int)$row['quota'],
'size' => $row['size'] ? $row['size'] : 0,
'size' => $row['size'] ? (int)$row['size'] : 0,
'acl' => (bool)$row['acl'],
'manage' => $this->getManageAcl($mappings)
];
Expand Down
26 changes: 22 additions & 4 deletions lib/Trash/TrashBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\Files\Storage\IStorage;
use OCP\Files\IRootFolder;
use OCP\IUser;

class TrashBackend implements ITrashBackend {
Expand All @@ -58,12 +59,16 @@ class TrashBackend implements ITrashBackend {
/** @var VersionsBackend */
private $versionsBackend;

/** @var IRootFolder */
private $rootFolder;

public function __construct(
FolderManager $folderManager,
TrashManager $trashManager,
Folder $appFolder,
MountProvider $mountProvider,
ACLManagerFactory $aclManagerFactory,
IRootFolder $rootFolder,
VersionsBackend $versionsBackend
) {
$this->folderManager = $folderManager;
Expand All @@ -72,6 +77,7 @@ public function __construct(
$this->mountProvider = $mountProvider;
$this->aclManagerFactory = $aclManagerFactory;
$this->versionsBackend = $versionsBackend;
$this->rootFolder = $rootFolder;
}

public function listTrashRoot(IUser $user): array {
Expand Down Expand Up @@ -349,15 +355,25 @@ public function cleanTrashFolder(int $folderid) {
public function expire(Expiration $expiration): array {
$size = 0;
$count = 0;
$folders = $this->folderManager->getAllFolders();
$folders = $this->folderManager->getAllFoldersWithSize($this->rootFolder->getMountPoint()->getNumericStorageId());
foreach ($folders as $folder) {
$folderId = $folder['id'];
$trashItems = $this->trashManager->listTrashForFolders([$folderId]);

// calculate size of trash items
$sizeInTrash = 0;
$trashFolder = $this->getTrashFolder($folderId);
$nodes = []; // cache
foreach ($trashItems as $groupTrashItem) {
if ($expiration->isExpired($groupTrashItem['deleted_time'])) {
$nodeName = $groupTrashItem['name'] . '.d' . $groupTrashItem['deleted_time'];
$nodes[$nodeName] = $node = $trashFolder->get($nodeName);
$sizeInTrash += $node->getSize();
}
foreach ($trashItems as $groupTrashItem) {
if ($expiration->isExpired($groupTrashItem['deleted_time'], $folder['quota'] < ($folder['size'] + $sizeInTrash))) {
try {
$node = $trashFolder->get($groupTrashItem['name'] . '.d' . $groupTrashItem['deleted_time']);
$nodeName = $groupTrashItem['name'] . '.d' . $groupTrashItem['deleted_time'];
$node = $nodes[$nodeName];
$size += $node->getSize();
$count += 1;
} catch (NotFoundException $e) {
Expand All @@ -369,7 +385,9 @@ public function expire(Expiration $expiration): array {
}
$node->getStorage()->getCache()->remove($node->getInternalPath());
$this->trashManager->removeItem($folderId, $groupTrashItem['name'], $groupTrashItem['deleted_time']);
$this->versionsBackend->deleteAllVersionsForFile($folderId, $groupTrashItem['file_id']);
if (!is_null($groupTrashItem['file_id'])) {
$this->versionsBackend->deleteAllVersionsForFile($folderId, $groupTrashItem['file_id']);
}
} else {
break;
}
Expand Down
10 changes: 1 addition & 9 deletions tests/psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,13 @@
</MissingDependency>
</file>
<file src="lib/AppInfo/Application.php">
<MissingDependency occurrences="13">
<MissingDependency occurrences="17">
<code>$c-&gt;getServer()-&gt;getRootFolder()</code>
<code>ExpireGroupVersions</code>
<code>ExpireGroupVersions</code>
<code>ExpireGroupVersionsPlaceholder</code>
<code>GroupVersionsExpireManager</code>
<code>GroupVersionsExpireManager</code>
<code>TrashBackend</code>
<code>TrashBackend</code>
<code>VersionsBackend</code>
<code>VersionsBackend</code>
<code>\OCA\GroupFolders\BackgroundJob\ExpireGroupVersions</code>
<code>\OCA\GroupFolders\BackgroundJob\ExpireGroupVersions</code>
<code>\OCA\GroupFolders\BackgroundJob\ExpireGroupVersionsPlaceholder</code>
</MissingDependency>
Expand Down Expand Up @@ -67,9 +62,6 @@
<code>GroupFolderStorage</code>
<code>GroupMountPoint</code>
</MissingDependency>
<UndefinedDocblockClass occurrences="1">
<code>$this-&gt;mountProviderCollection-&gt;getHomeMountForUser($user)-&gt;getStorage()</code>
</UndefinedDocblockClass>
</file>
<file src="lib/Versions/ExpireManager.php">
<TypeDoesNotContainType occurrences="2">
Expand Down

0 comments on commit b887742

Please sign in to comment.