Skip to content

Commit

Permalink
Implement skeleton folder support (#69)
Browse files Browse the repository at this point in the history
When creating a new collective, copy over the skeleton folder instead of
creating an empty folder.
  • Loading branch information
mejo- committed Aug 22, 2020
1 parent fb8fbdc commit 21bd107
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 130 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ organize together. Come and gather in collectives to build shared knowledge.
* **Well-known [Markdown](https://en.wikipedia.org/wiki/Markdown) syntax**
for page formatting

## Usage

### Custom skeletons for new collectives

It's possible to customize the skeletons for new collectives by putting files
in the app skeleton directory at `data/app_<INSTANCE_ID>/collectives/skeleton`.
New collectives get the contents of this skeleton directory copied over.

`README.md` is the landing page that is opened automatically when entering a
collective.

If the skeleton directory doesn't contain a `README.md`, the default landing
page from `collectives/skeleton/README.md` will be copied into the collectives
directory instead.

## Dependencies

For installation (see below), the following tools need to be available:
Expand Down
6 changes: 2 additions & 4 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
namespace OCA\Collectives\AppInfo;

use Closure;
use OCA\Collectives\Mount\CollectiveRootPathHelper;
use OCA\Collectives\Mount\CollectiveFolderManager;
use OCA\Collectives\Mount\MountProvider;
use OCA\Collectives\Service\CollectiveHelper;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Files\Config\IMountProviderCollection;
use OCP\Files\IRootFolder;
use OCP\IUserSession;
use Psr\Container\ContainerInterface;

Expand All @@ -31,8 +30,7 @@ public function register(IRegistrationContext $context): void {
$context->registerService(MountProvider::class, function (ContainerInterface $c) {
return new MountProvider(
$c->get(CollectiveHelper::class),
$c->get(CollectiveRootPathHelper::class),
$c->get(IRootFolder::class),
$c->get(CollectiveFolderManager::class),
$c->get(IUserSession::class)
);
});
Expand Down
101 changes: 101 additions & 0 deletions lib/Mount/CollectiveFolderManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace OCA\Collectives\Mount;

use OC\Files\Node\LazyFolder;
use OC\SystemConfig;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;

class CollectiveFolderManager {
public const SKELETON_DIR = 'skeleton';
public const LANDING_PAGE = 'README.md';

/** @var SystemConfig */
private $systemConfig;

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

/**
* MountProvider constructor.
*
* @param SystemConfig $systemConfig
* @param IRootFolder $rootFolder
*/
public function __construct(
IRootFolder $rootFolder,
SystemConfig $systemConfig) {
$this->systemConfig = $systemConfig;
$this->rootFolder = $rootFolder;
}

public function getRootPath(): string {
$instanceId = $this->systemConfig->getValue('instanceid', null);
if (null === $instanceId) {
throw new \RuntimeException('no instance id!');
}

return 'appdata_' . $instanceId . '/collectives';
}

/**
* @return Folder
*/
public function getRootFolder(): Folder {
$rootFolder = $this->rootFolder;
return (new LazyFolder(function () use ($rootFolder) {
try {
return $rootFolder->get($this->getRootPath());
} catch (NotFoundException $e) {
return $rootFolder->newFolder($this->getRootPath());
}
}));
}

/**
* @param Folder $folder
*
* @return Folder
* @throws NotPermittedException
*/
public function getSkeletonFolder(Folder $folder): Folder {
try {
$skeletonFolder = $folder->get(self::SKELETON_DIR);
if (!$skeletonFolder instanceof Folder) {
throw new NotFoundException('Not a folder: ' . $skeletonFolder->getPath());
}
} catch (NotFoundException $e) {
$skeletonFolder = $folder->newFolder(self::SKELETON_DIR);
}

return $skeletonFolder;
}

/**
* @param int $id
* @param bool $create
*
* @return Folder|null
* @throws NotPermittedException
*/
public function getFolder(int $id, bool $create = true): ?Folder {
try {
$folder = $this->getRootFolder()->get((string)$id);
if (!$folder instanceof Folder) {
return null;
}
} catch (NotFoundException $e) {
if (!$create) {
return null;
}

$folder = $this->getSkeletonFolder($this->getRootFolder())
->copy($this->getRootFolder()->getPath() . '/' . (string)$id);
}

return $folder;
}
}
26 changes: 13 additions & 13 deletions lib/Mount/CollectiveMountPoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,33 @@ class CollectiveMountPoint extends MountPoint {
/** @var int */
private $folderId;

/** @var CollectiveRootPathHelper */
private $collectiveRootPathHelper;
/** @var CollectiveFolderManager */
private $collectiveFolderManager;

/**
* CollectiveMountPoint constructor.
*
* @param int|null $folderId
* @param CollectiveRootPathHelper $collectiveRootPathHelper
* @param CollectiveStorage $storage
* @param string $mountPoint
* @param array|null $arguments
* @param IStorageFactory|null $loader
* @param array|null $mountOptions
* @param int|null $mountId
* @param int|null $folderId
* @param CollectiveFolderManager $collectiveFolderManager
* @param CollectiveStorage $storage
* @param string $mountPoint
* @param array|null $arguments
* @param IStorageFactory|null $loader
* @param array|null $mountOptions
* @param int|null $mountId
*
* @throws \Exception
*/
public function __construct(?int $folderId,
CollectiveRootPathHelper $collectiveRootPathHelper,
CollectiveFolderManager $collectiveFolderManager,
CollectiveStorage $storage,
string $mountPoint,
array $arguments = null,
IStorageFactory $loader = null,
array $mountOptions = null,
int $mountId = null) {
$this->folderId = $folderId;
$this->collectiveRootPathHelper = $collectiveRootPathHelper;
$this->collectiveFolderManager = $collectiveFolderManager;
parent::__construct($storage, $mountPoint, $arguments, $loader, $mountOptions, $mountId);
}

Expand Down Expand Up @@ -77,6 +77,6 @@ public function getFolderId(): int {
* @return string
*/
public function getSourcePath(): string {
return '/' . $this->collectiveRootPathHelper->get() . '/' . $this->getFolderId();
return '/' . $this->collectiveFolderManager->getRootFolder()->getPath() . '/' . $this->getFolderId();
}
}
28 changes: 0 additions & 28 deletions lib/Mount/CollectiveRootPathHelper.php

This file was deleted.

78 changes: 9 additions & 69 deletions lib/Mount/MountProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@

namespace OCA\Collectives\Mount;

use OC\Files\Node\LazyFolder;
use OC\Files\Storage\Wrapper\Jail;
use OCA\Collectives\Service\CollectiveHelper;
use OCP\Files\Config\IMountProvider;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
Expand All @@ -16,16 +13,11 @@
use OCP\IUserSession;

class MountProvider implements IMountProvider {
private const LANDING_PAGE = 'README.md';

/** @var CollectiveHelper */
private $collectiveHelper;

/** @var CollectiveRootPathHelper */
private $collectiveRootPathHelper;

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

/** @var IUserSession */
private $userSession;
Expand All @@ -34,18 +26,15 @@ class MountProvider implements IMountProvider {
* MountProvider constructor.
*
* @param CollectiveHelper $collectiveHelper
* @param CollectiveRootPathHelper $collectiveRootPathHelper
* @param IRootFolder $rootFolder
* @param CollectiveFolderManager $collectiveFolderManager
* @param IUserSession $userSession
*/
public function __construct(
CollectiveHelper $collectiveHelper,
CollectiveRootPathHelper $collectiveRootPathHelper,
IRootFolder $rootFolder,
CollectiveFolderManager $collectiveFolderManager,
IUserSession $userSession) {
$this->collectiveHelper = $collectiveHelper;
$this->collectiveRootPathHelper = $collectiveRootPathHelper;
$this->rootFolder = $rootFolder;
$this->collectiveFolderManager = $collectiveFolderManager;
$this->userSession = $userSession;
}

Expand Down Expand Up @@ -81,14 +70,6 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader) {
}, $folders);
}

/**
* @return string|null
*/
private function getCurrentUID(): ?string {
$user = $this->userSession->getUser();
return $user ? $user->getUID() : null;
}

/**
* @param int $id
* @param string $mountPoint
Expand All @@ -107,10 +88,10 @@ public function getMount(int $id,
IUser $user = null): IMountPoint {
if (!$cacheEntry) {
// trigger folder creation
$this->getFolder($id);
$this->collectiveFolderManager->getFolder($id);
}

$storage = $this->getCollectivesRootFolder()->getStorage();
$storage = $this->collectiveFolderManager->getRootFolder()->getStorage();

$rootPath = $this->getJailPath($id);

Expand All @@ -128,7 +109,7 @@ public function getMount(int $id,

return new CollectiveMountPoint(
$id,
$this->collectiveRootPathHelper,
$this->collectiveFolderManager,
$collectiveStorage,
$mountPoint,
null,
Expand All @@ -142,47 +123,6 @@ public function getMount(int $id,
* @return string
*/
public function getJailPath(int $folderId): string {
return $this->getCollectivesRootFolder()->getInternalPath() . '/' . $folderId;
}

/**
* @return Folder
*/
private function getCollectivesRootFolder(): Folder {
$rootFolder = $this->rootFolder;
return (new LazyFolder(function () use ($rootFolder) {
try {
return $rootFolder->get($this->collectiveRootPathHelper->get());
} catch (NotFoundException $e) {
return $rootFolder->newFolder($this->collectiveRootPathHelper->get());
}
}));
}

/**
* @param int $id
* @param bool $create
*
* @return Folder|null
* @throws NotPermittedException
*/
public function getFolder(int $id, bool $create = true): ?Folder {
try {
$folder = $this->getCollectivesRootFolder()->get((string)$id);
if (!$folder instanceof Folder) {
return null;
}
} catch (NotFoundException $e) {
if ($create) {
$folder = $this->getCollectivesRootFolder()->newFolder((string)$id);
}
return null;
}

if ($create && !$folder->nodeExists(self::LANDING_PAGE)) {
$folder->newFile(self::LANDING_PAGE);
}

return $folder;
return $this->collectiveFolderManager->getRootFolder()->getInternalPath() . '/' . $folderId;
}
}
Loading

0 comments on commit 21bd107

Please sign in to comment.