protected function calculateTotalSize(Node $node)
 {
     $size = $node['contentProperties']['size'] ?: 0;
     if ($node->isFolder() || $this->input->getOption('assets')) {
         foreach ($node->getChildren() as $child) {
             $size += $this->calculateTotalSize($child);
         }
     }
     return $size;
 }
Example #2
0
 protected function main()
 {
     $this->init();
     $remotePath = $this->input->getArgument('remote_path');
     if ($this->input->getOption('id')) {
         if (!($node = Node::loadById($remotePath))) {
             throw new \Exception("No node exists with ID '{$remotePath}'.");
         }
     } else {
         if (!($node = Node::loadByPath($remotePath))) {
             throw new \Exception("No node exists at remote path '{$remotePath}'.");
         }
     }
     $result = $node->trash();
     if ($result['success']) {
         $this->output->writeln("<info>Successfully trashed node at '{$remotePath}'</info>");
         if ($this->output->isVerbose()) {
             $this->output->writeln(json_encode($result['data']));
         }
     } else {
         $this->output->getErrorOutput()->writeln("<error>Failed to trash node at '{$remotePath}'</error>");
         if ($this->output->isVerbose()) {
             $this->output->getErrorOutput()->writeln(json_encode($result['data']));
         }
     }
 }
Example #3
0
 protected function main()
 {
     $this->init();
     $remotePath = $this->input->getArgument('remote_path');
     $savePath = $this->input->getArgument('local_path') ?: getcwd();
     if ($this->input->getOption('id')) {
         if (!($node = Node::loadById($remotePath))) {
             throw new \Exception("No node exists with ID '{$remotePath}'.");
         }
     } else {
         if (!($node = Node::loadByPath($remotePath))) {
             throw new \Exception("No node exists at remote path '{$remotePath}'.");
         }
     }
     $node->download($savePath, function ($result, $dest) {
         if ($result['success']) {
             $this->output->writeln("<info>Successfully downloaded file to '{$dest}'</info>");
         } else {
             $this->output->getErrorOutput()->writeln("<error>Failed to download node to '{$dest}'</error>");
             if ($this->output->isVerbose()) {
                 $this->output->getErrorOutput()->writeln(json_encode($result['data']));
             }
         }
     });
 }
Example #4
0
 protected function main()
 {
     $this->init();
     $remotePath = $this->input->getArgument('remote_path') ?: '';
     if ($this->input->getOption('id')) {
         if (!($node = Node::loadById($remotePath))) {
             throw new \Exception("No node exists with ID '{$remotePath}'.");
         }
     } else {
         if (!($node = Node::loadByPath($remotePath))) {
             throw new \Exception("No node exists at remote path '{$remotePath}'.");
         }
     }
     if ($node->isFolder()) {
         throw new \Exception("Links can only be created for files.");
     }
     $response = $node->getMetadata(true);
     if ($response['success']) {
         if (isset($response['data']['tempLink'])) {
             $this->output->writeln($response['data']['tempLink']);
         } else {
             $this->output->getErrorOutput()->writeln("<error>Failed retrieving temporary link. Make sure you have permission.</error>");
         }
     } else {
         $this->output->getErrorOutput()->writeln("<error>Failed retrieving metadata for node '{$remotePath}'</error>");
     }
 }
Example #5
0
 protected function buildMarkdownTree(Node $node, $includeAssets = false, $prefix = '')
 {
     static $first;
     if (is_null($first)) {
         $first = false;
         if ($node->isFolder()) {
             $this->output->writeln("<blue>{$node['name']}</blue>");
         } else {
             $this->output->writeln($node['name']);
         }
     }
     foreach ($node->getChildren() as $node) {
         $this->output->writeln("{$prefix}- {$node['name']}");
         if ($node->isFolder() || $includeAssets === true) {
             $this->buildMarkdownTree($node, $includeAssets, "{$prefix}  ");
         }
     }
 }
 protected function main()
 {
     $this->init();
     $sort = Command::SORT_BY_NAME;
     if ($this->input->getOption('time')) {
         $sort = Command::SORT_BY_TIME;
     }
     $this->listNodes(Node::filter([['status' => 'PENDING']]), $sort);
 }
Example #7
0
 protected function main()
 {
     $this->init();
     $id = $this->input->getArgument('id');
     if (!($node = Node::loadById($id))) {
         throw new \Exception("No node exists with ID '{$id}'.");
     }
     $this->output->writeln($node->getPath());
 }
