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:
authorJulien Veyssier <eneiluj@posteo.net>2022-06-08 18:44:49 +0300
committerJulien Veyssier <eneiluj@posteo.net>2022-09-06 15:44:53 +0300
commit3fec1f052dbb8cbe33172e779ac853eeb934ee62 (patch)
tree9cbdb5e28225dce8e45b14b06829668615fb6f55 /lib/Service/ImageService.php
parent3af1eb84126c4bb9396b701c963ee229cdc26c66 (diff)
allow media file upload, handle display in ImageView
Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
Diffstat (limited to 'lib/Service/ImageService.php')
-rw-r--r--lib/Service/ImageService.php257
1 files changed, 186 insertions, 71 deletions
diff --git a/lib/Service/ImageService.php b/lib/Service/ImageService.php
index 901575355..f305a5e39 100644
--- a/lib/Service/ImageService.php
+++ b/lib/Service/ImageService.php
@@ -31,12 +31,14 @@ use OCA\Text\Controller\ImageController;
use OCP\Constants;
use OCP\Files\Folder;
use OCP\Files\File;
+use OCP\Files\IMimeTypeDetector;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\IPreview;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IShare;
+use OCP\Util;
use Throwable;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ConnectException;
@@ -57,10 +59,6 @@ class ImageService {
*/
private $rootFolder;
/**
- * @var IClientService
- */
- private $clientService;
- /**
* @var LoggerInterface
*/
private $logger;
@@ -68,21 +66,25 @@ class ImageService {
* @var IPreview
*/
private $previewManager;
+ /**
+ * @var IMimeTypeDetector
+ */
+ private $mimeTypeDetector;
public function __construct(IRootFolder $rootFolder,
LoggerInterface $logger,
ShareManager $shareManager,
IPreview $previewManager,
- IClientService $clientService) {
+ IMimeTypeDetector $mimeTypeDetector) {
$this->rootFolder = $rootFolder;
$this->shareManager = $shareManager;
- $this->clientService = $clientService;
$this->logger = $logger;
$this->previewManager = $previewManager;
+ $this->mimeTypeDetector = $mimeTypeDetector;
}
/**
- * Get image content or preview from file id
+ * Get image content or preview from file name
* @param int $documentId
* @param string $imageFileName
* @param string $userId
@@ -91,9 +93,9 @@ class ImageService {
* @throws \OCP\Files\InvalidPathException
* @throws \OCP\Files\NotPermittedException
*/
- public function getImage(int $documentId, string $imageFileName, string $userId) {
+ public function getImageFile(int $documentId, string $imageFileName, string $userId) {
$textFile = $this->getTextFile($documentId, $userId);
- return $this->getImagePreview($imageFileName, $textFile);
+ return $this->getImageFilePreview($imageFileName, $textFile);
}
/**
@@ -107,9 +109,9 @@ class ImageService {
* @throws \OCP\Files\InvalidPathException
* @throws \OC\User\NoUserException
*/
- public function getImagePublic(int $documentId, string $imageFileName, string $shareToken) {
+ public function getImageFilePublic(int $documentId, string $imageFileName, string $shareToken) {
$textFile = $this->getTextFilePublic($documentId, $shareToken);
- return $this->getImagePreview($imageFileName, $textFile);
+ return $this->getImageFilePreview($imageFileName, $textFile);
}
/**
@@ -121,10 +123,10 @@ class ImageService {
* @throws \OCP\Files\InvalidPathException
* @throws \OC\User\NoUserException
*/
- private function getImagePreview(string $imageFileName, File $textFile) {
+ private function getImageFilePreview(string $imageFileName, File $textFile) {
$attachmentFolder = $this->getAttachmentDirectoryForFile($textFile, true);
$imageFile = $attachmentFolder->get($imageFileName);
- if ($imageFile instanceof File) {
+ if ($imageFile instanceof File && in_array($imageFile->getMimetype(), ImageController::IMAGE_MIME_TYPES)) {
if ($this->previewManager->isMimeSupported($imageFile->getMimeType())) {
return $this->previewManager->getPreview($imageFile, 1024, 1024);
}
@@ -134,6 +136,168 @@ class ImageService {
}
/**
+ * Get media file from file name
+ * @param int $documentId
+ * @param string $mediaFileName
+ * @param string $userId
+ * @return File|\OCP\Files\Node|ISimpleFile|null
+ * @throws NotFoundException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function getMediaFile(int $documentId, string $mediaFileName, string $userId) {
+ $textFile = $this->getTextFile($documentId, $userId);
+ return $this->getMediaFullFile($mediaFileName, $textFile);
+ }
+
+ /**
+ * Get image content or preview from file id in public context
+ * @param int $documentId
+ * @param string $mediaFileName
+ * @param string $shareToken
+ * @return File|\OCP\Files\Node|ISimpleFile|null
+ * @throws NotFoundException
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OC\User\NoUserException
+ */
+ public function getMediaFilePublic(int $documentId, string $mediaFileName, string $shareToken) {
+ $textFile = $this->getTextFilePublic($documentId, $shareToken);
+ return $this->getMediaFullFile($mediaFileName, $textFile);
+ }
+
+ /**
+ * @param string $mediaFileName
+ * @param File $textFile
+ * @return File|null
+ * @throws NotFoundException
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OC\User\NoUserException
+ */
+ private function getMediaFullFile(string $mediaFileName, File $textFile): ?File {
+ $attachmentFolder = $this->getAttachmentDirectoryForFile($textFile, true);
+ $mediaFile = $attachmentFolder->get($mediaFileName);
+ if ($mediaFile instanceof File) {
+ return $mediaFile;
+ }
+ return null;
+ }
+
+ /**
+ * @param int $documentId
+ * @param string $mediaFileName
+ * @param string $userId
+ * @return array|null
+ * @throws NotFoundException
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OC\User\NoUserException
+ */
+ public function getMediaFilePreview(int $documentId, string $mediaFileName, string $userId): ?array {
+ $textFile = $this->getTextFile($documentId, $userId);
+ return $this->getMediaFilePreviewFile($mediaFileName, $textFile);
+ }
+ /**
+ * @param int $documentId
+ * @param string $mediaFileName
+ * @param string $shareToken
+ * @return array|null
+ * @throws NotFoundException
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OC\User\NoUserException
+ */
+ public function getMediaFilePreviewPublic(int $documentId, string $mediaFileName, string $shareToken): ?array {
+ $textFile = $this->getTextFilePublic($documentId, $shareToken);
+ return $this->getMediaFilePreviewFile($mediaFileName, $textFile);
+ }
+
+ /**
+ * Get media preview or mimetype icon address
+ * @param string $mediaFileName
+ * @param File $textFile
+ * @return array|null
+ * @throws NotFoundException
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OC\User\NoUserException
+ */
+ private function getMediaFilePreviewFile(string $mediaFileName, File $textFile): ?array {
+ $attachmentFolder = $this->getAttachmentDirectoryForFile($textFile, true);
+ $mediaFile = $attachmentFolder->get($mediaFileName);
+ if ($mediaFile instanceof File) {
+ if ($this->previewManager->isMimeSupported($mediaFile->getMimeType())) {
+ try {
+ return [
+ 'type' => 'file',
+ 'file' => $this->previewManager->getPreview($mediaFile, 1024, 1024),
+ ];
+ } catch (NotFoundException $e) {
+ // the preview might not be found even if the mimetype is supported
+ }
+ }
+ // fallback: mimetype icon URL
+ return [
+ 'type' => 'icon',
+ 'iconUrl' => $this->mimeTypeDetector->mimeTypeIcon($mediaFile->getMimeType()),
+ ];
+ }
+ return null;
+ }
+
+ /**
+ * @param int $documentId
+ * @param string $mediaFileName
+ * @param string $userId
+ * @return array|null
+ * @throws NotFoundException
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OC\User\NoUserException
+ */
+ public function getMediaFileMetadataPrivate(int $documentId, string $mediaFileName, string $userId): ?array {
+ $textFile = $this->getTextFile($documentId, $userId);
+ return $this->getMediaFileMetadata($mediaFileName, $textFile);
+ }
+
+ /**
+ * @param int $documentId
+ * @param string $mediaFileName
+ * @param string $shareToken
+ * @return array|null
+ * @throws NotFoundException
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OC\User\NoUserException
+ */
+ public function getMediaFileMetadataPublic(int $documentId, string $mediaFileName, string $shareToken): ?array {
+ $textFile = $this->getTextFilePublic($documentId, $shareToken);
+ return $this->getMediaFileMetadata($mediaFileName, $textFile);
+ }
+
+ /**
+ * @param string $mediaFileName
+ * @param File $textFile
+ * @return array|null
+ * @throws NotFoundException
+ * @throws NotPermittedException
+ * @throws \OCP\Files\InvalidPathException
+ * @throws \OC\User\NoUserException
+ */
+ private function getMediaFileMetadata(string $mediaFileName, File $textFile): ?array {
+ $attachmentFolder = $this->getAttachmentDirectoryForFile($textFile, true);
+ $mediaFile = $attachmentFolder->get($mediaFileName);
+ if ($mediaFile instanceof File) {
+ return [
+ 'size' => Util::humanFileSize($mediaFile->getSize()),
+ 'mtime' => $mediaFile->getMTime(),
+ ];
+ }
+ return null;
+ }
+
+ /**
* Save an uploaded image in the attachment folder
*
* @param int $documentId
@@ -221,21 +385,15 @@ class ImageService {
* @throws \OCP\Files\InvalidPathException
*/
private function copyImageFile(File $imageFile, Folder $saveDir, File $textFile): array {
- $mimeType = $imageFile->getMimeType();
- if (in_array($mimeType, ImageController::IMAGE_MIME_TYPES, true)) {
- $fileName = $this->getUniqueFileName($saveDir, $imageFile->getName());
- $targetPath = $saveDir->getPath() . '/' . $fileName;
- $targetFile = $imageFile->copy($targetPath);
- // get file type and name
- return [
- 'name' => $fileName,
- 'dirname' => $saveDir->getName(),
- 'id' => $targetFile->getId(),
- 'documentId' => $textFile->getId(),
- ];
- }
+ $fileName = $this->getUniqueFileName($saveDir, $imageFile->getName());
+ $targetPath = $saveDir->getPath() . '/' . $fileName;
+ $targetFile = $imageFile->copy($targetPath);
return [
- 'error' => 'Unsupported file type',
+ 'name' => $fileName,
+ 'dirname' => $saveDir->getName(),
+ 'id' => $targetFile->getId(),
+ 'documentId' => $textFile->getId(),
+ 'mimetype' => $targetFile->getMimetype(),
];
}
@@ -390,49 +548,6 @@ class ImageService {
}
/**
- * Download a file and write it to a resource
- * @param string $url
- * @param $resource
- * @return array
- */
- private function simpleDownload(string $url, $resource): array {
- $client = $this->clientService->newClient();
- try {
- $options = [
- // does not work with sink if SSE is enabled
- // 'sink' => $resource,
- // rather use stream and write to the file ourselves
- 'stream' => true,
- 'timeout' => 0,
- 'headers' => [
- 'User-Agent' => 'Nextcloud Text',
- ],
- ];
-
- $response = $client->get($url, $options);
- $body = $response->getBody();
- while (!feof($body)) {
- // write ~5 MB chunks
- $chunk = fread($body, 5000000);
- fwrite($resource, $chunk);
- }
-
- return ['Content-Type' => $response->getHeader('Content-Type')];
- } catch (ServerException | ClientException $e) {
- //$response = $e->getResponse();
- //if ($response->getStatusCode() === 401) {
- $this->logger->warning('Impossible to download image', ['exception' => $e]);
- return ['error' => 'Impossible to download image'];
- } catch (ConnectException $e) {
- $this->logger->error('Connection error', ['exception' => $e]);
- return ['error' => 'Connection error'];
- } catch (Throwable | Exception $e) {
- $this->logger->error('Unknown download error', ['exception' => $e]);
- return ['error' => 'Unknown download error'];
- }
- }
-
- /**
* Actually delete attachment files which are not pointed in the markdown content
*
* @param int $fileId
@@ -498,7 +613,7 @@ class ImageService {
$matches = [];
// matches ![ANY_CONSIDERED_CORRECT_BY_PHP-MARKDOWN](.attachments.DOCUMENT_ID/ANY_FILE_NAME) and captures FILE_NAME
preg_match_all(
- '/\!\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[\])*\])*\])*\])*\])*\])*\]\(\.attachments\.'.$fileId.'\/([^)&]+)\)/',
+ '/\!\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[(?>[^\[\]]+|\[\])*\])*\])*\])*\])*\])*\]\(\.attachments\.' . $fileId . '\/([^)&]+)\)/',
$content,
$matches,
PREG_SET_ORDER