aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_versioning/versionstorage.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_versioning/versionstorage.php')
-rw-r--r--apps/files_versioning/versionstorage.php386
1 files changed, 0 insertions, 386 deletions
diff --git a/apps/files_versioning/versionstorage.php b/apps/files_versioning/versionstorage.php
deleted file mode 100644
index d083e623df9..00000000000
--- a/apps/files_versioning/versionstorage.php
+++ /dev/null
@@ -1,386 +0,0 @@
-<?php
-/**
- * ownCloud file storage implementation for Git repositories
- * @author Craig Roberts
- * @copyright 2012 Craig Roberts craig0990@googlemail.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/>.
- */
-
-// Include Granite
-require_once('lib_granite.php');
-
-// Create a top-level 'Backup' directory if it does not already exist
-$user = OC_User::getUser();
-if (OC_Filesystem::$loaded and !OC_Filesystem::is_dir('/Backup')) {
- OC_Filesystem::mkdir('/Backup');
- OC_Preferences::setValue(OC_User::getUser(), 'files_versioning', 'head', 'HEAD');
-}
-
-// Generate the repository path (currently using 'full' repositories, as opposed to bare ones)
-$repo_path = DIRECTORY_SEPARATOR
- . OC_User::getUser()
- . DIRECTORY_SEPARATOR
- . 'files'
- . DIRECTORY_SEPARATOR
- . 'Backup';
-
-// Mount the 'Backup' folder using the versioned storage provider below
-OC_Filesystem::mount('OC_Filestorage_Versioned', array('repo'=>$repo_path), $repo_path . DIRECTORY_SEPARATOR);
-
-class OC_Filestorage_Versioned extends OC_Filestorage {
-
- /**
- * Holds an instance of Granite\Git\Repository
- */
- protected $repo;
-
- /**
- * Constructs a new OC_Filestorage_Versioned instance, expects an associative
- * array with a `repo` key set to the path of the repository's `.git` folder
- *
- * @param array $parameters An array containing the key `repo` pointing to the
- * repository path.
- */
- public function __construct($parameters) {
- // Get the full path to the repository folder
- $path = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data')
- . $parameters['repo']
- . DIRECTORY_SEPARATOR
- . '.git'
- . DIRECTORY_SEPARATOR;
-
- try {
- // Attempt to load the repository
- $this->repo = new Granite\Git\Repository($path);
- } catch (InvalidArgumentException $e) {
- // $path is not a valid Git repository, we must create one
- Granite\Git\Repository::init($path);
-
- // Load the newly-initialised repository
- $this->repo = new Granite\Git\Repository($path);
-
- /**
- * Create an initial commit with a README file
- * FIXME: This functionality should be transferred to the Granite library
- */
- $blob = new Granite\Git\Blob($this->repo->path());
- $blob->content('Your Backup directory is now ready for use.');
-
- // Create a new tree to hold the README file
- $tree = $this->repo->factory('tree');
- // Create a tree node to represent the README blob
- $tree_node = new Granite\Git\Tree\Node('README', '100644', $blob->sha());
- $tree->nodes(array($tree_node->name() => $tree_node));
-
- // Create an initial commit
- $commit = new Granite\Git\Commit($this->repo->path());
- $user_string = OC_User::getUser() . ' ' . time() . ' +0000';
- $commit->author($user_string);
- $commit->committer($user_string);
- $commit->message('Initial commit');
- $commit->tree($tree);
-
- // Write it all to disk
- $blob->write();
- $tree->write();
- $commit->write();
-
- // Update the HEAD for the 'master' branch
- $this->repo->head('master', $commit->sha());
- }
-
- // Update the class pointer to the HEAD
- $head = OC_Preferences::getValue(OC_User::getUser(), 'files_versioning', 'head', 'HEAD');
-
- // Load the most recent commit if the preference is not set
- if ($head == 'HEAD') {
- $this->head = $this->repo->head()->sha();
- } else {
- $this->head = $head;
- }
- }
-
- public function mkdir($path) {
- if (mkdir("versioned:/{$this->repo->path()}$path#{$this->head}")) {
- $this->head = $this->repo->head()->sha();
- OC_Preferences::setValue(OC_User::getUser(), 'files_versioning', 'head', $head);
- return true;
- }
-
- return false;
- }
-
- public function rmdir($path) {
-
- }
-
- /**
- * Returns a directory handle to the requested path, or FALSE on failure
- *
- * @param string $path The directory path to open
- *
- * @return boolean|resource A directory handle, or FALSE on failure
- */
- public function opendir($path) {
- return opendir("versioned:/{$this->repo->path()}$path#{$this->head}");
- }
-
- /**
- * Returns TRUE if $path is a directory, or FALSE if not
- *
- * @param string $path The path to check
- *
- * @return boolean
- */
- public function is_dir($path) {
- return $this->filetype($path) == 'dir';
- }
-
- /**
- * Returns TRUE if $path is a file, or FALSE if not
- *
- * @param string $path The path to check
- *
- * @return boolean
- */
- public function is_file($path) {
- return $this->filetype($path) == 'file';
- }
-
- public function stat($path)
- {
- return stat("versioned:/{$this->repo->path()}$path#{$this->head}");
- }
-
- /**
- * Returns the strings 'dir' or 'file', depending on the type of $path
- *
- * @param string $path The path to check
- *
- * @return string Returns 'dir' if a directory, 'file' otherwise
- */
- public function filetype($path) {
- if ($path == "" || $path == "/") {
- return 'dir';
- } else {
- if (substr($path, -1) == '/') {
- $path = substr($path, 0, -1);
- }
-
- $node = $this->tree_search($this->repo, $this->repo->factory('commit', $this->head)->tree(), $path);
-
- // Does it exist, or is it new?
- if ($node == null) {
- // New file
- return 'file';
- } else {
- // Is it a tree?
- try {
- $this->repo->factory('tree', $node);
- return 'dir';
- } catch (InvalidArgumentException $e) {
- // Nope, must be a blob
- return 'file';
- }
- }
- }
- }
-
- public function filesize($path) {
- return filesize("versioned:/{$this->repo->path()}$path#{$this->head}");
- }
-
- /**
- * Returns a boolean value representing whether $path is readable
- *
- * @param string $path The path to check
- *(
- * @return boolean Whether or not the path is readable
- */
- public function is_readable($path) {
- return true;
- }
-
- /**
- * Returns a boolean value representing whether $path is writable
- *
- * @param string $path The path to check
- *(
- * @return boolean Whether or not the path is writable
- */
- public function is_writable($path) {
-
- $head = OC_Preferences::getValue(OC_User::getUser(), 'files_versioning', 'head', 'HEAD');
- if ($head !== 'HEAD' && $head !== $this->repo->head()->sha()) {
- // Cannot modify previous commits
- return false;
- }
- return true;
- }
-
- /**
- * Returns a boolean value representing whether $path exists
- *
- * @param string $path The path to check
- *(
- * @return boolean Whether or not the path exists
- */
- public function file_exists($path) {
- return file_exists("versioned:/{$this->repo->path()}$path#{$this->head}");
- }
-
- /**
- * Returns an integer value representing the inode change time
- * (NOT IMPLEMENTED)
- *
- * @param string $path The path to check
- *(
- * @return int Timestamp of the last inode change
- */
- public function filectime($path) {
- return -1;
- }
-
- /**
- * Returns an integer value representing the file modification time
- *
- * @param string $path The path to check
- *(
- * @return int Timestamp of the last file modification
- */
- public function filemtime($path) {
- return filemtime("versioned:/{$this->repo->path()}$path#{$this->head}");
- }
-
- public function file_get_contents($path) {
- return file_get_contents("versioned:/{$this->repo->path()}$path#{$this->head}");
- }
-
- public function file_put_contents($path, $data) {
- $success = file_put_contents("versioned:/{$this->repo->path()}$path#{$this->head}", $data);
- if ($success !== false) {
- // Update the HEAD in the preferences
- OC_Preferences::setValue(OC_User::getUser(), 'files_versioning', 'head', $this->repo->head()->sha());
- return $success;
- }
-
- return false;
- }
-
- public function unlink($path) {
-
- }
-
- public function rename($path1, $path2) {
-
- }
-
- public function copy($path1, $path2) {
-
- }
-
- public function fopen($path, $mode) {
- return fopen("versioned:/{$this->repo->path()}$path#{$this->head}", $mode);
- }
-
- public function getMimeType($path) {
- if ($this->filetype($path) == 'dir') {
- return 'httpd/unix-directory';
- } elseif ($this->filesize($path) == 0) {
- // File's empty, returning text/plain allows opening in the web editor
- return 'text/plain';
- } else {
- $finfo = new finfo(FILEINFO_MIME_TYPE);
- /**
- * We need to represent the repository path, the file path, and the
- * revision, which can be simply achieved with a convention of using
- * `.git` in the repository directory (bare or not) and the '#part'
- * segment of a URL to specify the revision. For example
- *
- * versioned://var/www/myrepo.git/docs/README.md#HEAD ('bare' repo)
- * versioned://var/www/myrepo/.git/docs/README.md#HEAD ('full' repo)
- * versioned://var/www/myrepo/.git/docs/README.md#6a8f...8a54 ('full' repo and SHA-1 commit ID)
- */
- $mime = $finfo->buffer(file_get_contents("versioned:/{$this->repo->path()}$path#{$this->head}"));
- return $mime;
- }
- }
-
- /**
- * Generates a hash based on the file contents
- *
- * @param string $type The hashing algorithm to use (e.g. 'md5', 'sha256', etc.)
- * @param string $path The file to be hashed
- * @param boolean $raw Outputs binary data if true, lowercase hex digits otherwise
- *
- * @return string Hashed string representing the file contents
- */
- public function hash($type, $path, $raw) {
- return hash($type, file_get_contents($path), $raw);
- }
-
- public function free_space($path) {
- }
-
- public function search($query) {
-
- }
-
- public function touch($path, $mtime=null) {
-
- }
-
-
- public function getLocalFile($path) {
- }
-
- /**
- * Recursively searches a tree for a path, returning FALSE if is not found
- * or an SHA-1 id if it is found.
- *
- * @param string $repo The repository containing the tree object
- * @param string $tree The tree object to search
- * @param string $path The path to search for (relative to the tree)
- * @param int $depth The depth of the current search (for recursion)
- *
- * @return string|boolean The SHA-1 id of the sub-tree
- */
- private function tree_search($repo, $tree, $path, $depth = 0)
- {
- $paths = array_values(explode(DIRECTORY_SEPARATOR, $path));
-
- $current_path = $paths[$depth];
-
- $nodes = $tree->nodes();
- foreach ($nodes as $node) {
- if ($node->name() == $current_path) {
-
- if (count($paths)-1 == $depth) {
- // Stop, found it
- return $node->sha();
- }
-
- // Recurse if necessary
- if ($node->isDirectory()) {
- $tree = $this->repo->factory('tree', $node->sha());
- return $this->tree_search($repo, $tree, $path, $depth + 1);
- }
- }
- }
-
- return false;
- }
-
-}