<commit_before><?php
/**
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>.at>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 *
 * @copyright Copyright (c) 2016, ownCloud, Inc.
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program 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, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

namespace OCA\Files_External\Lib\Storage;

use GuzzleHttp\Exception\RequestException;
use Icewind\Streams\IteratorDirectory;
use Icewind\Streams\RetryWrapper;

set_include_path(get_include_path().PATH_SEPARATOR.
	\OC_App::getAppPath('files_external').'/3rdparty/google-api-php-client/src');
require_once 'Google/autoload.php';

class Google extends \OC\Files\Storage\Common {

	private $client;
	private $id;
	private $service;
	private $driveFiles;

	private static $tempFiles = array();

	// Google Doc mimetypes
	const FOLDER = 'application/vnd.google-apps.folder';
	const DOCUMENT = 'application/vnd.google-apps.document';
	const SPREADSHEET = 'application/vnd.google-apps.spreadsheet';
	const DRAWING = 'application/vnd.google-apps.drawing';
	const PRESENTATION = 'application/vnd.google-apps.presentation';
	const MAP = 'application/vnd.google-apps.map';

	public function __construct($params) {
		if (isset($params['configured']) && $params['configured'] === 'true'
			&& isset($params['client_id']) && isset($params['client_secret'])
			&& isset($params['token'])
		) {
			$this->client = new \Google_Client();
			$this->client->setClientId($params['client_id']);
			$this->client->setClientSecret($params['client_secret']);
			$this->client->setScopes(array('https://www.googleapis.com/auth/drive'));
			$this->client->setAccessToken($params['token']);
			// if curl isn't available we're likely to run into
			// https://github.com/google/google-api-php-client/issues/59
			// - disable gzip to avoid it.
			if (!function_exists('curl_version') || !function_exists('curl_exec')) {
				$this->client->setClassConfig("Google_Http_Request", "disable_gzip", true);
			}
			// note: API connection is lazy
			$this->service = new \Google_Service_Drive($this->client);
			$token = json_decode($params['token'], true);
			$this->id = 'google::'.substr($params['client_id'], 0, 30).$token['created'];
		} else {
			throw new \Exception('Creating Google storage failed');
		}
	}

	public function getId() {
		return $this->id;
	}

	/**
	 * Get the Google_Service_Drive_DriveFile object for the specified path.
	 * Returns false on failure.
	 * @param string $path
	 * @return \Google_Service_Drive_DriveFile|false
	 */
	private function getDriveFile($path) {
		// Remove leading and trailing slashes
		$path = trim($path, '/');
		if ($path === '.') {
			$path = '';
		}
		if (isset($this->driveFiles[$path])) {
			return $this->driveFiles[$path];
		} else if ($path === '') {
			$root = $this->service->files->get('root');
			$this->driveFiles[$path] = $root;
			return $root;
		} else {
			// Google Drive SDK does not have methods for retrieving files by path
			// Instead we must find the id of the parent folder of the file
			$parentId = $this->getDriveFile('')->getId();
			$folderNames = explode('/', $path);
			$path = '';
			// Loop through each folder of this path to get to the file
			foreach ($folderNames as $name) {
				// Reconstruct path from beginning
				if ($path === '') {
					$path .= $name;
				} else {
					$path .= '/'.$name;
				}
				if (isset($this->driveFiles[$path])) {
					$parentId = $this->driveFiles[$path]->getId();
				} else {
					$q = "title='" . str_replace("'","\\'", $name) . "' and '" . str_replace("'","\\'", $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
						if (count($result) > 1) {
							$this->onDuplicateFileDetected($path);
							return false;
						} else {
							$file = current($result);
							$this->driveFiles[$path] = $file;
							$parentId = $file->getId();
						}
					} else {
						// Google Docs have no extension in their title, so try without extension
						$pos = strrpos($path, '.');
						if ($pos !== false) {
							$pathWithoutExt = substr($path, 0, $pos);
							$file = $this->getDriveFile($pathWithoutExt);
							if ($file && $this->isGoogleDocFile($file)) {
								// Switch cached Google_Service_Drive_DriveFile to the correct index
								unset($this->driveFiles[$pathWithoutExt]);
								$this->driveFiles[$path] = $file;
								$parentId = $file->getId();
							} else {
								return false;
							}
						} else {
							return false;
						}
					}
				}
			}
			return $this->driveFiles[$path];
		}
	}

	/**
	 * Set the Google_Service_Drive_DriveFile object in the cache
	 * @param string $path
	 * @param \Google_Service_Drive_DriveFile|false $file
	 */
	private function setDriveFile($path, $file) {
		$path = trim($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;
				}<commit_msg>Fix GDrive test rename overwrite folder<commit_after><?php
/**
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 *
 * @copyright Copyright (c) 2016, ownCloud, Inc.
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program 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, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

namespace OCA\Files_External\Lib\Storage;

use GuzzleHttp\Exception\RequestException;
use Icewind\Streams\IteratorDirectory;
use Icewind\Streams\RetryWrapper;

set_include_path(get_include_path().PATH_SEPARATOR.
	\OC_App::getAppPath('files_external').'/3rdparty/google-api-php-client/src');
require_once 'Google/autoload.php';

class Google extends \OC\Files\Storage\Common {

	private $client;
	private $id;
	private $service;
	private $driveFiles;

	private static $tempFiles = array();

	// Google Doc mimetypes
	const FOLDER = 'application/vnd.google-apps.folder';
	const DOCUMENT = 'application/vnd.google-apps.document';
	const SPREADSHEET = 'application/vnd.google-apps.spreadsheet';
	const DRAWING = 'application/vnd.google-apps.drawing';
	const PRESENTATION = 'application/vnd.google-apps.presentation';
	const MAP = 'application/vnd.google-apps.map';

	public function __construct($params) {
		if (isset($params['configured']) && $params['configured'] === 'true'
			&& isset($params['client_id']) && isset($params['client_secret'])
			&& isset($params['token'])
		) {
			$this->client = new \Google_Client();
			$this->client->setClientId($params['client_id']);
			$this->client->setClientSecret($params['client_secret']);
			$this->client->setScopes(array('https://www.googleapis.com/auth/drive'));
			$this->client->setAccessToken($params['token']);
			// if curl isn't available we're likely to run into
			// https://github.com/google/google-api-php-client/issues/59
			// - disable gzip to avoid it.
			if (!function_exists('curl_version') || !function_exists('curl_exec')) {
				$this->client->setClassConfig("Google_Http_Request", "disable_gzip", true);
			}
			// note: API connection is lazy
			$this->service = new \Google_Service_Drive($this->client);
			$token = json_decode($params['token'], true);
			$this->id = 'google::'.substr($params['client_id'], 0, 30).$token['created'];
		} else {
			throw new \Exception('Creating Google storage failed');
		}
	}

	public function getId() {
		return $this->id;
	}

	/**
	 * Get the Google_Service_Drive_DriveFile object for the specified path.
	 * Returns false on failure.
	 * @param string $path
	 * @return \Google_Service_Drive_DriveFile|false
	 */
	private function getDriveFile($path) {
		// Remove leading and trailing slashes
		$path = trim($path, '/');
		if ($path === '.') {
			$path = '';
		}
		if (isset($this->driveFiles[$path])) {
			return $this->driveFiles[$path];
		} else if ($path === '') {
			$root = $this->service->files->get('root');
			$this->driveFiles[$path] = $root;
			return $root;
		} else {
			// Google Drive SDK does not have methods for retrieving files by path
			// Instead we must find the id of the parent folder of the file
			$parentId = $this->getDriveFile('')->getId();
			$folderNames = explode('/', $path);
			$path = '';
			// Loop through each folder of this path to get to the file
			foreach ($folderNames as $name) {
				// Reconstruct path from beginning
				if ($path === '') {
					$path .= $name;
				} else {
					$path .= '/'.$name;
				}
				if (isset($this->driveFiles[$path])) {
					$parentId = $this->driveFiles[$path]->getId();
				} else {
					$q = "title='" . str_replace("'","\\'", $name) . "' and '" . str_replace("'","\\'", $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
						if (count($result) > 1) {
							$this->onDuplicateFileDetected($path);
							return false;
						} else {
							$file = current($result);
							$this->driveFiles[$path] = $file;
							$parentId = $file->getId();
						}
					} else {
						// Google Docs have no extension in their title, so try without extension
						$pos = strrpos($path, '.');
						if ($pos !== false) {
							$pathWithoutExt = substr($path, 0, $pos);
							$file = $this->getDriveFile($pathWithoutExt);
							if ($file && $this->isGoogleDocFile($file)) {
								// Switch cached Google_Service_Drive_DriveFile to the correct index
								unset($this->driveFiles[$pathWithoutExt]);
								$this->driveFiles[$path] = $file;
								$parentId = $file->getId();
							} else {
								return false;
							}
						} else {
							return false;
						}
					}
				}
			}
			return $this->driveFiles[$path];
		}
	}

	/**
	 * Set the Google_Service_Drive_DriveFile object in the cache
	 * @param string $path
	 * @param \Google_Service_Drive_DriveFile|false $file
	 */
	private function setDriveFile($path, $file) {
		$path = trim($path, '/');
		$this->driveFiles[$path] = $file;
		if ($file === false) {
			// Remove all children
			$len = strlen($path);
			foreach ($this->driveFiles as $key => $file) {
				if (substr($key, 0, $len) === $path) {
					unset($this->driveFiles[$key]);
				}
{'fraction_non_alphanumeric': 0.169872595553335, 'fraction_numerical': 0.0028312099258889166, 'mean_word_length': 3.5150375939849625, 'pattern_counts': {'":': 0, '<': 91, '<?xml version=': 0, '>': 179, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2265281', 'n_tokens_mistral': 4459, 'n_tokens_neox': 3749, 'n_words': 993}