From 00e2b46017dc7bb83937e2d21a3bf5bcdb91b4e0 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 13 Jul 2013 11:02:07 -0400 Subject: [PATCH] Fix 'most' Google Drive tests --- apps/files_external/lib/google.php | 212 +++++++++++++++++---------- apps/files_external/tests/google.php | 18 ++- 2 files changed, 148 insertions(+), 82 deletions(-) diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 18ea5fca16..00b3f3c32b 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -1,23 +1,23 @@ . -*/ + * ownCloud + * + * @author Michael Gapczynski + * @copyright 2012 Michael Gapczynski mtgap@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + */ namespace OC\Files\Storage; @@ -96,7 +96,7 @@ class Google extends \OC\Files\Storage\Common { if (isset($this->driveFiles[$path])) { $parentId = $this->driveFiles[$path]->getId(); } else { - $q = "title='".$name."' and '".$parentId."' in parents"; + $q = "title='".$name."' and '".$parentId."' in parents and trashed = false"; $result = $this->service->files->listFiles(array('q' => $q))->getItems(); if (!empty($result)) { // Google Drive allows files with the same name, ownCloud doesn't @@ -132,6 +132,25 @@ class Google extends \OC\Files\Storage\Common { } } + /** + * Set the Google_DriveFile object in the cache + * @param string $path + * @param Google_DriveFile|false $file + */ + private function setDriveFile($path, $file) { + $path = trim($this->root.$path, '/'); + $this->driveFiles[$path] = $file; + if ($file === false) { + // Set all child paths as false + $len = strlen($path); + foreach ($this->driveFiles as $key => $file) { + if (substr($key, 0, $len) === $path) { + $this->driveFiles[$key] = false; + } + } + } + } + /** * Write a log message to inform about duplicate file names * @param string $path @@ -141,7 +160,8 @@ class Google extends \OC\Files\Storage\Common { $user = $about->getName(); \OCP\Util::writeLog('files_external', 'Ignoring duplicate file name: '.$path.' on Google Drive for Google user: '.$user, - \OCP\Util::INFO); + \OCP\Util::INFO + ); } /** @@ -165,22 +185,41 @@ class Google extends \OC\Files\Storage\Common { } public function mkdir($path) { - $parentFolder = $this->getDriveFile(dirname($path)); - if ($parentFolder) { - $folder = new \Google_DriveFile(); - $folder->setTitle(basename($path)); - $folder->setMimeType(self::FOLDER); - $parent = new \Google_ParentReference(); - $parent->setId($parentFolder->getId()); - $folder->setParents(array($parent)); - return (bool)$this->service->files->insert($folder); - } else { - return false; + if (!$this->is_dir($path)) { + $parentFolder = $this->getDriveFile(dirname($path)); + if ($parentFolder) { + $folder = new \Google_DriveFile(); + $folder->setTitle(basename($path)); + $folder->setMimeType(self::FOLDER); + $parent = new \Google_ParentReference(); + $parent->setId($parentFolder->getId()); + $folder->setParents(array($parent)); + $result = $this->service->files->insert($folder); + if ($result) { + $this->setDriveFile($path, $result); + } + return (bool)$result; + } } + return false; } public function rmdir($path) { - return $this->unlink($path); + if (trim($this->root.$path, '/') === '') { + $dir = $this->opendir($path); + while ($file = readdir($dir)) { + if (!\OC\Files\Filesystem::isIgnoredDir($file)) { + if (!$this->unlink($path.'/'.$file)) { + return false; + } + } + } + closedir($dir); + $this->driveFiles = array(); + return true; + } else { + return $this->unlink($path); + } } public function opendir($path) { @@ -196,12 +235,12 @@ class Google extends \OC\Files\Storage\Common { if ($pageToken !== true) { $params['pageToken'] = $pageToken; } - $params['q'] = "'".$folder->getId()."' in parents"; + $params['q'] = "'".$folder->getId()."' in parents and trashed = false"; $children = $this->service->files->listFiles($params); foreach ($children->getItems() as $child) { $name = $child->getTitle(); // Check if this is a Google Doc i.e. no extension in name - if ($child->getFileExtension() == '' + if ($child->getFileExtension() === '' && $child->getMimeType() !== self::FOLDER ) { $name .= '.'.$this->getGoogleDocExtension($child->getMimeType()); @@ -213,29 +252,22 @@ class Google extends \OC\Files\Storage\Common { } // Google Drive allows files with the same name, ownCloud doesn't // Prevent opendir() from returning any duplicate files - if (isset($this->driveFiles[$filepath]) && !isset($duplicates[$filepath])) { - // Save this key to unset later in case there are more than 2 duplicates - $duplicates[$filepath] = $name; + $key = array_search($name, $files); + if ($key !== false || isset($duplicates[$filepath])) { + if (!isset($duplicates[$filepath])) { + $duplicates[$filepath] = true; + $this->setDriveFile($filepath, false); + unset($files[$key]); + $this->onDuplicateFileDetected($filepath); + } } else { // Cache the Google_DriveFile for future use - $this->driveFiles[$filepath] = $child; + $this->setDriveFile($filepath, $child); $files[] = $name; } } $pageToken = $children->getNextPageToken(); } - // Remove all duplicate files - foreach ($duplicates as $filepath => $name) { - unset($this->driveFiles[$filepath]); - $key = array_search($name, $files); - unset($files[$key]); - $this->onDuplicateFileDetected($filepath); - } - // Reindex $files array if duplicates were removed - // This is necessary for \OC\Files\Stream\Dir - if (!empty($duplicates)) { - $files = array_values($files); - } \OC\Files\Stream\Dir::register('google'.$path, $files); return opendir('fakedir://google'.$path); } else { @@ -285,7 +317,7 @@ class Google extends \OC\Files\Storage\Common { } public function isReadable($path) { - return true; + return $this->file_exists($path); } public function isUpdatable($path) { @@ -304,7 +336,11 @@ class Google extends \OC\Files\Storage\Common { public function unlink($path) { $file = $this->getDriveFile($path); if ($file) { - return (bool)$this->service->files->trash($file->getId()); + $result = $this->service->files->trash($file->getId()); + if ($result) { + $this->setDriveFile($path, false); + } + return (bool)$result; } else { return false; } @@ -322,9 +358,16 @@ class Google extends \OC\Files\Storage\Common { $parent = new \Google_ParentReference(); $parent->setId($parentFolder2->getId()); $file->setParents(array($parent)); + } else { + return false; } } - return (bool)$this->service->files->patch($file->getId(), $file); + $result = $this->service->files->patch($file->getId(), $file); + if ($result) { + $this->setDriveFile($path1, false); + $this->setDriveFile($path2, $result); + } + return (bool)$result; } else { return false; } @@ -361,7 +404,7 @@ class Google extends \OC\Files\Storage\Common { } } } - return null; + return false; case 'w': case 'wb': case 'a': @@ -390,23 +433,28 @@ class Google extends \OC\Files\Storage\Common { $path = self::$tempFiles[$tmpFile]; $parentFolder = $this->getDriveFile(dirname($path)); if ($parentFolder) { - $file = new \Google_DriveFile(); - $file->setTitle(basename($path)); - $mimetype = \OC_Helper::getMimeType($tmpFile); - $file->setMimeType($mimetype); - $parent = new \Google_ParentReference(); - $parent->setId($parentFolder->getId()); - $file->setParents(array($parent)); // TODO Research resumable upload + $mimetype = \OC_Helper::getMimeType($tmpFile); $data = file_get_contents($tmpFile); $params = array( 'data' => $data, 'mimeType' => $mimetype, ); + $result = false; if ($this->file_exists($path)) { - $this->service->files->update($file->getId(), $file, $params); + $file = $this->getDriveFile($path); + $result = $this->service->files->update($file->getId(), $file, $params); } else { - $this->service->files->insert($file, $params); + $file = new \Google_DriveFile(); + $file->setTitle(basename($path)); + $file->setMimeType($mimetype); + $parent = new \Google_ParentReference(); + $parent->setId($parentFolder->getId()); + $file->setParents(array($parent)); + $result = $this->service->files->insert($file, $params); + } + if ($result) { + $this->setDriveFile($path, $result); } } unlink($tmpFile); @@ -444,18 +492,31 @@ class Google extends \OC\Files\Storage\Common { public function touch($path, $mtime = null) { $file = $this->getDriveFile($path); + $result = false; if ($file) { if (isset($mtime)) { $file->setModifiedDate($mtime); - $this->service->files->patch($file->getId(), $file, array( + $result = $this->service->files->patch($file->getId(), $file, array( 'setModifiedDate' => true, )); } else { - return (bool)$this->service->files->touch($file->getId()); + $result = $this->service->files->touch($file->getId()); } } else { - return false; + $parentFolder = $this->getDriveFile(dirname($path)); + if ($parentFolder) { + $file = new \Google_DriveFile(); + $file->setTitle(basename($path)); + $parent = new \Google_ParentReference(); + $parent->setId($parentFolder->getId()); + $file->setParents(array($parent)); + $result = $this->service->files->insert($file); + } } + if ($result) { + $this->setDriveFile($path, $result); + } + return (bool)$result; } public function test() { @@ -500,14 +561,17 @@ class Google extends \OC\Files\Storage\Common { // Check if a file in this folder has been updated // There is no way to filter by folder at the API level... foreach ($changes->getItems() as $change) { - foreach ($change->getFile()->getParents() as $parent) { - if ($parent->getId() === $folderId) { - $result = true; - // Check if there are changes in different folders - } else if ($change->getId() <= $largestChangeId) { - // Decrement id so this change is fetched when called again - $largestChangeId = $change->getId(); - $largestChangeId--; + $file = $change->getFile(); + if ($file) { + foreach ($file->getParents() as $parent) { + if ($parent->getId() === $folderId) { + $result = true; + // Check if there are changes in different folders + } else if ($change->getId() <= $largestChangeId) { + // Decrement id so this change is fetched when called again + $largestChangeId = $change->getId(); + $largestChangeId--; + } } } } diff --git a/apps/files_external/tests/google.php b/apps/files_external/tests/google.php index f344163a8b..12faabb902 100644 --- a/apps/files_external/tests/google.php +++ b/apps/files_external/tests/google.php @@ -1,5 +1,4 @@ config = include('files_external/tests/config.php'); - if ( ! is_array($this->config) or ! isset($this->config['google']) or ! $this->config['google']['run']) { - $this->markTestSkipped('Google backend not configured'); + if (!is_array($this->config) || !isset($this->config['google']) + || !$this->config['google']['run'] + ) { + $this->markTestSkipped('Google Drive backend not configured'); } - $this->config['google']['root'] .= '/' . $id; //make sure we have an new empty folder to work in $this->instance = new \OC\Files\Storage\Google($this->config['google']); } - public function tearDown() { + protected function tearDown() { if ($this->instance) { $this->instance->rmdir('/'); } } -} +} \ No newline at end of file