@@ -22,100 +22,100 @@  | 
                                                    ||
| 22 | 22 | use Psr\Log\LoggerInterface;  | 
                                                        
| 23 | 23 | |
| 24 | 24 |  class GenerateMetadataJob extends TimedJob { | 
                                                        
| 25 | - // Default file size limit for metadata generation (MBytes).  | 
                                                        |
| 26 | - protected const DEFAULT_MAX_FILESIZE = 256;  | 
                                                        |
| 27 | -  | 
                                                        |
| 28 | - public function __construct(  | 
                                                        |
| 29 | - ITimeFactory $time,  | 
                                                        |
| 30 | - private IConfig $config,  | 
                                                        |
| 31 | - private IAppConfig $appConfig,  | 
                                                        |
| 32 | - private IRootFolder $rootFolder,  | 
                                                        |
| 33 | - private IUserManager $userManager,  | 
                                                        |
| 34 | - private IFilesMetadataManager $filesMetadataManager,  | 
                                                        |
| 35 | - private IJobList $jobList,  | 
                                                        |
| 36 | - private LoggerInterface $logger,  | 
                                                        |
| 37 | -	) { | 
                                                        |
| 38 | - parent::__construct($time);  | 
                                                        |
| 39 | -  | 
                                                        |
| 40 | - $this->setTimeSensitivity(self::TIME_INSENSITIVE);  | 
                                                        |
| 41 | - $this->setInterval(24 * 60 * 60);  | 
                                                        |
| 42 | - }  | 
                                                        |
| 43 | -  | 
                                                        |
| 44 | -	protected function run(mixed $argument): void { | 
                                                        |
| 45 | -		if ($this->appConfig->getValueBool('core', 'metadataGenerationDone', false)) { | 
                                                        |
| 46 | - return;  | 
                                                        |
| 47 | - }  | 
                                                        |
| 48 | -  | 
                                                        |
| 49 | -		$lastHandledUser = $this->appConfig->getValueString('core', 'metadataGenerationLastHandledUser', ''); | 
                                                        |
| 50 | -  | 
                                                        |
| 51 | -		$users = $this->userManager->search(''); | 
                                                        |
| 52 | -  | 
                                                        |
| 53 | - // we'll only start timer once we have found a valid user to handle  | 
                                                        |
| 54 | - // meaning NOW if we have not handled any user from a previous run  | 
                                                        |
| 55 | - $startTime = ($lastHandledUser === '') ? time() : null;  | 
                                                        |
| 56 | -		foreach ($users as $user) { | 
                                                        |
| 57 | - $userId = $user->getUID();  | 
                                                        |
| 58 | -  | 
                                                        |
| 59 | - // if we already handled a previous run, we start timer only when we face the last handled user  | 
                                                        |
| 60 | -			if ($startTime === null) { | 
                                                        |
| 61 | -				if ($userId === $lastHandledUser) { | 
                                                        |
| 62 | - $startTime = time();  | 
                                                        |
| 63 | - }  | 
                                                        |
| 64 | - continue;  | 
                                                        |
| 65 | - }  | 
                                                        |
| 66 | -  | 
                                                        |
| 67 | -			$this->appConfig->setValueString('core', 'metadataGenerationLastHandledUser', $userId); | 
                                                        |
| 68 | - $this->scanFilesForUser($user->getUID());  | 
                                                        |
| 69 | -  | 
                                                        |
| 70 | - // Stop if execution time is more than one hour.  | 
                                                        |
| 71 | -			if (time() - $startTime > 3600) { | 
                                                        |
| 72 | - return;  | 
                                                        |
| 73 | - }  | 
                                                        |
| 74 | - }  | 
                                                        |
| 75 | -  | 
                                                        |
| 76 | -		$this->appConfig->deleteKey('core', 'metadataGenerationLastHandledUser'); | 
                                                        |
| 77 | -		$this->appConfig->setValueBool('core', 'metadataGenerationDone', true); | 
                                                        |
| 78 | - }  | 
                                                        |
| 79 | -  | 
                                                        |
| 80 | -	private function scanFilesForUser(string $userId): void { | 
                                                        |
| 81 | - $userFolder = $this->rootFolder->getUserFolder($userId);  | 
                                                        |
| 82 | - $this->scanFolder($userFolder);  | 
                                                        |
| 83 | - }  | 
                                                        |
| 84 | -  | 
                                                        |
| 85 | -	private function scanFolder(Folder $folder): void { | 
                                                        |
| 86 | - // Do not scan share and other moveable mounts.  | 
                                                        |
| 87 | -		if ($folder->getMountPoint() instanceof MoveableMount) { | 
                                                        |
| 88 | - return;  | 
                                                        |
| 89 | - }  | 
                                                        |
| 90 | -  | 
                                                        |
| 91 | -		foreach ($folder->getDirectoryListing() as $node) { | 
                                                        |
| 92 | -			if ($node instanceof Folder) { | 
                                                        |
| 93 | - $this->scanFolder($node);  | 
                                                        |
| 94 | - continue;  | 
                                                        |
| 95 | - }  | 
                                                        |
| 96 | -  | 
                                                        |
| 97 | - // Don't generate metadata for files bigger than configured metadata_max_filesize  | 
                                                        |
| 98 | - // Files are loaded in memory so very big files can lead to an OOM on the server  | 
                                                        |
| 99 | - $nodeSize = $node->getSize();  | 
                                                        |
| 100 | -			$nodeLimit = $this->config->getSystemValueInt('metadata_max_filesize', self::DEFAULT_MAX_FILESIZE); | 
                                                        |
| 101 | - $nodeLimitMib = $nodeLimit * 1024 * 1024;  | 
                                                        |
| 102 | -			if ($nodeSize > $nodeLimitMib) { | 
                                                        |
| 103 | -				$this->logger->debug('Skipping generating metadata for fileid ' . $node->getId() . " as its size exceeds configured 'metadata_max_filesize'."); | 
                                                        |
| 104 | - continue;  | 
                                                        |
| 105 | - }  | 
                                                        |
| 106 | -  | 
                                                        |
| 107 | -			try { | 
                                                        |
| 108 | - $this->filesMetadataManager->getMetadata($node->getId(), false);  | 
                                                        |
| 109 | -			} catch (FilesMetadataNotFoundException) { | 
                                                        |
| 110 | -				try { | 
                                                        |
| 111 | - $this->filesMetadataManager->refreshMetadata(  | 
                                                        |
| 112 | - $node,  | 
                                                        |
| 113 | - IFilesMetadataManager::PROCESS_LIVE | IFilesMetadataManager::PROCESS_BACKGROUND  | 
                                                        |
| 114 | - );  | 
                                                        |
| 115 | -				} catch (\Throwable $ex) { | 
                                                        |
| 116 | -					$this->logger->warning('Error while generating metadata for fileid ' . $node->getId(), ['exception' => $ex]); | 
                                                        |
| 117 | - }  | 
                                                        |
| 118 | - }  | 
                                                        |
| 119 | - }  | 
                                                        |
| 120 | - }  | 
                                                        |
| 25 | + // Default file size limit for metadata generation (MBytes).  | 
                                                        |
| 26 | + protected const DEFAULT_MAX_FILESIZE = 256;  | 
                                                        |
| 27 | +  | 
                                                        |
| 28 | + public function __construct(  | 
                                                        |
| 29 | + ITimeFactory $time,  | 
                                                        |
| 30 | + private IConfig $config,  | 
                                                        |
| 31 | + private IAppConfig $appConfig,  | 
                                                        |
| 32 | + private IRootFolder $rootFolder,  | 
                                                        |
| 33 | + private IUserManager $userManager,  | 
                                                        |
| 34 | + private IFilesMetadataManager $filesMetadataManager,  | 
                                                        |
| 35 | + private IJobList $jobList,  | 
                                                        |
| 36 | + private LoggerInterface $logger,  | 
                                                        |
| 37 | +    ) { | 
                                                        |
| 38 | + parent::__construct($time);  | 
                                                        |
| 39 | +  | 
                                                        |
| 40 | + $this->setTimeSensitivity(self::TIME_INSENSITIVE);  | 
                                                        |
| 41 | + $this->setInterval(24 * 60 * 60);  | 
                                                        |
| 42 | + }  | 
                                                        |
| 43 | +  | 
                                                        |
| 44 | +    protected function run(mixed $argument): void { | 
                                                        |
| 45 | +        if ($this->appConfig->getValueBool('core', 'metadataGenerationDone', false)) { | 
                                                        |
| 46 | + return;  | 
                                                        |
| 47 | + }  | 
                                                        |
| 48 | +  | 
                                                        |
| 49 | +        $lastHandledUser = $this->appConfig->getValueString('core', 'metadataGenerationLastHandledUser', ''); | 
                                                        |
| 50 | +  | 
                                                        |
| 51 | +        $users = $this->userManager->search(''); | 
                                                        |
| 52 | +  | 
                                                        |
| 53 | + // we'll only start timer once we have found a valid user to handle  | 
                                                        |
| 54 | + // meaning NOW if we have not handled any user from a previous run  | 
                                                        |
| 55 | + $startTime = ($lastHandledUser === '') ? time() : null;  | 
                                                        |
| 56 | +        foreach ($users as $user) { | 
                                                        |
| 57 | + $userId = $user->getUID();  | 
                                                        |
| 58 | +  | 
                                                        |
| 59 | + // if we already handled a previous run, we start timer only when we face the last handled user  | 
                                                        |
| 60 | +            if ($startTime === null) { | 
                                                        |
| 61 | +                if ($userId === $lastHandledUser) { | 
                                                        |
| 62 | + $startTime = time();  | 
                                                        |
| 63 | + }  | 
                                                        |
| 64 | + continue;  | 
                                                        |
| 65 | + }  | 
                                                        |
| 66 | +  | 
                                                        |
| 67 | +            $this->appConfig->setValueString('core', 'metadataGenerationLastHandledUser', $userId); | 
                                                        |
| 68 | + $this->scanFilesForUser($user->getUID());  | 
                                                        |
| 69 | +  | 
                                                        |
| 70 | + // Stop if execution time is more than one hour.  | 
                                                        |
| 71 | +            if (time() - $startTime > 3600) { | 
                                                        |
| 72 | + return;  | 
                                                        |
| 73 | + }  | 
                                                        |
| 74 | + }  | 
                                                        |
| 75 | +  | 
                                                        |
| 76 | +        $this->appConfig->deleteKey('core', 'metadataGenerationLastHandledUser'); | 
                                                        |
| 77 | +        $this->appConfig->setValueBool('core', 'metadataGenerationDone', true); | 
                                                        |
| 78 | + }  | 
                                                        |
| 79 | +  | 
                                                        |
| 80 | +    private function scanFilesForUser(string $userId): void { | 
                                                        |
| 81 | + $userFolder = $this->rootFolder->getUserFolder($userId);  | 
                                                        |
| 82 | + $this->scanFolder($userFolder);  | 
                                                        |
| 83 | + }  | 
                                                        |
| 84 | +  | 
                                                        |
| 85 | +    private function scanFolder(Folder $folder): void { | 
                                                        |
| 86 | + // Do not scan share and other moveable mounts.  | 
                                                        |
| 87 | +        if ($folder->getMountPoint() instanceof MoveableMount) { | 
                                                        |
| 88 | + return;  | 
                                                        |
| 89 | + }  | 
                                                        |
| 90 | +  | 
                                                        |
| 91 | +        foreach ($folder->getDirectoryListing() as $node) { | 
                                                        |
| 92 | +            if ($node instanceof Folder) { | 
                                                        |
| 93 | + $this->scanFolder($node);  | 
                                                        |
| 94 | + continue;  | 
                                                        |
| 95 | + }  | 
                                                        |
| 96 | +  | 
                                                        |
| 97 | + // Don't generate metadata for files bigger than configured metadata_max_filesize  | 
                                                        |
| 98 | + // Files are loaded in memory so very big files can lead to an OOM on the server  | 
                                                        |
| 99 | + $nodeSize = $node->getSize();  | 
                                                        |
| 100 | +            $nodeLimit = $this->config->getSystemValueInt('metadata_max_filesize', self::DEFAULT_MAX_FILESIZE); | 
                                                        |
| 101 | + $nodeLimitMib = $nodeLimit * 1024 * 1024;  | 
                                                        |
| 102 | +            if ($nodeSize > $nodeLimitMib) { | 
                                                        |
| 103 | +                $this->logger->debug('Skipping generating metadata for fileid ' . $node->getId() . " as its size exceeds configured 'metadata_max_filesize'."); | 
                                                        |
| 104 | + continue;  | 
                                                        |
| 105 | + }  | 
                                                        |
| 106 | +  | 
                                                        |
| 107 | +            try { | 
                                                        |
| 108 | + $this->filesMetadataManager->getMetadata($node->getId(), false);  | 
                                                        |
| 109 | +            } catch (FilesMetadataNotFoundException) { | 
                                                        |
| 110 | +                try { | 
                                                        |
| 111 | + $this->filesMetadataManager->refreshMetadata(  | 
                                                        |
| 112 | + $node,  | 
                                                        |
| 113 | + IFilesMetadataManager::PROCESS_LIVE | IFilesMetadataManager::PROCESS_BACKGROUND  | 
                                                        |
| 114 | + );  | 
                                                        |
| 115 | +                } catch (\Throwable $ex) { | 
                                                        |
| 116 | +                    $this->logger->warning('Error while generating metadata for fileid ' . $node->getId(), ['exception' => $ex]); | 
                                                        |
| 117 | + }  | 
                                                        |
| 118 | + }  | 
                                                        |
| 119 | + }  | 
                                                        |
| 120 | + }  | 
                                                        |
| 121 | 121 | }  | 
                                                        
