|
|
|
@ -31,35 +31,41 @@ use OCP\AppFramework\Utility\ITimeFactory; |
|
|
|
use OCP\BackgroundJob\IJobList; |
|
|
|
use OCP\BackgroundJob\QueuedJob; |
|
|
|
use OCP\Files\AppData\IAppDataFactory; |
|
|
|
use OCP\Files\IAppData; |
|
|
|
use OCP\Files\NotFoundException; |
|
|
|
use OCP\Files\NotPermittedException; |
|
|
|
use OCP\Files\SimpleFS\ISimpleFolder; |
|
|
|
use OCP\IConfig; |
|
|
|
use OCP\IDBConnection; |
|
|
|
use Psr\Log\LoggerInterface; |
|
|
|
|
|
|
|
class MigrateBackgroundImages extends QueuedJob { |
|
|
|
public const TIME_SENSITIVE = 0; |
|
|
|
|
|
|
|
protected const STAGE_PREPARE = 'prepare'; |
|
|
|
protected const STAGE_EXECUTE = 'execute'; |
|
|
|
// will be saved in appdata/theming/global/
|
|
|
|
protected const STATE_FILE_NAME = '25_dashboard_to_theming_migration_users.txt'; |
|
|
|
|
|
|
|
private IConfig $config; |
|
|
|
private IAppDataFactory $appDataFactory; |
|
|
|
private IJobList $jobList; |
|
|
|
private IDBConnection $dbc; |
|
|
|
private IAppData $appData; |
|
|
|
private LoggerInterface $logger; |
|
|
|
|
|
|
|
public function __construct( |
|
|
|
ITimeFactory $time, |
|
|
|
IAppDataFactory $appDataFactory, |
|
|
|
IConfig $config, |
|
|
|
IJobList $jobList, |
|
|
|
IDBConnection $dbc |
|
|
|
IDBConnection $dbc, |
|
|
|
IAppData $appData, |
|
|
|
LoggerInterface $logger |
|
|
|
) { |
|
|
|
parent::__construct($time); |
|
|
|
$this->config = $config; |
|
|
|
$this->appDataFactory = $appDataFactory; |
|
|
|
$this->jobList = $jobList; |
|
|
|
$this->dbc = $dbc; |
|
|
|
$this->appData = $appData; |
|
|
|
$this->logger = $logger; |
|
|
|
} |
|
|
|
|
|
|
|
protected function run($argument): void { |
|
|
|
@ -99,13 +105,13 @@ class MigrateBackgroundImages extends QueuedJob { |
|
|
|
$this->jobList->add(self::class, self::STAGE_EXECUTE); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @throws NotPermittedException |
|
|
|
* @throws NotFoundException |
|
|
|
*/ |
|
|
|
protected function runMigration(): void { |
|
|
|
$storedUserIds = $this->config->getAppValue('theming', '25_background_image_migration'); |
|
|
|
if ($storedUserIds === '') { |
|
|
|
return; |
|
|
|
} |
|
|
|
$allUserIds = \json_decode(\gzuncompress($storedUserIds), true); |
|
|
|
$notSoFastMode = isset($allUserIds[5000]); |
|
|
|
$allUserIds = $this->readUserIdsToProcess(); |
|
|
|
$notSoFastMode = count($allUserIds) > 5000; |
|
|
|
$dashboardData = $this->appDataFactory->get('dashboard'); |
|
|
|
|
|
|
|
$userIds = $notSoFastMode ? array_slice($allUserIds, 0, 5000) : $allUserIds; |
|
|
|
@ -128,13 +134,76 @@ class MigrateBackgroundImages extends QueuedJob { |
|
|
|
$this->storeUserIdsToProcess($remainingUserIds); |
|
|
|
$this->jobList->add(self::class, ['stage' => self::STAGE_EXECUTE]); |
|
|
|
} else { |
|
|
|
$this->config->deleteAppValue('theming', '25_background_image_migration'); |
|
|
|
$this->deleteStateFile(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @throws NotPermittedException |
|
|
|
* @throws NotFoundException |
|
|
|
*/ |
|
|
|
protected function readUserIdsToProcess(): array { |
|
|
|
$globalFolder = $this->appData->getFolder('global'); |
|
|
|
if ($globalFolder->fileExists(self::STATE_FILE_NAME)) { |
|
|
|
$file = $globalFolder->getFile(self::STATE_FILE_NAME); |
|
|
|
try { |
|
|
|
$userIds = \json_decode($file->getContent(), true); |
|
|
|
} catch (NotFoundException $e) { |
|
|
|
$userIds = []; |
|
|
|
} |
|
|
|
if ($userIds === null) { |
|
|
|
$userIds = []; |
|
|
|
} |
|
|
|
} else { |
|
|
|
$userIds = []; |
|
|
|
} |
|
|
|
return $userIds; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @throws NotFoundException |
|
|
|
*/ |
|
|
|
protected function storeUserIdsToProcess(array $userIds): void { |
|
|
|
$storableUserIds = \gzcompress(\json_encode($userIds), 9); |
|
|
|
$this->config->setAppValue('theming', '25_background_image_migration', $storableUserIds); |
|
|
|
$storableUserIds = \json_encode($userIds); |
|
|
|
$globalFolder = $this->appData->getFolder('global'); |
|
|
|
try { |
|
|
|
if ($globalFolder->fileExists(self::STATE_FILE_NAME)) { |
|
|
|
$file = $globalFolder->getFile(self::STATE_FILE_NAME); |
|
|
|
} else { |
|
|
|
$file = $globalFolder->newFile(self::STATE_FILE_NAME); |
|
|
|
} |
|
|
|
$file->putContent($storableUserIds); |
|
|
|
} catch (NotFoundException $e) { |
|
|
|
} catch (NotPermittedException $e) { |
|
|
|
$this->logger->warning('Lacking permissions to create {file}', |
|
|
|
[ |
|
|
|
'app' => 'theming', |
|
|
|
'file' => self::STATE_FILE_NAME, |
|
|
|
'exception' => $e, |
|
|
|
] |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @throws NotFoundException |
|
|
|
*/ |
|
|
|
protected function deleteStateFile(): void { |
|
|
|
$globalFolder = $this->appData->getFolder('global'); |
|
|
|
if ($globalFolder->fileExists(self::STATE_FILE_NAME)) { |
|
|
|
$file = $globalFolder->getFile(self::STATE_FILE_NAME); |
|
|
|
try { |
|
|
|
$file->delete(); |
|
|
|
} catch (NotPermittedException $e) { |
|
|
|
$this->logger->info('Could not delete {name} due to permissions. It is safe to delete manually inside data -> appdata -> theming -> global.', |
|
|
|
[ |
|
|
|
'app' => 'theming', |
|
|
|
'name' => $file->getName(), |
|
|
|
'exception' => $e, |
|
|
|
] |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
|