From 9aacccf719d1d115be48299d04f7cb72a68f1c87 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Fri, 23 Nov 2018 19:41:46 -0100 Subject: [PATCH] Document, Image and Caching Signed-off-by: Maxence Lange --- appinfo/database.xml | 67 ++++++ lib/Db/CacheDocumentsRequest.php | 87 ++++++++ lib/Db/CacheDocumentsRequestBuilder.php | 121 +++++++++++ lib/Db/CoreRequestBuilder.php | 54 +++++ .../CacheDocumentDoesNotExistException.php | 8 + lib/Model/ActivityPub/Document.php | 192 ++++++++++++++++++ lib/Model/ActivityPub/Image.php | 83 ++++++++ lib/Service/ActivityPub/DocumentService.php | 82 ++++++++ 8 files changed, 694 insertions(+) create mode 100644 lib/Db/CacheDocumentsRequest.php create mode 100644 lib/Db/CacheDocumentsRequestBuilder.php create mode 100644 lib/Exceptions/CacheDocumentDoesNotExistException.php create mode 100644 lib/Model/ActivityPub/Document.php create mode 100644 lib/Model/ActivityPub/Image.php create mode 100644 lib/Service/ActivityPub/DocumentService.php diff --git a/appinfo/database.xml b/appinfo/database.xml index d942c063..58e8360e 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -374,5 +374,72 @@ + + *dbprefix*social_cache_documents + + + + id + string + 127 + true + true + + + + type + text + 31 + true + + + + media_type + text + 63 + true + + + + mime_type + text + 63 + true + + + + url + text + 127 + true + + + + local_copy + text + 127 + true + + + + creation + timestamp + + + + caching + timestamp + + + + unique_url + true + + url + + + +
+ diff --git a/lib/Db/CacheDocumentsRequest.php b/lib/Db/CacheDocumentsRequest.php new file mode 100644 index 00000000..7837ad5d --- /dev/null +++ b/lib/Db/CacheDocumentsRequest.php @@ -0,0 +1,87 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + +namespace OCA\Social\Db; + + +use DateTime; +use OCA\Social\Exceptions\CacheDocumentDoesNotExistException; +use OCA\Social\Exceptions\SocialAppConfigException; +use OCA\Social\Exceptions\UrlCloudException; +use OCA\Social\Model\ActivityPub\Document; +use OCP\DB\QueryBuilder\IQueryBuilder; + +class CacheDocumentsRequest extends CacheDocumentsRequestBuilder { + + + /** + * insert cache about an Actor in database. + * + * @param Document $document + */ + public function save(Document $document) { + $qb = $this->getCacheDocumentsInsertSql(); + $qb->setValue('id', $qb->createNamedParameter($document->getId())) + ->setValue('type', $qb->createNamedParameter($document->getType())) + ->setValue('url', $qb->createNamedParameter($document->getUrl())) + ->setValue('local_copy', $qb->createNamedParameter($document->getLocalCopy())) + ->setValue( + 'creation', + $qb->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE) + ); + $qb->execute(); + } + + + /** + * @param string $url + * + * @return Document + * @throws CacheDocumentDoesNotExistException + * @throws SocialAppConfigException + * @throws UrlCloudException + */ + public function getFromSource(string $url) { + $qb = $this->getCacheDocumentsSelectSql(); + $this->limitToUrl($qb, $url); + + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new CacheDocumentDoesNotExistException(); + } + + return $this->parseCacheDocumentsSelectSql($data); + } + +} + diff --git a/lib/Db/CacheDocumentsRequestBuilder.php b/lib/Db/CacheDocumentsRequestBuilder.php new file mode 100644 index 00000000..853ed0f4 --- /dev/null +++ b/lib/Db/CacheDocumentsRequestBuilder.php @@ -0,0 +1,121 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + +namespace OCA\Social\Db; + + +use daita\MySmallPhpTools\Traits\TArrayTools; +use OCA\Social\Exceptions\SocialAppConfigException; +use OCA\Social\Exceptions\UrlCloudException; +use OCA\Social\Model\ActivityPub\Document; +use OCP\DB\QueryBuilder\IQueryBuilder; + +class CacheDocumentsRequestBuilder extends CoreRequestBuilder { + + + use TArrayTools; + + + /** + * Base of the Sql Insert request + * + * @return IQueryBuilder + */ + protected function getCacheDocumentsInsertSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->insert(self::TABLE_CACHE_DOCUMENTS); + + return $qb; + } + + + /** + * Base of the Sql Update request + * + * @return IQueryBuilder + */ + protected function getCacheDocumentsUpdateSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update(self::TABLE_CACHE_DOCUMENTS); + + return $qb; + } + + + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function getCacheDocumentsSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + + /** @noinspection PhpMethodParametersCountMismatchInspection */ + $qb->select( + 'cd.id', 'cd.type', 'cd.media_type', 'cd.mime_type', 'cd.url', 'cd.local_copy', + 'cd.creation', 'cd.caching' + ) + ->from(self::TABLE_CACHE_DOCUMENTS, 'cd'); + + $this->defaultSelectAlias = 'cd'; + + return $qb; + } + + + /** + * Base of the Sql Delete request + * + * @return IQueryBuilder + */ + protected function getCacheDocumentsDeleteSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->delete(self::TABLE_CACHE_DOCUMENTS); + + return $qb; + } + + + /** + * @param array $data + * + * @return Document + * @throws UrlCloudException + * @throws SocialAppConfigException + */ + protected function parseCacheDocumentsSelectSql(array $data): Document { + $document = new Document(); + $document->setUrlCloud($this->configService->getCloudAddress()); + $document->importFromDatabase($data); + + return $document; + } + +} + diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index c6496cef..902b0888 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -446,6 +446,60 @@ class CoreRequestBuilder { return $actor; } + + /** + * @param IQueryBuilder $qb + * @param string $fieldDocumentId + */ + protected function leftJoinCacheDocuments(IQueryBuilder &$qb, string $fieldDocumentId) { + if ($qb->getType() !== QueryBuilder::SELECT) { + return; + } + + $expr = $qb->expr(); + $pf = $this->defaultSelectAlias; + +// /** @noinspection PhpMethodParametersCountMismatchInspection */ + $qb->selectAlias('cd.id', 'cachedocument_id') + ->selectAlias('cd.type', 'cachedocument_type') + ->selectAlias('cd.mime_type', 'cachedocument_mime_type') + ->selectAlias('cd.media_type', 'cachedocument_media_type') + ->selectAlias('cd.url', 'cachedocument_url') + ->selectAlias('cd.local_copy', 'cachedocument_local_copy') + ->selectAlias('cd.caching', 'cachedocument_caching') + ->selectAlias('ca.creation', 'cachedocument_creation') + ->leftJoin( + $this->defaultSelectAlias, CoreRequestBuilder::TABLE_CACHE_DOCUMENTS, 'cd', + $expr->eq($pf . '.' . $fieldDocumentId, 'cd.id') + ); + } + + + /** + * @param array $data + * + * @return Document + * @throws InvalidResourceException + */ + protected function parseCacheDocumentsLeftJoin(array $data): Document { + $new = []; + + foreach ($data as $k => $v) { + if (substr($k, 0, 14) === 'cachedocument_') { + $new[substr($k, 14)] = $v; + } + } + $document = new Document(); + + $document->importFromDatabase($new); + + if ($document->getType() !== Image::TYPE) { + throw new InvalidResourceException(); + } + + return $document; + } + } diff --git a/lib/Exceptions/CacheDocumentDoesNotExistException.php b/lib/Exceptions/CacheDocumentDoesNotExistException.php new file mode 100644 index 00000000..1bc25dda --- /dev/null +++ b/lib/Exceptions/CacheDocumentDoesNotExistException.php @@ -0,0 +1,8 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + + +namespace OCA\Social\Model\ActivityPub; + + +use JsonSerializable; +use OCA\Social\Exceptions\UrlCloudException; + + +/** + * Class Document + * + * @package OCA\Social\Model\ActivityPub + */ +class Document extends ACore implements JsonSerializable { + + + const TYPE = 'Document'; + + + /** @var string */ + private $mediaType = ''; + + /** @var string */ + private $mimeType = ''; + + /** @var string */ + private $localCopy = ''; + + /** @var string */ + private $caching = ''; + + + /** + * Document constructor. + * + * @param ACore $parent + */ + public function __construct($parent = null) { + parent::__construct($parent); + + $this->setType(self::TYPE); + } + + + /** + * @return string + */ + public function getMediaType(): string { + return $this->mediaType; + } + + /** + * @param string $mediaType + * + * @return ACore + */ + public function setMediaType(string $mediaType): ACore { + $this->mediaType = $mediaType; + + return $this; + } + + + /** + * @return string + */ + public function getMimeType(): string { + return $this->mimeType; + } + + /** + * @param string $mimeType + * + * @return ACore + */ + public function setMimeType(string $mimeType): ACore { + $this->mimeType = $mimeType; + + return $this; + } + + + /** + * @return string + */ + public function getLocalCopy(): string { + return $this->localCopy; + } + + /** + * @param string $localCopy + * + * @return Document + */ + public function setLocalCopy(string $localCopy): Document { + $this->localCopy = $localCopy; + + return $this; + } + + + /** + * @return string + */ + public function getCaching(): string { + return $this->caching; + } + + /** + * @param string $caching + * + * @return Document + */ + public function setCaching(string $caching): Document { + $this->caching = $caching; + + return $this; + } + + + /** + * @param array $data + * + * @throws UrlCloudException + */ + public function import(array $data) { + parent::import($data); + + $this->setMediaType($this->get('mediaType', $data, '')); + + if ($this->getId() === '') { + $this->generateUniqueId('/documents/g'); + } + } + + + /** + * @param array $data + */ + public function importFromDatabase(array $data) { + parent::importFromDatabase($data); + + $this->setMediaType($this->get('media_type', $data, '')); + $this->setMimeType($this->get('mime_type', $data, '')); + $this->setCaching($this->get('caching', $data, '')); + } + + /** + * @return array + */ + public function jsonSerialize(): array { + return array_merge( + parent::jsonSerialize(), + [ + 'mediaType' => $this->getMediaType(), + 'mimeType' => $this->getMimeType(), + 'localCopy' => $this->getLocalCopy() + ] + ); + } + +} + diff --git a/lib/Model/ActivityPub/Image.php b/lib/Model/ActivityPub/Image.php new file mode 100644 index 00000000..5947c4a6 --- /dev/null +++ b/lib/Model/ActivityPub/Image.php @@ -0,0 +1,83 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + + +namespace OCA\Social\Model\ActivityPub; + + +use JsonSerializable; +use OCA\Social\Exceptions\UrlCloudException; + + +/** + * Class Image + * + * @package OCA\Social\Model\ActivityPub + */ +class Image extends Document implements JsonSerializable { + + + const TYPE = 'Image'; + + + /** + * Image constructor. + * + * @param ACore $parent + */ + public function __construct($parent = null) { + parent::__construct($parent); + + $this->setType(self::TYPE); + } + + + /** + * @param array $data + * + * @throws UrlCloudException + */ + public function import(array $data) { + parent::import($data); + } + + + /** + * @return array + */ + public function jsonSerialize(): array { + return array_merge( + parent::jsonSerialize(), + [ + ] + ); + } + +} + diff --git a/lib/Service/ActivityPub/DocumentService.php b/lib/Service/ActivityPub/DocumentService.php new file mode 100644 index 00000000..dc72c46a --- /dev/null +++ b/lib/Service/ActivityPub/DocumentService.php @@ -0,0 +1,82 @@ + + * @copyright 2018, Maxence Lange + * @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 . + * + */ + +namespace OCA\Social\Service\ActivityPub; + + +use OCA\Social\Db\CacheDocumentsRequest; +use OCA\Social\Model\ActivityPub\ACore; +use OCA\Social\Service\ICoreService; +use OCA\Social\Service\MiscService; + + +class DocumentService implements ICoreService { + + /** @var CacheDocumentsRequest */ + private $cacheDocumentsRequest; + + /** @var MiscService */ + private $miscService; + + + /** + * DocumentService constructor. + * + * @param CacheDocumentsRequest $cacheDocumentsRequest + * @param MiscService $miscService + */ + public function __construct( + CacheDocumentsRequest $cacheDocumentsRequest, MiscService $miscService + ) { + $this->cacheDocumentsRequest = $cacheDocumentsRequest; + $this->miscService = $miscService; + } + + + public function getFromCache(array $documents) { + + } + + + /** + * @param ACore $item + */ + public function parse(ACore $item) { + // TODO: Implement parse() method. + } + + /** + * @param ACore $item + */ + public function delete(ACore $item) { + // TODO: Implement delete() method. + } + +} +