Skip to content

Commit

Permalink
Merge pull request #1377 from nextcloud/bugfix/noid/use-proper-emptyt…
Browse files Browse the repository at this point in the history
…emplate
  • Loading branch information
juliusknorr authored Jan 14, 2022
2 parents 03d939e + 5a95699 commit 42cfd25
Show file tree
Hide file tree
Showing 20 changed files with 991 additions and 289 deletions.
3 changes: 2 additions & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<description><![CDATA[This application can connect to a Collabora Online (or other) server (WOPI-like Client). Nextcloud is the WOPI Host. Please read the documentation to learn more about that.
You can also edit your documents off-line with the Collabora Office app from the **[Android](https://play.google.com/store/apps/details?id=com.collabora.libreoffice)** and **[iOS](https://apps.apple.com/us/app/collabora-office/id1440482071)** store.]]></description>
<version>5.0.0-beta1</version>
<version>6.0.0-dev.1</version>
<licence>agpl</licence>
<author>Collabora Productivity based on work of Frank Karlitschek, Victor Dubiniuk</author>
<types>
Expand All @@ -31,6 +31,7 @@ You can also edit your documents off-line with the Collabora Office app from the
</dependencies>
<background-jobs>
<job>OCA\Richdocuments\Backgroundjobs\ObtainCapabilities</job>
<job>OCA\Richdocuments\Backgroundjobs\Cleanup</job>
</background-jobs>
<commands>
<command>OCA\Richdocuments\Command\ActivateConfig</command>
Expand Down
3 changes: 2 additions & 1 deletion appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@

['name' => 'document#createFromTemplate', 'url' => 'indexTemplate', 'verb' => 'GET'],
['name' => 'document#publicPage', 'url' => '/public', 'verb' => 'GET'],
['name' => 'document#create', 'url' => 'ajax/documents/create', 'verb' => 'POST'],

// external api access
['name' => 'document#extAppGetData', 'url' => '/ajax/extapp/data/{fileId}', 'verb' => 'POST'],
Expand Down Expand Up @@ -67,6 +66,8 @@
['name' => 'templates#delete', 'url' => '/template/{fileId}', 'verb' => 'DELETE'],
],
'ocs' => [
['name' => 'documentAPI#create', 'url' => '/api/v1/file', 'verb' => 'POST'],

['name' => 'OCS#createDirect', 'url' => '/api/v1/document', 'verb' => 'POST'],
['name' => 'OCS#createPublic', 'url' => '/api/v1/share', 'verb' => 'POST'],
['name' => 'OCS#createPublicFromInitiator', 'url' => '/api/v1/direct/share/initiator', 'verb' => 'POST'],
Expand Down
9 changes: 8 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
{
"name": "nextcloud/richdocuments",
"type": "project",
"minimum-stability": "dev",
"prefer-stable" : true,
"config": {
"platform": {
"php": "7.3"
}
},
"require-dev": {
"roave/security-advisories": "dev-master",
"christophwurst/nextcloud": "^21.0",
"christophwurst/nextcloud": "dev-master",
"jakub-onderka/php-parallel-lint": "^1.0.0",
"psalm/phar": "^4.7"
},
Expand Down
506 changes: 442 additions & 64 deletions composer.lock

Large diffs are not rendered by default.

Binary file removed emptyTemplates/odttemplate.odt
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 3 additions & 2 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use OCA\Richdocuments\AppConfig;
use OCA\Richdocuments\Capabilities;
use OCA\Richdocuments\Middleware\WOPIMiddleware;
use OCA\Richdocuments\Listener\FileCreatedFromTemplateListener;
use OCA\Richdocuments\PermissionManager;
use OCA\Richdocuments\Preview\MSExcel;
use OCA\Richdocuments\Preview\MSWord;
Expand All @@ -48,6 +49,7 @@
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Template\FileCreatedFromTemplateEvent;
use OCP\Files\Template\ITemplateManager;
use OCP\Files\Template\TemplateFileCreator;
use OCP\IConfig;
Expand All @@ -68,6 +70,7 @@ public function register(IRegistrationContext $context): void {
$context->registerTemplateProvider(CollaboraTemplateProvider::class);
$context->registerCapability(Capabilities::class);
$context->registerMiddleWare(WOPIMiddleware::class);
$context->registerEventListener(FileCreatedFromTemplateEvent::class, FileCreatedFromTemplateListener::class);
}

public function boot(IBootContext $context): void {
Expand Down Expand Up @@ -183,9 +186,7 @@ public function registerProvider() {
return $container->query(OOXML::class);
});

// \OC::$server->getLogger()->debug('==== Richdocuments Application registerProvider: calling manager registerProvider:');
$previewManager->registerProvider('/application\/vnd.oasis.opendocument.*/', function() use ($container) {
// \OC::$server->getLogger()->debug('==== Richdocuments Application registerProvider lambda. OpenDocument::class=' . OpenDocument::class);
return $container->query(OpenDocument::class);
});

Expand Down
49 changes: 49 additions & 0 deletions lib/Backgroundjobs/Cleanup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <[email protected]>
*
* @author Roeland Jago Douma <[email protected]>
*
* @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/>.
*
*/

namespace OCA\Richdocuments\Backgroundjobs;

use OC\BackgroundJob\TimedJob;
use OCA\Richdocuments\Service\CapabilitiesService;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;

class Cleanup extends TimedJob {

/** @var IDBConnection */
private $db;

public function __construct(IDBConnection $db) {
$this->db = $db;

$this->setInterval(60*60);
}

protected function run($argument) {
// Expire template mappings for file creation
$query = $this->db->getQueryBuilder();
$query->delete('richdocuments_template')
->where($query->expr()->lte('timestamp', $query->createNamedParameter(time() - 60, IQueryBuilder::PARAM_INT)));
$query->executeStatement();
}
}
145 changes: 145 additions & 0 deletions lib/Controller/DocumentAPIController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php
/*
* @copyright Copyright (c) 2021 Julius Härtl <[email protected]>
*
* @author Julius Härtl <[email protected]>
*
* @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\Richdocuments\Controller;

use Exception;
use OCA\Richdocuments\AppInfo\Application;
use OCA\Richdocuments\Helper;
use OCA\Richdocuments\TemplateManager;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\IL10N;
use OCP\IRequest;
use OCP\Share\IManager;
use Psr\Log\LoggerInterface;
use Throwable;

class DocumentAPIController extends \OCP\AppFramework\OCSController {

private $rootFolder;
private $shareManager;
private $templateManager;
private $l10n;
private $logger;
private $userId;

public function __construct(IRequest $request, IRootFolder $rootFolder, IManager $shareManager, TemplateManager $templateManager, IL10N $l10n, LoggerInterface $logger, $userId) {
parent::__construct(Application::APPNAME, $request);
$this->rootFolder = $rootFolder;
$this->shareManager = $shareManager;
$this->templateManager = $templateManager;
$this->l10n = $l10n;
$this->logger = $logger;
$this->userId = $userId;
}

/**
* Create a file from a public share link of a folder
*
* As the server template API for file creation is not available there, we need a dedicated API
* in order to properly create files as public page visitors. This is being called in the new file
* actions in src/view/NewFileMenu.js
*
* @NoAdminRequired
* @PublicPage
*/
public function create(string $mimeType, string $fileName, string $directoryPath = '/', string $shareToken = null): JSONResponse {
try {
if ($shareToken !== null) {
$share = $this->shareManager->getShareByToken($shareToken);
}

$rootFolder = $shareToken !== null ? $share->getNode() : $this->rootFolder->getUserFolder($this->userId);
$folder = $rootFolder->get($directoryPath);

if (!($folder instanceof Folder)) {
throw new Exception('Node is not a folder');
}
} catch (Throwable $e) {
$this->logger->error('Failed to create document', ['exception' => $e]);
return new JSONResponse([
'status' => 'error',
'message' => $this->l10n->t('Cannot create document')
], Http::STATUS_BAD_REQUEST);
}

$basename = $this->l10n->t('New Document.odt');
switch ($mimeType) {
case 'application/vnd.oasis.opendocument.spreadsheet':
$basename = $this->l10n->t('New Spreadsheet.ods');
break;
case 'application/vnd.oasis.opendocument.presentation':
$basename = $this->l10n->t('New Presentation.odp');
break;
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
$basename = $this->l10n->t('New Document.docx');
break;
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
$basename = $this->l10n->t('New Spreadsheet.xlsx');
break;
case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
$basename = $this->l10n->t('New Presentation.pptx');
break;
default:
break;
}

if (!$fileName) {
$fileName = Helper::getNewFileName($folder, $basename);
}

if ($folder->nodeExists($fileName)) {
return new JSONResponse([
'status' => 'error',
'message' => $this->l10n->t('File already exists')
], Http::STATUS_BAD_REQUEST);
}

try {
$file = $folder->newFile($fileName);
$templateType = $this->templateManager->getTemplateTypeForExtension(pathinfo($fileName, PATHINFO_EXTENSION));
$empty = $this->templateManager->getEmpty($templateType);
$templateFile = array_shift($empty);
$file->putContent($this->templateManager->getEmptyFileContent($file->getExtension()));
if ($this->templateManager->isSupportedTemplateSource($templateFile->getExtension())) {
// Only use TemplateSource if supported filetype
$this->templateManager->setTemplateSource($file->getId(), $templateFile->getId());
}
} catch (Exception $e) {
$this->logger->error('Failed to create file from template', ['exception' => $e]);
return new JSONResponse([
'status' => 'error',
'message' => $this->l10n->t('Not allowed to create document')
], Http::STATUS_BAD_REQUEST);
}
return new JSONResponse([
'status' => 'success',
'data' => \OCA\Files\Helper::formatFileInfo($file->getFileInfo())
]);
}
}
Loading

0 comments on commit 42cfd25

Please sign in to comment.