]> source.dussan.org Git - nextcloud-server.git/commitdiff
Revert "Remove inefficient fed share scanner" 32806/head
authorCarl Schwan <carl@carlschwan.eu>
Fri, 10 Jun 2022 08:29:23 +0000 (10:29 +0200)
committerCarl Schwan <carl@carlschwan.eu>
Fri, 10 Jun 2022 08:29:42 +0000 (10:29 +0200)
This reverts commit ce319143142e2ee998ef4794b04ad684c4ffa911.

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
apps/files_sharing/lib/External/Scanner.php
apps/files_sharing/tests/External/ScannerTest.php

index 009e206b959a58ae282a781273c23cc133b99c99..cfde56103daa9d504268a4c013e40a95727f4128 100644 (file)
@@ -29,11 +29,29 @@ use OC\ForbiddenException;
 use OCP\Files\NotFoundException;
 use OCP\Files\StorageInvalidException;
 use OCP\Files\StorageNotAvailableException;
+use OCP\Http\Client\LocalServerException;
+use Psr\Log\LoggerInterface;
 
 class Scanner extends \OC\Files\Cache\Scanner {
        /** @var \OCA\Files_Sharing\External\Storage */
        protected $storage;
 
+       /** {@inheritDoc} */
+       public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $lock = true) {
+               try {
+                       if (!$this->storage->remoteIsOwnCloud()) {
+                               return parent::scan($path, $recursive, $reuse, $lock);
+                       }
+               } catch (LocalServerException $e) {
+                       // Scanner doesn't have dependency injection
+                       \OC::$server->get(LoggerInterface::class)
+                               ->warning('Trying to scan files inside invalid external storage: ' . $this->storage->getRemote() . ' for mountpoint ' . $this->storage->getMountPoint() . ' and id ' . $this->storage->getId());
+                       return;
+               }
+
+               $this->scanAll();
+       }
+
        /**
         * Scan a single file and store it in the cache.
         * If an exception happened while accessing the external storage,
@@ -63,4 +81,56 @@ class Scanner extends \OC\Files\Cache\Scanner {
                        $this->storage->checkStorageAvailability();
                }
        }
+
+       /**
+        * Checks the remote share for changes.
+        * If changes are available, scan them and update
+        * the cache.
+        * @throws NotFoundException
+        * @throws StorageInvalidException
+        * @throws \Exception
+        */
+       public function scanAll() {
+               try {
+                       $data = $this->storage->getShareInfo();
+               } catch (\Exception $e) {
+                       $this->storage->checkStorageAvailability();
+                       throw new \Exception(
+                               'Error while scanning remote share: "' .
+                               $this->storage->getRemote() . '" ' .
+                               $e->getMessage()
+                       );
+               }
+               if ($data['status'] === 'success') {
+                       $this->addResult($data['data'], '');
+               } else {
+                       throw new \Exception(
+                               'Error while scanning remote share: "' .
+                               $this->storage->getRemote() . '"'
+                       );
+               }
+       }
+
+       /**
+        * @param array $data
+        * @param string $path
+        */
+       private function addResult($data, $path) {
+               $id = $this->cache->put($path, $data);
+               if (isset($data['children'])) {
+                       $children = [];
+                       foreach ($data['children'] as $child) {
+                               $children[$child['name']] = true;
+                               $this->addResult($child, ltrim($path . '/' . $child['name'], '/'));
+                       }
+
+                       $existingCache = $this->cache->getFolderContentsById($id);
+                       foreach ($existingCache as $existingChild) {
+                               // if an existing child is not in the new data, remove it
+                               if (!isset($children[$existingChild['name']])) {
+                                       $this->cache->remove(ltrim($path . '/' . $existingChild['name'], '/'));
+                               }
+                       }
+               }
+       }
 }
index 2d2486737dc1062a55bc47e2059d8a4d31925611..57696a697eb8e45a6318b5c9ef6f6411be42f193 100644 (file)
@@ -50,6 +50,18 @@ class ScannerTest extends TestCase {
                $this->scanner = new Scanner($this->storage);
        }
 
+       public function testScanAll() {
+               $this->storage->expects($this->any())
+                       ->method('getShareInfo')
+                       ->willReturn(['status' => 'success', 'data' => []]);
+
+               // FIXME add real tests, we are currently only checking for
+               // Declaration of OCA\Files_Sharing\External\Scanner::*() should be
+               // compatible with OC\Files\Cache\Scanner::*()
+               $this->scanner->scanAll();
+               $this->addToAssertionCount(1);
+       }
+
        public function testScan() {
                $this->storage->expects($this->any())
                        ->method('getShareInfo')