@@ -100,7 +100,7 @@ discard block  | 
                                                    ||
| 100 | 100 |  			$nodeLimit = $this->config->getSystemValueInt('metadata_max_filesize', self::DEFAULT_MAX_FILESIZE); | 
                                                        
| 101 | 101 | $nodeLimitMib = $nodeLimit * 1024 * 1024;  | 
                                                        
| 102 | 102 |  			if ($nodeSize > $nodeLimitMib) { | 
                                                        
| 103 | -				$this->logger->debug('Skipping generating metadata for fileid ' . $node->getId() . " as its size exceeds configured 'metadata_max_filesize'."); | 
                                                        |
| 103 | +				$this->logger->debug('Skipping generating metadata for fileid '.$node->getId()." as its size exceeds configured 'metadata_max_filesize'."); | 
                                                        |
| 104 | 104 | continue;  | 
                                                        
| 105 | 105 | }  | 
                                                        
| 106 | 106 | |
@@ -113,7 +113,7 @@ discard block  | 
                                                    ||
| 113 | 113 | IFilesMetadataManager::PROCESS_LIVE | IFilesMetadataManager::PROCESS_BACKGROUND  | 
                                                        
| 114 | 114 | );  | 
                                                        
| 115 | 115 |  				} catch (\Throwable $ex) { | 
                                                        
| 116 | -					$this->logger->warning('Error while generating metadata for fileid ' . $node->getId(), ['exception' => $ex]); | 
                                                        |
| 116 | +					$this->logger->warning('Error while generating metadata for fileid '.$node->getId(), ['exception' => $ex]); | 
                                                        |
| 117 | 117 | }  | 
                                                        
| 118 | 118 | }  | 
                                                        
| 119 | 119 | }  |