You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
4.1 KiB

PoC: SystemTags endpoint to return tags used by a user with meta data Target case is photos app: when visiting the tags category, all systemtags of the whole cloud are retrieved. In subequent steps the next tag is requested until the browser view is filled with tag tiles (i.e. previews are requested just as well). With this approach, we incorpoate the dav search and look for user related tags that are used by them, and already returns the statistics (number of files tagged with the respective tag) as well as a file id for the purpose to load the preview. This defaults to the file with the highest id. Call: curl -s -u 'user:password' \ 'https://my.nc.srv/remote.php/dav/systemtags-current' \ -X PROPFIND -H 'Accept: text/plain' \ -H 'Accept-Language: en-US,en;q=0.5' -H 'Depth: 1' \ -H 'Content-Type: text/plain;charset=UTF-8' \ --data @/home/doe/request-systemtag-props.xml With request-systemtag-props.xml: <?xml version="1.0" encoding="UTF-8"?> <d:propfind xmlns:d="DAV:"> <d:prop xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns"> <oc:id/> <oc:display-name/> <oc:user-visible/> <oc:user-assignable/> <oc:can-assign/> <nc:files-assigned/> <nc:reference-fileid/> </d:prop> </d:propfind> Example output: … <d:response> <d:href>/master/remote.php/dav/systemtags/84</d:href> <d:propstat> <d:prop> <oc:id>84</oc:id> <oc:display-name>Computer</oc:display-name> <oc:user-visible>true</oc:user-visible> <oc:user-assignable>true</oc:user-assignable> <oc:can-assign>true</oc:can-assign> <nc:files-assigned>42</nc:files-assigned> <nc:reference-fileid>924022</nc:reference-fileid> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/remote.php/dav/systemtags/97</d:href> <d:propstat> <d:prop> <oc:id>97</oc:id> <oc:display-name>Bear</oc:display-name> <oc:user-visible>true</oc:user-visible> <oc:user-assignable>true</oc:user-assignable> <oc:can-assign>true</oc:can-assign> <nc:files-assigned>1</nc:files-assigned> <nc:reference-fileid>923422</nc:reference-fileid> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> … Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
3 years ago
PoC: SystemTags endpoint to return tags used by a user with meta data Target case is photos app: when visiting the tags category, all systemtags of the whole cloud are retrieved. In subequent steps the next tag is requested until the browser view is filled with tag tiles (i.e. previews are requested just as well). With this approach, we incorpoate the dav search and look for user related tags that are used by them, and already returns the statistics (number of files tagged with the respective tag) as well as a file id for the purpose to load the preview. This defaults to the file with the highest id. Call: curl -s -u 'user:password' \ 'https://my.nc.srv/remote.php/dav/systemtags-current' \ -X PROPFIND -H 'Accept: text/plain' \ -H 'Accept-Language: en-US,en;q=0.5' -H 'Depth: 1' \ -H 'Content-Type: text/plain;charset=UTF-8' \ --data @/home/doe/request-systemtag-props.xml With request-systemtag-props.xml: <?xml version="1.0" encoding="UTF-8"?> <d:propfind xmlns:d="DAV:"> <d:prop xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns"> <oc:id/> <oc:display-name/> <oc:user-visible/> <oc:user-assignable/> <oc:can-assign/> <nc:files-assigned/> <nc:reference-fileid/> </d:prop> </d:propfind> Example output: … <d:response> <d:href>/master/remote.php/dav/systemtags/84</d:href> <d:propstat> <d:prop> <oc:id>84</oc:id> <oc:display-name>Computer</oc:display-name> <oc:user-visible>true</oc:user-visible> <oc:user-assignable>true</oc:user-assignable> <oc:can-assign>true</oc:can-assign> <nc:files-assigned>42</nc:files-assigned> <nc:reference-fileid>924022</nc:reference-fileid> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/remote.php/dav/systemtags/97</d:href> <d:propstat> <d:prop> <oc:id>97</oc:id> <oc:display-name>Bear</oc:display-name> <oc:user-visible>true</oc:user-visible> <oc:user-assignable>true</oc:user-assignable> <oc:can-assign>true</oc:can-assign> <nc:files-assigned>1</nc:files-assigned> <nc:reference-fileid>923422</nc:reference-fileid> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> … Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
3 years ago
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2019 Robin Appelman <robin@icewind.nl>
  5. *
  6. * @author Maxence Lange <maxence@artificial-owl.com>
  7. * @author Robin Appelman <robin@icewind.nl>
  8. *
  9. * @license GNU AGPL version 3 or any later version
  10. *
  11. * This program is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Affero General Public License as
  13. * published by the Free Software Foundation, either version 3 of the
  14. * License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Affero General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. *
  24. */
  25. namespace OC\Files\Cache;
  26. use OC\DB\QueryBuilder\QueryBuilder;
  27. use OC\SystemConfig;
  28. use OCP\DB\QueryBuilder\IQueryBuilder;
  29. use OCP\IDBConnection;
  30. use Psr\Log\LoggerInterface;
  31. /**
  32. * Query builder with commonly used helpers for filecache queries
  33. */
  34. class CacheQueryBuilder extends QueryBuilder {
  35. private ?string $alias = null;
  36. public function __construct(IDBConnection $connection, SystemConfig $systemConfig, LoggerInterface $logger) {
  37. parent::__construct($connection, $systemConfig, $logger);
  38. }
  39. public function selectTagUsage(): self {
  40. $this
  41. ->select('systemtag.name', 'systemtag.id', 'systemtag.visibility', 'systemtag.editable')
  42. ->selectAlias($this->createFunction('COUNT(filecache.fileid)'), 'number_files')
  43. ->selectAlias($this->createFunction('MAX(filecache.fileid)'), 'ref_file_id')
  44. ->from('filecache', 'filecache')
  45. ->leftJoin('filecache', 'systemtag_object_mapping', 'systemtagmap', $this->expr()->andX(
  46. $this->expr()->eq('filecache.fileid', $this->expr()->castColumn('systemtagmap.objectid', IQueryBuilder::PARAM_INT)),
  47. $this->expr()->eq('systemtagmap.objecttype', $this->createNamedParameter('files'))
  48. ))
  49. ->leftJoin('systemtagmap', 'systemtag', 'systemtag', $this->expr()->andX(
  50. $this->expr()->eq('systemtag.id', 'systemtagmap.systemtagid'),
  51. $this->expr()->eq('systemtag.visibility', $this->createNamedParameter(true))
  52. ))
  53. ->groupBy('systemtag.name', 'systemtag.id', 'systemtag.visibility', 'systemtag.editable');
  54. return $this;
  55. }
  56. public function selectFileCache(string $alias = null, bool $joinExtendedCache = true) {
  57. $name = $alias ?: 'filecache';
  58. $this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", "$name.name", 'mimetype', 'mimepart', 'size', 'mtime',
  59. 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum', 'unencrypted_size')
  60. ->from('filecache', $name);
  61. if ($joinExtendedCache) {
  62. $this->addSelect('metadata_etag', 'creation_time', 'upload_time');
  63. $this->leftJoin($name, 'filecache_extended', 'fe', $this->expr()->eq("$name.fileid", 'fe.fileid'));
  64. }
  65. $this->alias = $name;
  66. return $this;
  67. }
  68. public function whereStorageId(int $storageId) {
  69. $this->andWhere($this->expr()->eq('storage', $this->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
  70. return $this;
  71. }
  72. public function whereFileId(int $fileId) {
  73. $alias = $this->alias;
  74. if ($alias) {
  75. $alias .= '.';
  76. } else {
  77. $alias = '';
  78. }
  79. $this->andWhere($this->expr()->eq("{$alias}fileid", $this->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
  80. return $this;
  81. }
  82. public function wherePath(string $path) {
  83. $this->andWhere($this->expr()->eq('path_hash', $this->createNamedParameter(md5($path))));
  84. return $this;
  85. }
  86. public function whereParent(int $parent) {
  87. $alias = $this->alias;
  88. if ($alias) {
  89. $alias .= '.';
  90. } else {
  91. $alias = '';
  92. }
  93. $this->andWhere($this->expr()->eq("{$alias}parent", $this->createNamedParameter($parent, IQueryBuilder::PARAM_INT)));
  94. return $this;
  95. }
  96. public function whereParentInParameter(string $parameter) {
  97. $alias = $this->alias;
  98. if ($alias) {
  99. $alias .= '.';
  100. } else {
  101. $alias = '';
  102. }
  103. $this->andWhere($this->expr()->in("{$alias}parent", $this->createParameter($parameter)));
  104. return $this;
  105. }
  106. }