Example #8
0
 protected function main()
 {
     $this->init();
     $remotePath = $this->input->getArgument('remote_path');
     if ($node = Node::loadByPath($remotePath)) {
         throw new \Exception("Node already exists at remote path '{$remotePath}'. Make sure it's not in the trash.");
     }
     $result = $this->clouddrive->createDirectoryPath($remotePath);
     if (!$result['success']) {
         $this->output->writeln("Failed to create remote path '{$remotePath}': " . json_encode($result['data']));
     } else {
         $this->output->writeln("Successfully created remote path '{$remotePath}': " . json_encode($result['data']));
     }
 }
Example #9
0
 protected function main()
 {
     $this->init();
     $query = $this->input->getArgument('query');
     if ($this->input->getOption('md5')) {
         $nodes = Node::loadByMd5($query);
     } else {
         $nodes = Node::searchNodesByName($query);
     }
     $sort = Command::SORT_BY_NAME;
     if ($this->input->getOption('time')) {
         $sort = Command::SORT_BY_TIME;
     }
     $this->listNodes($nodes, $sort);
 }
Example #10
0
 protected function main()
 {
     $this->initOnlineCommand();
     $remotePath = $this->input->getArgument('remote_path');
     if ($this->input->getOption('id')) {
         if (!($node = Node::loadById($remotePath))) {
             throw new \Exception("No node exists with ID '{$remotePath}'.");
         }
     } else {
         if (!($node = Node::loadByPath($remotePath))) {
             throw new \Exception("No node exists at remote path '{$remotePath}'.");
         }
     }
     if ($node->isFolder()) {
         throw new \Exception("Folder downloads are not currently supported.");
     }
     $node->download($this->output->getStream());
 }
Example #11
0
 protected function main()
 {
     $this->init();
     $path = $this->input->getArgument('path') ?: '';
     if ($this->input->getOption('id')) {
         if (!($node = Node::loadById($path))) {
             throw new \Exception("No node exists with ID '{$path}'.");
         }
     } else {
         if (!($node = Node::loadByPath($path))) {
             throw new \Exception("No node exists at remote path '{$path}'.");
         }
     }
     if ($this->config['json.pretty']) {
         $this->output->writeln(json_encode($node, JSON_PRETTY_PRINT));
     } else {
         $this->output->writeln(json_encode($node));
     }
 }
Example #12
0
 protected function main()
 {
     $this->init();
     $remotePath = $this->input->getArgument('remote_path');
     if ($this->input->getOption('id')) {
         if (!($node = Node::loadById($remotePath))) {
             throw new \Exception("No node exists with ID '{$remotePath}'.");
         }
     } else {
         if (!($node = Node::loadByPath($remotePath))) {
             throw new \Exception("No node exists at remote path '{$remotePath}'.");
         }
     }
     $result = $node->restore();
     if ($result['success']) {
         $this->output->writeln("Successfully restored node at '{$remotePath}': " . json_encode($result['data']));
     } else {
         $this->output->writeln("Failed to restore node at '{$remotePath}': " . json_encode($result['data']));
     }
 }
Example #13
0
 protected function main()
 {
     $this->init();
     $this->clouddrive->getAccount()->authorize();
     $remotePath = $this->input->getArgument('remote_path') ?: '';
     $sort = Command::SORT_BY_NAME;
     if ($this->input->getOption('time')) {
         $sort = Command::SORT_BY_TIME;
     }
     if ($this->input->getOption('id')) {
         if (!($node = Node::loadById($remotePath))) {
             throw new \Exception("No node exists with ID '{$remotePath}'.");
         }
     } else {
         if (!($node = Node::loadByPath($remotePath))) {
             throw new \Exception("No node exists at remote path '{$remotePath}'.");
         }
     }
     if ($node->isFolder() || $this->input->getOption('assets')) {
         $this->listNodes($node->getChildren(), $sort);
     } else {
         $this->listNodes([$node], $sort);
     }
 }
Example #14
0
 protected function main()
 {
     $this->init();
     $nodePath = $this->input->getArgument('node');
     $newPath = $this->input->getArgument('new_path');
     if (!($node = Node::loadByPath($nodePath))) {
         throw new \Exception("No node exists at remote path '{$nodePath}'.");
     }
     if (!($newParent = Node::loadByPath($newPath))) {
         throw new \Exception("No node exists at remote path '{$newPath}'.");
     }
     $result = $node->move($newParent);
     if ($result['success']) {
         $this->output->writeln("<info>Successfully moved node '{$node['name']}' to '{$newPath}'</info>");
         if ($this->output->isVerbose()) {
             $this->output->writeln(json_encode($result['data']));
         }
     } else {
         $this->output->getErrorOutput()->writeln("<error>Failed to move node '{$node['name']}' to '{$newPath}'</error>");
         if ($this->output->isVerbose()) {
             $this->output->getErrorOutput()->writeln(json_encode($result['data']));
         }
     }
 }
