public function execute(Job $job)
 {
     $this->configuration->setStorageApi($this->storageApi);
     $accounts = $this->configuration->getAccounts();
     $options = $job->getParams();
     $status = [];
     if (isset($options['external'])) {
         // load files by tag from SAPI
         if (!isset($options['external']['account'])) {
             throw new UserException("Missing field 'account'");
         }
         try {
             $this->configuration->create();
         } catch (\Exception $e) {
             // create configuration if not exists
         }
         $account = new Account($this->configuration, uniqid('external'));
         $account->fromArray($options['external']['account']);
         $writer = $this->writerFactory->create($account);
         if (!isset($options['external']['query'])) {
             throw new UserException("Missing field 'query'");
         }
         $queryString = $options['external']['query'];
         $queryString .= ' -tags:wr-google-drive-processed';
         if (isset($options['external']['filterByRunId']) && $options['external']['filterByRunId']) {
             $parentRunId = $this->getParentRunId($job->getRunId());
             if ($parentRunId) {
                 $queryString .= ' +tags:runId-' . $parentRunId;
             }
         }
         $uploadedFiles = $this->storageApi->listFiles((new ListFilesOptions())->setQuery($queryString));
         if (empty($uploadedFiles)) {
             throw new UserException("No file matches your query '" . $queryString . "'");
         }
         foreach ($uploadedFiles as $uploadedFile) {
             $tmpFile = $this->temp->createTmpFile('wr-gd');
             file_put_contents($tmpFile->getPathname(), fopen($uploadedFile['url'], 'r'));
             $file = new File(['id' => $uploadedFile['id'], 'title' => $uploadedFile['name'], 'targetFolder' => isset($options['external']['targetFolder']) ? $options['external']['targetFolder'] : null, 'type' => File::TYPE_FILE, 'pathname' => $tmpFile, 'size' => $uploadedFile['sizeBytes']]);
             $gdFiles = $writer->listFiles(['q' => "trashed=false and name='" . $uploadedFile['name'] . "'"]);
             if (!empty($gdFiles['files'])) {
                 $lastGdFile = array_shift($gdFiles['files']);
                 $file->setGoogleId($lastGdFile['id']);
             }
             $file = $writer->process($file);
             // tag file 'wr-google-drive-processed'
             $this->storageApi->addFileTag($uploadedFile['id'], 'wr-google-drive-processed');
         }
         // delete temporary account
         $this->configuration->removeAccount($account->getAccountId());
     } else {
         $fileFilter = null;
         if (isset($options['config'])) {
             if (!isset($accounts[$options['config']])) {
                 throw new UserException("Config '" . $options['config'] . "' does not exist.");
             }
             $accounts = [$options['config'] => $accounts[$options['config']]];
             if (isset($options['file'])) {
                 /** @var Account $account */
                 $account = $accounts[$options['config']];
                 if (null == $account->getFile($options['file'])) {
                     throw new UserException("File '" . $options['file'] . "' not found");
                 }
                 $fileFilter = $options['file'];
             }
         }
         /** @var Account $account */
         foreach ($accounts as $accountId => $account) {
             $writer = $this->writerFactory->create($account);
             $files = $account->getFiles();
             /** @var File $file */
             foreach ($files as $file) {
                 if ($fileFilter != null && $file->getId() != $fileFilter) {
                     continue;
                 }
                 $file->setPathname($this->temp->createTmpFile()->getPathname());
                 try {
                     $tableExporter = new TableExporter($this->storageApi);
                     $tableExporter->exportTable($file->getTableId(), $file->getPathname(), []);
                 } catch (ClientException $e) {
                     throw new UserException($e->getMessage(), $e, ['file' => $file->toArray()]);
                 }
                 $file = $writer->process($file);
                 $status[$account->getAccountName()][$file->getTitle()] = 'ok';
             }
             // updated changes to files
             $account->save();
         }
     }
     return $status;
 }
 /**
  * @param $id
  * @return JsonResponse
  */
 public function deleteConfigAction($id)
 {
     $this->configuration->removeAccount($id);
     return $this->createJsonResponse([], 204);
 }