[Pkg-owncloud-commits] [owncloud] 37/90: Add \OC\TempManager to handle creating and cleaning temporary files

David Prévot taffit at moszumanska.debian.org
Fri Feb 6 21:10:46 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository owncloud.

commit 344606b2c80d0384364d0c691aedb45c7476df5c
Author: Robin Appelman <icewind at owncloud.com>
Date:   Wed Oct 22 17:33:36 2014 +0200

    Add \OC\TempManager to handle creating and cleaning temporary files
    
    Conflicts:
    	lib/private/server.php
    	lib/public/iservercontainer.php
---
 lib/private/server.php          |  12 ++++
 lib/private/tempmanager.php     | 146 ++++++++++++++++++++++++++++++++++++++++
 lib/public/iservercontainer.php |   7 ++
 lib/public/itempmanager.php     |  38 +++++++++++
 tests/lib/tempmanager.php       | 143 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 346 insertions(+)

diff --git a/lib/private/server.php b/lib/private/server.php
index adb815c..86c0602 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -210,6 +210,10 @@ class Server extends SimpleContainer implements IServerContainer {
 			$config = $c->query('AllConfig');
 			return new HTTPHelper($config);
 		});
+		$this->registerService('TempManager', function ($c) {
+			/** @var Server $c */
+			return new TempManager(get_temp_dir(), $c->getLogger());
+		});
 	}
 
 	/**
@@ -510,4 +514,12 @@ class Server extends SimpleContainer implements IServerContainer {
 		return $this->query('HTTPHelper');
 	}
 
+	/**
+	 * Get the manager for temporary files and folders
+	 *
+	 * @return \OCP\ITempManager
+	 */
+	function getTempManager() {
+		return $this->query('TempManager');
+	}
 }