Example #15
0
 /**
  * {@inheritdoc}
  */
 public function findNodesByName($name)
 {
     $nodes = ORM::for_table('nodes')->select('raw_data')->where('name', $name)->find_many();
     foreach ($nodes as &$node) {
         $node = new Node(json_decode($node->as_array()['raw_data'], true));
     }
     return $nodes;
 }
Example #16
0
 /**
  * Determine if a node matching the given path exists remotely. If a local
  * path is given, the MD5 will be compared as well.
  *
  * @param string      $remotePath The remote path to check
  * @param null|string $localPath  Local path of file to compare MD5
  *
  * @return array
  * @throws \Exception'
  */
 public function nodeExists($remotePath, $localPath = null)
 {
     if (is_null($file = Node::loadByPath($remotePath))) {
         if (!is_null($localPath)) {
             if (!empty($nodes = Node::loadByMd5(md5_file($localPath)))) {
                 $ids = [];
                 foreach ($nodes as $node) {
                     $ids[] = $node['id'];
                 }
                 return ['success' => true, 'data' => ['message' => "File(s) with same MD5: " . implode(', ', $ids), 'path_match' => false, 'md5_match' => true, 'nodes' => $nodes]];
             }
         }
         return ['success' => false, 'data' => ['message' => "File {$remotePath} does not exist.", 'path_match' => false, 'md5_match' => false]];
     }
     $retval = ['success' => true, 'data' => ['message' => "File {$remotePath} exists.", 'path_match' => true, 'md5_match' => false, 'node' => $file]];
     if (!is_null($localPath)) {
         if (!is_null($file['contentProperties']['md5'])) {
             if (md5_file($localPath) !== $file['contentProperties']['md5']) {
                 $retval['data']['message'] = "File {$remotePath} exists but does not match local checksum.";
             } else {
                 $retval['data']['message'] = "File {$remotePath} exists and is identical to local copy.";
                 $retval['data']['md5_match'] = true;
             }
         } else {
             $retval['data']['message'] = "File {$remotePath} exists but no checksum is available.";
         }
     }
     return $retval;
 }
Example #17
0
 /**
  * Upload a single file to Amazon Cloud Drive.
  *
  * @param resource     $resource     The local path to the file to upload
  * @param string     $remotePath    The remote folder to upload the file to, including the file name
  * @param bool|false $overwrite     Whether to overwrite the file if it already
  *                                  exists remotely
  * @param bool       $suppressDedup Disables checking for duplicates when uploading
  *
  * @return array
  */
 public function uploadStream($resource, $remotePath, $overwrite = false, $suppressDedup = false)
 {
     $retval = ['success' => false, 'data' => [], 'response_code' => null];
     $info = pathinfo($remotePath);
     if ($info['dirname'] == '.') {
         $info['dirname'] = '/';
     }
     $remotePath = $this->getPathString($this->getPathArray($info['dirname']));
     if (!($remoteFolder = Node::loadByPath($remotePath))) {
         $response = $this->createDirectoryPath($remotePath);
         if ($response['success'] === false) {
             return $response;
         }
         $remoteFolder = $response['data'];
     }
     $response = $this->nodeExists("{$remotePath}/{$info['basename']}", $resource);
     if ($response['success'] === true) {
         $pathMatch = $response['data']['path_match'];
         $md5Match = $response['data']['md5_match'];
         if ($pathMatch === true && $md5Match === true) {
             // Skip if path and MD5 match
             $retval['data'] = $response['data'];
             return $retval;
         } else {
             if ($pathMatch === true && $md5Match === false) {
                 // If path is the same and checksum differs, only overwrite
                 if ($overwrite === true) {
                     return $response['data']['node']->overwrite($resource);
                 }
                 $retval['data'] = $response['data'];
                 return $retval;
             } else {
                 if ($pathMatch === false && $md5Match === true) {
                     // If path differs and checksum is the same, check for dedup
                     if ($suppressDedup === false) {
                         $retval['data'] = $response['data'];
                         return $retval;
                     }
                 }
             }
         }
     }
     $suppressDedup = $suppressDedup ? '?suppress=deduplication' : '';
     $response = $this->httpClient->post("{$this->account->getContentUrl()}nodes{$suppressDedup}", ['headers' => ['Authorization' => "Bearer {$this->account->getToken()['access_token']}"], 'multipart' => [['name' => 'metadata', 'contents' => json_encode(['kind' => 'FILE', 'name' => $info['basename'], 'parents' => [$remoteFolder['id']]])], ['name' => 'file', 'contents' => $resource, 'filename' => $info['basename']]], 'exceptions' => false]);
     $retval['data'] = json_decode((string) $response->getBody(), true);
     $retval['response_code'] = $response->getStatusCode();
     if (($retval['response_code'] = $response->getStatusCode()) === 201) {
         $retval['success'] = true;
         (new Node($retval['data']))->save();
     }
     return $retval;
 }
 /**
  * Get the timestamp of a file.
  *
  * @param string $path
  *
  * @return array|false
  */
 public function getTimestamp($path)
 {
     if (!($node = Node::loadByPath($path))) {
         return false;
     }
     return ['timestamp' => (new \DateTime($node['modifiedDate']))->getTimestamp()];
 }
