Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/text.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2019-04-13 21:28:28 +0300
committerJulius Härtl <jus@bitgrid.net>2019-04-13 21:28:28 +0300
commit1bdb0ff3eaa0f8a874bbf306ca5fe8a45f8e6ff4 (patch)
tree69363d95e38dc7b02a55c4e2cf3a9149f75cbb46 /lib/Controller
parent66adbbbe655ef62f1545a39c2bf31630455af8da (diff)
Add first working version of collaborative editing
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib/Controller')
-rw-r--r--lib/Controller/PublicSessionController.php51
-rw-r--r--lib/Controller/SessionController.php79
2 files changed, 113 insertions, 17 deletions
diff --git a/lib/Controller/PublicSessionController.php b/lib/Controller/PublicSessionController.php
new file mode 100644
index 000000000..446b02fde
--- /dev/null
+++ b/lib/Controller/PublicSessionController.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Härtl <jus@bitgrid.net>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+declare(strict_types=1);
+
+
+namespace OCA\Text\Controller;
+
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\FileDisplayResponse;
+use OCP\Files\IRootFolder;
+use OCP\ICacheFactory;
+use OCP\IRequest;
+use OCP\ITempManager;
+use OCP\Security\ISecureRandom;
+
+class PublicSessionController extends SessionController {
+
+ /**
+ * TODO: maybe set guestUserId in middleware
+ */
+
+ /**
+ * @PublicPage
+ */
+ public function push($transaction): DataResponse {
+ parent::push($transaction);
+ }
+
+}
diff --git a/lib/Controller/SessionController.php b/lib/Controller/SessionController.php
index 0ce4c1e03..7416bd5c3 100644
--- a/lib/Controller/SessionController.php
+++ b/lib/Controller/SessionController.php
@@ -4,10 +4,14 @@ declare(strict_types=1);
namespace OCA\Text\Controller;
+use OCA\Text\Service\DocumentService;
+use OCA\Text\Service\SessionService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
+use OCP\AppFramework\Http\NotFoundResponse;
use OCP\Files\IRootFolder;
+use OCP\Files\NotFoundException;
use OCP\ICacheFactory;
use OCP\IRequest;
use OCP\ITempManager;
@@ -15,51 +19,92 @@ use OCP\Security\ISecureRandom;
class SessionController extends Controller {
+ private $cache;
+ private $sessionService;
+ private $documentService;
- private $userId;
- private $secureRandom;
-
- public function __construct(string $appName, IRequest $request, ICacheFactory $cacheFactory, ITempManager $tempManager, $userId, IRootFolder $rootFolder, ISecureRandom $secureRandom) {
+ public function __construct(string $appName, IRequest $request, ICacheFactory $cacheFactory, SessionService $sessionService, DocumentService $documentService) {
parent::__construct($appName, $request);
- $this->userId = $userId;
- $this->file = $rootFolder->get('example.md');
- $this->secureRandom = $secureRandom;
+ $this->cache = $cacheFactory->createDistributed('textSession');
+ $this->sessionService = $sessionService;
+ $this->documentService = $documentService;
+ }
+
+ /**
+ * Initialize the session as a client so it can use the other methods
+ *
+ * @NoCSRFRequired
+ * @NoAdminRequired
+ */
+ public function create($file) {
+ $document = $this->documentService->createDocumentByPath($file);
+ $session = $this->sessionService->initSession($document->getId());
+ return new DataResponse([
+ 'document' => $document,
+ 'session' => $session
+ ]);
}
/**
+ *
+ *
* @NoCSRFRequired
* @NoAdminRequired
*/
- public function init() {
- $sessionId = $this->secureRandom->generate(32, ISecureRandom::CHAR_DIGITS);
- $token = $this->secureRandom->generate(32);
- // save session to database
- // return session details
+ public function fetch($documentId, $sessionId, $token) {
+ if ($this->sessionService->isValidSession($documentId, $sessionId, $token)) {
+ $this->sessionService->removeInactiveSessions($documentId);
+ $file = $this->documentService->getBaseFile($documentId);
+ return new FileDisplayResponse($file);
+ }
+ return new NotFoundResponse();
}
/**
+ * Close existing session when quiting the client gracefully
+ * This reduces some cleanup work if used by the client
+ *
* @NoCSRFRequired
* @NoAdminRequired
*/
- public function push($transaction): DataResponse {
+ public function close($documentId, $sessionId, $token): DataResponse {
+ // TODO: To implement
return new DataResponse([]);
}
/**
+ * Client tries to commit a set of transactions to the document
+ *
* @NoCSRFRequired
* @NoAdminRequired
*/
- public function get() {
- return new FileDisplayResponse($this->file);
+ public function push($documentId, $sessionId, $token, $version, $steps): DataResponse {
+ if ($this->sessionService->isValidSession($documentId, $sessionId, $token)) {
+ try {
+ $steps = $this->documentService->addStep($documentId, $sessionId, $steps, $version);
+ } catch (\Exception $e) {
+ return new DataResponse($e->getMessage(), 500);
+ }
+ return new DataResponse($steps);
+ }
+ return new DataResponse([], 500);
}
/**
+ * Eventsource based handler
+ *
* @NoCSRFRequired
* @NoAdminRequired
*/
- public function sync($transaction): DataResponse {
- return new DataResponse([]);
+ public function sync($documentId, $version = 0): DataResponse {
+ if ($version === $this->cache->get('document-version-'.$documentId)) {
+ return new DataResponse(['steps' => []]);
+ }
+ return new DataResponse([
+ 'steps' => $this->documentService->getSteps($documentId, $version),
+ 'sessions' => $this->sessionService->getActiveSessions($documentId)
+ ]);
}
}