]> source.dussan.org Git - nextcloud-server.git/commitdiff
Fix 'most' Google Drive tests
authorMichael Gapczynski <mtgap@owncloud.com>
Sat, 13 Jul 2013 15:02:07 +0000 (11:02 -0400)
committerVictor Dubiniuk <victor.dubiniuk@gmail.com>
Sat, 3 Aug 2013 12:40:38 +0000 (15:40 +0300)
apps/files_external/lib/google.php
apps/files_external/tests/google.php

index 18ea5fca16fc6007c753f997bb061d138148965e..00b3f3c32b699ce8127cbf7ce98a9e998b58f62a 100644 (file)
@@ -1,23 +1,23 @@
 <?php
 /**
-* 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 <http://www.gnu.org/licenses/>.
-*/
+ * 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 <http://www.gnu.org/licenses/>.
+ */
 
 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--;
+                                                                       }
                                                                }
                                                        }
                                                }
index f344163a8b9a5ff2ef70c79519129947394bb1c6..12faabb902dbe7c5d39bc8efdd581cabbc6fb159 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 /**
  * ownCloud
  *
 
 namespace Test\Files\Storage;
 
+require_once 'files_external/lib/google.php';
+
 class Google extends Storage {
+
        private $config;
 
-       public function setUp() {
-               $id = uniqid();
+       protected function setUp() {
                $this->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