Example #19
0
 /**
  * @throws \Exception
  */
 protected function initOnlineCommand()
 {
     if (count($this->config) === 0) {
         throw new \Exception('Account has not been authorized. Please do so using the `init` command.');
     }
     $this->cacheStore = $this->generateCacheStore();
     if ($this->config['email'] && $this->config['client-id'] && $this->config['client-secret']) {
         $clouddrive = new CloudDrive($this->config['email'], $this->config['client-id'], $this->config['client-secret'], $this->cacheStore);
         if ($this->output->getVerbosity() === 2) {
             $this->output->writeln("Authorizing...", OutputInterface::VERBOSITY_VERBOSE);
         }
         if ($clouddrive->getAccount()->authorize()['success']) {
             if ($this->output->getVerbosity() === 2) {
                 $this->output->writeln("Done.");
             }
             $this->clouddrive = $clouddrive;
             Node::init($this->clouddrive->getAccount(), $this->cacheStore);
         } else {
             throw new \Exception('Account has not been authorized. Please do so using the `init` command.');
         }
     }
 }
Example #20
0
 /**
  * Sync the local cache with the remote changes. If checkpoint is null, this
  * will sync all remote node data.
  *
  * @throws \Exception
  */
 public function sync()
 {
     $params = ['maxNodes' => 5000];
     if ($this->checkpoint) {
         $params['includePurged'] = "true";
     }
     while (true) {
         if ($this->checkpoint) {
             $params['checkpoint'] = $this->checkpoint;
         }
         $loop = true;
         $response = $this->httpClient->post("{$this->getMetadataUrl()}changes", ['headers' => ['Authorization' => "Bearer {$this->token['access_token']}"], 'body' => json_encode($params), 'exceptions' => false]);
         if ($response->getStatusCode() !== 200) {
             throw new \Exception((string) $response->getBody());
         }
         $data = explode("\n", (string) $response->getBody());
         foreach ($data as $part) {
             $part = json_decode($part, true);
             if (isset($part['end']) && $part['end'] === true) {
                 break;
             }
             if (isset($part['reset']) && $part['reset'] === true) {
                 $this->cache->deleteAllNodes();
             }
             if (isset($part['nodes'])) {
                 if (empty($part['nodes'])) {
                     $loop = false;
                 } else {
                     foreach ($part['nodes'] as $node) {
                         $node = new Node($node);
                         if ($node['status'] === 'PURGED') {
                             $node->delete();
                         } else {
                             $node->save();
                         }
                     }
                 }
             }
             if (isset($part['checkpoint'])) {
                 $this->checkpoint = $part['checkpoint'];
             }
             $this->save();
         }
         if (!$loop) {
             break;
         }
     }
 }
Example #21
0
 /**
  * Move a FILE or FOLDER `Node` to a new remote location.
  *
  * @param \CloudDrive\Node $newFolder
  *
  * @return array
  * @throws \Exception
  */
 public function move(Node $newFolder)
 {
     if (!$newFolder->isFolder()) {
         throw new \Exception("New destination node is not a folder.");
     }
     if (!$this->isFile() && !$this->isFolder()) {
         throw new \Exception("Moving a node can only be performed on FILE and FOLDER kinds.");
     }
     $retval = ['success' => false, 'data' => []];
     $response = self::$httpClient->post(self::$account->getMetadataUrl() . "nodes/{$newFolder['id']}/children", ['headers' => ['Authorization' => 'Bearer ' . self::$account->getToken()['access_token']], 'json' => ['fromParent' => $this['parents'][0], 'childId' => $this['id']], 'exceptions' => false]);
     $retval['data'] = json_decode((string) $response->getBody(), true);
     if ($response->getStatusCode() === 200) {
         $retval['success'] = true;
         $this->replace($retval['data']);
         $this->save();
     }
     return $retval;
 }