diff --git a/lib/private/tempmanager.php b/lib/private/tempmanager.php
new file mode 100644
index 0000000..a3bb07f
--- /dev/null
+++ b/lib/private/tempmanager.php
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC;
+
+use OCP\ILogger;
+use OCP\ITempManager;
+
+class TempManager implements ITempManager {
+	/**
+	 * Current temporary files and folders
+	 *
+	 * @var string[]
+	 */
+	protected $current = array();
+
+	/**
+	 * i.e. /tmp on linux systems
+	 *
+	 * @var string
+	 */
+	protected $tmpBaseDir;
+
+	/**
+	 * @var \OCP\ILogger
+	 */
+	protected $log;
+
+	/**
+	 * @param string $baseDir
+	 * @param \OCP\ILogger $logger
+	 */
+	public function __construct($baseDir, ILogger $logger) {
+		$this->tmpBaseDir = $baseDir;
+		$this->log = $logger;
+	}
+
+	protected function generatePath($postFix) {
+		return $this->tmpBaseDir . '/oc_tmp_' . md5(time() . rand()) . $postFix;
+	}
+
+	/**
+	 * Create a temporary file and return the path
+	 *
+	 * @param string $postFix
+	 * @return string
+	 */
+	public function getTemporaryFile($postFix = '') {
+		$file = $this->generatePath($postFix);
+		if (is_writable($this->tmpBaseDir)) {
+			touch($file);
+			$this->current[] = $file;
+			return $file;
+		} else {
+			$this->log->warning(
+				'Can not create a temporary file in directory {dir}. Check it exists and has correct permissions',
+				array(
+					'dir' => $this->tmpBaseDir
+				)
+			);
+			return false;
+		}
+	}
+
+	/**
+	 * Create a temporary folder and return the path
+	 *
+	 * @param string $postFix
+	 * @return string
+	 */
+	public function getTemporaryFolder($postFix = '') {
+		$path = $this->generatePath($postFix);
+		if (is_writable($this->tmpBaseDir)) {
+			mkdir($path);
+			$this->current[] = $path;
+			return $path . '/';
+		} else {
+			$this->log->warning(
+				'Can not create a temporary folder in directory {dir}. Check it exists and has correct permissions',
+				array(
+					'dir' => $this->tmpBaseDir
+				)
+			);
+			return false;
+		}
+	}
+
+	/**
+	 * Remove the temporary files and folders generated during this request
+	 */
+	public function clean() {
+		$this->cleanFiles($this->current);
+	}
+
+	protected function cleanFiles($files) {
+		foreach ($files as $file) {
+			if (file_exists($file)) {
+				try {
+					\OC_Helper::rmdirr($file);
+				} catch (\UnexpectedValueException $ex) {
+					$this->log->warning(
+						"Error deleting temporary file/folder: {file} - Reason: {error}",
+						array(
+							'file' => $file,
+							'error' => $ex->getMessage()
+						)
+					);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Remove old temporary files and folders that were failed to be cleaned
+	 */
+	public function cleanOld() {
+		$this->cleanFiles($this->getOldFiles());
+	}
+
+	/**
+	 * Get all temporary files and folders generated by oc older than an hour
+	 *
+	 * @return string[]
+	 */
+	protected function getOldFiles() {
+		$cutOfTime = time() - 3600;
+		$files = array();
+		$dh = opendir($this->tmpBaseDir);
+		while (($file = readdir($dh)) !== false) {
+			if (substr($file, 0, 7) === 'oc_tmp_') {
+				$path = $this->tmpBaseDir . '/' . $file;
+				$mtime = filemtime($path);
+				if ($mtime < $cutOfTime) {
+					$files[] = $path;
+				}
+			}
+		}
+		return $files;
+	}
+}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index d1d6487..f9adc46 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -232,4 +232,11 @@ interface IServerContainer {
 	 * @return \OC\HTTPHelper
 	 */
 	function getHTTPHelper();
+
+	/**
+	 * Get the manager for temporary files and folders
+	 *
+	 * @return \OCP\ITempManager
+	 */
+	function getTempManager();
 }
diff --git a/lib/public/itempmanager.php b/lib/public/itempmanager.php
new file mode 100644
index 0000000..ebd9497
--- /dev/null
+++ b/lib/public/itempmanager.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP;
+
+interface ITempManager {
+	/**
+	 * Create a temporary file and return the path
+	 *
+	 * @param string $postFix
+	 * @return string
+	 */
+	public function getTemporaryFile($postFix = '');
+
+	/**
+	 * Create a temporary folder and return the path
+	 *
+	 * @param string $postFix
+	 * @return string
+	 */
+	public function getTemporaryFolder($postFix = '');
+
+	/**
+	 * Remove the temporary files and folders generated during this request
+	 */
+	public function clean();
+
+	/**
+	 * Remove old temporary files and folders that were failed to be cleaned
+	 */
+	public function cleanOld();
+}
diff --git a/tests/lib/tempmanager.php b/tests/lib/tempmanager.php
new file mode 100644
index 0000000..f16fbce
--- /dev/null
+++ b/tests/lib/tempmanager.php
@@ -0,0 +1,143 @@
+<?php
+
+/**
+ * Copyright (c) 2014 Robin Appelman <icewind at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test;
+
+use OC\Log;
+
+class NullLogger extends Log {
+	public function __construct($logger = null) {
+		//disable original constructor
+	}
+
+	public function log($level, $message, array $context = array()) {
+		//noop
+	}
+}
+
+class TempManager extends \PHPUnit_Framework_TestCase {
+	protected $baseDir;
+
+	public function setUp() {
+		$this->baseDir = get_temp_dir() . '/oc_tmp_test';
+		if (!is_dir($this->baseDir)) {
+			mkdir($this->baseDir);
+		}
+	}
+
+	public function tearDown() {
+		\OC_Helper::rmdirr($this->baseDir);
+	}
+
+	/**
+	 * @param \Psr\Log\LoggerInterface $logger
+	 * @return \OC\TempManager
+	 */
+	protected function getManager($logger = null) {
+		if (!$logger) {
+			$logger = new NullLogger();
+		}
+		return new \OC\TempManager($this->baseDir, $logger);
+	}
+
+	public function testGetFile() {
+		$manager = $this->getManager();
+		$file = $manager->getTemporaryFile('.txt');
+		$this->assertStringEndsWith('.txt', $file);
+		$this->assertTrue(is_file($file));
+		$this->assertTrue(is_writable($file));
+
+		file_put_contents($file, 'bar');
+		$this->assertEquals('bar', file_get_contents($file));
+	}
+
+	public function testGetFolder() {
+		$manager = $this->getManager();
+		$folder = $manager->getTemporaryFolder();
+		$this->assertStringEndsWith('/', $folder);
+		$this->assertTrue(is_dir($folder));
+		$this->assertTrue(is_writable($folder));
+
+		file_put_contents($folder . 'foo.txt', 'bar');
+		$this->assertEquals('bar', file_get_contents($folder . 'foo.txt'));
+	}
+
+	public function testCleanFiles() {
+		$manager = $this->getManager();
+		$file1 = $manager->getTemporaryFile('.txt');
+		$file2 = $manager->getTemporaryFile('.txt');
+		$this->assertTrue(file_exists($file1));
+		$this->assertTrue(file_exists($file2));
+
+		$manager->clean();
+
+		$this->assertFalse(file_exists($file1));
+		$this->assertFalse(file_exists($file2));
+	}
+
+	public function testCleanFolder() {
+		$manager = $this->getManager();
+		$folder1 = $manager->getTemporaryFolder();
+		$folder2 = $manager->getTemporaryFolder();
+		touch($folder1 . 'foo.txt');
+		touch($folder1 . 'bar.txt');
+		$this->assertTrue(file_exists($folder1));
+		$this->assertTrue(file_exists($folder2));
+		$this->assertTrue(file_exists($folder1 . 'foo.txt'));
+		$this->assertTrue(file_exists($folder1 . 'bar.txt'));
+
+		$manager->clean();
+
+		$this->assertFalse(file_exists($folder1));
+		$this->assertFalse(file_exists($folder2));
+		$this->assertFalse(file_exists($folder1 . 'foo.txt'));
+		$this->assertFalse(file_exists($folder1 . 'bar.txt'));
+	}
+
+	public function testCleanOld() {
+		$manager = $this->getManager();
+		$oldFile = $manager->getTemporaryFile('.txt');
+		$newFile = $manager->getTemporaryFile('.txt');
+		$folder = $manager->getTemporaryFolder();
+		$nonOcFile = $this->baseDir . '/foo.txt';
+		file_put_contents($nonOcFile, 'bar');
+
+		$past = time() - 2 * 3600;
+		touch($oldFile, $past);
+		touch($folder, $past);
+		touch($nonOcFile, $past);
+
+		$manager2 = $this->getManager();
+		$manager2->cleanOld();
+		$this->assertFalse(file_exists($oldFile));
+		$this->assertFalse(file_exists($folder));
+		$this->assertTrue(file_exists($nonOcFile));
+		$this->assertTrue(file_exists($newFile));
+	}
+
+	public function testLogCantCreateFile() {
+		$logger = $this->getMock('\Test\NullLogger');
+		$manager = $this->getManager($logger);
+		chmod($this->baseDir, 0500);
+		$logger->expects($this->once())
+			->method('warning')
+			->with($this->stringContains('Can not create a temporary file in directory'));
+		$this->assertFalse($manager->getTemporaryFile('.txt'));
+	}
+
+	public function testLogCantCreateFolder() {
+		$logger = $this->getMock('\Test\NullLogger');
+		$manager = $this->getManager($logger);
+		chmod($this->baseDir, 0500);
+		$logger->expects($this->once())
+			->method('warning')
+			->with($this->stringContains('Can not create a temporary folder in directory'));
+		$this->assertFalse($manager->getTemporaryFolder());
+	}
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list