Fix 'most' Google Drive tests

This commit is contained in:
Michael Gapczynski 2013-07-13 11:02:07 -04:00
parent 24b4806af4
commit 00e2b46017
2 changed files with 148 additions and 82 deletions

View 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--;
}
}
}
}

View file

@ -1,5 +1,4 @@
<?php
/**
* ownCloud
*
@ -22,22 +21,25 @@
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('/');
}
}
}
}