From bd834220959bf7edcc4cce4bfe6c77e0a4649b8b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Sep 2012 18:30:48 +0200 Subject: [PATCH 001/262] put filestorages in a namespace --- apps/files_encryption/tests/proxy.php | 2 +- apps/files_external/appinfo/app.php | 16 ++--- apps/files_external/lib/amazons3.php | 14 ++-- apps/files_external/lib/config.php | 18 ++--- apps/files_external/lib/dropbox.php | 18 ++--- apps/files_external/lib/ftp.php | 6 +- apps/files_external/lib/google.php | 18 ++--- apps/files_external/lib/smb.php | 4 +- apps/files_external/lib/streamwrapper.php | 5 +- apps/files_external/lib/swift.php | 12 ++-- apps/files_external/lib/webdav.php | 12 ++-- apps/files_external/personal.php | 2 +- apps/files_external/tests/amazons3.php | 2 +- apps/files_external/tests/ftp.php | 2 +- apps/files_external/tests/google.php | 2 +- apps/files_external/tests/smb.php | 2 +- apps/files_external/tests/swift.php | 2 +- apps/files_external/tests/webdav.php | 2 +- apps/files_sharing/appinfo/app.php | 4 +- apps/files_sharing/lib/sharedstorage.php | 68 ++++++++++--------- lib/base.php | 3 + lib/{filestorage => files/storage}/common.php | 44 +++++------- .../storage}/commontest.php | 10 +-- lib/{filestorage => files/storage}/local.php | 17 +++-- .../storage/storage.php} | 28 +++----- lib/files/storage/temporary.php | 26 +++++++ lib/filestorage/temporary.php | 17 ----- lib/filesystem.php | 12 ++-- lib/filesystemview.php | 12 ++-- lib/util.php | 4 +- tests/lib/cache/file.php | 2 +- tests/lib/filestorage.php | 2 +- tests/lib/filestorage/commontest.php | 2 +- tests/lib/filestorage/local.php | 2 +- tests/lib/filesystem.php | 4 +- 35 files changed, 205 insertions(+), 191 deletions(-) rename lib/{filestorage => files/storage}/common.php (83%) rename lib/{filestorage => files/storage}/commontest.php (88%) rename lib/{filestorage => files/storage}/local.php (90%) rename lib/{filestorage.php => files/storage/storage.php} (71%) create mode 100644 lib/files/storage/temporary.php delete mode 100644 lib/filestorage/temporary.php diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index 042011a6c8..d600bbc407 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -30,7 +30,7 @@ class Test_CryptProxy extends UnitTestCase { //set up temporary storage OC_Filesystem::clearMounts(); - OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); + OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); OC_Filesystem::init('/'.$user.'/files'); diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 837d35c9c6..c58cfcd0f5 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -6,14 +6,14 @@ * See the COPYING-README file. */ -OC::$CLASSPATH['OC_FileStorage_StreamWrapper']='apps/files_external/lib/streamwrapper.php'; -OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php'; -OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_external/lib/webdav.php'; -OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php'; -OC::$CLASSPATH['OC_Filestorage_SWIFT']='apps/files_external/lib/swift.php'; -OC::$CLASSPATH['OC_Filestorage_SMB']='apps/files_external/lib/smb.php'; -OC::$CLASSPATH['OC_Filestorage_AmazonS3']='apps/files_external/lib/amazons3.php'; -OC::$CLASSPATH['OC_Filestorage_Dropbox']='apps/files_external/lib/dropbox.php'; +OC::$CLASSPATH['OC\Files\Storage\StreamWrapper']='apps/files_external/lib/streamwrapper.php'; +OC::$CLASSPATH['OC\Files\Storage\FTP']='apps/files_external/lib/ftp.php'; +OC::$CLASSPATH['OC\Files\Storage\DAV']='apps/files_external/lib/webdav.php'; +OC::$CLASSPATH['OC\Files\Storage\Google']='apps/files_external/lib/google.php'; +OC::$CLASSPATH['OC\Files\Storage\SWIFT']='apps/files_external/lib/swift.php'; +OC::$CLASSPATH['OC\Files\Storage\SMB']='apps/files_external/lib/smb.php'; +OC::$CLASSPATH['OC\Files\Storage\AmazonS3']='apps/files_external/lib/amazons3.php'; +OC::$CLASSPATH['OC\Files\Storage\Dropbox']='apps/files_external/lib/dropbox.php'; OC::$CLASSPATH['OC_Mount_Config']='apps/files_external/lib/config.php'; OCP\App::registerAdmin('files_external', 'settings'); diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 41ec3c70b4..a17a70ed38 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -22,7 +22,9 @@ require_once 'aws-sdk/sdk.class.php'; -class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { +namespace OC\Files\Storage; + +class AmazonS3 extends \OC\Files\Storage\Common { private $s3; private $bucket; @@ -33,7 +35,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { // TODO options: storage class, encryption server side, encrypt before upload? public function __construct($params) { - $this->s3 = new AmazonS3(array('key' => $params['key'], 'secret' => $params['secret'])); + $this->s3 = new \AmazonS3(array('key' => $params['key'], 'secret' => $params['secret'])); $this->bucket = $params['bucket']; } @@ -96,7 +98,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { foreach ($response->body->CommonPrefixes as $object) { $files[] = basename($object->Prefix); } - OC_FakeDirStream::$dirs['amazons3'.$path] = $files; + \OC_FakeDirStream::$dirs['amazons3'.$path] = $files; return opendir('fakedir://amazons3'.$path); } return false; @@ -160,7 +162,7 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { switch ($mode) { case 'r': case 'rb': - $tmpFile = OC_Helper::tmpFile(); + $tmpFile = \OC_Helper::tmpFile(); $handle = fopen($tmpFile, 'w'); $response = $this->s3->get_object($this->bucket, $path, array('fileDownload' => $handle)); if ($response->isOK()) { @@ -184,8 +186,8 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { } else { $ext = ''; } - $tmpFile = OC_Helper::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + $tmpFile = \OC_Helper::tmpFile($ext); + \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index eec31ec2ef..db09fbdd82 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -39,14 +39,14 @@ class OC_Mount_Config { */ public static function getBackends() { return array( - 'OC_Filestorage_Local' => array('backend' => 'Local', 'configuration' => array('datadir' => 'Location')), - 'OC_Filestorage_AmazonS3' => array('backend' => 'Amazon S3', 'configuration' => array('key' => 'Key', 'secret' => '*Secret', 'bucket' => 'Bucket')), - 'OC_Filestorage_Dropbox' => array('backend' => 'Dropbox', 'configuration' => array('configured' => '#configured','app_key' => 'App key', 'app_secret' => 'App secret', 'token' => '#token', 'token_secret' => '#token_secret'), 'custom' => 'dropbox'), - 'OC_Filestorage_FTP' => array('backend' => 'FTP', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure ftps://')), - 'OC_Filestorage_Google' => array('backend' => 'Google Drive', 'configuration' => array('configured' => '#configured', 'token' => '#token', 'token_secret' => '#token secret'), 'custom' => 'google'), - 'OC_Filestorage_SWIFT' => array('backend' => 'OpenStack Swift', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'token' => '*Token', 'root' => '&Root', 'secure' => '!Secure ftps://')), - 'OC_Filestorage_SMB' => array('backend' => 'SMB', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'share' => 'Share', 'root' => '&Root')), - 'OC_Filestorage_DAV' => array('backend' => 'WebDAV', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure https://')) + '\OC\Files\Storage\Local' => array('backend' => 'Local', 'configuration' => array('datadir' => 'Location')), + '\OC\Files\Storage\AmazonS3' => array('backend' => 'Amazon S3', 'configuration' => array('key' => 'Key', 'secret' => '*Secret', 'bucket' => 'Bucket')), + '\OC\Files\Storage\Dropbox' => array('backend' => 'Dropbox', 'configuration' => array('configured' => '#configured','app_key' => 'App key', 'app_secret' => 'App secret', 'token' => '#token', 'token_secret' => '#token_secret'), 'custom' => 'dropbox'), + '\OC\Files\Storage\FTP' => array('backend' => 'FTP', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure ftps://')), + '\OC\Files\Storage\Google' => array('backend' => 'Google Drive', 'configuration' => array('configured' => '#configured', 'token' => '#token', 'token_secret' => '#token secret'), 'custom' => 'google'), + '\OC\Files\Storage\SWIFT' => array('backend' => 'OpenStack Swift', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'token' => '*Token', 'root' => '&Root', 'secure' => '!Secure ftps://')), + '\OC\Files\Storage\SMB' => array('backend' => 'SMB', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'share' => 'Share', 'root' => '&Root')), + '\OC\Files\Storage\DAV' => array('backend' => 'WebDAV', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure https://')) ); } @@ -124,7 +124,7 @@ class OC_Mount_Config { if ($isPersonal) { // Verify that the mount point applies for the current user // Prevent non-admin users from mounting local storage - if ($applicable != OCP\User::getUser() || $class == 'OC_Filestorage_Local') { + if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') { return false; } $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index bb86894e55..746364668f 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -22,7 +22,9 @@ require_once 'Dropbox/autoload.php'; -class OC_Filestorage_Dropbox extends OC_Filestorage_Common { +namespace OC\Files\Storage; + +class Dropbox extends \OC\Files\Storage\Common { private $dropbox; private $metaData = array(); @@ -31,11 +33,11 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { public function __construct($params) { if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['app_key']) && isset($params['app_secret']) && isset($params['token']) && isset($params['token_secret'])) { - $oauth = new Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']); + $oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']); $oauth->setToken($params['token'], $params['token_secret']); - $this->dropbox = new Dropbox_API($oauth, 'dropbox'); + $this->dropbox = new \Dropbox_API($oauth, 'dropbox'); } else { - throw new Exception('Creating OC_Filestorage_Dropbox storage failed'); + throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed'); } } @@ -95,7 +97,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { foreach ($contents as $file) { $files[] = basename($file['path']); } - OC_FakeDirStream::$dirs['dropbox'.$path] = $files; + \OC_FakeDirStream::$dirs['dropbox'.$path] = $files; return opendir('fakedir://dropbox'.$path); } return false; @@ -177,7 +179,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { switch ($mode) { case 'r': case 'rb': - $tmpFile = OC_Helper::tmpFile(); + $tmpFile = \OC_Helper::tmpFile(); try { $data = $this->dropbox->getFile($path); file_put_contents($tmpFile, $data); @@ -203,8 +205,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { } else { $ext = ''; } - $tmpFile = OC_Helper::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + $tmpFile = \OC_Helper::tmpFile($ext); + \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 261141455c..140a21ffe1 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -6,7 +6,9 @@ * See the COPYING-README file. */ -class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{ +namespace OC\Files\Storage; + +class FTP extends \OC\Files\Storage\StreamWrapper{ private $password; private $user; private $host; @@ -69,7 +71,7 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); + \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); if($this->file_exists($path)) { $this->getFile($path,$tmpFile); } diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 9b83dcee53..51c5d219aa 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -22,7 +22,9 @@ require_once 'Google/common.inc.php'; -class OC_Filestorage_Google extends OC_Filestorage_Common { +namespace OC\Files\Storage; + +class Google extends \OC\Files\Storage\Common { private $consumer; private $oauth_token; @@ -35,12 +37,12 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['token']) && isset($params['token_secret'])) { $consumer_key = isset($params['consumer_key']) ? $params['consumer_key'] : 'anonymous'; $consumer_secret = isset($params['consumer_secret']) ? $params['consumer_secret'] : 'anonymous'; - $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); - $this->oauth_token = new OAuthToken($params['token'], $params['token_secret']); - $this->sig_method = new OAuthSignatureMethod_HMAC_SHA1(); + $this->consumer = new \OAuthConsumer($consumer_key, $consumer_secret); + $this->oauth_token = new \OAuthToken($params['token'], $params['token_secret']); + $this->sig_method = new \OAuthSignatureMethod_HMAC_SHA1(); $this->entries = array(); } else { - throw new Exception('Creating OC_Filestorage_Google storage failed'); + throw new \Exception('Creating \OC\Files\Storage\Google storage failed'); } } @@ -96,7 +98,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); } if ($isDownload) { - $tmpFile = OC_Helper::tmpFile(); + $tmpFile = \OC_Helper::tmpFile(); $handle = fopen($tmpFile, 'w'); curl_setopt($curl, CURLOPT_FILE, $handle); } @@ -399,7 +401,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } else { $ext = ''; } - $tmpFile = OC_Helper::tmpFile($ext); + $tmpFile = \OC_Helper::tmpFile($ext); OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); @@ -438,7 +440,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { } if (isset($uploadUri) && $handle = fopen($path, 'r')) { $uploadUri .= '?convert=false'; - $mimetype = OC_Helper::getMimeType($path); + $mimetype = \OC_Helper::getMimeType($path); $size = filesize($path); $headers = array('X-Upload-Content-Type: ' => $mimetype, 'X-Upload-Content-Length: ' => $size); $postData = ''; diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index e5ba7a1774..d4882ed024 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -8,7 +8,9 @@ require_once 'smb4php/smb.php'; -class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{ +namespace OC\Files\Storage; + +class SMB extends \OC\Files\Storage\StreamWrapper{ private $password; private $user; private $host; diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index 7263ef2325..750bdbaf4d 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -6,8 +6,9 @@ * See the COPYING-README file. */ +namespace OC\Files\Storage; -abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{ +abstract class StreamWrapper extends \OC\Files\Storage\Common{ abstract public function constructUrl($path); public function mkdir($path) { @@ -84,6 +85,4 @@ abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{ return stat($this->constructUrl($path)); } - - } diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index c29d28b44c..c67cf59df6 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -8,7 +8,9 @@ require_once 'php-cloudfiles/cloudfiles.php'; -class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ +namespace OC\Files\Storage; + +class SWIFT extends \OC\Files\Storage\Common{ private $host; private $root; private $user; @@ -272,10 +274,10 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } - $this->auth = new CF_Authentication($this->user, $this->token, null, $this->host); + $this->auth = new \CF_Authentication($this->user, $this->token, null, $this->host); $this->auth->authenticate(); - $this->conn = new CF_Connection($this->auth); + $this->conn = new \CF_Connection($this->auth); if(!$this->containerExists($this->root)) { $this->rootContainer=$this->createContainer('/'); @@ -341,7 +343,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ $subContainers=$this->getSubContainers($container); $files=array_merge($files,$subContainers); $id=$this->getContainerName($path); - OC_FakeDirStream::$dirs[$id]=$files; + \OC_FakeDirStream::$dirs[$id]=$files; return opendir('fakedir://'.$id); } @@ -426,7 +428,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ case 'c': case 'c+': $tmpFile=$this->getTmpFile($path); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); + \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); self::$tempFiles[$tmpFile]=$path; return fopen('close://'.$tmpFile,$mode); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 3c18b227fa..70210b49ee 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -6,7 +6,9 @@ * See the COPYING-README file. */ -class OC_FileStorage_DAV extends OC_Filestorage_Common{ +namespace OC\Files\Storage; + +class DAV extends \OC\Files\Storage\Common{ private $password; private $user; private $host; @@ -42,7 +44,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ 'password' => $this->password, ); - $this->client = new OC_Connector_Sabre_Client($settings); + $this->client = new \OC_Connector_Sabre_Client($settings); if($caview = \OCP\Files::getStorage('files_external')) { $certPath=\OCP\Config::getSystemValue('datadirectory').$caview->getAbsolutePath("").'rootcerts.crt'; @@ -78,12 +80,12 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ try{ $response=$this->client->propfind($path, array(),1); $id=md5('webdav'.$this->root.$path); - OC_FakeDirStream::$dirs[$id]=array(); + \OC_FakeDirStream::$dirs[$id]=array(); $files=array_keys($response); array_shift($files);//the first entry is the current directory foreach($files as $file) { $file = urldecode(basename($file)); - OC_FakeDirStream::$dirs[$id][]=$file; + \OC_FakeDirStream::$dirs[$id][]=$file; } return opendir('fakedir://'.$id); }catch(Exception $e) { @@ -161,7 +163,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); + \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); if($this->file_exists($path)) { $this->getFile($path,$tmpFile); } diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php index f0d76460f5..a678f345c8 100755 --- a/apps/files_external/personal.php +++ b/apps/files_external/personal.php @@ -24,7 +24,7 @@ OCP\Util::addScript('files_external', 'settings'); OCP\Util::addStyle('files_external', 'settings'); $backends = OC_Mount_Config::getBackends(); // Remove local storage -unset($backends['OC_Filestorage_Local']); +unset($backends['\OC\Files\Storage\Local']); $tmpl = new OCP\Template('files_external', 'settings'); $tmpl->assign('isAdminPage', false, false); $tmpl->assign('mounts', OC_Mount_Config::getPersonalMountPoints()); diff --git a/apps/files_external/tests/amazons3.php b/apps/files_external/tests/amazons3.php index b9b4cf65bd..ad1c453abb 100644 --- a/apps/files_external/tests/amazons3.php +++ b/apps/files_external/tests/amazons3.php @@ -34,7 +34,7 @@ if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['r $id = uniqid(); $this->config = include('apps/files_external/tests/config.php'); $this->config['amazons3']['bucket'] = $id; // Make sure we have a new empty bucket to work in - $this->instance = new OC_Filestorage_AmazonS3($this->config['amazons3']); + $this->instance = new \OC\Files\Storage\AmazonS3($this->config['amazons3']); } public function tearDown() { diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php index 12f3ec3908..105f7b485b 100644 --- a/apps/files_external/tests/ftp.php +++ b/apps/files_external/tests/ftp.php @@ -18,7 +18,7 @@ if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']) { $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $this->config['ftp']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_FTP($this->config['ftp']); + $this->instance=new \OC\Files\Storage\FTP($this->config['ftp']); } public function tearDown() { diff --git a/apps/files_external/tests/google.php b/apps/files_external/tests/google.php index d2a6358ade..e96c2263e1 100644 --- a/apps/files_external/tests/google.php +++ b/apps/files_external/tests/google.php @@ -33,7 +33,7 @@ if(!is_array($config) or !isset($config['google']) or !$config['google']['run']) $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_Google($this->config['google']); + $this->instance=new \OC\Files\Storage\Google($this->config['google']); } public function tearDown() { diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index 7de4fddbb3..a0c5d83473 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -19,7 +19,7 @@ if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) { $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $this->config['smb']['root'].=$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_SMB($this->config['smb']); + $this->instance=new \OC\Files\Storage\SMB($this->config['smb']); } public function tearDown() { diff --git a/apps/files_external/tests/swift.php b/apps/files_external/tests/swift.php index a6f5eace1c..3e1485b0f3 100644 --- a/apps/files_external/tests/swift.php +++ b/apps/files_external/tests/swift.php @@ -18,7 +18,7 @@ if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']) { $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $this->config['swift']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_SWIFT($this->config['swift']); + $this->instance=new \OC\Files\Storage\SWIFT($this->config['swift']); } diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php index 74d980aa3f..6b1121c9d0 100644 --- a/apps/files_external/tests/webdav.php +++ b/apps/files_external/tests/webdav.php @@ -18,7 +18,7 @@ if(!is_array($config) or !isset($config['webdav']) or !$config['webdav']['run']) $id=uniqid(); $this->config=include('apps/files_external/tests/config.php'); $this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_DAV($this->config['webdav']); + $this->instance=new \OC\Files\Storage\DAV($this->config['webdav']); } public function tearDown() { diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 109f86b2e8..210c78ad17 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -2,8 +2,8 @@ OC::$CLASSPATH['OC_Share_Backend_File'] = "apps/files_sharing/lib/share/file.php"; OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'apps/files_sharing/lib/share/folder.php'; -OC::$CLASSPATH['OC_Filestorage_Shared'] = "apps/files_sharing/lib/sharedstorage.php"; -OCP\Util::connectHook('OC_Filesystem', 'setup', 'OC_Filestorage_Shared', 'setup'); +OC::$CLASSPATH['OC\Files\Storage\Shared'] = "apps/files_sharing/lib/sharedstorage.php"; +OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); OCP\Util::addScript('files_sharing', 'share'); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 6dba76955a..f1539610b0 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -20,10 +20,12 @@ * */ +namespace OC\Files\Storage; + /** * Convert target path to source path and pass the function call to the correct storage provider */ -class OC_Filestorage_Shared extends OC_Filestorage_Common { +class Shared extends \OC\Files\Storage\Common { private $sharedFolder; private $files = array(); @@ -50,7 +52,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if (isset($this->files[$folder])) { $file = $this->files[$folder]; } else { - $file = OCP\Share::getItemSharedWith('folder', $folder, OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $file = OCP\Share::getItemSharedWith('folder', $folder, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); } if ($file) { $this->files[$target]['path'] = $file['path'].substr($target, strlen($folder)); @@ -58,7 +60,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { return $this->files[$target]; } } else { - $file = OCP\Share::getItemSharedWith('file', $target, OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $file = OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); if ($file) { $this->files[$target] = $file; return $this->files[$target]; @@ -78,7 +80,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $file = $this->getFile($target); if (isset($file['path'])) { $uid = substr($file['path'], 1, strpos($file['path'], '/', 1) - 1); - OC_Filesystem::mount('OC_Filestorage_Local', array('datadir' => OC_User::getHome($uid)), $uid); + \OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); return $file['path']; } return false; @@ -103,7 +105,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { * @return Source file path with mount point stripped out */ private function getInternalPath($path) { - $mountPoint = OC_Filesystem::getMountPoint($path); + $mountPoint = \OC_Filesystem::getMountPoint($path); $internalPath = substr($path, strlen($mountPoint)); return $internalPath; } @@ -112,7 +114,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->mkdir($this->getInternalPath($source)); } return false; @@ -120,7 +122,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->rmdir($this->getInternalPath($source)); } return false; @@ -128,11 +130,11 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function opendir($path) { if ($path == '' || $path == '/') { - $files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_Folder::FORMAT_OPENDIR); - OC_FakeDirStream::$dirs['shared'] = $files; + $files = OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); + \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->opendir($this->getInternalPath($source)); } return false; @@ -142,7 +144,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->is_dir($this->getInternalPath($source)); } return false; @@ -150,7 +152,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function is_file($path) { if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->is_file($this->getInternalPath($source)); } return false; @@ -163,7 +165,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->stat($this->getInternalPath($source)); } return false; @@ -173,7 +175,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->filetype($this->getInternalPath($source)); } return false; @@ -183,7 +185,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->filesize($this->getInternalPath($source)); } return false; @@ -225,7 +227,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->file_exists($this->getInternalPath($source)); } return false; @@ -246,7 +248,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->filectime($this->getInternalPath($source)); } } @@ -267,7 +269,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->filemtime($this->getInternalPath($source)); } } @@ -280,8 +282,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { 'target' => $this->sharedFolder.$path, 'source' => $source, ); - OCP\Util::emitHook('OC_Filestorage_Shared', 'file_get_contents', $info); - $storage = OC_Filesystem::getStorage($source); + OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); + $storage = \OC_Filesystem::getStorage($source); return $storage->file_get_contents($this->getInternalPath($source)); } } @@ -296,8 +298,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { 'target' => $this->sharedFolder.$path, 'source' => $source, ); - OCP\Util::emitHook('OC_Filestorage_Shared', 'file_put_contents', $info); - $storage = OC_Filesystem::getStorage($source); + OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); + $storage = \OC_Filesystem::getStorage($source); $result = $storage->file_put_contents($this->getInternalPath($source), $data); return $result; } @@ -308,7 +310,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->unlink($this->getInternalPath($source)); } else if (dirname($path) == '/' || dirname($path) == '.') { // Unshare the file from the user if in the root of the Shared folder @@ -332,7 +334,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - $storage = OC_Filesystem::getStorage($oldSource); + $storage = \OC_Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } else { @@ -347,7 +349,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { return $this->unlink($path1); } } else { - $storage = OC_Filesystem::getStorage($oldSource); + $storage = \OC_Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } @@ -361,7 +363,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($this->isCreatable(dirname($path2))) { $source = $this->fopen($path1, 'r'); $target = $this->fopen($path2, 'w'); - return OC_Helper::streamCopy($source, $target); + return \OC_Helper::streamCopy($source, $target); } return false; } @@ -392,8 +394,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { 'source' => $source, 'mode' => $mode, ); - OCP\Util::emitHook('OC_Filestorage_Shared', 'fopen', $info); - $storage = OC_Filesystem::getStorage($source); + OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); + $storage = \OC_Filesystem::getStorage($source); return $storage->fopen($this->getInternalPath($source), $mode); } return false; @@ -404,7 +406,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->getMimeType($this->getInternalPath($source)); } return false; @@ -413,21 +415,21 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->free_space($this->getInternalPath($source)); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->getLocalFile($this->getInternalPath($source)); } return false; } public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { - $storage = OC_Filesystem::getStorage($source); + $storage = \OC_Filesystem::getStorage($source); return $storage->touch($this->getInternalPath($source), $mtime); } return false; @@ -435,7 +437,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public static function setup($options) { $user_dir = $options['user_dir']; - OC_Filesystem::mount('OC_Filestorage_Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); + \OC_Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } /** diff --git a/lib/base.php b/lib/base.php index 1c6cc70b0e..3b2ab8d5eb 100644 --- a/lib/base.php +++ b/lib/base.php @@ -81,6 +81,9 @@ class OC{ elseif(strpos($className, 'OC_')===0) { $path = strtolower(str_replace('_', '/', substr($className, 3)) . '.php'); } + elseif(strpos($className, 'OC\\')===0) { + $path = strtolower(str_replace('\\', '/', substr($className, 3)) . '.php'); + } elseif(strpos($className, 'OCP\\')===0) { $path = 'public/'.strtolower(str_replace('\\', '/', substr($className, 3)) . '.php'); } diff --git a/lib/filestorage/common.php b/lib/files/storage/common.php similarity index 83% rename from lib/filestorage/common.php rename to lib/files/storage/common.php index 351714437c..0a60ff757e 100644 --- a/lib/filestorage/common.php +++ b/lib/files/storage/common.php @@ -1,38 +1,26 @@ . -*/ + * Copyright (c) 2012 Robin Appelman + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; /** * Storage backend class for providing common filesystem operation methods * which are not storage-backend specific. * - * OC_Filestorage_Common is never used directly; it is extended by all other + * \OC\Files\Storage\Common is never used directly; it is extended by all other * storage backends, where its methods may be overridden, and additional * (backend-specific) methods are defined. * - * Some OC_Filestorage_Common methods call functions which are first defined + * Some \OC\Files\Storage\Common methods call functions which are first defined * in classes which extend it, e.g. $this->stat() . */ -abstract class OC_Filestorage_Common extends OC_Filestorage { +abstract class Common extends \OC\Files\Storage\Storage { public function __construct($parameters) {} // abstract public function mkdir($path); @@ -104,7 +92,7 @@ abstract class OC_Filestorage_Common extends OC_Filestorage { public function copy($path1,$path2) { $source=$this->fopen($path1,'r'); $target=$this->fopen($path2,'w'); - $count=OC_Helper::streamCopy($source,$target); + $count=\OC_Helper::streamCopy($source,$target); return $count>0; } // abstract public function fopen($path,$mode); @@ -198,9 +186,9 @@ abstract class OC_Filestorage_Common extends OC_Filestorage { }else{ $extension=''; } - $tmpFile=OC_Helper::tmpFile($extension); + $tmpFile=\OC_Helper::tmpFile($extension); file_put_contents($tmpFile,$head); - $mime=OC_Helper::getMimeType($tmpFile); + $mime=\OC_Helper::getMimeType($tmpFile); unlink($tmpFile); return $mime; } @@ -227,13 +215,13 @@ abstract class OC_Filestorage_Common extends OC_Filestorage { }else{ $extension=''; } - $tmpFile=OC_Helper::tmpFile($extension); + $tmpFile=\OC_Helper::tmpFile($extension); $target=fopen($tmpFile,'w'); - OC_Helper::streamCopy($source,$target); + \OC_Helper::streamCopy($source,$target); return $tmpFile; } public function getLocalFolder($path) { - $baseDir=OC_Helper::tmpFolder(); + $baseDir=\OC_Helper::tmpFolder(); $this->addLocalFolder($path,$baseDir); return $baseDir; } diff --git a/lib/filestorage/commontest.php b/lib/files/storage/commontest.php similarity index 88% rename from lib/filestorage/commontest.php rename to lib/files/storage/commontest.php index b88bb232c3..773bfffcb4 100644 --- a/lib/filestorage/commontest.php +++ b/lib/files/storage/commontest.php @@ -22,18 +22,20 @@ */ /** - * test implementation for OC_FileStorage_Common with OC_FileStorage_Local + * test implementation for \OC\Files\Storage\Common with \OC\Files\Storage\Local */ -class OC_Filestorage_CommonTest extends OC_Filestorage_Common{ +namespace OC\Files\Storage; + +class CommonTest extends \OC\Files\Storage\Common{ /** * underlying local storage used for missing functions - * @var OC_FileStorage_Local + * @var \OC\Files\Storage\Local */ private $storage; public function __construct($params) { - $this->storage=new OC_Filestorage_Local($params); + $this->storage=new \OC\Files\Storage\Local($params); } public function mkdir($path) { diff --git a/lib/filestorage/local.php b/lib/files/storage/local.php similarity index 90% rename from lib/filestorage/local.php rename to lib/files/storage/local.php index e26d3d3ef9..e47441499a 100644 --- a/lib/filestorage/local.php +++ b/lib/files/storage/local.php @@ -1,8 +1,17 @@ + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + /** * for local filestore, we only have to map the paths */ -class OC_Filestorage_Local extends OC_Filestorage_Common{ +class Local extends \OC\Files\Storage\Common{ protected $datadir; public function __construct($arguments) { $this->datadir=$arguments['datadir']; @@ -86,11 +95,11 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{ } public function rename($path1,$path2) { if (!$this->isUpdatable($path1)) { - OC_Log::write('core','unable to rename, file is not writable : '.$path1,OC_Log::ERROR); + \OC_Log::write('core','unable to rename, file is not writable : '.$path1,\OC_Log::ERROR); return false; } if(! $this->file_exists($path1)) { - OC_Log::write('core','unable to rename, file does not exists : '.$path1,OC_Log::ERROR); + \OC_Log::write('core','unable to rename, file does not exists : '.$path1,\OC_Log::ERROR); return false; } @@ -129,7 +138,7 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{ public function getMimeType($path) { if($this->isReadable($path)) { - return OC_Helper::getMimeType($this->datadir.$path); + return \OC_Helper::getMimeType($this->datadir.$path); }else{ return false; } diff --git a/lib/filestorage.php b/lib/files/storage/storage.php similarity index 71% rename from lib/filestorage.php rename to lib/files/storage/storage.php index 5bfd09253d..a2f6cb7ec3 100644 --- a/lib/filestorage.php +++ b/lib/files/storage/storage.php @@ -1,29 +1,17 @@ . -*/ + * Copyright (c) 2012 Robin Appelman + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; /** * Provde a common interface to all different storage options */ -abstract class OC_Filestorage{ +abstract class Storage{ abstract public function __construct($parameters); abstract public function mkdir($path); abstract public function rmdir($path); diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php new file mode 100644 index 0000000000..0e69c9112a --- /dev/null +++ b/lib/files/storage/temporary.php @@ -0,0 +1,26 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Storage; + +/** + * local storage backnd in temporary folder for testing purpores + */ +class Temporary extends OC\Files\Storage\Local{ + public function __construct($arguments) { + $this->datadir=\OC_Helper::tmpFolder(); + } + + public function cleanUp() { + \OC_Helper::rmdirr($this->datadir); + } + + public function __destruct() { + $this->cleanUp(); + } +} diff --git a/lib/filestorage/temporary.php b/lib/filestorage/temporary.php deleted file mode 100644 index 876ba045a6..0000000000 --- a/lib/filestorage/temporary.php +++ /dev/null @@ -1,17 +0,0 @@ -datadir=OC_Helper::tmpFolder(); - } - - public function cleanUp() { - OC_Helper::rmdirr($this->datadir); - } - - public function __destruct() { - $this->cleanUp(); - } -} diff --git a/lib/filesystem.php b/lib/filesystem.php index 92eb4fa477..9b022d8fef 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -48,7 +48,7 @@ class OC_Filesystem{ static private $mounts=array(); public static $loaded=false; /** - * @var OC_Filestorage $defaultInstance + * @var \OC\Files\Storage\Storage $defaultInstance */ static private $defaultInstance; @@ -181,7 +181,7 @@ class OC_Filesystem{ /** * get the storage object for a path * @param string path - * @return OC_Filestorage + * @return \OC\Files\Storage\Storage */ static public function getStorage($path) { $mountpoint=self::getMountPoint($path); @@ -276,7 +276,7 @@ class OC_Filesystem{ * create a new storage of a specific type * @param string type * @param array arguments - * @return OC_Filestorage + * @return \OC\Files\Storage\Storage */ static private function createStorage($class,$arguments) { if(class_exists($class)) { @@ -320,9 +320,9 @@ class OC_Filesystem{ } /** - * mount an OC_Filestorage in our virtual filesystem - * @param OC_Filestorage storage - * @param string mountpoint + * mount an \OC\Files\Storage\Storage in our virtual filesystem + * @param \OC\Files\Storage\Storage storage + * @param string mountpoint */ static public function mount($class,$arguments,$mountpoint) { if($mountpoint[0]!='/') { diff --git a/lib/filesystemview.php b/lib/filesystemview.php index 743f940301..36fef48551 100644 --- a/lib/filesystemview.php +++ b/lib/filesystemview.php @@ -35,7 +35,7 @@ * are triggered correctly. * * Filesystem functions are not called directly; they are passed to the correct - * OC_Filestorage object + * \OC\Files\Storage\Storage object */ class OC_FilesystemView { @@ -115,7 +115,7 @@ class OC_FilesystemView { /** * get the storage object for a path * @param string path - * @return OC_Filestorage + * @return \OC\Files\Storage\Storage */ public function getStorage($path) { if (!isset($this->storage_cache[$path])) { @@ -161,7 +161,7 @@ class OC_FilesystemView { /** * the following functions operate with arguments and return values identical * to those of their PHP built-in equivalents. Mostly they are merely wrappers - * for OC_Filestorage via basicOperation(). + * for \OC\Files\Storage\Storage via basicOperation(). */ public function mkdir($path) { return $this->basicOperation('mkdir', $path, array('create', 'write')); @@ -173,7 +173,7 @@ class OC_FilesystemView { return $this->basicOperation('opendir', $path, array('read')); } public function readdir($handle) { - $fsLocal= new OC_Filestorage_Local( array( 'datadir' => '/' ) ); + $fsLocal= new \OC\Files\Storage\Local( array( 'datadir' => '/' ) ); return $fsLocal->readdir( $handle ); } public function is_dir($path) { @@ -540,7 +540,7 @@ class OC_FilesystemView { } /** - * @brief abstraction layer for basic filesystem functions: wrapper for OC_Filestorage + * @brief abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage * @param string $operation * @param string #path * @param array (optional) hooks @@ -549,7 +549,7 @@ class OC_FilesystemView { * * This method takes requests for basic filesystem functions (e.g. reading & writing * files), processes hooks and proxies, sanitises paths, and finally passes them on to - * OC_Filestorage for delegation to a storage backend for execution + * \OC\Files\Storage\Storage for delegation to a storage backend for execution */ private function basicOperation($operation, $path, $hooks=array(), $extraParam=null) { $postFix=(substr($path,-1,1)==='/')?'/':''; diff --git a/lib/util.php b/lib/util.php index 5046550d6a..78976c9660 100755 --- a/lib/util.php +++ b/lib/util.php @@ -34,7 +34,7 @@ class OC_Util { $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); //first set up the local "root" storage if(!self::$rootMounted) { - OC_Filesystem::mount('OC_Filestorage_Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); + OC_Filesystem::mount('\OC\Files\Storage\Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); self::$rootMounted=true; } @@ -46,7 +46,7 @@ class OC_Util { mkdir( $userdirectory, 0755, true ); } //jail the user into his "home" directory - OC_Filesystem::mount('OC_Filestorage_Local', array('datadir' => $user_root), $user); + OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); OC_Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); OC_FileProxy::register($quotaProxy); diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 00be005d08..1dd1ff7fa8 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -39,7 +39,7 @@ class Test_Cache_File extends Test_Cache { //set up temporary storage OC_Filesystem::clearMounts(); - OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); + OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); OC_User::clearBackends(); OC_User::useBackend(new OC_User_Dummy()); diff --git a/tests/lib/filestorage.php b/tests/lib/filestorage.php index 3f7bb7b62d..bfb40bcd67 100644 --- a/tests/lib/filestorage.php +++ b/tests/lib/filestorage.php @@ -22,7 +22,7 @@ abstract class Test_FileStorage extends UnitTestCase { /** - * @var OC_Filestorage instance + * @var \OC\Files\Storage\Storage instance */ protected $instance; diff --git a/tests/lib/filestorage/commontest.php b/tests/lib/filestorage/commontest.php index 89e83589e5..0e52e91678 100644 --- a/tests/lib/filestorage/commontest.php +++ b/tests/lib/filestorage/commontest.php @@ -30,7 +30,7 @@ class Test_Filestorage_CommonTest extends Test_FileStorage { if(!file_exists($this->tmpDir)) { mkdir($this->tmpDir); } - $this->instance=new OC_Filestorage_CommonTest(array('datadir'=>$this->tmpDir)); + $this->instance=new \OC\Files\Storage\CommonTest(array('datadir'=>$this->tmpDir)); } public function tearDown() { diff --git a/tests/lib/filestorage/local.php b/tests/lib/filestorage/local.php index f68fb69b97..7bb27830ba 100644 --- a/tests/lib/filestorage/local.php +++ b/tests/lib/filestorage/local.php @@ -27,7 +27,7 @@ class Test_Filestorage_Local extends Test_FileStorage { private $tmpDir; public function setUp() { $this->tmpDir=OC_Helper::tmpFolder(); - $this->instance=new OC_Filestorage_Local(array('datadir'=>$this->tmpDir)); + $this->instance=new \OC\Files\Storage\Local(array('datadir'=>$this->tmpDir)); } public function tearDown() { diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index 1cfa35e305..5f5d393ed5 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -46,13 +46,13 @@ class Test_Filesystem extends UnitTestCase{ } public function testMount() { - OC_Filesystem::mount('OC_Filestorage_Local',self::getStorageData(),'/'); + OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); $this->assertEqual('/',OC_Filesystem::getMountPoint('/some/folder')); $this->assertEqual('',OC_Filesystem::getInternalPath('/')); $this->assertEqual('some/folder',OC_Filesystem::getInternalPath('/some/folder')); - OC_Filesystem::mount('OC_Filestorage_Local',self::getStorageData(),'/some'); + OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/folder')); $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/')); From e8d3a4768541980fcc391117e5a173875b2f75e0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Sep 2012 22:50:10 +0200 Subject: [PATCH 002/262] add getId to storage backends --- lib/files/storage/common.php | 1 + lib/files/storage/commontest.php | 3 +++ lib/files/storage/local.php | 3 +++ lib/files/storage/storage.php | 1 + 4 files changed, 8 insertions(+) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 0a60ff757e..1f8b620480 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -23,6 +23,7 @@ namespace OC\Files\Storage; abstract class Common extends \OC\Files\Storage\Storage { public function __construct($parameters) {} +// abstract public function getId(); // abstract public function mkdir($path); // abstract public function rmdir($path); // abstract public function opendir($path); diff --git a/lib/files/storage/commontest.php b/lib/files/storage/commontest.php index 773bfffcb4..2b42cfe115 100644 --- a/lib/files/storage/commontest.php +++ b/lib/files/storage/commontest.php @@ -38,6 +38,9 @@ class CommonTest extends \OC\Files\Storage\Common{ $this->storage=new \OC\Files\Storage\Local($params); } + public function getId(){ + return 'test::'.$this->storage->getId(); + } public function mkdir($path) { return $this->storage->mkdir($path); } diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index e47441499a..78e4877a00 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -19,6 +19,9 @@ class Local extends \OC\Files\Storage\Common{ $this->datadir.='/'; } } + public function getId(){ + return 'local::'.$this->datadir; + } public function mkdir($path) { return @mkdir($this->datadir.$path); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index a2f6cb7ec3..bd4cc4743b 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -13,6 +13,7 @@ namespace OC\Files\Storage; */ abstract class Storage{ abstract public function __construct($parameters); + abstract public function getId(); abstract public function mkdir($path); abstract public function rmdir($path); abstract public function opendir($path); From 68f65b657c398d44508d20b56ccf9ddbee8e3521 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Sep 2012 22:53:10 +0200 Subject: [PATCH 003/262] add OC_Filesystem::resolvePath to get the storage backend and internal path for a file in one go --- lib/filesystem.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/filesystem.php b/lib/filesystem.php index 9b022d8fef..ef8b3fef5b 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -194,6 +194,24 @@ class OC_Filesystem{ } } + /** + * resolve a path to a storage and internal path + * @param string $path + * @return array consisting of the storage and the internal path + */ + static public function resolvePath($path){ + $mountpoint=self::getMountPoint($path); + if($mountpoint) { + if(!isset(OC_Filesystem::$storages[$mountpoint])) { + $mount=OC_Filesystem::$mounts[$mountpoint]; + OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'],$mount['arguments']); + } + $storage = OC_Filesystem::$storages[$mountpoint]; + $internalPath=substr($path,strlen($mountpoint)); + return array($storage, $internalPath); + } + } + static public function init($root) { if(self::$defaultInstance) { return false; From c94fe38d3900acff474c909aaa730d7ab51f914d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 12 Sep 2012 23:25:57 +0200 Subject: [PATCH 004/262] add getPermissions to storage backends to get all permission flags in one go --- lib/files/storage/common.php | 19 +++++++++++++++++++ lib/files/storage/storage.php | 1 + 2 files changed, 20 insertions(+) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 1f8b620480..b2b4ea8eee 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -54,6 +54,25 @@ abstract class Common extends \OC\Files\Storage\Storage { public function isSharable($path) { return $this->isReadable($path); } + public function getPermissions($path){ + $permissions = 0; + if($this->isCreatable($path)){ + $permissions |= OCP\Share::PERMISSION_CREATE; + } + if($this->isReadable($path)){ + $permissions |= OCP\Share::PERMISSION_READ; + } + if($this->isUpdatable($path)){ + $permissions |= OCP\Share::PERMISSION_UPDATE; + } + if($this->isDeletable($path)){ + $permissions |= OCP\Share::PERMISSION_DELETE; + } + if($this->isSharable($path)){ + $permissions |= OCP\Share::PERMISSION_SHARE; + } + return $permissions; + } // abstract public function file_exists($path); public function filectime($path) { $stat = $this->stat($path); diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index bd4cc4743b..f149c61830 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -27,6 +27,7 @@ abstract class Storage{ abstract public function isUpdatable($path); abstract public function isDeletable($path); abstract public function isSharable($path); + abstract public function getPermissions($path); abstract public function file_exists($path); abstract public function filectime($path); abstract public function filemtime($path); From 954596c251cb3132878d8d5eafcc37c47b3f520e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 16 Sep 2012 16:52:32 +0200 Subject: [PATCH 005/262] rework filecache to work directly on storage backends wip --- lib/files/cache/cache.php | 189 ++++++++++++++++++++++++++++++++++++ lib/files/cache/scanner.php | 78 +++++++++++++++ lib/files/file.php | 61 ++++++++++++ 3 files changed, 328 insertions(+) create mode 100644 lib/files/cache/cache.php create mode 100644 lib/files/cache/scanner.php create mode 100644 lib/files/file.php diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php new file mode 100644 index 0000000000..8fc575948d --- /dev/null +++ b/lib/files/cache/cache.php @@ -0,0 +1,189 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +class Cache { + /** + * @var array partial data for the cache + */ + private static $partial = array(); + + /** + * get the stored metadata of a file or folder + * + * @param \OC\Files\File or int $file + * @return array + */ + static public function get($file) { + if ($file instanceof \OC\Files\File) { + $where = 'WHERE `storage` = ? AND `path_hash` = ?'; + $params = array($file->getStorageId(), $file->getInternalPath()); + } else { //file id + $where = 'WHERE `fileid` = ?'; + $params = array($file); + } + $query = \OC_DB::prepare( + 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + FROM `*PREFIX*filecache` ' . $where); + $result=$query->execute($params); + return $result->fetchRow(); + } + + /** + * store meta data for a file or folder + * + * @param \OC\Files\File $file + * @param array $data + * + * @return int file id + */ + static public function put(\OC\Files\File $file, array $data) { + if ($id = self::getId($file) > -1) { + self::update($id, $data); + return $id; + } else { + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { //add any saved partial data + $data = array_merge($data, self::$partial[$key]); + unset(self::$partial[$key]); + } + + $requiredFields = array('size', 'mtime', 'mimetype'); + foreach ($requiredFields as $field) { + if (!isset($data[$field])) { //data not complete save as partial and return + self::$partial[$key] = $data; + return -1; + } + } + + $data['path'] = $file->getInternalPath(); + $data['parent'] = self::getParentId($file); + $data['name'] = basename($file->getInternalPath()); + + list($queryParts, $params) = self::buildParts($data); + $queryParts[] = '`storage`'; + $params[] = $file->getStorageId(); + $valuesPlaceholder = array_fill(0, count($queryParts), '?'); + + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); + $query->execute($params); + + return \OC_DB::insertid('*PREFIX*filecache'); + } + } + + /** + * update the metadata in the cache + * + * @param int $id + * @param array $data + */ + static public function update($id, array $data) { + list($queryParts, $params) = self::buildParts($data); + $params[] = $id; + + $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? WHERE fileid = ?'); + $query->execute($params); + } + + /** + * extract query parts and params array from data array + * + * @param array $data + * @return array + */ + private static function buildParts(array $data) { + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); + + $params = array(); + $queryParts = array(); + foreach ($data as $name => $value) { + if (array_search($name, $fields) !== false) { + $params[] = $value; + $queryParts[] = '`' . $name . '`'; + if ($name === 'path') { + $params[] = md5($value); + $queryParts[] = '`path_hash`'; + } elseif ($name === 'mimetype') { + $params[] = substr($value, 0, strpos($value, '/')); + $queryParts[] = '`mimepart`'; + } + } + } + return array($queryParts, $params); + } + + /** + * get the file id for a file + * + * @param \OC\Files\File $file + * @return int + */ + static public function getId(\OC\Files\File $file) { + $storageId = $file->getStorageId(); + $pathHash = md5($file->getInternalPath()); + + $query = \OC_DB::prepare('SELECT id FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $result = $query->execute(array($storageId, $pathHash)); + + if ($row = $result->fetchRow()) { + return $row['id']; + } else { + return -1; + } + } + + /** + * get the id of the parent folder of a file + * + * @param \OC\Files\File $file + * return int + */ + static public function getParentId(\OC\Files\File $file) { + $path = $file->getInternalPath(); + if ($path === '/' or $path === '') { + return -1; + } else { + return self::getId(new \OC\Files\File($file->getStorage(), dirname($path))); + } + } + + /** + * check if a file is available in the cache + * + * @param \OC\Files\File $file + * @return bool + */ + static public function inCache(\OC\Files\File $file) { + return self::getId($file) != -1; + } + + /** + * remove a file or folder from the cache + * + * @param \OC\Files\File $file + */ + public function remove(\OC\Files\File $file) { + $storageId = $file->getStorageId(); + $pathHash = md5($file->getInternalPath()); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query->execute(array($storageId, $pathHash)); + } + + /** + * remove all entries for files that are stored on $storage form the cache + * + * @param \OC\Files\Storage\Storage $storage + */ + public function removeStorage(\OC\Files\Storage\Storage $storage) { + $storageId = $storage->getId(); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); + $query->execute(array($storageId)); + } +} diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php new file mode 100644 index 0000000000..8f2c5bda5c --- /dev/null +++ b/lib/files/cache/scanner.php @@ -0,0 +1,78 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +class Scanner { + const SCAN_RECURSIVE = true; + const SCAN_SHALLOW = false; + + /** + * get all the metadata of a file or folder + * * + * @param \OC\Files\File $file + * @return array with metadata of the file + */ + public static function getData(\OC\Files\File $file) { + $data = array(); + $storage = $file->getStorage(); + $path = $file->getInternalPath(); + if (!$storage->isReadable($path)) return null; //cant read, nothing we can do + clearstatcache(); + $data['mimetype'] = $storage->getMimeType($path); + $data['mtime'] = $storage->filemtime($path); + if ($data['mimetype'] == 'httpd/unix-directory') { + $data['size'] = -1; //unknown + $data['permissions'] = $storage->getPermissions($path . '/'); + } else { + $data['size'] = $storage->filesize($path); + $data['permissions'] = $storage->getPermissions($path); + } + return $data; + } + + /** + * scan a single file and store it in the cache + * + * @param \OC\Files\File $file + * @return array with metadata of the scanned file + */ + public static function scanFile(\OC\Files\File $file) { + $data = self::getData($file); + Cache::put($file, $data); + return $data; + } + + /** + * scan all the files in a folder and store them in the cache + * + * @param \OC\Files\File $folder + * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive + * @return int the size of the scanned folder or -1 if the size is unknown at this stage + */ + public static function scan(\OC\Files\File $folder, $recursive) { + $size = 0; + $storage = $folder->getStorage(); + $path = $folder->getInternalPath(); + if ($dh = $storage->opendir($path)) { + while ($file = readdir($dh)) { + if ($file !== '.' and $file !== '..') { + $child = new \OC\Files\File($storage, $path . '/' . $file); + $data = self::scanFile($child); + if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { + $data['size'] = self::scan($child, self::SCAN_RECURSIVE); + } + if ($data['size'] >= 0 and $size >= 0) { + $size += $data['size']; + } + } + } + } + return $size; + } +} diff --git a/lib/files/file.php b/lib/files/file.php new file mode 100644 index 0000000000..b6432e6345 --- /dev/null +++ b/lib/files/file.php @@ -0,0 +1,61 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files; + +/** + * representation of the location a file or folder is stored + */ + +class File{ + /** + * @var Storage\Storage $storage + */ + private $storage; + /** + * @var string internalPath + */ + private $internalPath; + + public function __construct(Storage\Storage $storage, $internalPath){ + $this->storage = $storage; + $this->internalPath = $internalPath; + } + + public static function resolve($fullPath){ + $storage = null; + $internalPath = ''; + list($storage, $internalPath) = \OC_Filesystem::resolvePath($fullPath); + return new File($storage, $internalPath); + } + + /** + * get the internal path of the file inside the filestorage + * @return string + */ + public function getInternalPath(){ + return $this->internalPath; + } + + /** + * get the storage the file is stored in + * @return \OC\Files\Storage\Storage + */ + public function getStorage(){ + return $this->storage; + } + + /** + * get the id of the storage the file is stored in + * @return string + */ + public function getStorageId(){ + return $this->storage->getId(); + } + +} From 153cd802a9bbc0f5a5f67fe428af7ca78185011f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 14:40:04 +0200 Subject: [PATCH 006/262] add partial file data to the result of Cache::get --- lib/files/cache/cache.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 8fc575948d..9d90ab041f 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -31,7 +31,13 @@ class Cache { $query = \OC_DB::prepare( 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` FROM `*PREFIX*filecache` ' . $where); - $result=$query->execute($params); + $result = $query->execute($params); + + //merge partial data + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { + $result=array_merge($result, self::$partial[$key]); + } return $result->fetchRow(); } From 96b798a59f236f4251ced87ecac9da55e82d1685 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 14:51:15 +0200 Subject: [PATCH 007/262] move storage backend test cases to their own namespace --- apps/files_external/tests/amazons3.php | 8 +++--- apps/files_external/tests/ftp.php | 8 +++--- apps/files_external/tests/google.php | 6 +++-- apps/files_external/tests/smb.php | 8 +++--- apps/files_external/tests/swift.php | 6 +++-- apps/files_external/tests/webdav.php | 6 +++-- .../storage}/commontest.php | 8 +++--- .../{filestorage => files/storage}/local.php | 10 ++++---- .../storage/storage.php} | 25 ++++++++++--------- 9 files changed, 50 insertions(+), 35 deletions(-) rename tests/lib/{filestorage => files/storage}/commontest.php (91%) rename tests/lib/{filestorage => files/storage}/local.php (87%) rename tests/lib/{filestorage.php => files/storage/storage.php} (93%) diff --git a/apps/files_external/tests/amazons3.php b/apps/files_external/tests/amazons3.php index ad1c453abb..cf372aecbd 100644 --- a/apps/files_external/tests/amazons3.php +++ b/apps/files_external/tests/amazons3.php @@ -20,12 +20,14 @@ * License along with this library. If not, see . */ +namespace Test\Files\Storage; + $config = include('apps/files_external/tests/config.php'); if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['run']) { - abstract class Test_Filestorage_AmazonS3 extends Test_FileStorage{} + abstract class AmazonS3 extends Storage{} return; } else { - class Test_Filestorage_AmazonS3 extends Test_FileStorage { + class AmazonS3 extends Storage { private $config; private $id; @@ -38,7 +40,7 @@ if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['r } public function tearDown() { - $s3 = new AmazonS3(array('key' => $this->config['amazons3']['key'], 'secret' => $this->config['amazons3']['secret'])); + $s3 = new \AmazonS3(array('key' => $this->config['amazons3']['key'], 'secret' => $this->config['amazons3']['secret'])); if ($s3->delete_all_objects($this->id)) { $s3->delete_bucket($this->id); } diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php index 105f7b485b..8a0821e25a 100644 --- a/apps/files_external/tests/ftp.php +++ b/apps/files_external/tests/ftp.php @@ -6,12 +6,14 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']) { - abstract class Test_Filestorage_FTP extends Test_FileStorage{} + abstract class FTP extends Storage{} return; }else{ - class Test_Filestorage_FTP extends Test_FileStorage { + class FTP extends Storage { private $config; public function setUp() { @@ -22,7 +24,7 @@ if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']) { } public function tearDown() { - OCP\Files::rmdirr($this->instance->constructUrl('')); + \OCP\Files::rmdirr($this->instance->constructUrl('')); } } } diff --git a/apps/files_external/tests/google.php b/apps/files_external/tests/google.php index e96c2263e1..fff6461c91 100644 --- a/apps/files_external/tests/google.php +++ b/apps/files_external/tests/google.php @@ -20,12 +20,14 @@ * License along with this library. If not, see . */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); if(!is_array($config) or !isset($config['google']) or !$config['google']['run']) { - abstract class Test_Filestorage_Google extends Test_FileStorage{} + abstract class Google extends Storage{} return; }else{ - class Test_Filestorage_Google extends Test_FileStorage { + class Google extends Storage { private $config; diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index a0c5d83473..87b110a241 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -8,11 +8,13 @@ $config=include('apps/files_external/tests/config.php'); +namespace Test\Files\Storage; + if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) { - abstract class Test_Filestorage_SMB extends Test_FileStorage{} + abstract class SMB extends Storage{} return; }else{ - class Test_Filestorage_SMB extends Test_FileStorage { + class SMB extends Storage { private $config; public function setUp() { @@ -23,7 +25,7 @@ if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) { } public function tearDown() { - OCP\Files::rmdirr($this->instance->constructUrl('')); + \OCP\Files::rmdirr($this->instance->constructUrl('')); } } } diff --git a/apps/files_external/tests/swift.php b/apps/files_external/tests/swift.php index 3e1485b0f3..98a97f99b5 100644 --- a/apps/files_external/tests/swift.php +++ b/apps/files_external/tests/swift.php @@ -6,12 +6,14 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']) { - abstract class Test_Filestorage_SWIFT extends Test_FileStorage{} + abstract class SWIFT extends Storage{} return; }else{ - class Test_Filestorage_SWIFT extends Test_FileStorage { + class SWIFT extends Storage { private $config; public function setUp() { diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php index 6b1121c9d0..cddd0d513e 100644 --- a/apps/files_external/tests/webdav.php +++ b/apps/files_external/tests/webdav.php @@ -6,12 +6,14 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); if(!is_array($config) or !isset($config['webdav']) or !$config['webdav']['run']) { - abstract class Test_Filestorage_DAV extends Test_FileStorage{} + abstract class DAV extends Storage{} return; }else{ - class Test_Filestorage_DAV extends Test_FileStorage { + class DAV extends Storage { private $config; public function setUp() { diff --git a/tests/lib/filestorage/commontest.php b/tests/lib/files/storage/commontest.php similarity index 91% rename from tests/lib/filestorage/commontest.php rename to tests/lib/files/storage/commontest.php index 0e52e91678..2e3808e2d9 100644 --- a/tests/lib/filestorage/commontest.php +++ b/tests/lib/files/storage/commontest.php @@ -20,7 +20,9 @@ * */ -class Test_Filestorage_CommonTest extends Test_FileStorage { +namespace Test\Files\Storage; + +class CommonTest extends Storage { /** * @var string tmpDir */ @@ -34,8 +36,8 @@ class Test_Filestorage_CommonTest extends Test_FileStorage { } public function tearDown() { - OC_Helper::rmdirr($this->tmpDir); + \OC_Helper::rmdirr($this->tmpDir); } } -?> \ No newline at end of file +?> diff --git a/tests/lib/filestorage/local.php b/tests/lib/files/storage/local.php similarity index 87% rename from tests/lib/filestorage/local.php rename to tests/lib/files/storage/local.php index 7bb27830ba..6672368e67 100644 --- a/tests/lib/filestorage/local.php +++ b/tests/lib/files/storage/local.php @@ -20,19 +20,19 @@ * */ -class Test_Filestorage_Local extends Test_FileStorage { +namespace Test\Files\Storage; + +class Local extends Storage { /** * @var string tmpDir */ private $tmpDir; public function setUp() { - $this->tmpDir=OC_Helper::tmpFolder(); + $this->tmpDir=\OC_Helper::tmpFolder(); $this->instance=new \OC\Files\Storage\Local(array('datadir'=>$this->tmpDir)); } public function tearDown() { - OC_Helper::rmdirr($this->tmpDir); + \OC_Helper::rmdirr($this->tmpDir); } } - -?> \ No newline at end of file diff --git a/tests/lib/filestorage.php b/tests/lib/files/storage/storage.php similarity index 93% rename from tests/lib/filestorage.php rename to tests/lib/files/storage/storage.php index bfb40bcd67..9c8581b259 100644 --- a/tests/lib/filestorage.php +++ b/tests/lib/files/storage/storage.php @@ -20,7 +20,9 @@ * */ -abstract class Test_FileStorage extends UnitTestCase { +namespace Test\Files\Storage; + +abstract class Storage extends \UnitTestCase { /** * @var \OC\Files\Storage\Storage instance */ @@ -83,7 +85,7 @@ abstract class Test_FileStorage extends UnitTestCase { * test the various uses of file_get_contents and file_put_contents */ public function testGetPutContents() { - $sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; + $sourceFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; $sourceText=file_get_contents($sourceFile); //fill a file with string data @@ -103,21 +105,21 @@ abstract class Test_FileStorage extends UnitTestCase { $this->assertEqual('httpd/unix-directory',$this->instance->getMimeType('/')); $this->assertEqual(false,$this->instance->getMimeType('/non/existing/file')); - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile,'r')); $this->assertEqual('text/plain',$this->instance->getMimeType('/lorem.txt')); - $pngFile=OC::$SERVERROOT.'/tests/data/logo-wide.png'; + $pngFile=\OC::$SERVERROOT.'/tests/data/logo-wide.png'; $this->instance->file_put_contents('/logo-wide.png',file_get_contents($pngFile,'r')); $this->assertEqual('image/png',$this->instance->getMimeType('/logo-wide.png')); - $svgFile=OC::$SERVERROOT.'/tests/data/logo-wide.svg'; + $svgFile=\OC::$SERVERROOT.'/tests/data/logo-wide.svg'; $this->instance->file_put_contents('/logo-wide.svg',file_get_contents($svgFile,'r')); $this->assertEqual('image/svg+xml',$this->instance->getMimeType('/logo-wide.svg')); } public function testCopyAndMove() { - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; $this->instance->file_put_contents('/source.txt',file_get_contents($textFile)); $this->instance->copy('/source.txt','/target.txt'); $this->assertTrue($this->instance->file_exists('/target.txt')); @@ -130,7 +132,7 @@ abstract class Test_FileStorage extends UnitTestCase { } public function testLocal() { - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile)); $localFile=$this->instance->getLocalFile('/lorem.txt'); $this->assertTrue(file_exists($localFile)); @@ -151,7 +153,7 @@ abstract class Test_FileStorage extends UnitTestCase { } public function testStat() { - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; $ctimeStart=time(); $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile)); $this->assertTrue($this->instance->isReadable('/lorem.txt')); @@ -198,7 +200,6 @@ abstract class Test_FileStorage extends UnitTestCase { fclose($fh); clearstatcache(); $mtimeEnd=time(); - $originalCTime=$cTime; $mTime=$this->instance->filemtime('/lorem.txt'); $this->assertTrue(($mtimeStart-1)<=$mTime); $this->assertTrue($mTime<=($mtimeEnd+1)); @@ -208,11 +209,11 @@ abstract class Test_FileStorage extends UnitTestCase { } public function testSearch() { - $textFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; + $textFile=\OC::$SERVERROOT.'/tests/data/lorem.txt'; $this->instance->file_put_contents('/lorem.txt',file_get_contents($textFile,'r')); - $pngFile=OC::$SERVERROOT.'/tests/data/logo-wide.png'; + $pngFile=\OC::$SERVERROOT.'/tests/data/logo-wide.png'; $this->instance->file_put_contents('/logo-wide.png',file_get_contents($pngFile,'r')); - $svgFile=OC::$SERVERROOT.'/tests/data/logo-wide.svg'; + $svgFile=\OC::$SERVERROOT.'/tests/data/logo-wide.svg'; $this->instance->file_put_contents('/logo-wide.svg',file_get_contents($svgFile,'r')); $result=$this->instance->search('logo'); $this->assertEqual(2,count($result)); From b206d16b104f0474cfd41944b857a3981948b94d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 14:51:34 +0200 Subject: [PATCH 008/262] add support for loading namespaced test cases --- lib/base.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/base.php b/lib/base.php index 7a09946b9d..38568e2749 100644 --- a/lib/base.php +++ b/lib/base.php @@ -95,6 +95,9 @@ class OC{ } elseif(strpos($className, 'Test_')===0) { $path = 'tests/lib/'.strtolower(str_replace('_', '/', substr($className, 5)) . '.php'); + } + elseif(strpos($className, 'Test\\')===0) { + $path = 'tests/lib/'.strtolower(str_replace('\\', '/', substr($className, 5)) . '.php'); }else{ return false; } From 46896be0d482f5dcec85ec32b232dd8a205f3e41 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:03:17 +0200 Subject: [PATCH 009/262] fix namespace error in temporary storage backend --- lib/files/storage/temporary.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/storage/temporary.php b/lib/files/storage/temporary.php index 0e69c9112a..ffc55e2750 100644 --- a/lib/files/storage/temporary.php +++ b/lib/files/storage/temporary.php @@ -11,7 +11,7 @@ namespace OC\Files\Storage; /** * local storage backnd in temporary folder for testing purpores */ -class Temporary extends OC\Files\Storage\Local{ +class Temporary extends Local{ public function __construct($arguments) { $this->datadir=\OC_Helper::tmpFolder(); } From 73eedd8fc8326616a356c8b8c40826d9dba92f31 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:43:10 +0200 Subject: [PATCH 010/262] some simple test cases for the new filecache --- tests/lib/files/cache/cache.php | 88 +++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tests/lib/files/cache/cache.php diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php new file mode 100644 index 0000000000..168489a721 --- /dev/null +++ b/tests/lib/files/cache/cache.php @@ -0,0 +1,88 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +use \OC\Files\Cache\Cache as FileCache; + +class Cache extends \UnitTestCase { + /** + * @var \OC\Files\Storage\Temporary $storage; + */ + private $storage; + + private function createPath($path) { + return new \OC\Files\File($this->storage, $path); + } + + public function testSimple() { + $file1 = $this->createPath('foo'); + $file2 = $this->createPath('foo/bar'); + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $data2 = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + + $this->assertFalse(FileCache::inCache($file1)); + $this->assertEqual(FileCache::get($file1), null); + + $id1 = FileCache::put($file1, $data1); + $this->assertTrue(FileCache::inCache($file1)); + $cacheData1 = FileCache::get($file1); + foreach ($data1 as $key => $value) { + $this->assertEqual($value, $cacheData1[$key]); + } + $this->assertEqual($cacheData1['fileid'], $id1); + $this->assertEqual($id1, FileCache::getId($file1)); + + $this->assertFalse(FileCache::inCache($file2)); + $id2 = FileCache::put($file2, $data2); + $this->assertTrue(FileCache::inCache($file2)); + $cacheData2 = FileCache::get($file2); + foreach ($data2 as $key => $value) { + $this->assertEqual($value, $cacheData2[$key]); + } + $this->assertEqual($cacheData1['fileid'], $cacheData2['parent']); + $this->assertEqual($cacheData2['fileid'], $id2); + $this->assertEqual($id2, FileCache::getId($file2)); + $this->assertEqual($id1, FileCache::getParentId($file2)); + + $newSize = 1050; + $newId2 = FileCache::put($file2, array('size' => $newSize)); + $cacheData2 = FileCache::get($file2); + $this->assertEqual($newId2, $id2); + $this->assertEqual($cacheData2['size'], $newSize); + $this->assertEqual($cacheData1, FileCache::get($file1)); + + FileCache::remove($file2); + $this->assertFalse(FileCache::inCache($file2)); + $this->assertEqual(FileCache::get($file2), null); + $this->assertTrue(FileCache::inCache($file1)); + + $this->assertEqual($cacheData1, FileCache::get($id1)); + } + + public function testPartial() { + $file1 = $this->createPath('foo'); + + FileCache::put($file1, array('size' => 10)); + $this->assertEqual(array('size' => 10), FileCache::get($file1)); + + FileCache::put($file1, array('mtime' => 15)); + $this->assertEqual(array('size' => 10, 'mtime' => 15), FileCache::get($file1)); + + FileCache::put($file1, array('size' => 12)); + $this->assertEqual(array('size' => 12, 'mtime' => 15), FileCache::get($file1)); + } + + public function tearDown() { + FileCache::removeStorage($this->storage); + } + + public function setUp() { + $this->storage = new \OC\Files\Storage\Temporary(array()); + } +} From 97b0eabc850f64949282b471288c93d7148c72ff Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:43:48 +0200 Subject: [PATCH 011/262] fix several problems in the new filecache in order to complete the tests --- lib/files/cache/cache.php | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d90ab041f..5d4cb9dd2b 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -23,22 +23,25 @@ class Cache { static public function get($file) { if ($file instanceof \OC\Files\File) { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($file->getStorageId(), $file->getInternalPath()); + $params = array($file->getStorageId(), md5($file->getInternalPath())); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `id`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); + $data = $result->fetchRow(); //merge partial data - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { - $result=array_merge($result, self::$partial[$key]); + if (!$data and $file instanceof \OC\Files\File) { + $key = $file->getStorageId() . '::' . $file->getInternalPath(); + if (isset(self::$partial[$key])) { + $data = self::$partial[$key]; + } } - return $result->fetchRow(); + return $data; } /** @@ -50,13 +53,13 @@ class Cache { * @return int file id */ static public function put(\OC\Files\File $file, array $data) { - if ($id = self::getId($file) > -1) { + if (($id = self::getId($file)) > -1) { self::update($id, $data); return $id; } else { $key = $file->getStorageId() . '::' . $file->getInternalPath(); if (isset(self::$partial[$key])) { //add any saved partial data - $data = array_merge($data, self::$partial[$key]); + $data = array_merge(self::$partial[$key], $data); unset(self::$partial[$key]); } @@ -77,7 +80,7 @@ class Cache { $params[] = $file->getStorageId(); $valuesPlaceholder = array_fill(0, count($queryParts), '?'); - $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ' VALUES(' . implode(', ', $valuesPlaceholder) . ')'); + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); return \OC_DB::insertid('*PREFIX*filecache'); @@ -135,11 +138,11 @@ class Cache { $storageId = $file->getStorageId(); $pathHash = md5($file->getInternalPath()); - $query = \OC_DB::prepare('SELECT id FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); $result = $query->execute(array($storageId, $pathHash)); if ($row = $result->fetchRow()) { - return $row['id']; + return $row['fileid']; } else { return -1; } @@ -175,7 +178,7 @@ class Cache { * * @param \OC\Files\File $file */ - public function remove(\OC\Files\File $file) { + static public function remove(\OC\Files\File $file) { $storageId = $file->getStorageId(); $pathHash = md5($file->getInternalPath()); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); @@ -187,7 +190,7 @@ class Cache { * * @param \OC\Files\Storage\Storage $storage */ - public function removeStorage(\OC\Files\Storage\Storage $storage) { + static public function removeStorage(\OC\Files\Storage\Storage $storage) { $storageId = $storage->getId(); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); $query->execute(array($storageId)); From 6fafd5d4e9d23cd98738a3b00ce0053d6b6e3dff Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 22 Sep 2012 15:48:39 +0200 Subject: [PATCH 012/262] this should be done elsewhere if needed --- lib/files/cache/cache.php | 2 +- lib/files/cache/scanner.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5d4cb9dd2b..0c1d6788ec 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -152,7 +152,7 @@ class Cache { * get the id of the parent folder of a file * * @param \OC\Files\File $file - * return int + * @return int */ static public function getParentId(\OC\Files\File $file) { $path = $file->getInternalPath(); diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 8f2c5bda5c..e8e9c71c4e 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -23,7 +23,6 @@ class Scanner { $storage = $file->getStorage(); $path = $file->getInternalPath(); if (!$storage->isReadable($path)) return null; //cant read, nothing we can do - clearstatcache(); $data['mimetype'] = $storage->getMimeType($path); $data['mtime'] = $storage->filemtime($path); if ($data['mimetype'] == 'httpd/unix-directory') { From f360d7c736b08f48f1abcea1e0b93dc890178c94 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 23 Sep 2012 01:51:00 +0200 Subject: [PATCH 013/262] add getId to shared storage backend --- apps/files_sharing/lib/sharedstorage.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index f1539610b0..876e719956 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -91,7 +91,7 @@ class Shared extends \OC\Files\Storage\Common { * @param string Shared target file path * @return Returns CRUDS permissions granted or false if not found */ - private function getPermissions($target) { + public function getPermissions($target) { $file = $this->getFile($target); if (isset($file['permissions'])) { return $file['permissions']; @@ -449,4 +449,8 @@ class Shared extends \OC\Files\Storage\Common { //TODO return false; } + + public function getId(){ + return 'shared::' . $this->sharedFolder; + } } From dcf995fff3ecc2780d3187744397461d1a14c041 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 23 Sep 2012 15:25:03 +0200 Subject: [PATCH 014/262] add Cache::getFolderContent --- lib/files/cache/cache.php | 19 +++++++++++++++++++ tests/lib/files/cache/cache.php | 23 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 0c1d6788ec..f8808ad0b4 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -44,6 +44,25 @@ class Cache { return $data; } + /** + * get the metadata of all files stored in $folder + * + * @param \OC\Files\File $folder + * @return array + */ + static public function getFolderContents($folder) { + $fileId = self::getId($folder); + if ($fileId > -1) { + $query = \OC_DB::prepare( + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + FROM `*PREFIX*filecache` WHERE parent = ?'); + $result = $query->execute(array($fileId)); + return $result->fetchAll(); + } else { + return array(); + } + } + /** * store meta data for a file or folder * diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 168489a721..9f35cd889a 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -78,6 +78,29 @@ class Cache extends \UnitTestCase { $this->assertEqual(array('size' => 12, 'mtime' => 15), FileCache::get($file1)); } + public function testFolder() { + $file1 = $this->createPath('folder'); + $file2 = $this->createPath('folder/bar'); + $file3 = $this->createPath('folder/foo'); + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $fileData = array(); + $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); + + FileCache::put($file1, $data1); + FileCache::put($file2, $fileData['bar']); + FileCache::put($file3, $fileData['foo']); + + $content = FileCache::getFolderContents($file1); + $this->assertEqual(count($content), 2); + foreach ($content as $cachedData) { + $data = $fileData[$cachedData['name']]; + foreach ($data as $name => $value) { + $this->assertEqual($value, $cachedData[$name]); + } + } + } + public function tearDown() { FileCache::removeStorage($this->storage); } From 522d7df860fb47d3cc56e315850dda2797569ac5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 26 Sep 2012 17:52:02 +0200 Subject: [PATCH 015/262] convert Cache to a non-static class that handles the cache for a single storage backend --- lib/files/cache/cache.php | 121 ++++++++++++++++++-------------- lib/files/cache/scanner.php | 1 + tests/lib/files/cache/cache.php | 82 +++++++++++----------- 3 files changed, 110 insertions(+), 94 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index f8808ad0b4..167cc5d13f 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -9,21 +9,36 @@ namespace OC\Files\Cache; class Cache { + /** + * @var \OC\Files\Storage\Storage + */ + private $storage; + /** * @var array partial data for the cache */ - private static $partial = array(); + private $partial = array(); + + private $storageId; + + /** + * @param \OC\Files\Storage\Storage $storage + */ + public function __construct(\OC\Files\Storage\Storage $storage) { + $this->storage = $storage; + $this->storageId = $storage->getId(); + } /** * get the stored metadata of a file or folder * - * @param \OC\Files\File or int $file + * @param string/int $file * @return array */ - static public function get($file) { - if ($file instanceof \OC\Files\File) { + public function get($file) { + if (is_string($file)) { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($file->getStorageId(), md5($file->getInternalPath())); + $params = array($this->storageId, md5($file)); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); @@ -35,23 +50,28 @@ class Cache { $data = $result->fetchRow(); //merge partial data - if (!$data and $file instanceof \OC\Files\File) { - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { - $data = self::$partial[$key]; + if (!$data and is_string($file)) { + if (isset($this->partial[$file])) { + $data = $this->partial[$file]; } + } else { + //fix types + $data['fileid'] = (int)$data['fileid']; + $data['size'] = (int)$data['size']; + $data['mtime'] = (int)$data['mtime']; } + return $data; } /** * get the metadata of all files stored in $folder * - * @param \OC\Files\File $folder + * @param string $folder * @return array */ - static public function getFolderContents($folder) { - $fileId = self::getId($folder); + public function getFolderContents($folder) { + $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` @@ -66,43 +86,42 @@ class Cache { /** * store meta data for a file or folder * - * @param \OC\Files\File $file + * @param string $file * @param array $data * * @return int file id */ - static public function put(\OC\Files\File $file, array $data) { - if (($id = self::getId($file)) > -1) { - self::update($id, $data); + public function put($file, array $data) { + if (($id = $this->getId($file)) > -1) { + $this->update($id, $data); return $id; } else { - $key = $file->getStorageId() . '::' . $file->getInternalPath(); - if (isset(self::$partial[$key])) { //add any saved partial data - $data = array_merge(self::$partial[$key], $data); - unset(self::$partial[$key]); + if (isset($this->partial[$file])) { //add any saved partial data + $data = array_merge($this->partial[$file], $data); + unset($this->partial[$file]); } $requiredFields = array('size', 'mtime', 'mimetype'); foreach ($requiredFields as $field) { if (!isset($data[$field])) { //data not complete save as partial and return - self::$partial[$key] = $data; + $this->partial[$file] = $data; return -1; } } - $data['path'] = $file->getInternalPath(); - $data['parent'] = self::getParentId($file); - $data['name'] = basename($file->getInternalPath()); + $data['path'] = $file; + $data['parent'] = $this->getParentId($file); + $data['name'] = basename($file); - list($queryParts, $params) = self::buildParts($data); + list($queryParts, $params) = $this->buildParts($data); $queryParts[] = '`storage`'; - $params[] = $file->getStorageId(); + $params[] = $this->storageId; $valuesPlaceholder = array_fill(0, count($queryParts), '?'); $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); - return \OC_DB::insertid('*PREFIX*filecache'); + return (int) \OC_DB::insertid('*PREFIX*filecache'); } } @@ -112,8 +131,8 @@ class Cache { * @param int $id * @param array $data */ - static public function update($id, array $data) { - list($queryParts, $params) = self::buildParts($data); + public function update($id, array $data) { + list($queryParts, $params) = $this->buildParts($data); $params[] = $id; $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? WHERE fileid = ?'); @@ -126,7 +145,7 @@ class Cache { * @param array $data * @return array */ - private static function buildParts(array $data) { + static function buildParts(array $data) { $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); $params = array(); @@ -150,15 +169,14 @@ class Cache { /** * get the file id for a file * - * @param \OC\Files\File $file + * @param string $file * @return int */ - static public function getId(\OC\Files\File $file) { - $storageId = $file->getStorageId(); - $pathHash = md5($file->getInternalPath()); + public function getId($file) { + $pathHash = md5($file); $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($storageId, $pathHash)); + $result = $query->execute(array($this->storageId, $pathHash)); if ($row = $result->fetchRow()) { return $row['fileid']; @@ -170,48 +188,43 @@ class Cache { /** * get the id of the parent folder of a file * - * @param \OC\Files\File $file + * @param string $file * @return int */ - static public function getParentId(\OC\Files\File $file) { - $path = $file->getInternalPath(); - if ($path === '/' or $path === '') { + public function getParentId($file) { + if ($file === '/' or $file === '') { return -1; } else { - return self::getId(new \OC\Files\File($file->getStorage(), dirname($path))); + return $this->getId(dirname($file)); } } /** * check if a file is available in the cache * - * @param \OC\Files\File $file + * @param string $file * @return bool */ - static public function inCache(\OC\Files\File $file) { - return self::getId($file) != -1; + public function inCache($file) { + return $this->getId($file) != -1; } /** * remove a file or folder from the cache * - * @param \OC\Files\File $file + * @param string $file */ - static public function remove(\OC\Files\File $file) { - $storageId = $file->getStorageId(); - $pathHash = md5($file->getInternalPath()); + public function remove($file) { + $pathHash = md5($file); $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $query->execute(array($storageId, $pathHash)); + $query->execute(array($this->storageId, $pathHash)); } /** - * remove all entries for files that are stored on $storage form the cache - * - * @param \OC\Files\Storage\Storage $storage + * remove all entries for files that are stored on the storage from the cache */ - static public function removeStorage(\OC\Files\Storage\Storage $storage) { - $storageId = $storage->getId(); + public function clear() { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); - $query->execute(array($storageId)); + $query->execute(array($this->storageId)); } } diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e8e9c71c4e..17fc0fb2e8 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -15,6 +15,7 @@ class Scanner { /** * get all the metadata of a file or folder * * + * * @param \OC\Files\File $file * @return array with metadata of the file */ diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 9f35cd889a..24dd38fa73 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -16,82 +16,83 @@ class Cache extends \UnitTestCase { */ private $storage; - private function createPath($path) { - return new \OC\Files\File($this->storage, $path); - } + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; public function testSimple() { - $file1 = $this->createPath('foo'); - $file2 = $this->createPath('foo/bar'); + $file1 = 'foo'; + $file2 = 'foo/bar'; $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); $data2 = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); - $this->assertFalse(FileCache::inCache($file1)); - $this->assertEqual(FileCache::get($file1), null); + $this->assertFalse($this->cache->inCache($file1)); + $this->assertEqual($this->cache->get($file1), null); - $id1 = FileCache::put($file1, $data1); - $this->assertTrue(FileCache::inCache($file1)); - $cacheData1 = FileCache::get($file1); + $id1 = $this->cache->put($file1, $data1); + $this->assertTrue($this->cache->inCache($file1)); + $cacheData1 = $this->cache->get($file1); foreach ($data1 as $key => $value) { $this->assertEqual($value, $cacheData1[$key]); } $this->assertEqual($cacheData1['fileid'], $id1); - $this->assertEqual($id1, FileCache::getId($file1)); + $this->assertEqual($id1, $this->cache->getId($file1)); - $this->assertFalse(FileCache::inCache($file2)); - $id2 = FileCache::put($file2, $data2); - $this->assertTrue(FileCache::inCache($file2)); - $cacheData2 = FileCache::get($file2); + $this->assertFalse($this->cache->inCache($file2)); + $id2 = $this->cache->put($file2, $data2); + $this->assertTrue($this->cache->inCache($file2)); + $cacheData2 = $this->cache->get($file2); foreach ($data2 as $key => $value) { $this->assertEqual($value, $cacheData2[$key]); } $this->assertEqual($cacheData1['fileid'], $cacheData2['parent']); $this->assertEqual($cacheData2['fileid'], $id2); - $this->assertEqual($id2, FileCache::getId($file2)); - $this->assertEqual($id1, FileCache::getParentId($file2)); + $this->assertEqual($id2, $this->cache->getId($file2)); + $this->assertEqual($id1, $this->cache->getParentId($file2)); $newSize = 1050; - $newId2 = FileCache::put($file2, array('size' => $newSize)); - $cacheData2 = FileCache::get($file2); + $newId2 = $this->cache->put($file2, array('size' => $newSize)); + $cacheData2 = $this->cache->get($file2); $this->assertEqual($newId2, $id2); $this->assertEqual($cacheData2['size'], $newSize); - $this->assertEqual($cacheData1, FileCache::get($file1)); + $this->assertEqual($cacheData1, $this->cache->get($file1)); - FileCache::remove($file2); - $this->assertFalse(FileCache::inCache($file2)); - $this->assertEqual(FileCache::get($file2), null); - $this->assertTrue(FileCache::inCache($file1)); + $this->cache->remove($file2); + $this->assertFalse($this->cache->inCache($file2)); + $this->assertEqual($this->cache->get($file2), null); + $this->assertTrue($this->cache->inCache($file1)); - $this->assertEqual($cacheData1, FileCache::get($id1)); + $this->assertEqual($cacheData1, $this->cache->get($id1)); } public function testPartial() { - $file1 = $this->createPath('foo'); + $file1 = 'foo'; - FileCache::put($file1, array('size' => 10)); - $this->assertEqual(array('size' => 10), FileCache::get($file1)); + $this->cache->put($file1, array('size' => 10)); + $this->assertEqual(array('size' => 10), $this->cache->get($file1)); - FileCache::put($file1, array('mtime' => 15)); - $this->assertEqual(array('size' => 10, 'mtime' => 15), FileCache::get($file1)); + $this->cache->put($file1, array('mtime' => 15)); + $this->assertEqual(array('size' => 10, 'mtime' => 15), $this->cache->get($file1)); - FileCache::put($file1, array('size' => 12)); - $this->assertEqual(array('size' => 12, 'mtime' => 15), FileCache::get($file1)); + $this->cache->put($file1, array('size' => 12)); + $this->assertEqual(array('size' => 12, 'mtime' => 15), $this->cache->get($file1)); } public function testFolder() { - $file1 = $this->createPath('folder'); - $file2 = $this->createPath('folder/bar'); - $file3 = $this->createPath('folder/foo'); + $file1 = 'folder'; + $file2 = 'folder/bar'; + $file3 = 'folder/foo'; $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); $fileData = array(); $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); - FileCache::put($file1, $data1); - FileCache::put($file2, $fileData['bar']); - FileCache::put($file3, $fileData['foo']); + $this->cache->put($file1, $data1); + $this->cache->put($file2, $fileData['bar']); + $this->cache->put($file3, $fileData['foo']); - $content = FileCache::getFolderContents($file1); + $content = $this->cache->getFolderContents($file1); $this->assertEqual(count($content), 2); foreach ($content as $cachedData) { $data = $fileData[$cachedData['name']]; @@ -102,10 +103,11 @@ class Cache extends \UnitTestCase { } public function tearDown() { - FileCache::removeStorage($this->storage); + $this->cache->clear(); } public function setUp() { $this->storage = new \OC\Files\Storage\Temporary(array()); + $this->cache = new \OC\Files\Cache\Cache($this->storage); } } From 92555eff711ff391f3af5ef6fb6f6414bfe012cf Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 2 Oct 2012 23:34:45 +0200 Subject: [PATCH 016/262] add encrypted column to the new filecache --- lib/files/cache/cache.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 167cc5d13f..9d8275e5e0 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -44,7 +44,7 @@ class Cache { $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); $data = $result->fetchRow(); @@ -59,6 +59,7 @@ class Cache { $data['fileid'] = (int)$data['fileid']; $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; + $data['encrypted'] = (bool)$data['encrypted']; } return $data; @@ -74,7 +75,7 @@ class Cache { $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE parent = ?'); $result = $query->execute(array($fileId)); return $result->fetchAll(); @@ -112,6 +113,7 @@ class Cache { $data['path'] = $file; $data['parent'] = $this->getParentId($file); $data['name'] = basename($file); + $data['encrypted'] = isset($data['encrypted']) ? ((int)$data['encrypted']) : 0; list($queryParts, $params) = $this->buildParts($data); $queryParts[] = '`storage`'; @@ -121,7 +123,7 @@ class Cache { $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); $query->execute($params); - return (int) \OC_DB::insertid('*PREFIX*filecache'); + return (int)\OC_DB::insertid('*PREFIX*filecache'); } } @@ -146,7 +148,7 @@ class Cache { * @return array */ static function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime'); + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); $params = array(); $queryParts = array(); From 1ed89760be5e1c5cf5b3fa7d40d845750b2840ab Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 2 Oct 2012 23:35:51 +0200 Subject: [PATCH 017/262] dont need this anymore --- tests/lib/files/cache/cache.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 24dd38fa73..48cdc1c8c8 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -8,8 +8,6 @@ namespace Test\Files\Cache; -use \OC\Files\Cache\Cache as FileCache; - class Cache extends \UnitTestCase { /** * @var \OC\Files\Storage\Temporary $storage; From 6134e554f2306c5309a793d4d3149a0f9b05ea5f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 2 Oct 2012 23:46:35 +0200 Subject: [PATCH 018/262] new filecache table --- db_structure.xml | 114 +++++++++++++++++------------------------------ lib/util.php | 2 +- 2 files changed, 41 insertions(+), 75 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 99a30cb613..8bbc6e5cc6 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -53,19 +53,27 @@ - *dbprefix*fscache + *dbprefix*filecache - id - 1 + fileid integer 0 true + 1 4 + + storage + text + + true + 64 + + path text @@ -85,9 +93,9 @@ parent integer - 0 + true - 8 + 4 @@ -95,39 +103,7 @@ text true - 300 - - - - user - text - - true - 64 - - - - size - integer - 0 - true - 8 - - - - ctime - integer - 0 - true - 8 - - - - mtime - integer - 0 - true - 8 + 250 @@ -135,7 +111,7 @@ text true - 96 + 64 @@ -146,32 +122,37 @@ 32 + + size + integer + + true + 4 + + + + mtime + integer + + true + 4 + + encrypted integer 0 true - 1 - - - - versioned - integer - 0 - true - 1 - - - - writable - integer - 0 - true - 1 + 4 - fscache_path_hash_index + storage_path_hash + true + + storage + ascending + path_hash ascending @@ -179,23 +160,8 @@ - parent_index - - parent - ascending - - - - - name_index - - name - ascending - - - - - parent_name_index + parent_name_hash + true parent ascending diff --git a/lib/util.php b/lib/util.php index 31dd376b9c..264d61319d 100755 --- a/lib/util.php +++ b/lib/util.php @@ -81,7 +81,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.9.0. This is not visible to the user - return array(4,86,11); + return array(4,86,12); } /** From 636c75ce061492751d0fb001e0bf7219df379f09 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:23:33 +0200 Subject: [PATCH 019/262] better parent path bahaviour for the filecache --- lib/files/cache/cache.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d8275e5e0..79673771e5 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -194,10 +194,14 @@ class Cache { * @return int */ public function getParentId($file) { - if ($file === '/' or $file === '') { + if ($file === '') { return -1; } else { - return $this->getId(dirname($file)); + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + return $this->getId($parent); } } From 96d7cd59978cc416bc0d9c5ac487af23692ef1d8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:24:10 +0200 Subject: [PATCH 020/262] correct namespace usage in common filestorage backend --- lib/files/storage/common.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index b2b4ea8eee..3886a04182 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -57,19 +57,19 @@ abstract class Common extends \OC\Files\Storage\Storage { public function getPermissions($path){ $permissions = 0; if($this->isCreatable($path)){ - $permissions |= OCP\Share::PERMISSION_CREATE; + $permissions |= \OCP\Share::PERMISSION_CREATE; } if($this->isReadable($path)){ - $permissions |= OCP\Share::PERMISSION_READ; + $permissions |= \OCP\Share::PERMISSION_READ; } if($this->isUpdatable($path)){ - $permissions |= OCP\Share::PERMISSION_UPDATE; + $permissions |= \OCP\Share::PERMISSION_UPDATE; } if($this->isDeletable($path)){ - $permissions |= OCP\Share::PERMISSION_DELETE; + $permissions |= \OCP\Share::PERMISSION_DELETE; } if($this->isSharable($path)){ - $permissions |= OCP\Share::PERMISSION_SHARE; + $permissions |= \OCP\Share::PERMISSION_SHARE; } return $permissions; } From e415e90c6d8a2e8bb129be7c63a7077c56ab3da8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:24:49 +0200 Subject: [PATCH 021/262] make filestorage scanner non-static and add a simple test case --- lib/files/cache/scanner.php | 64 ++++++++++++++++++++----------- tests/lib/files/cache/cache.php | 1 + tests/lib/files/cache/scanner.php | 47 +++++++++++++++++++++++ 3 files changed, 90 insertions(+), 22 deletions(-) create mode 100644 tests/lib/files/cache/scanner.php diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 17fc0fb2e8..721d0d825e 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -9,29 +9,42 @@ namespace OC\Files\Cache; class Scanner { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; + const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; + public function __construct(\OC\Files\Storage\Storage $storage) { + $this->storage = $storage; + $this->cache = new Cache($storage); + } + /** * get all the metadata of a file or folder * * * - * @param \OC\Files\File $file + * @param string $path * @return array with metadata of the file */ - public static function getData(\OC\Files\File $file) { + public function getData($path) { $data = array(); - $storage = $file->getStorage(); - $path = $file->getInternalPath(); - if (!$storage->isReadable($path)) return null; //cant read, nothing we can do - $data['mimetype'] = $storage->getMimeType($path); - $data['mtime'] = $storage->filemtime($path); + if (!$this->storage->isReadable($path)) return null; //cant read, nothing we can do + $data['mimetype'] = $this->storage->getMimeType($path); + $data['mtime'] = $this->storage->filemtime($path); if ($data['mimetype'] == 'httpd/unix-directory') { $data['size'] = -1; //unknown - $data['permissions'] = $storage->getPermissions($path . '/'); + $data['permissions'] = $this->storage->getPermissions($path . '/'); } else { - $data['size'] = $storage->filesize($path); - $data['permissions'] = $storage->getPermissions($path); + $data['size'] = $this->storage->filesize($path); + $data['permissions'] = $this->storage->getPermissions($path); } return $data; } @@ -39,33 +52,40 @@ class Scanner { /** * scan a single file and store it in the cache * - * @param \OC\Files\File $file + * @param string $file * @return array with metadata of the scanned file */ - public static function scanFile(\OC\Files\File $file) { - $data = self::getData($file); - Cache::put($file, $data); + public function scanFile($file) { + $data = $this->getData($file); + if ($file !== '') { + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + if (!$this->cache->inCache($parent)) { + $this->scanFile($parent); + } + } + $this->cache->put($file, $data); return $data; } /** * scan all the files in a folder and store them in the cache * - * @param \OC\Files\File $folder + * @param string $path * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ - public static function scan(\OC\Files\File $folder, $recursive) { + public function scan($path, $recursive) { $size = 0; - $storage = $folder->getStorage(); - $path = $folder->getInternalPath(); - if ($dh = $storage->opendir($path)) { + if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = new \OC\Files\File($storage, $path . '/' . $file); - $data = self::scanFile($child); + $child = $path . '/' . $file; + $data = $this->scanFile($child); if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { - $data['size'] = self::scan($child, self::SCAN_RECURSIVE); + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); } if ($data['size'] >= 0 and $size >= 0) { $size += $data['size']; diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 48cdc1c8c8..8cedadbf19 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -34,6 +34,7 @@ class Cache extends \UnitTestCase { foreach ($data1 as $key => $value) { $this->assertEqual($value, $cacheData1[$key]); } + $this->assertEqual($cacheData1['mimepart'], 'foo'); $this->assertEqual($cacheData1['fileid'], $id1); $this->assertEqual($id1, $this->cache->getId($file1)); diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php new file mode 100644 index 0000000000..3d1c1546ab --- /dev/null +++ b/tests/lib/files/cache/scanner.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Scanner extends \UnitTestCase { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var \OC\Files\Cache\Scanner $scanner + */ + private $scanner; + + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; + + function testFile() { + $data = "dummy file data\n"; + $this->storage->file_put_contents('foo.txt', $data); + $this->scanner->scanFile('foo.txt'); + + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $cachedData = $this->cache->get('foo.txt'); + $this->assertEqual($cachedData['size'], strlen($data)); + $this->assertEqual($cachedData['mimetype'], 'text/plain'); + } + + function setUp() { + $this->storage = new \OC\Files\Storage\Temporary(array()); + $this->scanner = new \OC\Files\Cache\Scanner($this->storage); + $this->cache = new \OC\Files\Cache\Cache($this->storage); + } + + function tearDown() { +// $this->cache->clear(); + } +} From 3c8e5ea3581cbbfc5acd3c229080bc63548d2827 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:31:13 +0200 Subject: [PATCH 022/262] this index cant be unique due to collisions of the root of different storages --- db_structure.xml | 1 - lib/util.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 8bbc6e5cc6..e0b9dc11e9 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -161,7 +161,6 @@ parent_name_hash - true parent ascending diff --git a/lib/util.php b/lib/util.php index 264d61319d..be9d1f4fb5 100755 --- a/lib/util.php +++ b/lib/util.php @@ -81,7 +81,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.9.0. This is not visible to the user - return array(4,86,12); + return array(4,86,13); } /** From 85be00be6595a3af168f6df963ffdeac8c3c6d5e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 11:40:09 +0200 Subject: [PATCH 023/262] add some more test cases for the scanner --- lib/files/cache/scanner.php | 6 ++++-- tests/lib/files/cache/scanner.php | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 721d0d825e..7d449204e8 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -77,12 +77,14 @@ class Scanner { * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ - public function scan($path, $recursive) { + public function scan($path, $recursive = self::SCAN_RECURSIVE) { + $this->scanFile($path); + $size = 0; if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = $path . '/' . $file; + $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 3d1c1546ab..7ee28dfc3f 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -33,6 +33,27 @@ class Scanner extends \UnitTestCase { $cachedData = $this->cache->get('foo.txt'); $this->assertEqual($cachedData['size'], strlen($data)); $this->assertEqual($cachedData['mimetype'], 'text/plain'); + $this->assertNotEqual($cachedData['parent'], -1); //parent folders should be scanned automatically + + $data = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->file_put_contents('foo.png', $data); + $this->scanner->scanFile('foo.png'); + + $this->assertEqual($this->cache->inCache('foo.png'), true); + $cachedData = $this->cache->get('foo.png'); + $this->assertEqual($cachedData['size'], strlen($data)); + $this->assertEqual($cachedData['mimetype'], 'image/png'); + } + + function testFolder() { + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->file_put_contents('foo.txt', $textData); + $this->storage->file_put_contents('foo.png', $imgData); + + $this->scanner->scan(''); + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $this->assertEqual($this->cache->inCache('foo.png'), true); } function setUp() { @@ -42,6 +63,6 @@ class Scanner extends \UnitTestCase { } function tearDown() { -// $this->cache->clear(); + $this->cache->clear(); } } From b9b9fd9dbaae47b3a15aed9694c18b95404550b0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 13:07:19 +0200 Subject: [PATCH 024/262] more tests and fixes for the filesystem scanner --- lib/files/cache/scanner.php | 15 +++++++++--- tests/lib/files/cache/scanner.php | 39 ++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 7d449204e8..e8f54c34be 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -86,15 +86,24 @@ class Scanner { if ($file !== '.' and $file !== '..') { $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); - if ($recursive === self::SCAN_RECURSIVE and $data['mimetype'] === 'httpd/unix-directory') { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + if ($data['mimetype'] === 'httpd/unix-directory') { + if ($recursive === self::SCAN_RECURSIVE) { + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + } else { + $data['size'] = -1; + } } - if ($data['size'] >= 0 and $size >= 0) { + if ($data['size'] === -1) { + $size = -1; + } elseif ($size !== -1) { $size += $data['size']; } } } } + if ($size !== -1) { + $this->cache->put($path, array('size' => $size)); + } return $size; } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 7ee28dfc3f..41286e69d3 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -45,15 +45,52 @@ class Scanner extends \UnitTestCase { $this->assertEqual($cachedData['mimetype'], 'image/png'); } - function testFolder() { + private function fillTestFolders() { $textData = "dummy file data\n"; $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->mkdir('folder'); $this->storage->file_put_contents('foo.txt', $textData); $this->storage->file_put_contents('foo.png', $imgData); + $this->storage->file_put_contents('folder/bar.txt', $textData); + } + + function testFolder() { + $this->fillTestFolders(); $this->scanner->scan(''); + $this->assertEqual($this->cache->inCache(''), true); $this->assertEqual($this->cache->inCache('foo.txt'), true); $this->assertEqual($this->cache->inCache('foo.png'), true); + $this->assertEqual($this->cache->inCache('folder'), true); + $this->assertEqual($this->cache->inCache('folder/bar.txt'), true); + + $cachedDataText = $this->cache->get('foo.txt'); + $cachedDataText2 = $this->cache->get('foo.txt'); + $cachedDataImage = $this->cache->get('foo.png'); + $cachedDataFolder = $this->cache->get(''); + $cachedDataFolder2 = $this->cache->get('folder'); + + $this->assertEqual($cachedDataImage['parent'], $cachedDataText['parent']); + $this->assertEqual($cachedDataFolder['fileid'], $cachedDataImage['parent']); + $this->assertEqual($cachedDataFolder['size'], $cachedDataImage['size'] + $cachedDataText['size'] + $cachedDataText2['size']); + $this->assertEqual($cachedDataFolder2['size'], $cachedDataText2['size']); + } + + function testShallow() { + $this->fillTestFolders(); + + $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $this->assertEqual($this->cache->inCache(''), true); + $this->assertEqual($this->cache->inCache('foo.txt'), true); + $this->assertEqual($this->cache->inCache('foo.png'), true); + $this->assertEqual($this->cache->inCache('folder'), true); + $this->assertEqual($this->cache->inCache('folder/bar.txt'), false); + + $cachedDataFolder = $this->cache->get(''); + $cachedDataFolder2 = $this->cache->get('folder'); + + $this->assertEqual($cachedDataFolder['size'], -1); + $this->assertEqual($cachedDataFolder2['size'], -1); } function setUp() { From c815fd5a5c8cba52b24327584e689498cb03fb3e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 8 Oct 2012 14:31:13 +0200 Subject: [PATCH 025/262] fix files_external test cases --- apps/files_external/tests/dropbox.php | 8 +++++--- apps/files_external/tests/smb.php | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/files_external/tests/dropbox.php b/apps/files_external/tests/dropbox.php index 64eb2556c9..e77e0767c9 100644 --- a/apps/files_external/tests/dropbox.php +++ b/apps/files_external/tests/dropbox.php @@ -6,19 +6,21 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('files_external/tests/config.php'); if(!is_array($config) or !isset($config['dropbox']) or !$config['dropbox']['run']) { - abstract class Test_Filestorage_Dropbox extends Test_FileStorage{} + abstract class Dropbox extends Storage{} return; }else{ - class Test_Filestorage_Dropbox extends Test_FileStorage { + class Dropbox extends Storage { private $config; public function setUp() { $id=uniqid(); $this->config=include('files_external/tests/config.php'); $this->config['dropbox']['root'].='/'.$id;//make sure we have an new empty folder to work in - $this->instance=new OC_Filestorage_Dropbox($this->config['dropbox']); + $this->instance=new \OC\Files\Storage\Dropbox($this->config['dropbox']); } public function tearDown() { diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php index 87b110a241..24728dc237 100644 --- a/apps/files_external/tests/smb.php +++ b/apps/files_external/tests/smb.php @@ -6,9 +6,10 @@ * See the COPYING-README file. */ +namespace Test\Files\Storage; + $config=include('apps/files_external/tests/config.php'); -namespace Test\Files\Storage; if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) { abstract class SMB extends Storage{} From 13515effc99bfad7e776d00476e897fa396a8c6c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 8 Oct 2012 14:58:21 +0200 Subject: [PATCH 026/262] add Cache::getStatus --- lib/files/cache/cache.php | 29 +++++++++++++++++++++++++++++ tests/lib/files/cache/cache.php | 10 ++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 79673771e5..5ef49246ea 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -9,6 +9,11 @@ namespace OC\Files\Cache; class Cache { + const NOT_FOUND = 0; + const PARTIAL = 1; //only partial data available, file not cached in the database + const SHALLOW = 2; //folder in cache, but not all child files are completely scanned + const COMPLETE = 3; + /** * @var \OC\Files\Storage\Storage */ @@ -233,4 +238,28 @@ class Cache { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); $query->execute(array($this->storageId)); } + + /** + * @param string $file + * + * @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE + */ + public function getStatus($file) { + $pathHash = md5($file); + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $result = $query->execute(array($this->storageId, $pathHash)); + if ($row = $result->fetchRow()) { + if ((int)$row['size'] === -1) { + return self::SHALLOW; + } else { + return self::COMPLETE; + } + } else { + if (isset($this->partial[$file])) { + return self::PARTIAL; + } else { + return self::NOT_FOUND; + } + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 8cedadbf19..177cf1c045 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -101,6 +101,16 @@ class Cache extends \UnitTestCase { } } + function testStatus() { + $this->assertEquals(\OC\Files\Cache\Cache::NOT_FOUND, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => -1)); + $this->assertEquals(\OC\Files\Cache\Cache::PARTIAL, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => -1, 'mtime' => 20, 'mimetype' => 'foo/file')); + $this->assertEquals(\OC\Files\Cache\Cache::SHALLOW, $this->cache->getStatus('foo')); + $this->cache->put('foo', array('size' => 10)); + $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo')); + } + public function tearDown() { $this->cache->clear(); } From d717a5e55ca54c6ddbaf2f35f0f19b707dcfe1c8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 11:51:14 +0200 Subject: [PATCH 027/262] remove old filecache --- lib/filecache.php | 511 --------------------------------------- lib/filecache/cached.php | 81 ------- lib/filecache/update.php | 217 ----------------- lib/filesystem.php | 12 +- lib/util.php | 7 - 5 files changed, 2 insertions(+), 826 deletions(-) delete mode 100644 lib/filecache.php delete mode 100644 lib/filecache/cached.php delete mode 100644 lib/filecache/update.php diff --git a/lib/filecache.php b/lib/filecache.php deleted file mode 100644 index 8fcb6fd940..0000000000 --- a/lib/filecache.php +++ /dev/null @@ -1,511 +0,0 @@ -. -* -*/ - -/** - * provide caching for filesystem info in the database - * - * not used by OC_Filesystem for reading filesystem info, - * instread apps should use OC_FileCache::get where possible - * - * It will try to keep the data up to date but changes from outside ownCloud can invalidate the cache - */ -class OC_FileCache{ - /** - * get the filesystem info from the cache - * @param string path - * @param string root (optional) - * @return array - * - * returns an associative array with the following keys: - * - size - * - mtime - * - ctime - * - mimetype - * - encrypted - * - versioned - */ - public static function get($path,$root=false) { - if(OC_FileCache_Update::hasUpdated($path,$root)) { - if($root===false) {//filesystem hooks are only valid for the default root - OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$path)); - }else{ - OC_FileCache_Update::update($path,$root); - } - } - return OC_FileCache_Cached::get($path,$root); - } - - /** - * put filesystem info in the cache - * @param string $path - * @param array data - * @param string root (optional) - * - * $data is an assiciative array in the same format as returned by get - */ - public static function put($path,$data,$root=false) { - if($root===false) { - $root=OC_Filesystem::getRoot(); - } - $fullpath=$root.$path; - $parent=self::getParentId($fullpath); - $id=self::getId($fullpath,''); - if(isset(OC_FileCache_Cached::$savedData[$fullpath])) { - $data=array_merge(OC_FileCache_Cached::$savedData[$fullpath],$data); - unset(OC_FileCache_Cached::$savedData[$fullpath]); - } - if($id!=-1) { - self::update($id,$data); - return; - } - - // add parent directory to the file cache if it does not exist yet. - if ($parent == -1 && $fullpath != $root) { - $parentDir = dirname($path); - self::scanFile($parentDir); - $parent = self::getParentId($fullpath); - } - - if(!isset($data['size']) or !isset($data['mtime'])) {//save incomplete data for the next time we write it - OC_FileCache_Cached::$savedData[$fullpath]=$data; - return; - } - if(!isset($data['encrypted'])) { - $data['encrypted']=false; - } - if(!isset($data['versioned'])) { - $data['versioned']=false; - } - $mimePart=dirname($data['mimetype']); - $data['size']=(int)$data['size']; - $data['ctime']=(int)$data['mtime']; - $data['writable']=(int)$data['writable']; - $data['encrypted']=(int)$data['encrypted']; - $data['versioned']=(int)$data['versioned']; - $user=OC_User::getUser(); - $query=OC_DB::prepare('INSERT INTO `*PREFIX*fscache`(`parent`, `name`, `path`, `path_hash`, `size`, `mtime`, `ctime`, `mimetype`, `mimepart`,`user`,`writable`,`encrypted`,`versioned`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)'); - $result=$query->execute(array($parent,basename($fullpath),$fullpath,md5($fullpath),$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned'])); - if(OC_DB::isError($result)) { - OC_Log::write('files','error while writing file('.$fullpath.') to cache',OC_Log::ERROR); - } - - if($cache=OC_Cache::getUserCache(true)) { - $cache->remove('fileid/'.$fullpath);//ensure we don't have -1 cached - } - } - - /** - * update filesystem info of a file - * @param int $id - * @param array $data - */ - private static function update($id,$data) { - $arguments=array(); - $queryParts=array(); - foreach(array('size','mtime','ctime','mimetype','encrypted','versioned','writable') as $attribute) { - if(isset($data[$attribute])) { - //Convert to int it args are false - if($data[$attribute] === false) { - $arguments[] = 0; - }else{ - $arguments[] = $data[$attribute]; - } - $queryParts[]='`'.$attribute.'`=?'; - } - } - if(isset($data['mimetype'])) { - $arguments[]=dirname($data['mimetype']); - $queryParts[]='`mimepart`=?'; - } - $arguments[]=$id; - - $sql = 'UPDATE `*PREFIX*fscache` SET '.implode(' , ',$queryParts).' WHERE `id`=?'; - $query=OC_DB::prepare($sql); - $result=$query->execute($arguments); - if(OC_DB::isError($result)) { - OC_Log::write('files','error while updating file('.$id.') in cache',OC_Log::ERROR); - } - } - - /** - * register a file move in the cache - * @param string oldPath - * @param string newPath - * @param string root (optional) - */ - public static function move($oldPath,$newPath,$root=false) { - if($root===false) { - $root=OC_Filesystem::getRoot(); - } - // If replacing an existing file, delete the file - if (self::inCache($newPath, $root)) { - self::delete($newPath, $root); - } - $oldPath=$root.$oldPath; - $newPath=$root.$newPath; - $newParent=self::getParentId($newPath); - $query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `parent`=? ,`name`=?, `path`=?, `path_hash`=? WHERE `path_hash`=?'); - $query->execute(array($newParent,basename($newPath),$newPath,md5($newPath),md5($oldPath))); - - if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$oldPath)) { - $cache->set('fileid/'.$newPath,$cache->get('fileid/'.$oldPath)); - $cache->remove('fileid/'.$oldPath); - } - - $query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `path` LIKE ?'); - $oldLength=strlen($oldPath); - $updateQuery=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `path`=?, `path_hash`=? WHERE `path_hash`=?'); - while($row= $query->execute(array($oldPath.'/%'))->fetchRow()) { - $old=$row['path']; - $new=$newPath.substr($old,$oldLength); - $updateQuery->execute(array($new,md5($new),md5($old))); - - if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$old)) { - $cache->set('fileid/'.$new,$cache->get('fileid/'.$old)); - $cache->remove('fileid/'.$old); - } - } - } - - /** - * delete info from the cache - * @param string path - * @param string root (optional) - */ - public static function delete($path,$root=false) { - if($root===false) { - $root=OC_Filesystem::getRoot(); - } - $query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache` WHERE `path_hash`=?'); - $query->execute(array(md5($root.$path))); - - //delete everything inside the folder - $query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache` WHERE `path` LIKE ?'); - $query->execute(array($root.$path.'/%')); - - OC_Cache::remove('fileid/'.$root.$path); - } - - /** - * return array of filenames matching the querty - * @param string $query - * @param boolean $returnData - * @param string root (optional) - * @return array of filepaths - */ - public static function search($search,$returnData=false,$root=false) { - if($root===false) { - $root=OC_Filesystem::getRoot(); - } - $rootLen=strlen($root); - if(!$returnData) { - $query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `name` LIKE ? AND `user`=?'); - }else{ - $query=OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `name` LIKE ? AND `user`=?'); - } - $result=$query->execute(array("%$search%",OC_User::getUser())); - $names=array(); - while($row=$result->fetchRow()) { - if(!$returnData) { - $names[]=substr($row['path'],$rootLen); - }else{ - $row['path']=substr($row['path'],$rootLen); - $names[]=$row; - } - } - return $names; - } - - /** - * get all files and folders in a folder - * @param string path - * @param string root (optional) - * @return array - * - * returns an array of assiciative arrays with the following keys: - * - name - * - size - * - mtime - * - ctime - * - mimetype - * - encrypted - * - versioned - */ - public static function getFolderContent($path,$root=false,$mimetype_filter='') { - if(OC_FileCache_Update::hasUpdated($path,$root,true)) { - OC_FileCache_Update::updateFolder($path,$root); - } - return OC_FileCache_Cached::getFolderContent($path,$root,$mimetype_filter); - } - - /** - * check if a file or folder is in the cache - * @param string $path - * @param string root (optional) - * @return bool - */ - public static function inCache($path,$root=false) { - return self::getId($path,$root)!=-1; - } - - /** - * get the file id as used in the cache - * @param string path - * @param string root (optional) - * @return int - */ - public static function getId($path,$root=false) { - if($root===false) { - $root=OC_Filesystem::getRoot(); - } - - $fullPath=$root.$path; - if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$fullPath)) { - return $cache->get('fileid/'.$fullPath); - } - - $query=OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `path_hash`=?'); - $result=$query->execute(array(md5($fullPath))); - if(OC_DB::isError($result)) { - OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR); - return -1; - } - - $result=$result->fetchRow(); - if(is_array($result)) { - $id=$result['id']; - }else{ - $id=-1; - } - if($cache=OC_Cache::getUserCache(true)) { - $cache->set('fileid/'.$fullPath,$id); - } - - return $id; - } - - /** - * get the file path from the id, relative to the home folder of the user - * @param int id - * @param string user (optional) - * @return string - */ - public static function getPath($id,$user='') { - if(!$user) { - $user=OC_User::getUser(); - } - $query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `id`=? AND `user`=?'); - $result=$query->execute(array($id,$user)); - $row=$result->fetchRow(); - $path=$row['path']; - $root='/'.$user.'/files'; - if(substr($path,0,strlen($root))!=$root) { - return false; - } - return substr($path,strlen($root)); - } - - /** - * get the file id of the parent folder, taking into account '/' has no parent - * @param string $path - * @return int - */ - private static function getParentId($path) { - if($path=='/') { - return -1; - }else{ - return self::getId(dirname($path),''); - } - } - - /** - * adjust the size of the parent folders - * @param string $path - * @param int $sizeDiff - * @param string root (optinal) - */ - public static function increaseSize($path,$sizeDiff, $root=false) { - if($sizeDiff==0) return; - $id=self::getId($path,$root); - while($id!=-1) {//walk up the filetree increasing the size of all parent folders - $query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `size`=`size`+? WHERE `id`=?'); - $query->execute(array($sizeDiff,$id)); - $id=self::getParentId($path); - $path=dirname($path); - } - } - - /** - * recursively scan the filesystem and fill the cache - * @param string $path - * @param OC_EventSource $enventSource (optional) - * @param int count (optional) - * @param string root (optional) - */ - public static function scan($path,$eventSource=false,&$count=0,$root=false) { - if($eventSource) { - $eventSource->send('scanning',array('file'=>$path,'count'=>$count)); - } - $lastSend=$count; - // NOTE: Ugly hack to prevent shared files from going into the cache (the source already exists somewhere in the cache) - if (substr($path, 0, 7) == '/Shared') { - return; - } - if($root===false) { - $view=OC_Filesystem::getView(); - }else{ - $view=new OC_FilesystemView($root); - } - self::scanFile($path,$root); - $dh=$view->opendir($path.'/'); - $totalSize=0; - if($dh) { - while (($filename = readdir($dh)) !== false) { - if($filename != '.' and $filename != '..') { - $file=$path.'/'.$filename; - if($view->is_dir($file.'/')) { - self::scan($file,$eventSource,$count,$root); - }else{ - $totalSize+=self::scanFile($file,$root); - $count++; - if($count>$lastSend+25 and $eventSource) { - $lastSend=$count; - $eventSource->send('scanning',array('file'=>$path,'count'=>$count)); - } - } - } - } - } - - OC_FileCache_Update::cleanFolder($path,$root); - self::increaseSize($path,$totalSize,$root); - } - - /** - * scan a single file - * @param string path - * @param string root (optional) - * @return int size of the scanned file - */ - public static function scanFile($path,$root=false) { - // NOTE: Ugly hack to prevent shared files from going into the cache (the source already exists somewhere in the cache) - if (substr($path, 0, 7) == '/Shared') { - return; - } - if($root===false) { - $view=OC_Filesystem::getView(); - }else{ - $view=new OC_FilesystemView($root); - } - if(!$view->is_readable($path)) return; //cant read, nothing we can do - clearstatcache(); - $mimetype=$view->getMimeType($path); - $stat=$view->stat($path); - if($mimetype=='httpd/unix-directory') { - $stat['size'] = 0; - $writable=$view->is_writable($path.'/'); - }else{ - $writable=$view->is_writable($path); - } - $stat['mimetype']=$mimetype; - $stat['writable']=$writable; - if($path=='/') { - $path=''; - } - self::put($path,$stat,$root); - return $stat['size']; - } - - /** - * find files by mimetype - * @param string $part1 - * @param string $part2 (optional) - * @param string root (optional) - * @return array of file paths - * - * $part1 and $part2 together form the complete mimetype. - * e.g. searchByMime('text','plain') - * - * seccond mimetype part can be ommited - * e.g. searchByMime('audio') - */ - public static function searchByMime($part1,$part2=null,$root=false) { - if($root===false) { - $root=OC_Filesystem::getRoot(); - } - $rootLen=strlen($root); - $root .= '%'; - $user=OC_User::getUser(); - if(!$part2) { - $query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `mimepart`=? AND `user`=? AND `path` LIKE ?'); - $result=$query->execute(array($part1,$user, $root)); - }else{ - $query=OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `mimetype`=? AND `user`=? AND `path` LIKE ? '); - $result=$query->execute(array($part1.'/'.$part2,$user, $root)); - } - $names=array(); - while($row=$result->fetchRow()) { - $names[]=substr($row['path'],$rootLen); - } - return $names; - } - - /** - * clean old pre-path_hash entries - */ - public static function clean() { - $query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache` WHERE LENGTH(`path_hash`)<30'); - $query->execute(); - } - - /** - * clear filecache entries - * @param string user (optonal) - */ - public static function clear($user='') { - if($user) { - $query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache` WHERE `user`=?'); - $query->execute(array($user)); - }else{ - $query=OC_DB::prepare('DELETE FROM `*PREFIX*fscache`'); - $query->execute(); - } - } - - /** - * trigger an update for the cache by setting the mtimes to 0 - * @param string $user (optional) - */ - public static function triggerUpdate($user=''){ - if($user) { - $query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 WHERE `user`=? AND `mimetype`="httpd/unix-directory"'); - $query->execute(array($user)); - }else{ - $query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 AND `mimetype`="httpd/unix-directory"'); - $query->execute(); - } - } -} - -//watch for changes and try to keep the cache up to date -OC_Hook::connect('OC_Filesystem','post_write','OC_FileCache_Update','fileSystemWatcherWrite'); -OC_Hook::connect('OC_Filesystem','post_delete','OC_FileCache_Update','fileSystemWatcherDelete'); -OC_Hook::connect('OC_Filesystem','post_rename','OC_FileCache_Update','fileSystemWatcherRename'); diff --git a/lib/filecache/cached.php b/lib/filecache/cached.php deleted file mode 100644 index 9b1eb4f780..0000000000 --- a/lib/filecache/cached.php +++ /dev/null @@ -1,81 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - - -/** - * get data from the filecache without checking for updates - */ -class OC_FileCache_Cached{ - public static $savedData=array(); - - public static function get($path,$root=false) { - if($root===false) { - $root=OC_Filesystem::getRoot(); - } - $path=$root.$path; - $stmt=OC_DB::prepare('SELECT `path`,`ctime`,`mtime`,`mimetype`,`size`,`encrypted`,`versioned`,`writable` FROM `*PREFIX*fscache` WHERE `path_hash`=?'); - if ( ! OC_DB::isError($stmt) ) { - $result=$stmt->execute(array(md5($path))); - if ( ! OC_DB::isError($result) ) { - $result = $result->fetchRow(); - } else { - OC:Log::write('OC_FileCache_Cached', 'could not execute get: '. OC_DB::getErrorMessage($result), OC_Log::ERROR); - $result = false; - } - } else { - OC_Log::write('OC_FileCache_Cached', 'could not prepare get: '. OC_DB::getErrorMessage($stmt), OC_Log::ERROR); - $result = false; - } - if(is_array($result)) { - if(isset(self::$savedData[$path])) { - $result=array_merge($result, self::$savedData[$path]); - } - return $result; - }else{ - if(isset(self::$savedData[$path])) { - return self::$savedData[$path]; - }else{ - return array(); - } - } - } - - /** - * get all files and folders in a folder - * @param string path - * @param string root (optional) - * @return array - * - * returns an array of assiciative arrays with the following keys: - * - path - * - name - * - size - * - mtime - * - ctime - * - mimetype - * - encrypted - * - versioned - */ - public static function getFolderContent($path,$root=false,$mimetype_filter='') { - if($root===false) { - $root=OC_Filesystem::getRoot(); - } - $parent=OC_FileCache::getId($path, $root); - if($parent==-1) { - return array(); - } - $query=OC_DB::prepare('SELECT `id`,`path`,`name`,`ctime`,`mtime`,`mimetype`,`size`,`encrypted`,`versioned`,`writable` FROM `*PREFIX*fscache` WHERE `parent`=? AND (`mimetype` LIKE ? OR `mimetype` = ?)'); - $result=$query->execute(array($parent, $mimetype_filter.'%', 'httpd/unix-directory'))->fetchAll(); - if(is_array($result)) { - return $result; - }else{ - OC_Log::write('files', 'getFolderContent(): file not found in cache ('.$path.')', OC_Log::DEBUG); - return false; - } - } -} \ No newline at end of file diff --git a/lib/filecache/update.php b/lib/filecache/update.php deleted file mode 100644 index 1b81f70d77..0000000000 --- a/lib/filecache/update.php +++ /dev/null @@ -1,217 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - - -/** - * handles updating the filecache according to outside changes - */ -class OC_FileCache_Update{ - /** - * check if a file or folder is updated outside owncloud - * @param string path - * @param string root (optional) - * @param boolean folder - * @return bool - */ - public static function hasUpdated($path,$root=false,$folder=false) { - if($root===false) { - $view=OC_Filesystem::getView(); - }else{ - $view=new OC_FilesystemView($root); - } - if(!$view->file_exists($path)) { - return false; - } - $cachedData=OC_FileCache_Cached::get($path, $root); - if(isset($cachedData['mtime'])) { - $cachedMTime=$cachedData['mtime']; - if($folder) { - return $view->hasUpdated($path.'/', $cachedMTime); - }else{ - return $view->hasUpdated($path, $cachedMTime); - } - }else{//file not in cache, so it has to be updated - if(($path=='/' or $path=='') and $root===false) {//dont auto update the home folder, it will be scanned - return false; - } - return true; - } - } - - /** - * delete non existing files from the cache - */ - public static function cleanFolder($path,$root=false) { - if($root===false) { - $view=OC_Filesystem::getView(); - }else{ - $view=new OC_FilesystemView($root); - } - - $cachedContent=OC_FileCache_Cached::getFolderContent($path,$root); - foreach($cachedContent as $fileData) { - $path=$fileData['path']; - $file=$view->getRelativePath($path); - if(!$view->file_exists($file)) { - if($root===false) {//filesystem hooks are only valid for the default root - OC_Hook::emit('OC_Filesystem', 'post_delete', array('path'=>$file)); - }else{ - self::delete($file, $root); - } - } - } - } - - /** - * update the cache according to changes in the folder - * @param string path - * @param string root (optional) - */ - public static function updateFolder($path,$root=false) { - if($root===false) { - $view=OC_Filesystem::getView(); - }else{ - $view=new OC_FilesystemView($root); - } - $dh=$view->opendir($path.'/'); - if($dh) {//check for changed/new files - while (($filename = readdir($dh)) !== false) { - if($filename != '.' and $filename != '..' and $filename != '') { - $file=$path.'/'.$filename; - $isDir=$view->is_dir($file); - if(self::hasUpdated($file, $root, $isDir)) { - if($isDir){ - self::updateFolder($file, $root); - }elseif($root===false) {//filesystem hooks are only valid for the default root - OC_Hook::emit('OC_Filesystem', 'post_write', array('path'=>$file)); - }else{ - self::update($file, $root); - } - } - } - } - } - - self::cleanFolder($path, $root); - - //update the folder last, so we can calculate the size correctly - if($root===false) {//filesystem hooks are only valid for the default root - OC_Hook::emit('OC_Filesystem', 'post_write', array('path'=>$path)); - }else{ - self::update($path, $root); - } - } - - /** - * called when changes are made to files - * @param array $params - * @param string root (optional) - */ - public static function fileSystemWatcherWrite($params) { - $path=$params['path']; - self::update($path); - } - - /** - * called when files are deleted - * @param array $params - * @param string root (optional) - */ - public static function fileSystemWatcherDelete($params) { - $path=$params['path']; - self::delete($path); - } - - /** - * called when files are deleted - * @param array $params - * @param string root (optional) - */ - public static function fileSystemWatcherRename($params) { - $oldPath=$params['oldpath']; - $newPath=$params['newpath']; - self::rename($oldPath, $newPath); - } - - /** - * update the filecache according to changes to the filesystem - * @param string path - * @param string root (optional) - */ - public static function update($path,$root=false) { - if($root===false) { - $view=OC_Filesystem::getView(); - }else{ - $view=new OC_FilesystemView($root); - } - - $mimetype=$view->getMimeType($path); - - $size=0; - $cached=OC_FileCache_Cached::get($path,$root); - $cachedSize=isset($cached['size'])?$cached['size']:0; - - if($view->is_dir($path.'/')) { - if(OC_FileCache::inCache($path, $root)) { - $cachedContent=OC_FileCache_Cached::getFolderContent($path, $root); - foreach($cachedContent as $file) { - $size+=$file['size']; - } - $mtime=$view->filemtime($path.'/'); - $ctime=$view->filectime($path.'/'); - $writable=$view->is_writable($path.'/'); - OC_FileCache::put($path, array('size'=>$size,'mtime'=>$mtime,'ctime'=>$ctime,'mimetype'=>$mimetype,'writable'=>$writable)); - }else{ - $count=0; - OC_FileCache::scan($path, null, $count, $root); - return; //increaseSize is already called inside scan - } - }else{ - $size=OC_FileCache::scanFile($path, $root); - } - OC_FileCache::increaseSize(dirname($path), $size-$cachedSize, $root); - } - - /** - * update the filesystem after a delete has been detected - * @param string path - * @param string root (optional) - */ - public static function delete($path,$root=false) { - $cached=OC_FileCache_Cached::get($path, $root); - if(!isset($cached['size'])) { - return; - } - $size=$cached['size']; - OC_FileCache::increaseSize(dirname($path), -$size, $root); - OC_FileCache::delete($path, $root); - } - - /** - * update the filesystem after a rename has been detected - * @param string oldPath - * @param string newPath - * @param string root (optional) - */ - public static function rename($oldPath,$newPath,$root=false) { - if(!OC_FileCache::inCache($oldPath, $root)) { - return; - } - if($root===false) { - $view=OC_Filesystem::getView(); - }else{ - $view=new OC_FilesystemView($root); - } - - $cached=OC_FileCache_Cached::get($oldPath, $root); - $oldSize=$cached['size']; - OC_FileCache::increaseSize(dirname($oldPath), -$oldSize, $root); - OC_FileCache::increaseSize(dirname($newPath), $oldSize, $root); - OC_FileCache::move($oldPath, $newPath); - } -} diff --git a/lib/filesystem.php b/lib/filesystem.php index 0d24b7203b..b73b52d420 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -254,13 +254,6 @@ class OC_Filesystem{ } } } - - $mtime=filemtime(OC::$SERVERROOT.'/config/mount.php'); - $previousMTime=OC_Appconfig::getValue('files','mountconfigmtime',0); - if($mtime>$previousMTime) {//mount config has changed, filecache needs to be updated - OC_FileCache::triggerUpdate(); - OC_Appconfig::setValue('files','mountconfigmtime',$mtime); - } } self::$loaded=true; @@ -399,7 +392,7 @@ class OC_Filesystem{ } /** - * checks if a file is blacklsited for storage in the filesystem + * checks if a file is blacklisted for storage in the filesystem * Listens to write and rename hooks * @param array $data from hook */ @@ -419,7 +412,7 @@ class OC_Filesystem{ } /** - * following functions are equivilent to their php buildin equivilents for arguments/return values. + * following functions are equivalent to their php builtin equivalents for arguments/return values. */ static public function mkdir($path) { return self::$defaultInstance->mkdir($path); @@ -592,4 +585,3 @@ OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook') OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook'); OC_Util::setupFS(); -require_once 'filecache.php'; diff --git a/lib/util.php b/lib/util.php index b21580cb01..557f731522 100755 --- a/lib/util.php +++ b/lib/util.php @@ -58,13 +58,6 @@ class OC_Util { OC_Filesystem::mount($options['class'], $options['options'], $mountPoint); } } - - $mtime=filemtime($user_root.'/mount.php'); - $previousMTime=OC_Preferences::getValue($user,'files','mountconfigmtime',0); - if($mtime>$previousMTime) {//mount config has changed, filecache needs to be updated - OC_FileCache::triggerUpdate($user); - OC_Preferences::setValue($user,'files','mountconfigmtime',$mtime); - } } OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $user_dir)); } From 9df60d27bd9dad6a37a0d763b808a5b1c5ade5c5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 11:54:44 +0200 Subject: [PATCH 028/262] move some code around --- lib/files/filesystem.php | 629 +++++++++++++++++++++ lib/{filesystemview.php => files/view.php} | 387 +++++++------ lib/filesystem.php | 562 ------------------ 3 files changed, 835 insertions(+), 743 deletions(-) create mode 100644 lib/files/filesystem.php rename lib/{filesystemview.php => files/view.php} (62%) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php new file mode 100644 index 0000000000..d0a96b59a0 --- /dev/null +++ b/lib/files/filesystem.php @@ -0,0 +1,629 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * Class for abstraction of filesystem functions + * This class won't call any filesystem functions for itself but but will pass them to the correct OC_Filestorage object + * this class should also handle all the file permission related stuff + * + * Hooks provided: + * read(path) + * write(path, &run) + * post_write(path) + * create(path, &run) (when a file is created, both create and write will be emited in that order) + * post_create(path) + * delete(path, &run) + * post_delete(path) + * rename(oldpath,newpath, &run) + * post_rename(oldpath,newpath) + * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emited in that order) + * post_rename(oldpath,newpath) + * + * the &run parameter can be set to false to prevent the operation from occuring + */ + +namespace OC\Files; + +class Filesystem { + static private $storages = array(); + static private $mounts = array(); + public static $loaded = false; + /** + * @var \OC\Files\Storage\Storage $defaultInstance + */ + static private $defaultInstance; + + + /** + * classname which used for hooks handling + * used as signalclass in OC_Hooks::emit() + */ + const CLASSNAME = 'OC_Filesystem'; + + /** + * signalname emited before file renaming + * + * @param oldpath + * @param newpath + */ + const signal_rename = 'rename'; + + /** + * signal emited after file renaming + * + * @param oldpath + * @param newpath + */ + const signal_post_rename = 'post_rename'; + + /** + * signal emited before file/dir creation + * + * @param path + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_create = 'create'; + + /** + * signal emited after file/dir creation + * + * @param path + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_post_create = 'post_create'; + + /** + * signal emits before file/dir copy + * + * @param oldpath + * @param newpath + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_copy = 'copy'; + + /** + * signal emits after file/dir copy + * + * @param oldpath + * @param newpath + */ + const signal_post_copy = 'post_copy'; + + /** + * signal emits before file/dir save + * + * @param path + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_write = 'write'; + + /** + * signal emits after file/dir save + * + * @param path + */ + const signal_post_write = 'post_write'; + + /** + * signal emits when reading file/dir + * + * @param path + */ + const signal_read = 'read'; + + /** + * signal emits when removing file/dir + * + * @param path + */ + const signal_delete = 'delete'; + + /** + * parameters definitions for signals + */ + const signal_param_path = 'path'; + const signal_param_oldpath = 'oldpath'; + const signal_param_newpath = 'newpath'; + + /** + * run - changing this flag to false in hook handler will cancel event + */ + const signal_param_run = 'run'; + + /** + * get the mountpoint of the storage object for a path + ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account + * + * @param string path + * @return string + */ + static public function getMountPoint($path) { + OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); + if (!$path) { + $path = '/'; + } + if ($path[0] !== '/') { + $path = '/' . $path; + } + $path = str_replace('//', '/', $path); + $foundMountPoint = ''; + $mountPoints = array_keys(OC_Filesystem::$mounts); + foreach ($mountPoints as $mountpoint) { + if ($mountpoint == $path) { + return $mountpoint; + } + if (strpos($path, $mountpoint) === 0 and strlen($mountpoint) > strlen($foundMountPoint)) { + $foundMountPoint = $mountpoint; + } + } + return $foundMountPoint; + } + + /** + * get the part of the path relative to the mountpoint of the storage it's stored in + * + * @param string path + * @return bool + */ + static public function getInternalPath($path) { + $mountPoint = self::getMountPoint($path); + $internalPath = substr($path, strlen($mountPoint)); + return $internalPath; + } + + /** + * get the storage object for a path + * + * @param string path + * @return \OC\Files\Storage\Storage + */ + static public function getStorage($path) { + $mountpoint = self::getMountPoint($path); + if ($mountpoint) { + if (!isset(OC_Filesystem::$storages[$mountpoint])) { + $mount = OC_Filesystem::$mounts[$mountpoint]; + OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']); + } + return OC_Filesystem::$storages[$mountpoint]; + } + } + + /** + * resolve a path to a storage and internal path + * + * @param string $path + * @return array consisting of the storage and the internal path + */ + static public function resolvePath($path) { + $mountpoint = self::getMountPoint($path); + if ($mountpoint) { + if (!isset(OC_Filesystem::$storages[$mountpoint])) { + $mount = OC_Filesystem::$mounts[$mountpoint]; + OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']); + } + $storage = OC_Filesystem::$storages[$mountpoint]; + $internalPath = substr($path, strlen($mountpoint)); + return array($storage, $internalPath); + } + } + + static public function init($root) { + if (self::$defaultInstance) { + return false; + } + self::$defaultInstance = new OC_FilesystemView($root); + +//load custom mount config + if (is_file(OC::$SERVERROOT . '/config/mount.php')) { + $mountConfig = include(OC::$SERVERROOT . '/config/mount.php'); + if (isset($mountConfig['global'])) { + foreach ($mountConfig['global'] as $mountPoint => $options) { + self::mount($options['class'], $options['options'], $mountPoint); + } + } + + if (isset($mountConfig['group'])) { + foreach ($mountConfig['group'] as $group => $mounts) { + if (OC_Group::inGroup(OC_User::getUser(), $group)) { + foreach ($mounts as $mountPoint => $options) { + $mountPoint = self::setUserVars($mountPoint); + foreach ($options as &$option) { + $option = self::setUserVars($option); + } + self::mount($options['class'], $options['options'], $mountPoint); + } + } + } + } + + if (isset($mountConfig['user'])) { + foreach ($mountConfig['user'] as $user => $mounts) { + if ($user === 'all' or strtolower($user) === strtolower(OC_User::getUser())) { + foreach ($mounts as $mountPoint => $options) { + $mountPoint = self::setUserVars($mountPoint); + foreach ($options as &$option) { + $option = self::setUserVars($option); + } + self::mount($options['class'], $options['options'], $mountPoint); + } + } + } + } + } + + self::$loaded = true; + } + + /** + * fill in the correct values for $user, and $password placeholders + * + * @param string intput + * @return string + */ + private static function setUserVars($input) { + return str_replace('$user', OC_User::getUser(), $input); + } + + /** + * get the default filesystem view + * + * @return OC_FilesystemView + */ + static public function getView() { + return self::$defaultInstance; + } + + /** + * tear down the filesystem, removing all storage providers + */ + static public function tearDown() { + self::$storages = array(); + } + + /** + * create a new storage of a specific type + * + * @param string type + * @param array arguments + * @return \OC\Files\Storage\Storage + */ + static private function createStorage($class, $arguments) { + if (class_exists($class)) { + try { + return new $class($arguments); + } catch (Exception $exception) { + OC_Log::write('core', $exception->getMessage(), OC_Log::ERROR); + return false; + } + } else { + OC_Log::write('core', 'storage backend ' . $class . ' not found', OC_Log::ERROR); + return false; + } + } + + /** + * change the root to a fake root + * + * @param string fakeRoot + * @return bool + */ + static public function chroot($fakeRoot) { + return self::$defaultInstance->chroot($fakeRoot); + } + + /** + * @brief get the relative path of the root data directory for the current user + * @return string + * + * Returns path like /admin/files + */ + static public function getRoot() { + return self::$defaultInstance->getRoot(); + } + + /** + * clear all mounts and storage backends + */ + public static function clearMounts() { + self::$mounts = array(); + self::$storages = array(); + } + + /** + * mount an \OC\Files\Storage\Storage in our virtual filesystem + * + * @param \OC\Files\Storage\Storage storage + * @param string mountpoint + */ + static public function mount($class, $arguments, $mountpoint) { + if ($mountpoint[0] != '/') { + $mountpoint = '/' . $mountpoint; + } + if (substr($mountpoint, -1) !== '/') { + $mountpoint = $mountpoint . '/'; + } + self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); + } + + /** + * return the path to a local version of the file + * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed + * + * @param string path + * @return string + */ + static public function getLocalFile($path) { + return self::$defaultInstance->getLocalFile($path); + } + + /** + * @param string path + * @return string + */ + static public function getLocalFolder($path) { + return self::$defaultInstance->getLocalFolder($path); + } + + /** + * return path to file which reflects one visible in browser + * + * @param string path + * @return string + */ + static public function getLocalPath($path) { + $datadir = OC_User::getHome(OC_User::getUser()) . '/files'; + $newpath = $path; + if (strncmp($newpath, $datadir, strlen($datadir)) == 0) { + $newpath = substr($path, strlen($datadir)); + } + return $newpath; + } + + /** + * check if the requested path is valid + * + * @param string path + * @return bool + */ + static public function isValidPath($path) { + if (!$path || $path[0] !== '/') { + $path = '/' . $path; + } + if (strstr($path, '/../') || strrchr($path, '/') === '/..') { + return false; + } + return true; + } + + /** + * checks if a file is blacklisted for storage in the filesystem + * Listens to write and rename hooks + * + * @param array $data from hook + */ + static public function isBlacklisted($data) { + $blacklist = array('.htaccess'); + if (isset($data['path'])) { + $path = $data['path']; + } else if (isset($data['newpath'])) { + $path = $data['newpath']; + } + if (isset($path)) { + $filename = strtolower(basename($path)); + if (in_array($filename, $blacklist)) { + $data['run'] = false; + } + } + } + + /** + * following functions are equivalent to their php builtin equivalents for arguments/return values. + */ + static public function mkdir($path) { + return self::$defaultInstance->mkdir($path); + } + + static public function rmdir($path) { + return self::$defaultInstance->rmdir($path); + } + + static public function opendir($path) { + return self::$defaultInstance->opendir($path); + } + + static public function readdir($path) { + return self::$defaultInstance->readdir($path); + } + + static public function is_dir($path) { + return self::$defaultInstance->is_dir($path); + } + + static public function is_file($path) { + return self::$defaultInstance->is_file($path); + } + + static public function stat($path) { + return self::$defaultInstance->stat($path); + } + + static public function filetype($path) { + return self::$defaultInstance->filetype($path); + } + + static public function filesize($path) { + return self::$defaultInstance->filesize($path); + } + + static public function readfile($path) { + return self::$defaultInstance->readfile($path); + } + + /** + * @deprecated Replaced by isReadable() as part of CRUDS + */ + static public function is_readable($path) { + return self::$defaultInstance->is_readable($path); + } + + /** + * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS + */ + static public function is_writable($path) { + return self::$defaultInstance->is_writable($path); + } + + static public function isCreatable($path) { + return self::$defaultInstance->isCreatable($path); + } + + static public function isReadable($path) { + return self::$defaultInstance->isReadable($path); + } + + static public function isUpdatable($path) { + return self::$defaultInstance->isUpdatable($path); + } + + static public function isDeletable($path) { + return self::$defaultInstance->isDeletable($path); + } + + static public function isSharable($path) { + return self::$defaultInstance->isSharable($path); + } + + static public function file_exists($path) { + return self::$defaultInstance->file_exists($path); + } + + static public function filectime($path) { + return self::$defaultInstance->filectime($path); + } + + static public function filemtime($path) { + return self::$defaultInstance->filemtime($path); + } + + static public function touch($path, $mtime = null) { + return self::$defaultInstance->touch($path, $mtime); + } + + static public function file_get_contents($path) { + return self::$defaultInstance->file_get_contents($path); + } + + static public function file_put_contents($path, $data) { + return self::$defaultInstance->file_put_contents($path, $data); + } + + static public function unlink($path) { + return self::$defaultInstance->unlink($path); + } + + static public function rename($path1, $path2) { + return self::$defaultInstance->rename($path1, $path2); + } + + static public function copy($path1, $path2) { + return self::$defaultInstance->copy($path1, $path2); + } + + static public function fopen($path, $mode) { + return self::$defaultInstance->fopen($path, $mode); + } + + static public function toTmpFile($path) { + return self::$defaultInstance->toTmpFile($path); + } + + static public function fromTmpFile($tmpFile, $path) { + return self::$defaultInstance->fromTmpFile($tmpFile, $path); + } + + static public function getMimeType($path) { + return self::$defaultInstance->getMimeType($path); + } + + static public function hash($type, $path, $raw = false) { + return self::$defaultInstance->hash($type, $path, $raw); + } + + static public function free_space($path = '/') { + return self::$defaultInstance->free_space($path); + } + + static public function search($query) { + return OC_FileCache::search($query); + } + + /** + * check if a file or folder has been updated since $time + * + * @param int $time + * @return bool + */ + static public function hasUpdated($path, $time) { + return self::$defaultInstance->hasUpdated($path, $time); + } + + static public function removeETagHook($params, $root = false) { + if (isset($params['path'])) { + $path = $params['path']; + } else { + $path = $params['oldpath']; + } + + if ($root) { // reduce path to the required part of it (no 'username/files') + $fakeRootView = new OC_FilesystemView($root); + $count = 1; + $path = str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); + } + + $path = self::normalizePath($path); + OC_Connector_Sabre_Node::removeETagPropertyForPath($path); + } + + /** + * normalize a path + * + * @param string path + * @param bool $stripTrailingSlash + * @return string + */ + public static function normalizePath($path, $stripTrailingSlash = true) { + if ($path == '') { + return '/'; + } +//no windows style slashes + $path = str_replace('\\', '/', $path); +//add leading slash + if ($path[0] !== '/') { + $path = '/' . $path; + } +//remove trainling slash + if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { + $path = substr($path, 0, -1); + } +//remove duplicate slashes + while (strpos($path, '//') !== false) { + $path = str_replace('//', '/', $path); + } +//normalize unicode if possible + if (class_exists('Normalizer')) { + $path = Normalizer::normalize($path); + } + return $path; + } +} + +OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); +OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); +OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); + +OC_Util::setupFS(); diff --git a/lib/filesystemview.php b/lib/files/view.php similarity index 62% rename from lib/filesystemview.php rename to lib/files/view.php index 071fc781f1..8c3f288f44 100644 --- a/lib/filesystemview.php +++ b/lib/files/view.php @@ -1,26 +1,11 @@ . + * Copyright (c) 2012 Robin Appelman + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ - /** * Class to provide access to ownCloud filesystem via a "view", and methods for * working with files within that view (e.g. read, write, delete, etc.). Each @@ -38,41 +23,45 @@ * \OC\Files\Storage\Storage object */ -class OC_FilesystemView { - private $fakeRoot=''; - private $internal_path_cache=array(); - private $storage_cache=array(); +namespace OC\Files; + +class View { + private $fakeRoot = ''; + private $internal_path_cache = array(); + private $storage_cache = array(); public function __construct($root) { - $this->fakeRoot=$root; + $this->fakeRoot = $root; } public function getAbsolutePath($path) { - if(!$path) { - $path='/'; + if (!$path) { + $path = '/'; } - if($path[0]!=='/') { - $path='/'.$path; + if ($path[0] !== '/') { + $path = '/' . $path; } - return $this->fakeRoot.$path; + return $this->fakeRoot . $path; } /** - * change the root to a fake toor - * @param string fakeRoot - * @return bool - */ + * change the root to a fake toor + * + * @param string fakeRoot + * @return bool + */ public function chroot($fakeRoot) { - if(!$fakeRoot=='') { - if($fakeRoot[0]!=='/') { - $fakeRoot='/'.$fakeRoot; + if (!$fakeRoot == '') { + if ($fakeRoot[0] !== '/') { + $fakeRoot = '/' . $fakeRoot; } } - $this->fakeRoot=$fakeRoot; + $this->fakeRoot = $fakeRoot; } /** * get the fake root + * * @return string */ public function getRoot() { @@ -80,10 +69,11 @@ class OC_FilesystemView { } /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * @param string path - * @return bool - */ + * get the part of the path relative to the mountpoint of the storage it's stored in + * + * @param string path + * @return bool + */ public function getInternalPath($path) { if (!isset($this->internal_path_cache[$path])) { $this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path)); @@ -93,30 +83,32 @@ class OC_FilesystemView { /** * get path relative to the root of the view + * * @param string path * @return string */ public function getRelativePath($path) { - if($this->fakeRoot=='') { + if ($this->fakeRoot == '') { return $path; } - if(strpos($path, $this->fakeRoot)!==0) { + if (strpos($path, $this->fakeRoot) !== 0) { return null; - }else{ - $path=substr($path, strlen($this->fakeRoot)); - if(strlen($path)===0) { + } else { + $path = substr($path, strlen($this->fakeRoot)); + if (strlen($path) === 0) { return '/'; - }else{ + } else { return $path; } } } /** - * get the storage object for a path - * @param string path - * @return \OC\Files\Storage\Storage - */ + * get the storage object for a path + * + * @param string path + * @return \OC\Files\Storage\Storage + */ public function getStorage($path) { if (!isset($this->storage_cache[$path])) { $this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path)); @@ -125,35 +117,37 @@ class OC_FilesystemView { } /** - * get the mountpoint of the storage object for a path + * get the mountpoint of the storage object for a path ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account - * - * @param string path - * @return string - */ + * + * @param string path + * @return string + */ public function getMountPoint($path) { return OC_Filesystem::getMountPoint($this->getAbsolutePath($path)); } /** - * return the path to a local version of the file - * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed - * @param string path - * @return string - */ + * return the path to a local version of the file + * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed + * + * @param string path + * @return string + */ public function getLocalFile($path) { - $parent=substr($path, 0, strrpos($path,'/')); - if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) { + $parent = substr($path, 0, strrpos($path, '/')); + if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { return $storage->getLocalFile($this->getInternalPath($path)); } } + /** * @param string path * @return string */ public function getLocalFolder($path) { - $parent=substr($path, 0, strrpos($path,'/')); - if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) { + $parent = substr($path, 0, strrpos($path, '/')); + if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { return $storage->getLocalFolder($this->getInternalPath($path)); } } @@ -166,105 +160,127 @@ class OC_FilesystemView { public function mkdir($path) { return $this->basicOperation('mkdir', $path, array('create', 'write')); } + public function rmdir($path) { return $this->basicOperation('rmdir', $path, array('delete')); } + public function opendir($path) { return $this->basicOperation('opendir', $path, array('read')); } + public function readdir($handle) { - $fsLocal= new \OC\Files\Storage\Local( array( 'datadir' => '/' ) ); - return $fsLocal->readdir( $handle ); + $fsLocal = new \OC\Files\Storage\Local(array('datadir' => '/')); + return $fsLocal->readdir($handle); } + public function is_dir($path) { - if($path=='/') { + if ($path == '/') { return true; } return $this->basicOperation('is_dir', $path); } + public function is_file($path) { - if($path=='/') { + if ($path == '/') { return false; } return $this->basicOperation('is_file', $path); } + public function stat($path) { return $this->basicOperation('stat', $path); } + public function filetype($path) { return $this->basicOperation('filetype', $path); } + public function filesize($path) { return $this->basicOperation('filesize', $path); } + public function readfile($path) { @ob_end_clean(); - $handle=$this->fopen($path, 'rb'); + $handle = $this->fopen($path, 'rb'); if ($handle) { - $chunkSize = 8192;// 8 MB chunks + $chunkSize = 8192; // 8 MB chunks while (!feof($handle)) { echo fread($handle, $chunkSize); flush(); } - $size=$this->filesize($path); + $size = $this->filesize($path); return $size; } return false; } + /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ + * @deprecated Replaced by isReadable() as part of CRUDS + */ public function is_readable($path) { - return $this->basicOperation('isReadable',$path); + return $this->basicOperation('isReadable', $path); } + /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ + * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS + */ public function is_writable($path) { - return $this->basicOperation('isUpdatable',$path); + return $this->basicOperation('isUpdatable', $path); } + public function isCreatable($path) { return $this->basicOperation('isCreatable', $path); } + public function isReadable($path) { return $this->basicOperation('isReadable', $path); } + public function isUpdatable($path) { return $this->basicOperation('isUpdatable', $path); } + public function isDeletable($path) { return $this->basicOperation('isDeletable', $path); } + public function isSharable($path) { return $this->basicOperation('isSharable', $path); } + public function file_exists($path) { - if($path=='/') { + if ($path == '/') { return true; } return $this->basicOperation('file_exists', $path); } + public function filectime($path) { return $this->basicOperation('filectime', $path); } + public function filemtime($path) { return $this->basicOperation('filemtime', $path); } - public function touch($path, $mtime=null) { + + public function touch($path, $mtime = null) { return $this->basicOperation('touch', $path, array('write'), $mtime); } + public function file_get_contents($path) { return $this->basicOperation('file_get_contents', $path, array('read')); } + public function file_put_contents($path, $data) { - if(is_resource($data)) {//not having to deal with streams in file_put_contents makes life easier + if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); $exists = $this->file_exists($path); $run = true; - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - if(!$exists) { + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if (!$exists) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, @@ -283,83 +299,86 @@ class OC_FilesystemView { ) ); } - if(!$run) { + if (!$run) { return false; } - $target=$this->fopen($path, 'w'); - if($target) { - $count=OC_Helper::streamCopy($data, $target); + $target = $this->fopen($path, 'w'); + if ($target) { + $count = OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ - if(!$exists) { + if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if (!$exists) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, - array( OC_Filesystem::signal_param_path => $path) + array(OC_Filesystem::signal_param_path => $path) ); } OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, - array( OC_Filesystem::signal_param_path => $path) + array(OC_Filesystem::signal_param_path => $path) ); } OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); return $count > 0; - }else{ + } else { return false; } } - }else{ + } else { return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data); } } + public function unlink($path) { return $this->basicOperation('unlink', $path, array('delete')); } - public function deleteAll( $directory, $empty = false ) { - return $this->basicOperation( 'deleteAll', $directory, array('delete'), $empty ); + + public function deleteAll($directory, $empty = false) { + return $this->basicOperation('deleteAll', $directory, array('delete'), $empty); } + public function rename($path1, $path2) { - $postFix1=(substr($path1,-1,1)==='/')?'/':''; - $postFix2=(substr($path2,-1,1)==='/')?'/':''; + $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; + $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); - if(OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + if (OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { $path1 = $this->getRelativePath($absolutePath1); $path2 = $this->getRelativePath($absolutePath2); - if($path1 == null or $path2 == null) { + if ($path1 == null or $path2 == null) { return false; } - $run=true; - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ + $run = true; + if ($this->fakeRoot == OC_Filesystem::getRoot()) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, - array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2, - OC_Filesystem::signal_param_run => &$run - ) + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath => $path2, + OC_Filesystem::signal_param_run => &$run + ) ); } - if($run) { - $mp1 = $this->getMountPoint($path1.$postFix1); - $mp2 = $this->getMountPoint($path2.$postFix2); - if($mp1 == $mp2) { - if($storage = $this->getStorage($path1)) { - $result = $storage->rename($this->getInternalPath($path1.$postFix1), $this->getInternalPath($path2.$postFix2)); + if ($run) { + $mp1 = $this->getMountPoint($path1 . $postFix1); + $mp2 = $this->getMountPoint($path2 . $postFix2); + if ($mp1 == $mp2) { + if ($storage = $this->getStorage($path1)) { + $result = $storage->rename($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); } } else { - $source = $this->fopen($path1.$postFix1, 'r'); - $target = $this->fopen($path2.$postFix2, 'w'); + $source = $this->fopen($path1 . $postFix1, 'r'); + $target = $this->fopen($path2 . $postFix2, 'w'); $count = OC_Helper::streamCopy($source, $target); $storage1 = $this->getStorage($path1); - $storage1->unlink($this->getInternalPath($path1.$postFix1)); - $result = $count>0; + $storage1->unlink($this->getInternalPath($path1 . $postFix1)); + $result = $count > 0; } - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ + if ($this->fakeRoot == OC_Filesystem::getRoot()) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, @@ -373,31 +392,32 @@ class OC_FilesystemView { } } } + public function copy($path1, $path2) { - $postFix1=(substr($path1,-1,1)==='/')?'/':''; - $postFix2=(substr($path2,-1,1)==='/')?'/':''; + $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; + $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); - if(OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + if (OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { $path1 = $this->getRelativePath($absolutePath1); $path2 = $this->getRelativePath($absolutePath2); - if($path1 == null or $path2 == null) { + if ($path1 == null or $path2 == null) { return false; } - $run=true; - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ + $run = true; + if ($this->fakeRoot == OC_Filesystem::getRoot()) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_copy, array( OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath=>$path2, + OC_Filesystem::signal_param_newpath => $path2, OC_Filesystem::signal_param_run => &$run ) ); - $exists=$this->file_exists($path2); - if($run and !$exists) { + $exists = $this->file_exists($path2); + if ($run and !$exists) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, @@ -407,7 +427,7 @@ class OC_FilesystemView { ) ); } - if($run) { + if ($run) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, @@ -418,28 +438,28 @@ class OC_FilesystemView { ); } } - if($run) { - $mp1=$this->getMountPoint($path1.$postFix1); - $mp2=$this->getMountPoint($path2.$postFix2); - if($mp1 == $mp2) { - if($storage = $this->getStorage($path1.$postFix1)) { - $result=$storage->copy($this->getInternalPath($path1.$postFix1), $this->getInternalPath($path2.$postFix2)); + if ($run) { + $mp1 = $this->getMountPoint($path1 . $postFix1); + $mp2 = $this->getMountPoint($path2 . $postFix2); + if ($mp1 == $mp2) { + if ($storage = $this->getStorage($path1 . $postFix1)) { + $result = $storage->copy($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); } } else { - $source = $this->fopen($path1.$postFix1, 'r'); - $target = $this->fopen($path2.$postFix2, 'w'); + $source = $this->fopen($path1 . $postFix1, 'r'); + $target = $this->fopen($path2 . $postFix2, 'w'); $result = OC_Helper::streamCopy($source, $target); } - if( $this->fakeRoot==OC_Filesystem::getRoot() ){ + if ($this->fakeRoot == OC_Filesystem::getRoot()) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_copy, array( OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath=>$path2 + OC_Filesystem::signal_param_newpath => $path2 ) ); - if(!$exists) { + if (!$exists) { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, @@ -449,7 +469,7 @@ class OC_FilesystemView { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, - array( OC_Filesystem::signal_param_path => $path2) + array(OC_Filesystem::signal_param_path => $path2) ); } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions OC_FileCache_Update::update($path2, $this->fakeRoot); @@ -459,12 +479,13 @@ class OC_FilesystemView { } } } + public function fopen($path, $mode) { - $hooks=array(); - switch($mode) { + $hooks = array(); + switch ($mode) { case 'r': case 'rb': - $hooks[]='read'; + $hooks[] = 'read'; break; case 'r+': case 'rb+': @@ -474,8 +495,8 @@ class OC_FilesystemView { case 'xb+': case 'a+': case 'ab+': - $hooks[]='read'; - $hooks[]='write'; + $hooks[] = 'read'; + $hooks[] = 'write'; break; case 'w': case 'wb': @@ -483,22 +504,23 @@ class OC_FilesystemView { case 'xb': case 'a': case 'ab': - $hooks[]='write'; + $hooks[] = 'write'; break; default: - OC_Log::write('core','invalid mode ('.$mode.') for '.$path,OC_Log::ERROR); + OC_Log::write('core', 'invalid mode (' . $mode . ') for ' . $path, OC_Log::ERROR); } return $this->basicOperation('fopen', $path, $hooks, $mode); } + public function toTmpFile($path) { - if(OC_Filesystem::isValidPath($path)) { + if (OC_Filesystem::isValidPath($path)) { $source = $this->fopen($path, 'r'); - if($source) { - $extension=''; - $extOffset=strpos($path, '.'); - if($extOffset !== false) { - $extension=substr($path, strrpos($path,'.')); + if ($source) { + $extension = ''; + $extOffset = strpos($path, '.'); + if ($extOffset !== false) { + $extension = substr($path, strrpos($path, '.')); } $tmpFile = OC_Helper::tmpFile($extension); file_put_contents($tmpFile, $source); @@ -506,13 +528,14 @@ class OC_FilesystemView { } } } + public function fromTmpFile($tmpFile, $path) { - if(OC_Filesystem::isValidPath($path)) { - if(!$tmpFile) { + if (OC_Filesystem::isValidPath($path)) { + if (!$tmpFile) { debug_print_backtrace(); } - $source=fopen($tmpFile, 'r'); - if($source) { + $source = fopen($tmpFile, 'r'); + if ($source) { $this->file_put_contents($path, $source); unlink($tmpFile); return true; @@ -526,8 +549,9 @@ class OC_FilesystemView { public function getMimeType($path) { return $this->basicOperation('getMimeType', $path); } + public function hash($type, $path, $raw = false) { - $postFix=(substr($path,-1,1)==='/')?'/':''; + $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); @@ -538,11 +562,11 @@ class OC_FilesystemView { OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_read, - array( OC_Filesystem::signal_param_path => $path) + array(OC_Filesystem::signal_param_path => $path) ); } - if ($storage = $this->getStorage($path.$postFix)) { - $result = $storage->hash($type, $this->getInternalPath($path.$postFix), $raw); + if ($storage = $this->getStorage($path . $postFix)) { + $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $raw); $result = OC_FileProxy::runPostProxies('hash', $absolutePath, $result); return $result; } @@ -550,7 +574,7 @@ class OC_FilesystemView { return null; } - public function free_space($path='/') { + public function free_space($path = '/') { return $this->basicOperation('free_space', $path); } @@ -566,26 +590,26 @@ class OC_FilesystemView { * files), processes hooks and proxies, sanitises paths, and finally passes them on to * \OC\Files\Storage\Storage for delegation to a storage backend for execution */ - private function basicOperation($operation, $path, $hooks=array(), $extraParam=null) { - $postFix=(substr($path,-1,1)==='/')?'/':''; + private function basicOperation($operation, $path, $hooks = array(), $extraParam = null) { + $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { + if (OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); - if($path == null) { + if ($path == null) { return false; } - $internalPath = $this->getInternalPath($path.$postFix); - $run=$this->runHooks($hooks,$path); - if($run and $storage = $this->getStorage($path.$postFix)) { - if(!is_null($extraParam)) { + $internalPath = $this->getInternalPath($path . $postFix); + $run = $this->runHooks($hooks, $path); + if ($run and $storage = $this->getStorage($path . $postFix)) { + if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); } else { $result = $storage->$operation($internalPath); } $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); - if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { - if($operation!='fopen') {//no post hooks for fopen, the file stream is still open - $this->runHooks($hooks,$path,true); + if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open + $this->runHooks($hooks, $path, true); } } return $result; @@ -594,24 +618,24 @@ class OC_FilesystemView { return null; } - private function runHooks($hooks,$path,$post=false) { - $prefix=($post)?'post_':''; - $run=true; - if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { - foreach($hooks as $hook) { - if($hook!='read') { + private function runHooks($hooks, $path, $post = false) { + $prefix = ($post) ? 'post_' : ''; + $run = true; + if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + foreach ($hooks as $hook) { + if ($hook != 'read') { OC_Hook::emit( OC_Filesystem::CLASSNAME, - $prefix.$hook, + $prefix . $hook, array( OC_Filesystem::signal_param_run => &$run, OC_Filesystem::signal_param_path => $path ) ); - } elseif(!$post) { + } elseif (!$post) { OC_Hook::emit( OC_Filesystem::CLASSNAME, - $prefix.$hook, + $prefix . $hook, array( OC_Filesystem::signal_param_path => $path ) @@ -624,6 +648,7 @@ class OC_FilesystemView { /** * check if a file or folder has been updated since $time + * * @param int $time * @return bool */ diff --git a/lib/filesystem.php b/lib/filesystem.php index b73b52d420..b1200f95bf 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -22,566 +22,4 @@ */ -/** - * Class for abstraction of filesystem functions - * This class won't call any filesystem functions for itself but but will pass them to the correct OC_Filestorage object - * this class should also handle all the file permission related stuff - * - * Hooks provided: - * read(path) - * write(path, &run) - * post_write(path) - * create(path, &run) (when a file is created, both create and write will be emited in that order) - * post_create(path) - * delete(path, &run) - * post_delete(path) - * rename(oldpath,newpath, &run) - * post_rename(oldpath,newpath) - * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emited in that order) - * post_rename(oldpath,newpath) - * - * the &run parameter can be set to false to prevent the operation from occuring - */ -class OC_Filesystem{ - static private $storages=array(); - static private $mounts=array(); - public static $loaded=false; - /** - * @var \OC\Files\Storage\Storage $defaultInstance - */ - static private $defaultInstance; - - - /** - * classname which used for hooks handling - * used as signalclass in OC_Hooks::emit() - */ - const CLASSNAME = 'OC_Filesystem'; - - /** - * signalname emited before file renaming - * @param oldpath - * @param newpath - */ - const signal_rename = 'rename'; - - /** - * signal emited after file renaming - * @param oldpath - * @param newpath - */ - const signal_post_rename = 'post_rename'; - - /** - * signal emited before file/dir creation - * @param path - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_create = 'create'; - - /** - * signal emited after file/dir creation - * @param path - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_post_create = 'post_create'; - - /** - * signal emits before file/dir copy - * @param oldpath - * @param newpath - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_copy = 'copy'; - - /** - * signal emits after file/dir copy - * @param oldpath - * @param newpath - */ - const signal_post_copy = 'post_copy'; - - /** - * signal emits before file/dir save - * @param path - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_write = 'write'; - - /** - * signal emits after file/dir save - * @param path - */ - const signal_post_write = 'post_write'; - - /** - * signal emits when reading file/dir - * @param path - */ - const signal_read = 'read'; - - /** - * signal emits when removing file/dir - * @param path - */ - const signal_delete = 'delete'; - - /** - * parameters definitions for signals - */ - const signal_param_path = 'path'; - const signal_param_oldpath = 'oldpath'; - const signal_param_newpath = 'newpath'; - - /** - * run - changing this flag to false in hook handler will cancel event - */ - const signal_param_run = 'run'; - - /** - * get the mountpoint of the storage object for a path - ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account - * - * @param string path - * @return string - */ - static public function getMountPoint($path) { - OC_Hook::emit(self::CLASSNAME,'get_mountpoint',array('path'=>$path)); - if(!$path) { - $path='/'; - } - if($path[0]!=='/') { - $path='/'.$path; - } - $path=str_replace('//', '/',$path); - $foundMountPoint=''; - $mountPoints=array_keys(OC_Filesystem::$mounts); - foreach($mountPoints as $mountpoint) { - if($mountpoint==$path) { - return $mountpoint; - } - if(strpos($path,$mountpoint)===0 and strlen($mountpoint)>strlen($foundMountPoint)) { - $foundMountPoint=$mountpoint; - } - } - return $foundMountPoint; - } - - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * @param string path - * @return bool - */ - static public function getInternalPath($path) { - $mountPoint=self::getMountPoint($path); - $internalPath=substr($path,strlen($mountPoint)); - return $internalPath; - } - /** - * get the storage object for a path - * @param string path - * @return \OC\Files\Storage\Storage - */ - static public function getStorage($path) { - $mountpoint=self::getMountPoint($path); - if($mountpoint) { - if(!isset(OC_Filesystem::$storages[$mountpoint])) { - $mount=OC_Filesystem::$mounts[$mountpoint]; - OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'],$mount['arguments']); - } - return OC_Filesystem::$storages[$mountpoint]; - } - } - - /** - * resolve a path to a storage and internal path - * @param string $path - * @return array consisting of the storage and the internal path - */ - static public function resolvePath($path){ - $mountpoint=self::getMountPoint($path); - if($mountpoint) { - if(!isset(OC_Filesystem::$storages[$mountpoint])) { - $mount=OC_Filesystem::$mounts[$mountpoint]; - OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'],$mount['arguments']); - } - $storage = OC_Filesystem::$storages[$mountpoint]; - $internalPath=substr($path,strlen($mountpoint)); - return array($storage, $internalPath); - } - } - - static public function init($root) { - if(self::$defaultInstance) { - return false; - } - self::$defaultInstance=new OC_FilesystemView($root); - - //load custom mount config - if(is_file(OC::$SERVERROOT.'/config/mount.php')) { - $mountConfig=include(OC::$SERVERROOT.'/config/mount.php'); - if(isset($mountConfig['global'])) { - foreach($mountConfig['global'] as $mountPoint=>$options) { - self::mount($options['class'],$options['options'],$mountPoint); - } - } - - if(isset($mountConfig['group'])) { - foreach($mountConfig['group'] as $group=>$mounts) { - if(OC_Group::inGroup(OC_User::getUser(),$group)) { - foreach($mounts as $mountPoint=>$options) { - $mountPoint=self::setUserVars($mountPoint); - foreach($options as &$option) { - $option=self::setUserVars($option); - } - self::mount($options['class'],$options['options'],$mountPoint); - } - } - } - } - - if(isset($mountConfig['user'])) { - foreach($mountConfig['user'] as $user=>$mounts) { - if($user==='all' or strtolower($user)===strtolower(OC_User::getUser())) { - foreach($mounts as $mountPoint=>$options) { - $mountPoint=self::setUserVars($mountPoint); - foreach($options as &$option) { - $option=self::setUserVars($option); - } - self::mount($options['class'],$options['options'],$mountPoint); - } - } - } - } - } - - self::$loaded=true; - } - - /** - * fill in the correct values for $user, and $password placeholders - * @param string intput - * @return string - */ - private static function setUserVars($input) { - return str_replace('$user',OC_User::getUser(),$input); - } - - /** - * get the default filesystem view - * @return OC_FilesystemView - */ - static public function getView() { - return self::$defaultInstance; - } - - /** - * tear down the filesystem, removing all storage providers - */ - static public function tearDown() { - self::$storages=array(); - } - - /** - * create a new storage of a specific type - * @param string type - * @param array arguments - * @return \OC\Files\Storage\Storage - */ - static private function createStorage($class,$arguments) { - if(class_exists($class)) { - try { - return new $class($arguments); - } catch (Exception $exception) { - OC_Log::write('core', $exception->getMessage(), OC_Log::ERROR); - return false; - } - }else{ - OC_Log::write('core','storage backend '.$class.' not found',OC_Log::ERROR); - return false; - } - } - - /** - * change the root to a fake root - * @param string fakeRoot - * @return bool - */ - static public function chroot($fakeRoot) { - return self::$defaultInstance->chroot($fakeRoot); - } - - /** - * @brief get the relative path of the root data directory for the current user - * @return string - * - * Returns path like /admin/files - */ - static public function getRoot() { - return self::$defaultInstance->getRoot(); - } - - /** - * clear all mounts and storage backends - */ - public static function clearMounts() { - self::$mounts=array(); - self::$storages=array(); - } - - /** - * mount an \OC\Files\Storage\Storage in our virtual filesystem - * @param \OC\Files\Storage\Storage storage - * @param string mountpoint - */ - static public function mount($class,$arguments,$mountpoint) { - if($mountpoint[0]!='/') { - $mountpoint='/'.$mountpoint; - } - if(substr($mountpoint,-1)!=='/') { - $mountpoint=$mountpoint.'/'; - } - self::$mounts[$mountpoint]=array('class'=>$class,'arguments'=>$arguments); - } - - /** - * return the path to a local version of the file - * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed - * @param string path - * @return string - */ - static public function getLocalFile($path) { - return self::$defaultInstance->getLocalFile($path); - } - /** - * @param string path - * @return string - */ - static public function getLocalFolder($path) { - return self::$defaultInstance->getLocalFolder($path); - } - - /** - * return path to file which reflects one visible in browser - * @param string path - * @return string - */ - static public function getLocalPath($path) { - $datadir = OC_User::getHome(OC_User::getUser()).'/files'; - $newpath = $path; - if (strncmp($newpath, $datadir, strlen($datadir)) == 0) { - $newpath = substr($path, strlen($datadir)); - } - return $newpath; - } - - /** - * check if the requested path is valid - * @param string path - * @return bool - */ - static public function isValidPath($path) { - if(!$path || $path[0]!=='/') { - $path='/'.$path; - } - if(strstr($path,'/../') || strrchr($path, '/') === '/..' ) { - return false; - } - return true; - } - - /** - * checks if a file is blacklisted for storage in the filesystem - * Listens to write and rename hooks - * @param array $data from hook - */ - static public function isBlacklisted($data) { - $blacklist = array('.htaccess'); - if (isset($data['path'])) { - $path = $data['path']; - } else if (isset($data['newpath'])) { - $path = $data['newpath']; - } - if (isset($path)) { - $filename = strtolower(basename($path)); - if (in_array($filename, $blacklist)) { - $data['run'] = false; - } - } - } - - /** - * following functions are equivalent to their php builtin equivalents for arguments/return values. - */ - static public function mkdir($path) { - return self::$defaultInstance->mkdir($path); - } - static public function rmdir($path) { - return self::$defaultInstance->rmdir($path); - } - static public function opendir($path) { - return self::$defaultInstance->opendir($path); - } - static public function readdir($path) { - return self::$defaultInstance->readdir($path); - } - static public function is_dir($path) { - return self::$defaultInstance->is_dir($path); - } - static public function is_file($path) { - return self::$defaultInstance->is_file($path); - } - static public function stat($path) { - return self::$defaultInstance->stat($path); - } - static public function filetype($path) { - return self::$defaultInstance->filetype($path); - } - static public function filesize($path) { - return self::$defaultInstance->filesize($path); - } - static public function readfile($path) { - return self::$defaultInstance->readfile($path); - } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - static public function is_readable($path) { - return self::$defaultInstance->is_readable($path); - } - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - static public function is_writable($path) { - return self::$defaultInstance->is_writable($path); - } - static public function isCreatable($path) { - return self::$defaultInstance->isCreatable($path); - } - static public function isReadable($path) { - return self::$defaultInstance->isReadable($path); - } - static public function isUpdatable($path) { - return self::$defaultInstance->isUpdatable($path); - } - static public function isDeletable($path) { - return self::$defaultInstance->isDeletable($path); - } - static public function isSharable($path) { - return self::$defaultInstance->isSharable($path); - } - static public function file_exists($path) { - return self::$defaultInstance->file_exists($path); - } - static public function filectime($path) { - return self::$defaultInstance->filectime($path); - } - static public function filemtime($path) { - return self::$defaultInstance->filemtime($path); - } - static public function touch($path, $mtime=null) { - return self::$defaultInstance->touch($path, $mtime); - } - static public function file_get_contents($path) { - return self::$defaultInstance->file_get_contents($path); - } - static public function file_put_contents($path,$data) { - return self::$defaultInstance->file_put_contents($path,$data); - } - static public function unlink($path) { - return self::$defaultInstance->unlink($path); - } - static public function rename($path1,$path2) { - return self::$defaultInstance->rename($path1,$path2); - } - static public function copy($path1,$path2) { - return self::$defaultInstance->copy($path1,$path2); - } - static public function fopen($path,$mode) { - return self::$defaultInstance->fopen($path,$mode); - } - static public function toTmpFile($path) { - return self::$defaultInstance->toTmpFile($path); - } - static public function fromTmpFile($tmpFile,$path) { - return self::$defaultInstance->fromTmpFile($tmpFile,$path); - } - - static public function getMimeType($path) { - return self::$defaultInstance->getMimeType($path); - } - static public function hash($type,$path, $raw = false) { - return self::$defaultInstance->hash($type,$path, $raw); - } - - static public function free_space($path='/') { - return self::$defaultInstance->free_space($path); - } - - static public function search($query) { - return OC_FileCache::search($query); - } - - /** - * check if a file or folder has been updated since $time - * @param int $time - * @return bool - */ - static public function hasUpdated($path,$time) { - return self::$defaultInstance->hasUpdated($path,$time); - } - - static public function removeETagHook($params, $root = false) { - if (isset($params['path'])) { - $path=$params['path']; - } else { - $path=$params['oldpath']; - } - - if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new OC_FilesystemView($root); - $count = 1; - $path=str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); - } - - $path = self::normalizePath($path); - OC_Connector_Sabre_Node::removeETagPropertyForPath($path); - } - - /** - * normalize a path - * @param string path - * @param bool $stripTrailingSlash - * @return string - */ - public static function normalizePath($path,$stripTrailingSlash=true) { - if($path=='') { - return '/'; - } - //no windows style slashes - $path=str_replace('\\','/',$path); - //add leading slash - if($path[0]!=='/') { - $path='/'.$path; - } - //remove trainling slash - if($stripTrailingSlash and strlen($path)>1 and substr($path,-1,1)==='/') { - $path=substr($path,0,-1); - } - //remove duplicate slashes - while(strpos($path,'//')!==false) { - $path=str_replace('//','/',$path); - } - //normalize unicode if possible - if(class_exists('Normalizer')) { - $path=Normalizer::normalize($path); - } - return $path; - } -} -OC_Hook::connect('OC_Filesystem','post_write', 'OC_Filesystem','removeETagHook'); -OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook'); -OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook'); - -OC_Util::setupFS(); From 07c53841899262fdd34304302ffaaf2704800c38 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 12:25:46 +0200 Subject: [PATCH 029/262] fix namespaces in filesystem and filesystemview --- lib/app.php | 6 +- lib/files/filesystem.php | 153 ++++++++++++----------- lib/files/view.php | 260 +++++++++++++++++++++------------------ 3 files changed, 225 insertions(+), 194 deletions(-) diff --git a/lib/app.php b/lib/app.php index 395230156f..4d7353e99d 100755 --- a/lib/app.php +++ b/lib/app.php @@ -714,16 +714,16 @@ class OC_App{ /** * @param string $appid - * @return OC_FilesystemView + * @return \OC\Files\View */ public static function getStorage($appid) { if(OC_App::isEnabled($appid)) {//sanity check if(OC_User::isLoggedIn()) { - $view = new OC_FilesystemView('/'.OC_User::getUser()); + $view = new \OC\Files\View('/'.OC_User::getUser()); if(!$view->file_exists($appid)) { $view->mkdir($appid); } - return new OC_FilesystemView('/'.OC_User::getUser().'/'.$appid); + return new \OC\Files\View('/'.OC_User::getUser().'/'.$appid); }else{ OC_Log::write('core', 'Can\'t get app storage, app, user not logged in', OC_Log::ERROR); return false; diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d0a96b59a0..f23f3a79e9 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -15,16 +15,16 @@ * read(path) * write(path, &run) * post_write(path) - * create(path, &run) (when a file is created, both create and write will be emited in that order) + * create(path, &run) (when a file is created, both create and write will be emitted in that order) * post_create(path) * delete(path, &run) * post_delete(path) * rename(oldpath,newpath, &run) * post_rename(oldpath,newpath) - * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emited in that order) + * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emitted in that order) * post_rename(oldpath,newpath) * - * the &run parameter can be set to false to prevent the operation from occuring + * the &run parameter can be set to false to prevent the operation from occurring */ namespace OC\Files; @@ -34,7 +34,7 @@ class Filesystem { static private $mounts = array(); public static $loaded = false; /** - * @var \OC\Files\Storage\Storage $defaultInstance + * @var \OC\Files\View $defaultInstance */ static private $defaultInstance; @@ -46,80 +46,80 @@ class Filesystem { const CLASSNAME = 'OC_Filesystem'; /** - * signalname emited before file renaming + * signalname emitted before file renaming * - * @param oldpath - * @param newpath + * @param string $oldpath + * @param string $newpath */ const signal_rename = 'rename'; /** - * signal emited after file renaming + * signal emitted after file renaming * - * @param oldpath - * @param newpath + * @param string $oldpath + * @param string $newpath */ const signal_post_rename = 'post_rename'; /** - * signal emited before file/dir creation + * signal emitted before file/dir creation * - * @param path - * @param run changing this flag to false in hook handler will cancel event + * @param string $path + * @param bool $run changing this flag to false in hook handler will cancel event */ const signal_create = 'create'; /** - * signal emited after file/dir creation + * signal emitted after file/dir creation * - * @param path - * @param run changing this flag to false in hook handler will cancel event + * @param string $path + * @param bool $run changing this flag to false in hook handler will cancel event */ const signal_post_create = 'post_create'; /** * signal emits before file/dir copy * - * @param oldpath - * @param newpath - * @param run changing this flag to false in hook handler will cancel event + * @param string $oldpath + * @param string $newpath + * @param bool $run changing this flag to false in hook handler will cancel event */ const signal_copy = 'copy'; /** * signal emits after file/dir copy * - * @param oldpath - * @param newpath + * @param string $oldpath + * @param string $newpath */ const signal_post_copy = 'post_copy'; /** * signal emits before file/dir save * - * @param path - * @param run changing this flag to false in hook handler will cancel event + * @param string $path + * @param bool $run changing this flag to false in hook handler will cancel event */ const signal_write = 'write'; /** * signal emits after file/dir save * - * @param path + * @param string $path */ const signal_post_write = 'post_write'; /** * signal emits when reading file/dir * - * @param path + * @param string $path */ const signal_read = 'read'; /** * signal emits when removing file/dir * - * @param path + * @param string $path */ const signal_delete = 'delete'; @@ -139,11 +139,11 @@ class Filesystem { * get the mountpoint of the storage object for a path ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account * - * @param string path + * @param string $path * @return string */ static public function getMountPoint($path) { - OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); + \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); if (!$path) { $path = '/'; } @@ -152,7 +152,7 @@ class Filesystem { } $path = str_replace('//', '/', $path); $foundMountPoint = ''; - $mountPoints = array_keys(OC_Filesystem::$mounts); + $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { if ($mountpoint == $path) { return $mountpoint; @@ -167,7 +167,7 @@ class Filesystem { /** * get the part of the path relative to the mountpoint of the storage it's stored in * - * @param string path + * @param string $path * @return bool */ static public function getInternalPath($path) { @@ -179,17 +179,19 @@ class Filesystem { /** * get the storage object for a path * - * @param string path + * @param string $path * @return \OC\Files\Storage\Storage */ static public function getStorage($path) { $mountpoint = self::getMountPoint($path); if ($mountpoint) { - if (!isset(OC_Filesystem::$storages[$mountpoint])) { - $mount = OC_Filesystem::$mounts[$mountpoint]; - OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']); + if (!isset(self::$storages[$mountpoint])) { + $mount = self::$mounts[$mountpoint]; + self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); } - return OC_Filesystem::$storages[$mountpoint]; + return self::$storages[$mountpoint]; + }else{ + return null; } } @@ -202,13 +204,15 @@ class Filesystem { static public function resolvePath($path) { $mountpoint = self::getMountPoint($path); if ($mountpoint) { - if (!isset(OC_Filesystem::$storages[$mountpoint])) { - $mount = OC_Filesystem::$mounts[$mountpoint]; - OC_Filesystem::$storages[$mountpoint] = OC_Filesystem::createStorage($mount['class'], $mount['arguments']); + if (!isset(self::$storages[$mountpoint])) { + $mount = self::$mounts[$mountpoint]; + self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); } - $storage = OC_Filesystem::$storages[$mountpoint]; + $storage = self::$storages[$mountpoint]; $internalPath = substr($path, strlen($mountpoint)); return array($storage, $internalPath); + }else{ + return array(null, null); } } @@ -216,11 +220,11 @@ class Filesystem { if (self::$defaultInstance) { return false; } - self::$defaultInstance = new OC_FilesystemView($root); + self::$defaultInstance = new View($root); -//load custom mount config - if (is_file(OC::$SERVERROOT . '/config/mount.php')) { - $mountConfig = include(OC::$SERVERROOT . '/config/mount.php'); + //load custom mount config + if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { + $mountConfig = include 'config/mount.php'; if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); @@ -229,7 +233,7 @@ class Filesystem { if (isset($mountConfig['group'])) { foreach ($mountConfig['group'] as $group => $mounts) { - if (OC_Group::inGroup(OC_User::getUser(), $group)) { + if (\OC_Group::inGroup(\OC_User::getUser(), $group)) { foreach ($mounts as $mountPoint => $options) { $mountPoint = self::setUserVars($mountPoint); foreach ($options as &$option) { @@ -243,7 +247,7 @@ class Filesystem { if (isset($mountConfig['user'])) { foreach ($mountConfig['user'] as $user => $mounts) { - if ($user === 'all' or strtolower($user) === strtolower(OC_User::getUser())) { + if ($user === 'all' or strtolower($user) === strtolower(\OC_User::getUser())) { foreach ($mounts as $mountPoint => $options) { $mountPoint = self::setUserVars($mountPoint); foreach ($options as &$option) { @@ -257,22 +261,24 @@ class Filesystem { } self::$loaded = true; + + return true; } /** * fill in the correct values for $user, and $password placeholders * - * @param string intput + * @param string $input * @return string */ private static function setUserVars($input) { - return str_replace('$user', OC_User::getUser(), $input); + return str_replace('$user', \OC_User::getUser(), $input); } /** * get the default filesystem view * - * @return OC_FilesystemView + * @return View */ static public function getView() { return self::$defaultInstance; @@ -288,20 +294,20 @@ class Filesystem { /** * create a new storage of a specific type * - * @param string type - * @param array arguments + * @param string $type + * @param array $arguments * @return \OC\Files\Storage\Storage */ static private function createStorage($class, $arguments) { if (class_exists($class)) { try { return new $class($arguments); - } catch (Exception $exception) { - OC_Log::write('core', $exception->getMessage(), OC_Log::ERROR); + } catch (\Exception $exception) { + \OC_Log::write('core', $exception->getMessage(), \OC_Log::ERROR); return false; } } else { - OC_Log::write('core', 'storage backend ' . $class . ' not found', OC_Log::ERROR); + \OC_Log::write('core', 'storage backend ' . $class . ' not found', \OC_Log::ERROR); return false; } } @@ -309,7 +315,7 @@ class Filesystem { /** * change the root to a fake root * - * @param string fakeRoot + * @param string $fakeRoot * @return bool */ static public function chroot($fakeRoot) { @@ -337,8 +343,9 @@ class Filesystem { /** * mount an \OC\Files\Storage\Storage in our virtual filesystem * - * @param \OC\Files\Storage\Storage storage - * @param string mountpoint + * @param \OC\Files\Storage\Storage $storage + * @param array $arguments + * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { if ($mountpoint[0] != '/') { @@ -354,7 +361,7 @@ class Filesystem { * return the path to a local version of the file * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed * - * @param string path + * @param string $path * @return string */ static public function getLocalFile($path) { @@ -362,7 +369,7 @@ class Filesystem { } /** - * @param string path + * @param string $path * @return string */ static public function getLocalFolder($path) { @@ -372,11 +379,11 @@ class Filesystem { /** * return path to file which reflects one visible in browser * - * @param string path + * @param string $path * @return string */ static public function getLocalPath($path) { - $datadir = OC_User::getHome(OC_User::getUser()) . '/files'; + $datadir = \OC_User::getHome(\OC_User::getUser()) . '/files'; $newpath = $path; if (strncmp($newpath, $datadir, strlen($datadir)) == 0) { $newpath = substr($path, strlen($datadir)); @@ -387,7 +394,7 @@ class Filesystem { /** * check if the requested path is valid * - * @param string path + * @param string $path * @return bool */ static public function isValidPath($path) { @@ -468,7 +475,7 @@ class Filesystem { * @deprecated Replaced by isReadable() as part of CRUDS */ static public function is_readable($path) { - return self::$defaultInstance->is_readable($path); + return self::$defaultInstance->isReadable($path); } /** @@ -559,7 +566,7 @@ class Filesystem { } static public function search($query) { - return OC_FileCache::search($query); + return Cache\Cache::search($query); } /** @@ -580,19 +587,19 @@ class Filesystem { } if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new OC_FilesystemView($root); + $fakeRootView = new View($root); $count = 1; - $path = str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); + $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count); } $path = self::normalizePath($path); - OC_Connector_Sabre_Node::removeETagPropertyForPath($path); + \OC_Connector_Sabre_Node::removeETagPropertyForPath($path); } /** * normalize a path * - * @param string path + * @param string $path * @param bool $stripTrailingSlash * @return string */ @@ -606,7 +613,7 @@ class Filesystem { if ($path[0] !== '/') { $path = '/' . $path; } -//remove trainling slash +//remove trailing slash if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { $path = substr($path, 0, -1); } @@ -616,14 +623,14 @@ class Filesystem { } //normalize unicode if possible if (class_exists('Normalizer')) { - $path = Normalizer::normalize($path); + $path = \Normalizer::normalize($path); } return $path; } } -OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); -OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); -OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); +\OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); +\OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); +\OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); -OC_Util::setupFS(); +\OC_Util::setupFS(); diff --git a/lib/files/view.php b/lib/files/view.php index 8c3f288f44..230455479c 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -45,9 +45,9 @@ class View { } /** - * change the root to a fake toor + * change the root to a fake root * - * @param string fakeRoot + * @param string $fakeRoot * @return bool */ public function chroot($fakeRoot) { @@ -71,12 +71,12 @@ class View { /** * get the part of the path relative to the mountpoint of the storage it's stored in * - * @param string path + * @param string $path * @return bool */ public function getInternalPath($path) { if (!isset($this->internal_path_cache[$path])) { - $this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path)); + $this->internal_path_cache[$path] = Filesystem::getInternalPath($this->getAbsolutePath($path)); } return $this->internal_path_cache[$path]; } @@ -84,7 +84,7 @@ class View { /** * get path relative to the root of the view * - * @param string path + * @param string $path * @return string */ public function getRelativePath($path) { @@ -106,12 +106,12 @@ class View { /** * get the storage object for a path * - * @param string path + * @param string $path * @return \OC\Files\Storage\Storage */ public function getStorage($path) { if (!isset($this->storage_cache[$path])) { - $this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path)); + $this->storage_cache[$path] = Filesystem::getStorage($this->getAbsolutePath($path)); } return $this->storage_cache[$path]; } @@ -120,35 +120,39 @@ class View { * get the mountpoint of the storage object for a path ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account * - * @param string path + * @param string $path * @return string */ public function getMountPoint($path) { - return OC_Filesystem::getMountPoint($this->getAbsolutePath($path)); + return Filesystem::getMountPoint($this->getAbsolutePath($path)); } /** * return the path to a local version of the file * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed * - * @param string path + * @param string $path * @return string */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { + if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { return $storage->getLocalFile($this->getInternalPath($path)); + } else { + return null; } } /** - * @param string path + * @param string $path * @return string */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (OC_Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { + if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { return $storage->getLocalFolder($this->getInternalPath($path)); + } else { + return null; } } @@ -274,28 +278,28 @@ class View { public function file_put_contents($path, $data) { if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier - $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); + if (\OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); $exists = $this->file_exists($path); $run = true; - if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if ($this->fakeRoot == Filesystem::getRoot()) { if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_create, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path, + Filesystem::signal_param_run => &$run ) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_write, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path, + Filesystem::signal_param_run => &$run ) ); } @@ -304,28 +308,30 @@ class View { } $target = $this->fopen($path, 'w'); if ($target) { - $count = OC_Helper::streamCopy($data, $target); + $count = \OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); - if ($this->fakeRoot == OC_Filesystem::getRoot()) { + if ($this->fakeRoot == Filesystem::getRoot()) { if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array(OC_Filesystem::signal_param_path => $path) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_create, + array(Filesystem::signal_param_path => $path) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array(OC_Filesystem::signal_param_path => $path) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_write, + array(Filesystem::signal_param_path => $path) ); } - OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); + \OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); return $count > 0; } else { return false; } + } else { + return false; } } else { return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data); @@ -343,9 +349,9 @@ class View { public function rename($path1, $path2) { $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; - $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); - $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); - if (OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); + $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); + if (\OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and Filesystem::isValidPath($path2)) { $path1 = $this->getRelativePath($absolutePath1); $path2 = $this->getRelativePath($absolutePath2); @@ -353,13 +359,13 @@ class View { return false; } $run = true; - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, Filesystem::signal_rename, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2, + Filesystem::signal_param_run => &$run ) ); } @@ -369,36 +375,42 @@ class View { if ($mp1 == $mp2) { if ($storage = $this->getStorage($path1)) { $result = $storage->rename($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + } else { + $result = false; } } else { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); - $count = OC_Helper::streamCopy($source, $target); + $count = \OC_Helper::streamCopy($source, $target); $storage1 = $this->getStorage($path1); $storage1->unlink($this->getInternalPath($path1 . $postFix1)); $result = $count > 0; } - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_rename, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_rename, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2 + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2 ) ); } return $result; + } else { + return false; } + } else { + return false; } } public function copy($path1, $path2) { $postFix1 = (substr($path1, -1, 1) === '/') ? '/' : ''; $postFix2 = (substr($path2, -1, 1) === '/') ? '/' : ''; - $absolutePath1 = OC_Filesystem::normalizePath($this->getAbsolutePath($path1)); - $absolutePath2 = OC_Filesystem::normalizePath($this->getAbsolutePath($path2)); - if (OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1)); + $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2)); + if (\OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and Filesystem::isValidPath($path2)) { $path1 = $this->getRelativePath($absolutePath1); $path2 = $this->getRelativePath($absolutePath2); @@ -406,34 +418,34 @@ class View { return false; } $run = true; - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_copy, + $exists = $this->file_exists($path2); + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_copy, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2, + Filesystem::signal_param_run => &$run ) ); - $exists = $this->file_exists($path2); if ($run and !$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_create, array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path2, + Filesystem::signal_param_run => &$run ) ); } if ($run) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_write, array( - OC_Filesystem::signal_param_path => $path2, - OC_Filesystem::signal_param_run => &$run + Filesystem::signal_param_path => $path2, + Filesystem::signal_param_run => &$run ) ); } @@ -444,39 +456,45 @@ class View { if ($mp1 == $mp2) { if ($storage = $this->getStorage($path1 . $postFix1)) { $result = $storage->copy($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + } else { + $result = false; } } else { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); - $result = OC_Helper::streamCopy($source, $target); + $result = \OC_Helper::streamCopy($source, $target); } - if ($this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_copy, + if ($this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_copy, array( - OC_Filesystem::signal_param_oldpath => $path1, - OC_Filesystem::signal_param_newpath => $path2 + Filesystem::signal_param_oldpath => $path1, + Filesystem::signal_param_newpath => $path2 ) ); if (!$exists) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array(OC_Filesystem::signal_param_path => $path2) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_create, + array(Filesystem::signal_param_path => $path2) ); } - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array(OC_Filesystem::signal_param_path => $path2) + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_post_write, + array(Filesystem::signal_param_path => $path2) ); } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions - OC_FileCache_Update::update($path2, $this->fakeRoot); - OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); +// OC_FileCache_Update::update($path2, $this->fakeRoot); + Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; + } else { + return false; } + } else { + return false; } } @@ -507,14 +525,14 @@ class View { $hooks[] = 'write'; break; default: - OC_Log::write('core', 'invalid mode (' . $mode . ') for ' . $path, OC_Log::ERROR); + \OC_Log::write('core', 'invalid mode (' . $mode . ') for ' . $path, \OC_Log::ERROR); } return $this->basicOperation('fopen', $path, $hooks, $mode); } public function toTmpFile($path) { - if (OC_Filesystem::isValidPath($path)) { + if (Filesystem::isValidPath($path)) { $source = $this->fopen($path, 'r'); if ($source) { $extension = ''; @@ -522,15 +540,19 @@ class View { if ($extOffset !== false) { $extension = substr($path, strrpos($path, '.')); } - $tmpFile = OC_Helper::tmpFile($extension); + $tmpFile = \OC_Helper::tmpFile($extension); file_put_contents($tmpFile, $source); return $tmpFile; + } else { + return false; } + } else { + return false; } } public function fromTmpFile($tmpFile, $path) { - if (OC_Filesystem::isValidPath($path)) { + if (Filesystem::isValidPath($path)) { if (!$tmpFile) { debug_print_backtrace(); } @@ -540,6 +562,7 @@ class View { unlink($tmpFile); return true; } else { + return false; } } else { return false; @@ -552,22 +575,22 @@ class View { public function hash($type, $path, $raw = false) { $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; - $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); + if (\OC_FileProxy::runPreProxies('hash', $absolutePath) && Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); if ($path == null) { return false; } - if (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_read, - array(OC_Filesystem::signal_param_path => $path) + if (Filesystem::$loaded && $this->fakeRoot == Filesystem::getRoot()) { + \OC_Hook::emit( + Filesystem::CLASSNAME, + Filesystem::signal_read, + array(Filesystem::signal_param_path => $path) ); } if ($storage = $this->getStorage($path . $postFix)) { $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $raw); - $result = OC_FileProxy::runPostProxies('hash', $absolutePath, $result); + $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); return $result; } } @@ -581,9 +604,9 @@ class View { /** * @brief abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage * @param string $operation - * @param string #path - * @param array (optional) hooks - * @param mixed (optional) $extraParam + * @param string $path + * @param array $hooks (optional) + * @param mixed $extraParam (optional) * @return mixed * * This method takes requests for basic filesystem functions (e.g. reading & writing @@ -592,8 +615,8 @@ class View { */ private function basicOperation($operation, $path, $hooks = array(), $extraParam = null) { $postFix = (substr($path, -1, 1) === '/') ? '/' : ''; - $absolutePath = OC_Filesystem::normalizePath($this->getAbsolutePath($path)); - if (OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { + $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); + if (\OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); if ($path == null) { return false; @@ -606,8 +629,8 @@ class View { } else { $result = $storage->$operation($internalPath); } - $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); - if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + $result = \OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); + if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) { if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open $this->runHooks($hooks, $path, true); } @@ -621,23 +644,23 @@ class View { private function runHooks($hooks, $path, $post = false) { $prefix = ($post) ? 'post_' : ''; $run = true; - if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { + if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) { foreach ($hooks as $hook) { if ($hook != 'read') { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, + \OC_Hook::emit( + Filesystem::CLASSNAME, $prefix . $hook, array( - OC_Filesystem::signal_param_run => &$run, - OC_Filesystem::signal_param_path => $path + Filesystem::signal_param_run => &$run, + Filesystem::signal_param_path => $path ) ); } elseif (!$post) { - OC_Hook::emit( - OC_Filesystem::CLASSNAME, + \OC_Hook::emit( + Filesystem::CLASSNAME, $prefix . $hook, array( - OC_Filesystem::signal_param_path => $path + Filesystem::signal_param_path => $path ) ); } @@ -649,6 +672,7 @@ class View { /** * check if a file or folder has been updated since $time * + * @param string $path * @param int $time * @return bool */ From 4b9fbf46e554f8bb368e6cf5a8f75ca5c56e8228 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 12:50:57 +0200 Subject: [PATCH 030/262] add depricated OC_Filessystem for compatibility --- lib/filesystem.php | 479 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 460 insertions(+), 19 deletions(-) diff --git a/lib/filesystem.php b/lib/filesystem.php index b1200f95bf..4189fe36c2 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -1,25 +1,466 @@ . -* -*/ + * Copyright (c) 2012 Robin Appelman + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +/** + * Class for abstraction of filesystem functions + * This class won't call any filesystem functions for itself but but will pass them to the correct OC_Filestorage object + * this class should also handle all the file permission related stuff + * + * Hooks provided: + * read(path) + * write(path, &run) + * post_write(path) + * create(path, &run) (when a file is created, both create and write will be emitted in that order) + * post_create(path) + * delete(path, &run) + * post_delete(path) + * rename(oldpath,newpath, &run) + * post_rename(oldpath,newpath) + * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emitted in that order) + * post_rename(oldpath,newpath) + * + * the &run parameter can be set to false to prevent the operation from occurring + */ +/** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ +class OC_Filesystem { + /** + * get the mountpoint of the storage object for a path + ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return string + */ + static public function getMountPoint($path) { + return \OC\Files\Filesystem::getMountPoint($path); + } + /** + * get the part of the path relative to the mountpoint of the storage it's stored in + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return bool + */ + static public function getInternalPath($path) { + return \OC\Files\Filesystem::getInternalPath($path); + } + + /** + * get the storage object for a path + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return \OC\Files\Storage\Storage + */ + static public function getStorage($path) { + return \OC\Files\Filesystem::getStorage($path); + } + + /** + * resolve a path to a storage and internal path + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return array consisting of the storage and the internal path + */ + static public function resolvePath($path) { + return \OC\Files\Filesystem::resolvePath($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function init($root) { + return \OC\Files\Filesystem::init($root); + } + + /** + * get the default filesystem view + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @return \OC\Files\View + */ + static public function getView() { + return \OC\Files\Filesystem::getView(); + } + + /** + * tear down the filesystem, removing all storage providers + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function tearDown() { + \OC\Files\Filesystem::tearDown(); + } + + /** + * change the root to a fake root + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $fakeRoot + * @return bool + */ + static public function chroot($fakeRoot) { + return \OC\Files\Filesystem::chroot($fakeRoot); + } + + /** + * @brief get the relative path of the root data directory for the current user + * @return string + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * Returns path like /admin/files + */ + static public function getRoot() { + return \OC\Files\Filesystem::getRoot(); + } + + /** + * clear all mounts and storage backends + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + public static function clearMounts() { + \OC\Files\Filesystem::clearMounts(); + } + + /** + * mount an \OC\Files\Storage\Storage in our virtual filesystem + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param \OC\Files\Storage\Storage $class + * @param array $arguments + * @param string $mountpoint + */ + static public function mount($class, $arguments, $mountpoint) { + \OC\Files\Filesystem::mount($class, $arguments, $mountpoint); + } + + /** + * return the path to a local version of the file + * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return string + */ + static public function getLocalFile($path) { + return \OC\Files\Filesystem::getLocalFile($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return string + */ + static public function getLocalFolder($path) { + return \OC\Files\Filesystem::getLocalFolder($path); + } + + /** + * return path to file which reflects one visible in browser + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return string + */ + static public function getLocalPath($path) { + return \OC\Files\Filesystem::getLocalPath($path); + } + + /** + * check if the requested path is valid + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @return bool + */ + static public function isValidPath($path) { + return \OC\Files\Filesystem::isValidPath($path); + } + + /** + * checks if a file is blacklisted for storage in the filesystem + * Listens to write and rename hooks + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param array $data from hook + */ + static public function isBlacklisted($data) { + \OC\Files\Filesystem::isBlacklisted($data); + } + + /** + * following functions are equivalent to their php builtin equivalents for arguments/return values. + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function mkdir($path) { + return \OC\Files\Filesystem::mkdir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function rmdir($path) { + return \OC\Files\Filesystem::rmdir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function opendir($path) { + return \OC\Files\Filesystem::opendir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function readdir($path) { + return \OC\Files\Filesystem::readdir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function is_dir($path) { + return \OC\Files\Filesystem::is_dir($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function is_file($path) { + return \OC\Files\Filesystem::is_file($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function stat($path) { + return \OC\Files\Filesystem::stat($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function filetype($path) { + return \OC\Files\Filesystem::filetype($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function filesize($path) { + return \OC\Files\Filesystem::filesize($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function readfile($path) { + return \OC\Files\Filesystem::readfile($path); + } + + /** + * @deprecated Replaced by isReadable() as part of CRUDS + */ + static public function is_readable($path) { + return \OC\Files\Filesystem::isReadable($path); + } + + /** + * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS + */ + static public function is_writable($path) { + return \OC\Files\Filesystem::is_writable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isCreatable($path) { + return \OC\Files\Filesystem::isCreatable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isReadable($path) { + return \OC\Files\Filesystem::isReadable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isUpdatable($path) { + return \OC\Files\Filesystem::isUpdatable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isDeletable($path) { + return \OC\Files\Filesystem::isDeletable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function isSharable($path) { + return \OC\Files\Filesystem::isSharable($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function file_exists($path) { + return \OC\Files\Filesystem::file_exists($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function filectime($path) { + return \OC\Files\Filesystem::filectime($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function filemtime($path) { + return \OC\Files\Filesystem::filemtime($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function touch($path, $mtime = null) { + return \OC\Files\Filesystem::touch($path, $mtime); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function file_get_contents($path) { + return \OC\Files\Filesystem::file_get_contents($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function file_put_contents($path, $data) { + return \OC\Files\Filesystem::file_put_contents($path, $data); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function unlink($path) { + return \OC\Files\Filesystem::unlink($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function rename($path1, $path2) { + return \OC\Files\Filesystem::rename($path1, $path2); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function copy($path1, $path2) { + return \OC\Files\Filesystem::copy($path1, $path2); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function fopen($path, $mode) { + return \OC\Files\Filesystem::fopen($path, $mode); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function toTmpFile($path) { + return \OC\Files\Filesystem::toTmpFile($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function fromTmpFile($tmpFile, $path) { + return \OC\Files\Filesystem::fromTmpFile($tmpFile, $path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function getMimeType($path) { + return \OC\Files\Filesystem::getMimeType($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function hash($type, $path, $raw = false) { + return \OC\Files\Filesystem::hash($type, $path, $raw); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function free_space($path = '/') { + return \OC\Files\Filesystem::free_space($path); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function search($query) { + return \OC\Files\Filesystem::search($query); + } + + /** + * check if a file or folder has been updated since $time + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @param int $time + * @return bool + */ + static public function hasUpdated($path, $time) { + return \OC\Files\Filesystem::hasUpdated($path, $time); + } + + /** + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + */ + static public function removeETagHook($params, $root = false) { + \OC\Files\Filesystem::removeETagHook($params, $root); + } + + /** + * normalize a path + * + * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem + * @param string $path + * @param bool $stripTrailingSlash + * @return string + */ + public static function normalizePath($path, $stripTrailingSlash = true) { + return \OC\Files\Filesystem::normalizePath($path, $stripTrailingSlash); + } +} From c88c54bbb054fe2d79b3a93604989d527b5dd444 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 12:51:15 +0200 Subject: [PATCH 031/262] make sure we can do our tests again --- lib/cache/file.php | 4 ++-- tests/lib/cache/file.php | 2 +- tests/lib/filesystem.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/cache/file.php b/lib/cache/file.php index 27d8b19f36..f9ecf41dca 100644 --- a/lib/cache/file.php +++ b/lib/cache/file.php @@ -15,11 +15,11 @@ class OC_Cache_File{ } if(OC_User::isLoggedIn()) { $subdir = 'cache'; - $view = new OC_FilesystemView('/'.OC_User::getUser()); + $view = new \OC\Files\View('/'.OC_User::getUser()); if(!$view->file_exists($subdir)) { $view->mkdir($subdir); } - $this->storage = new OC_FilesystemView('/'.OC_User::getUser().'/'.$subdir); + $this->storage = new \OC\Files\View('/'.OC_User::getUser().'/'.$subdir); return $this->storage; }else{ OC_Log::write('core', 'Can\'t get cache storage, user not logged in', OC_Log::ERROR); diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 1dd1ff7fa8..3e8fd8c1bb 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -51,7 +51,7 @@ class Test_Cache_File extends Test_Cache { OC_User::setUserId('test'); //set up the users dir - $rootView=new OC_FilesystemView(''); + $rootView=new \OC\Files\View(''); $rootView->mkdir('/test'); $this->instance=new OC_Cache_File(); diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index 8fc3ce641d..b402b86af1 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -84,7 +84,7 @@ class Test_Filesystem extends UnitTestCase { OC_Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); - $rootView=new OC_FilesystemView(''); + $rootView=new \OC\Files\View(''); $rootView->mkdir('/'.$user); $rootView->mkdir('/'.$user.'/files'); From aaa1b733642c41821a53bc6d04fab246bfe7f1e6 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 13:18:36 +0200 Subject: [PATCH 032/262] don't use depricated OC_Filesystem --- apps/files/ajax/autocomplete.php | 6 +- apps/files/ajax/newfile.php | 6 +- apps/files/ajax/upload.php | 4 +- apps/files/appinfo/filesync.php | 4 +- apps/files/download.php | 8 +-- apps/files/index.php | 14 ++-- apps/files_encryption/lib/crypt.php | 6 +- apps/files_encryption/lib/cryptstream.php | 2 +- apps/files_encryption/lib/proxy.php | 6 +- apps/files_encryption/tests/proxy.php | 30 ++++----- .../ajax/addRootCertificate.php | 12 ++-- apps/files_external/lib/config.php | 12 ++-- apps/files_sharing/lib/sharedstorage.php | 66 +++++++++---------- apps/files_sharing/public.php | 8 +-- apps/files_versions/lib/hooks.php | 4 +- apps/files_versions/lib/versions.php | 16 ++--- lib/connector/sabre/directory.php | 10 +-- lib/connector/sabre/file.php | 10 +-- lib/connector/sabre/node.php | 8 +-- lib/filechunking.php | 38 +++++------ lib/fileproxy/quota.php | 2 +- lib/files.php | 54 +++++++-------- lib/files/file.php | 2 +- lib/helper.php | 2 +- lib/image.php | 2 +- lib/ocs.php | 4 +- lib/public/files.php | 2 +- lib/public/share.php | 6 +- lib/util.php | 10 +-- settings/personal.php | 2 +- tests/lib/cache/file.php | 4 +- tests/lib/filesystem.php | 56 ++++++++-------- 32 files changed, 209 insertions(+), 207 deletions(-) diff --git a/apps/files/ajax/autocomplete.php b/apps/files/ajax/autocomplete.php index fae38368a8..d0dab9c2bd 100644 --- a/apps/files/ajax/autocomplete.php +++ b/apps/files/ajax/autocomplete.php @@ -33,8 +33,8 @@ $query=strtolower($query); $files=array(); -if(OC_Filesystem::file_exists($base) and OC_Filesystem::is_dir($base)) { - $dh = OC_Filesystem::opendir($base); +if(\OC\Files\Filesystem::file_exists($base) and \OC\Files\Filesystem::is_dir($base)) { + $dh = \OC\Files\Filesystem::opendir($base); if($dh) { if(substr($base, -1, 1)!='/') { $base=$base.'/'; @@ -43,7 +43,7 @@ if(OC_Filesystem::file_exists($base) and OC_Filesystem::is_dir($base)) { if ($file != "." && $file != "..") { if(substr(strtolower($file), 0, $queryLen)==$query) { $item=$base.$file; - if((!$dirOnly or OC_Filesystem::is_dir($item))) { + if((!$dirOnly or \OC\Files\Filesystem::is_dir($item))) { $files[]=(object)array('id'=>$item,'label'=>$item,'name'=>$item); } } diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 77d866979c..4d73970b68 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -63,12 +63,12 @@ if($source) { $ctx = stream_context_create(null, array('notification' =>'progress')); $sourceStream=fopen($source, 'rb', false, $ctx); $target=$dir.'/'.$filename; - $result=OC_Filesystem::file_put_contents($target, $sourceStream); + $result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream); if($result) { $meta = OC_FileCache::get($target); $mime=$meta['mimetype']; $id = OC_FileCache::getId($target); - $eventSource->send('success', array('mime'=>$mime, 'size'=>OC_Filesystem::filesize($target), 'id' => $id)); + $eventSource->send('success', array('mime'=>$mime, 'size'=>\OC\Files\Filesystem::filesize($target), 'id' => $id)); } else { $eventSource->send('error', "Error while downloading ".$source. ' to '.$target); } @@ -76,7 +76,7 @@ if($source) { exit(); } else { if($content) { - if(OC_Filesystem::file_put_contents($dir.'/'.$filename, $content)) { + if(\OC\Files\Filesystem::file_put_contents($dir.'/'.$filename, $content)) { $meta = OC_FileCache::get($dir.'/'.$filename); $id = OC_FileCache::getId($dir.'/'.$filename); OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index a4dcd80a2e..8bf7f10e18 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -38,7 +38,7 @@ $totalSize=0; foreach($files['size'] as $size) { $totalSize+=$size; } -if($totalSize>OC_Filesystem::free_space('/')) { +if($totalSize>\OC\Files\Filesystem::free_space('/')) { OCP\JSON::error(array("data" => array( "message" => "Not enough space available" ))); exit(); } @@ -48,7 +48,7 @@ if(strpos($dir, '..') === false) { $fileCount=count($files['name']); for($i=0;$i<$fileCount;$i++) { $target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]); - if(is_uploaded_file($files['tmp_name'][$i]) and OC_Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { + if(is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { $meta = OC_FileCache::get($target); $id = OC_FileCache::getId($target); $result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'], 'id'=>$id, 'name'=>basename($target)); diff --git a/apps/files/appinfo/filesync.php b/apps/files/appinfo/filesync.php index c1fe444cec..e755771de6 100644 --- a/apps/files/appinfo/filesync.php +++ b/apps/files/appinfo/filesync.php @@ -43,7 +43,7 @@ if ($type != 'oc_chunked') { die; } -if (!OC_Filesystem::is_file($file)) { +if (!\OC\Files\Filesystem::is_file($file)) { OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND); die; } @@ -51,7 +51,7 @@ if (!OC_Filesystem::is_file($file)) { switch($_SERVER['REQUEST_METHOD']) { case 'PUT': $input = fopen("php://input", "r"); - $org_file = OC_Filesystem::fopen($file, 'rb'); + $org_file = \OC\Files\Filesystem::fopen($file, 'rb'); $info = array( 'name' => basename($file), ); diff --git a/apps/files/download.php b/apps/files/download.php index ff6aefbbe0..b00a50a045 100644 --- a/apps/files/download.php +++ b/apps/files/download.php @@ -29,7 +29,7 @@ OCP\User::checkLoggedIn(); $filename = $_GET["file"]; -if(!OC_Filesystem::file_exists($filename)) { +if(!\OC\Files\Filesystem::file_exists($filename)) { header("HTTP/1.0 404 Not Found"); $tmpl = new OCP\Template( '', '404', 'guest' ); $tmpl->assign('file',$filename); @@ -37,12 +37,12 @@ if(!OC_Filesystem::file_exists($filename)) { exit; } -$ftype=OC_Filesystem::getMimeType( $filename ); +$ftype=\OC\Files\Filesystem::getMimeType( $filename ); header('Content-Type:'.$ftype); header('Content-Disposition: attachment; filename="'.basename($filename).'"'); OCP\Response::disableCaching(); -header('Content-Length: '.OC_Filesystem::filesize($filename)); +header('Content-Length: '.\OC\Files\Filesystem::filesize($filename)); @ob_end_clean(); -OC_Filesystem::readfile( $filename ); +\OC\Files\Filesystem::readfile( $filename ); diff --git a/apps/files/index.php b/apps/files/index.php index 493087d26f..b02aaf81c0 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -38,7 +38,7 @@ OCP\App::setActiveNavigationEntry( 'files_index' ); // Load the files $dir = isset( $_GET['dir'] ) ? stripslashes($_GET['dir']) : ''; // Redirect if directory does not exist -if(!OC_Filesystem::is_dir($dir.'/')) { +if(!\OC\Files\Filesystem::is_dir($dir.'/')) { header('Location: '.$_SERVER['SCRIPT_NAME'].''); exit(); } @@ -85,26 +85,26 @@ $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize') $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); $maxUploadFilesize = min($upload_max_filesize, $post_max_size); -$freeSpace=OC_Filesystem::free_space('/'); +$freeSpace=\OC\Files\Filesystem::free_space('/'); $freeSpace=max($freeSpace,0); $maxUploadFilesize = min($maxUploadFilesize ,$freeSpace); $permissions = OCP\Share::PERMISSION_READ; -if (OC_Filesystem::isUpdatable($dir.'/')) { +if (\OC\Files\Filesystem::isUpdatable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_UPDATE; } -if (OC_Filesystem::isDeletable($dir.'/')) { +if (\OC\Files\Filesystem::isDeletable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_DELETE; } -if (OC_Filesystem::isSharable($dir.'/')) { +if (\OC\Files\Filesystem::isSharable($dir.'/')) { $permissions |= OCP\Share::PERMISSION_SHARE; } $tmpl = new OCP\Template( 'files', 'index', 'user' ); $tmpl->assign( 'fileList', $list->fetchPage(), false ); $tmpl->assign( 'breadcrumb', $breadcrumbNav->fetchPage(), false ); -$tmpl->assign( 'dir', OC_Filesystem::normalizePath($dir)); -$tmpl->assign( 'isCreatable', OC_Filesystem::isCreatable($dir.'/')); +$tmpl->assign( 'dir', \OC\Files\Filesystem::normalizePath($dir)); +$tmpl->assign( 'isCreatable', \OC\Files\Filesystem::isCreatable($dir.'/')); $tmpl->assign('permissions', $permissions); $tmpl->assign( 'files', $files ); $tmpl->assign( 'uploadMaxFilesize', $maxUploadFilesize); diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 38d8edf28c..6bee8accf7 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -44,7 +44,7 @@ class OC_Crypt { } public static function init($login,$password) { - $view=new OC_FilesystemView('/'); + $view=new \OC\Files\View('/'); if(!$view->file_exists('/'.$login)) { $view->mkdir('/'.$login); } @@ -90,7 +90,7 @@ class OC_Crypt { // Write the file $proxyEnabled=OC_FileProxy::$enabled; OC_FileProxy::$enabled=false; - $view=new OC_FilesystemView('/'.$username); + $view=new \OC\Files\View('/'.$username); $view->file_put_contents('/encryption.key',$enckey); OC_FileProxy::$enabled=$proxyEnabled; } @@ -98,7 +98,7 @@ class OC_Crypt { public static function changekeypasscode($oldPassword, $newPassword) { if(OCP\User::isLoggedIn()) { $username=OCP\USER::getUser(); - $view=new OC_FilesystemView('/'.$username); + $view=new \OC\Files\View('/'.$username); // read old key $key=$view->file_get_contents('/encryption.key'); diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index 721a1b955d..89a071327a 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -38,7 +38,7 @@ class OC_CryptStream{ public function stream_open($path, $mode, $options, &$opened_path) { if(!self::$rootView) { - self::$rootView=new OC_FilesystemView(''); + self::$rootView=new \OC\Files\View(''); } $path=str_replace('crypt://','',$path); if(dirname($path)=='streams' and isset(self::$sourceStreams[basename($path)])) { diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index f61cd1e377..27abe3bb19 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -90,13 +90,13 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ fclose($result); $result=fopen('crypt://'.$path,$meta['mode']); }elseif(self::shouldEncrypt($path) and $meta['mode']!='r' and $meta['mode']!='rb') { - if(OC_Filesystem::file_exists($path) and OC_Filesystem::filesize($path)>0) { + if(\OC\Files\Filesystem::file_exists($path) and \OC\Files\Filesystem::filesize($path)>0) { //first encrypt the target file so we don't end up with a half encrypted file OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing',OCP\Util::DEBUG); - $tmp=fopen('php://temp'); + $tmp=fopen('php://temp', 'w+'); OCP\Files::streamCopy($result,$tmp); fclose($result); - OC_Filesystem::file_put_contents($path,$tmp); + \OC\Files\Filesystem::file_put_contents($path,$tmp); fclose($tmp); } $result=fopen('crypt://'.$path,$meta['mode']); diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index d600bbc407..c04e0e5c4f 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -29,13 +29,13 @@ class Test_CryptProxy extends UnitTestCase { OC_FileProxy::register(new OC_FileProxy_Encryption()); //set up temporary storage - OC_Filesystem::clearMounts(); - OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); - OC_Filesystem::init('/'.$user.'/files'); + \OC\Files\Filesystem::init('/'.$user.'/files'); //set up the users home folder in the temp storage - $rootView=new OC_FilesystemView(''); + $rootView=new \OC\Files\View(''); $rootView->mkdir('/'.$user); $rootView->mkdir('/'.$user.'/files'); } @@ -51,13 +51,13 @@ class Test_CryptProxy extends UnitTestCase { $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); $this->assertEqual($original,$fromFile); @@ -68,8 +68,8 @@ class Test_CryptProxy extends UnitTestCase { $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; $original=file_get_contents($file); - $rootView=new OC_FilesystemView(''); - $view=new OC_FilesystemView('/'.OC_User::getUser()); + $rootView=new \OC\Files\View(''); + $view=new \OC\Files\View('/'.OC_User::getUser()); $userDir='/'.OC_User::getUser().'/files'; $rootView->file_put_contents($userDir.'/file',$original); @@ -90,13 +90,13 @@ class Test_CryptProxy extends UnitTestCase { $file=__DIR__.'/binary'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); $this->assertEqual($original,$fromFile); @@ -104,13 +104,13 @@ class Test_CryptProxy extends UnitTestCase { $file=__DIR__.'/zeros'; $original=file_get_contents($file); - OC_Filesystem::file_put_contents('/file',$original); + \OC\Files\Filesystem::file_put_contents('/file',$original); OC_FileProxy::$enabled=false; - $stored=OC_Filesystem::file_get_contents('/file'); + $stored=\OC\Files\Filesystem::file_get_contents('/file'); OC_FileProxy::$enabled=true; - $fromFile=OC_Filesystem::file_get_contents('/file'); + $fromFile=\OC\Files\Filesystem::file_get_contents('/file'); $this->assertNotEqual($original,$stored); $this->assertEqual(strlen($original),strlen($fromFile)); } diff --git a/apps/files_external/ajax/addRootCertificate.php b/apps/files_external/ajax/addRootCertificate.php index e0a0239c95..6fef9aac1e 100644 --- a/apps/files_external/ajax/addRootCertificate.php +++ b/apps/files_external/ajax/addRootCertificate.php @@ -3,23 +3,23 @@ OCP\JSON::checkAppEnabled('files_external'); if ( !($filename = $_FILES['rootcert_import']['name']) ) { - header("Location: settings/personal.php"); + header("Location: settings/personal.php"); exit; } -$fh = fopen($_FILES['rootcert_import']['tmp_name'], 'r'); -$data = fread($fh, filesize($_FILES['rootcert_import']['tmp_name'])); +$fh = fopen($_FILES['rootcert_import']['tmp_name'], 'r'); +$data = fread($fh, filesize($_FILES['rootcert_import']['tmp_name'])); fclose($fh); $filename = $_FILES['rootcert_import']['name']; - -$view = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files_external/uploads'); + +$view = new \OC\Files\View('/'.\OCP\User::getUser().'/files_external/uploads'); if (!$view->file_exists('')) $view->mkdir(''); $isValid = openssl_pkey_get_public($data); //maybe it was just the wrong file format, try to convert it... if ($isValid == false) { - $data = chunk_split(base64_encode($data), 64, "\n"); + $data = chunk_split(base64_encode($data), 64, "\n"); $data = "-----BEGIN CERTIFICATE-----\n".$data."-----END CERTIFICATE-----\n"; $isValid = openssl_pkey_get_public($data); } diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index cb32fed203..7be2336019 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -109,10 +109,10 @@ class OC_Mount_Config { return $personal; } - /** - * Add directory for mount point to the filesystem - * @param OC_Fileview instance $view - * @param string path to mount point + /** + * Add directory for mount point to the filesystem + * @param OC_Fileview instance $view + * @param string path to mount point */ private static function addMountPointDirectory($view, $path) { $dir = ''; @@ -142,11 +142,11 @@ class OC_Mount_Config { if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') { return false; } - $view = new OC_FilesystemView('/'.OCP\User::getUser().'/files'); + $view = new \OC\Files\View('/'.OCP\User::getUser().'/files'); self::addMountPointDirectory($view, ltrim($mountPoint, '/')); $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); } else { - $view = new OC_FilesystemView('/'); + $view = new \OC\Files\View('/'); switch ($mountType) { case 'user': if ($applicable == "all") { diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 876e719956..e17c4b6e04 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -80,7 +80,7 @@ class Shared extends \OC\Files\Storage\Common { $file = $this->getFile($target); if (isset($file['path'])) { $uid = substr($file['path'], 1, strpos($file['path'], '/', 1) - 1); - \OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); + \\OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); return $file['path']; } return false; @@ -105,7 +105,7 @@ class Shared extends \OC\Files\Storage\Common { * @return Source file path with mount point stripped out */ private function getInternalPath($path) { - $mountPoint = \OC_Filesystem::getMountPoint($path); + $mountPoint = \OC\Files\Filesystem::getMountPoint($path); $internalPath = substr($path, strlen($mountPoint)); return $internalPath; } @@ -114,7 +114,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->mkdir($this->getInternalPath($source)); } return false; @@ -122,7 +122,7 @@ class Shared extends \OC\Files\Storage\Common { public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->rmdir($this->getInternalPath($source)); } return false; @@ -130,11 +130,11 @@ class Shared extends \OC\Files\Storage\Common { public function opendir($path) { if ($path == '' || $path == '/') { - $files = OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); + $files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->opendir($this->getInternalPath($source)); } return false; @@ -144,7 +144,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->is_dir($this->getInternalPath($source)); } return false; @@ -152,7 +152,7 @@ class Shared extends \OC\Files\Storage\Common { public function is_file($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->is_file($this->getInternalPath($source)); } return false; @@ -165,7 +165,7 @@ class Shared extends \OC\Files\Storage\Common { $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->stat($this->getInternalPath($source)); } return false; @@ -175,7 +175,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filetype($this->getInternalPath($source)); } return false; @@ -185,7 +185,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filesize($this->getInternalPath($source)); } return false; @@ -195,7 +195,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_CREATE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_CREATE); } public function isReadable($path) { @@ -206,28 +206,28 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_UPDATE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_UPDATE); } public function isDeletable($path) { if ($path == '') { return true; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_DELETE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_DELETE); } public function isSharable($path) { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\Share::PERMISSION_SHARE); + return ($this->getPermissions($path) & \OCP\Share::PERMISSION_SHARE); } public function file_exists($path) { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->file_exists($this->getInternalPath($source)); } return false; @@ -248,7 +248,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filectime($this->getInternalPath($source)); } } @@ -269,7 +269,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->filemtime($this->getInternalPath($source)); } } @@ -282,8 +282,8 @@ class Shared extends \OC\Files\Storage\Common { 'target' => $this->sharedFolder.$path, 'source' => $source, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->file_get_contents($this->getInternalPath($source)); } } @@ -298,8 +298,8 @@ class Shared extends \OC\Files\Storage\Common { 'target' => $this->sharedFolder.$path, 'source' => $source, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); + $storage = \OC\Files\Filesystem::getStorage($source); $result = $storage->file_put_contents($this->getInternalPath($source), $data); return $result; } @@ -310,7 +310,7 @@ class Shared extends \OC\Files\Storage\Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->unlink($this->getInternalPath($source)); } else if (dirname($path) == '/' || dirname($path) == '.') { // Unshare the file from the user if in the root of the Shared folder @@ -319,7 +319,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $itemType = 'file'; } - return OCP\Share::unshareFromSelf($itemType, $path); + return \OCP\Share::unshareFromSelf($itemType, $path); } } return false; @@ -334,7 +334,7 @@ class Shared extends \OC\Files\Storage\Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - $storage = \OC_Filesystem::getStorage($oldSource); + $storage = \OC\Files\Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } else { @@ -349,7 +349,7 @@ class Shared extends \OC\Files\Storage\Common { return $this->unlink($path1); } } else { - $storage = \OC_Filesystem::getStorage($oldSource); + $storage = \OC\Files\Filesystem::getStorage($oldSource); return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); } } @@ -394,8 +394,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, 'mode' => $mode, ); - OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); - $storage = \OC_Filesystem::getStorage($source); + \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->fopen($this->getInternalPath($source), $mode); } return false; @@ -406,7 +406,7 @@ class Shared extends \OC\Files\Storage\Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->getMimeType($this->getInternalPath($source)); } return false; @@ -415,21 +415,21 @@ class Shared extends \OC\Files\Storage\Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->free_space($this->getInternalPath($source)); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->getLocalFile($this->getInternalPath($source)); } return false; } public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { - $storage = \OC_Filesystem::getStorage($source); + $storage = \OC\Files\Filesystem::getStorage($source); return $storage->touch($this->getInternalPath($source), $mtime); } return false; @@ -437,7 +437,7 @@ class Shared extends \OC\Files\Storage\Common { public static function setup($options) { $user_dir = $options['user_dir']; - \OC_Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } /** diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 34340102a9..c5f4b39d70 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -73,7 +73,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { if (isset($_GET['path'])) { $path .= $_GET['path']; $dir .= $_GET['path']; - if (!OC_Filesystem::file_exists($path)) { + if (!\OC\Files\Filesystem::file_exists($path)) { header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); @@ -101,7 +101,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('owner', $uidOwner); // Show file list - if (OC_Filesystem::is_dir($path)) { + if (\OC\Files\Filesystem::is_dir($path)) { OCP\Util::addStyle('files', 'files'); OCP\Util::addScript('files', 'files'); OCP\Util::addScript('files', 'filelist'); @@ -157,7 +157,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl->assign('uidOwner', $uidOwner); $tmpl->assign('dir', basename($dir)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); if (isset($_GET['path'])) { $getPath = $_GET['path']; @@ -170,7 +170,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl->assign('uidOwner', $uidOwner); $tmpl->assign('dir', dirname($path)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); if ($type == 'file') { $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&file='.$_GET['file'].'&download'); } else { diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php index 9ec0b01a7f..7cb3170df2 100644 --- a/apps/files_versions/lib/hooks.php +++ b/apps/files_versions/lib/hooks.php @@ -21,9 +21,9 @@ class Hooks { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { - $versions = new Storage( new \OC_FilesystemView('') ); + $versions = new Storage( new \OC\Files\View('') ); - $path = $params[\OC_Filesystem::signal_param_path]; + $path = $params[\OC\Files\Filesystem::signal_param_path]; if($path<>'') $versions->store( $path ); diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 7d12e58f94..7f7837a742 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -58,8 +58,8 @@ class Storage { public function store($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $files_view = new \OC_FilesystemView('/'.$uid.'/files'); - $users_view = new \OC_FilesystemView('/'.$uid); + $files_view = new \OC\Files\View('/'.$uid.'/files'); + $users_view = new \OC\Files\View('/'.$uid); //check if source file already exist as version to avoid recursions. // todo does this check work? @@ -94,7 +94,7 @@ class Storage { // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval) if ($uid == \OCP\User::getUser()) { - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); $matches=glob($versionsFolderName.'/'.$filename.'.v*'); sort($matches); @@ -127,7 +127,7 @@ class Storage { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $users_view = new \OC_FilesystemView('/'.$uid); + $users_view = new \OC\Files\View('/'.$uid); // rollback if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) { @@ -150,7 +150,7 @@ class Storage { public static function isversioned($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); @@ -178,7 +178,7 @@ class Storage { if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName = \OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); $versions = array(); @@ -190,7 +190,7 @@ class Storage { $i = 0; - $files_view = new \OC_FilesystemView('/'.$uid.'/files'); + $files_view = new \OC\Files\View('/'.$uid.'/files'); $local_file = $files_view->getLocalFile($filename); foreach( $matches as $ma ) { @@ -245,7 +245,7 @@ class Storage { public static function expire($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 413efef73b..4fff3ba51b 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -62,7 +62,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa } } else { $newPath = $this->path . '/' . $name; - OC_Filesystem::file_put_contents($newPath, $data); + \OC\Files\Filesystem::file_put_contents($newPath, $data); return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath); } @@ -78,7 +78,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa public function createDirectory($name) { $newPath = $this->path . '/' . $name; - OC_Filesystem::mkdir($newPath); + \OC\Files\Filesystem::mkdir($newPath); } @@ -154,7 +154,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa public function childExists($name) { $path = $this->path . '/' . $name; - return OC_Filesystem::file_exists($path); + return \OC\Files\Filesystem::file_exists($path); } @@ -167,7 +167,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa if ($this->path != "/Shared") { foreach($this->getChildren() as $child) $child->delete(); - OC_Filesystem::rmdir($this->path); + \OC\Files\Filesystem::rmdir($this->path); } } @@ -181,7 +181,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $rootInfo=OC_FileCache_Cached::get(''); return array( $rootInfo['size'], - OC_Filesystem::free_space() + \OC\Files\Filesystem::free_space() ); } diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index 5bd38240d4..1770b49128 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -45,7 +45,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function put($data) { - OC_Filesystem::file_put_contents($this->path,$data); + \OC\Files\Filesystem::file_put_contents($this->path,$data); return OC_Connector_Sabre_Node::getETagPropertyForPath($this->path); } @@ -57,7 +57,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function get() { - return OC_Filesystem::fopen($this->path,'rb'); + return \OC\Files\Filesystem::fopen($this->path,'rb'); } @@ -68,7 +68,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function delete() { - OC_Filesystem::unlink($this->path); + \OC\Files\Filesystem::unlink($this->path); } @@ -107,7 +107,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * @return string|null Returns null if the ETag can not effectively be determined */ static protected function createETag($path) { - return OC_Filesystem::hash('md5', $path); + return \OC\Files\Filesystem::hash('md5', $path); } /** @@ -122,7 +122,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D return $this->fileinfo_cache['mimetype']; } - return OC_Filesystem::getMimeType($this->path); + return \OC\Files\Filesystem::getMimeType($this->path); } } diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index 72de972377..e7e83507ea 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -80,7 +80,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr $newPath = $parentPath . '/' . $newName; $oldPath = $this->path; - OC_Filesystem::rename($this->path,$newPath); + \OC\Files\Filesystem::rename($this->path,$newPath); $this->path = $newPath; @@ -99,9 +99,9 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr */ protected function getFileinfoCache() { if (!isset($this->fileinfo_cache)) { - if ($fileinfo_cache = OC_FileCache::get($this->path)) { + if ($fileinfo_cache = \OC\Files\Filesystem::get($this->path)) { } else { - $fileinfo_cache = OC_Filesystem::stat($this->path); + $fileinfo_cache = \OC\Files\Filesystem::stat($this->path); } $this->fileinfo_cache = $fileinfo_cache; @@ -130,7 +130,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * Even if the modification time is set to a custom value the access time is set to now. */ public function touch($mtime) { - OC_Filesystem::touch($this->path, $mtime); + \OC\Files\Filesystem::touch($this->path, $mtime); } /** diff --git a/lib/filechunking.php b/lib/filechunking.php index 5ab33c77ad..e616e3b12d 100644 --- a/lib/filechunking.php +++ b/lib/filechunking.php @@ -94,49 +94,49 @@ class OC_FileChunking { } public function file_assemble($path) { - $absolutePath = OC_Filesystem::normalizePath(OC_Filesystem::getView()->getAbsolutePath($path)); + $absolutePath = \OC\Files\Filesystem::normalizePath(\OC\Files\Filesystem::getView()->getAbsolutePath($path)); $data = ''; // use file_put_contents as method because that best matches what this function does - if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && OC_Filesystem::isValidPath($path)) { - $path = OC_Filesystem::getView()->getRelativePath($absolutePath); - $exists = OC_Filesystem::file_exists($path); + if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) && \OC\Files\Filesystem::isValidPath($path)) { + $path = \OC\Files\Filesystem::getView()->getRelativePath($absolutePath); + $exists = \OC\Files\Filesystem::file_exists($path); $run = true; if(!$exists) { OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_create, + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_create, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + \OC\Files\Filesystem::signal_param_path => $path, + \OC\Files\Filesystem::signal_param_run => &$run ) ); } OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_write, + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_write, array( - OC_Filesystem::signal_param_path => $path, - OC_Filesystem::signal_param_run => &$run + \OC\Files\Filesystem::signal_param_path => $path, + \OC\Files\Filesystem::signal_param_run => &$run ) ); if(!$run) { return false; } - $target = OC_Filesystem::fopen($path, 'w'); + $target = \OC\Files\Filesystem::fopen($path, 'w'); if($target) { $count = $this->assemble($target); fclose($target); if(!$exists) { OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_create, - array( OC_Filesystem::signal_param_path => $path) + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_post_create, + array( \OC\Files\Filesystem::signal_param_path => $path) ); } OC_Hook::emit( - OC_Filesystem::CLASSNAME, - OC_Filesystem::signal_post_write, - array( OC_Filesystem::signal_param_path => $path) + \OC\Files\Filesystem::CLASSNAME, + \OC\Files\Filesystem::signal_post_write, + array( \OC\Files\Filesystem::signal_param_path => $path) ); OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); return $count > 0; diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index 5a0dbdb6fe..bc5ef9c8df 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -88,7 +88,7 @@ class OC_FileProxy_Quota extends OC_FileProxy{ public function preCopy($path1,$path2) { if(!self::$rootView){ - self::$rootView = new OC_FilesystemView(''); + self::$rootView = new \OC\Files\View(''); } return (self::$rootView->filesize($path1)<$this->getFreeSpace() or $this->getFreeSpace()==0); } diff --git a/lib/files.php b/lib/files.php index 2b2b8b42dc..29322cf2d0 100644 --- a/lib/files.php +++ b/lib/files.php @@ -46,10 +46,10 @@ class OC_Files { if ($path == '/Shared') { list($info) = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT); }else{ - $info['size'] = OC_Filesystem::filesize($path); - $info['mtime'] = OC_Filesystem::filemtime($path); - $info['ctime'] = OC_Filesystem::filectime($path); - $info['mimetype'] = OC_Filesystem::getMimeType($path); + $info['size'] = \OC\Files\Filesystem::filesize($path); + $info['mtime'] = \OC\Files\Filesystem::filemtime($path); + $info['ctime'] = \OC\Files\Filesystem::filectime($path); + $info['mimetype'] = \OC\Files\Filesystem::getMimeType($path); $info['encrypted'] = false; $info['versioned'] = false; } @@ -64,7 +64,7 @@ class OC_Files { * @param dir $directory path under datadirectory */ public static function getDirectoryContent($directory, $mimetype_filter = '') { - $directory=OC_Filesystem::normalizePath($directory); + $directory=\OC\Files\Filesystem::normalizePath($directory); if($directory=='/') { $directory=''; } @@ -151,17 +151,17 @@ class OC_Files { } foreach($files as $file) { $file=$dir.'/'.$file; - if(OC_Filesystem::is_file($file)) { - $tmpFile=OC_Filesystem::toTmpFile($file); + if(\OC\Files\Filesystem::is_file($file)) { + $tmpFile=OC_F\OC\Files\Filesystemilesystem::toTmpFile($file); self::$tmpFiles[]=$tmpFile; $zip->addFile($tmpFile,basename($file)); - }elseif(OC_Filesystem::is_dir($file)) { + }elseif(\OC\Files\Filesystem::is_dir($file)) { self::zipAddDir($file,$zip); } } $zip->close(); set_time_limit($executionTime); - }elseif(OC_Filesystem::is_dir($dir.'/'.$files)) { + }elseif(\OC\Files\Filesystem::is_dir($dir.'/'.$files)) { self::validateZipDownload($dir,$files); $executionTime = intval(ini_get('max_execution_time')); set_time_limit(0); @@ -179,7 +179,7 @@ class OC_Files { $filename=$dir.'/'.$files; } @ob_end_clean(); - if($zip or OC_Filesystem::is_readable($filename)) { + if($zip or \OC\Files\Filesystem::is_readable($filename)) { header('Content-Disposition: attachment; filename="'.basename($filename).'"'); header('Content-Transfer-Encoding: binary'); OC_Response::disableCaching(); @@ -188,9 +188,9 @@ class OC_Files { header('Content-Type: application/zip'); header('Content-Length: ' . filesize($filename)); }else{ - header('Content-Type: '.OC_Filesystem::getMimeType($filename)); + header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); } - }elseif($zip or !OC_Filesystem::file_exists($filename)) { + }elseif($zip or !\OC\Files\Filesystem::file_exists($filename)) { header("HTTP/1.0 404 Not Found"); $tmpl = new OC_Template( '', '404', 'guest' ); $tmpl->assign('file',$filename); @@ -201,7 +201,7 @@ class OC_Files { } if($only_header) { if(!$zip) - header("Content-Length: ".OC_Filesystem::filesize($filename)); + header("Content-Length: ".\OC\Files\Filesystem::filesize($filename)); return ; } if($zip) { @@ -215,7 +215,7 @@ class OC_Files { } unlink($filename); }else{ - OC_Filesystem::readfile($filename); + \OC\Files\Filesystem::readfile($filename); } foreach(self::$tmpFiles as $tmpFile) { if(file_exists($tmpFile) and is_file($tmpFile)) { @@ -232,11 +232,11 @@ class OC_Files { foreach($files as $file) { $filename=$file['name']; $file=$dir.'/'.$filename; - if(OC_Filesystem::is_file($file)) { - $tmpFile=OC_Filesystem::toTmpFile($file); + if(\OC\Files\Filesystem::is_file($file)) { + $tmpFile=\OC\Files\Filesystem::toTmpFile($file); OC_Files::$tmpFiles[]=$tmpFile; $zip->addFile($tmpFile,$internalDir.$filename); - }elseif(OC_Filesystem::is_dir($file)) { + }elseif(\OC\Files\Filesystem::is_dir($file)) { self::zipAddDir($file,$zip,$internalDir); } } @@ -253,7 +253,7 @@ class OC_Files { if(OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared')) { $targetFile=self::normalizePath($targetDir.'/'.$target); $sourceFile=self::normalizePath($sourceDir.'/'.$source); - return OC_Filesystem::rename($sourceFile,$targetFile); + return \OC\Files\Filesystem::rename($sourceFile,$targetFile); } else { return false; } @@ -271,7 +271,7 @@ class OC_Files { if(OC_User::isLoggedIn()) { $targetFile=$targetDir.'/'.$target; $sourceFile=$sourceDir.'/'.$source; - return OC_Filesystem::copy($sourceFile,$targetFile); + return \OC\Files\Filesystem::copy($sourceFile,$targetFile); } } @@ -286,9 +286,9 @@ class OC_Files { if(OC_User::isLoggedIn()) { $file=$dir.'/'.$name; if($type=='dir') { - return OC_Filesystem::mkdir($file); + return \OC\Files\Filesystem::mkdir($file); }elseif($type=='file') { - $fileHandle=OC_Filesystem::fopen($file, 'w'); + $fileHandle=\OC\Files\Filesystem::fopen($file, 'w'); if($fileHandle) { fclose($fileHandle); return true; @@ -308,7 +308,7 @@ class OC_Files { public static function delete($dir,$file) { if(OC_User::isLoggedIn() && ($dir!= '' || $file != 'Shared')) { $file=$dir.'/'.$file; - return OC_Filesystem::unlink($file); + return \OC\Files\Filesystem::unlink($file); } } @@ -339,10 +339,10 @@ class OC_Files { $totalsize = 0; if(is_array($files)) { foreach($files as $file) { - $totalsize += OC_Filesystem::filesize($dir.'/'.$file); + $totalsize += \OC\Files\Filesystem::filesize($dir.'/'.$file); } }else{ - $totalsize += OC_Filesystem::filesize($dir.'/'.$files); + $totalsize += \OC\Files\Filesystem::filesize($dir.'/'.$files); } if($totalsize > $zipLimit) { $l = OC_L10N::get('lib'); @@ -368,7 +368,7 @@ class OC_Files { * @return string guessed mime type */ static function getMimeType($path) { - return OC_Filesystem::getMimeType($path); + return \OC\Files\Filesystem::getMimeType($path); } /** @@ -378,7 +378,7 @@ class OC_Files { * @return array */ static function getTree($path) { - return OC_Filesystem::getTree($path); + return \OC\Files\Filesystem::getTree($path); } /** @@ -402,7 +402,7 @@ class OC_Files { $httpCode=$info['http_code']; curl_close($ch); if($httpCode==200 or $httpCode==0) { - OC_Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file); + \OC\Files\Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file); return true; }else{ return false; diff --git a/lib/files/file.php b/lib/files/file.php index b6432e6345..0d33cea7ee 100644 --- a/lib/files/file.php +++ b/lib/files/file.php @@ -30,7 +30,7 @@ class File{ public static function resolve($fullPath){ $storage = null; $internalPath = ''; - list($storage, $internalPath) = \OC_Filesystem::resolvePath($fullPath); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); return new File($storage, $internalPath); } diff --git a/lib/helper.php b/lib/helper.php index 908a61b5a2..48e16cebd0 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -560,7 +560,7 @@ class OC_Helper { $newpath = $path . '/' . $filename; $counter = 2; - while (OC_Filesystem::file_exists($newpath)) { + while (\OC\Files\Filesystem::file_exists($newpath)) { $newname = $name . ' (' . $counter . ')' . $ext; $newpath = $path . '/' . $newname; $counter++; diff --git a/lib/image.php b/lib/image.php index 861353e039..94fe3ce827 100644 --- a/lib/image.php +++ b/lib/image.php @@ -470,7 +470,7 @@ class OC_Image { default: // this is mostly file created from encrypted file - $this->resource = imagecreatefromstring(\OC_Filesystem::file_get_contents(\OC_Filesystem::getLocalPath($imagepath))); + $this->resource = imagecreatefromstring(\OC\Files\Filesystem::file_get_contents(\OC\Files\Filesystem::getLocalPath($imagepath))); $itype = IMAGETYPE_PNG; OC_Log::write('core','OC_Image->loadFromFile, Default', OC_Log::DEBUG); break; diff --git a/lib/ocs.php b/lib/ocs.php index 7350c3c882..645380ddba 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -589,11 +589,11 @@ class OC_OCS { if(OC_User::userExists($user)) { // calculate the disc space $user_dir = '/'.$user.'/files'; - OC_Filesystem::init($user_dir); + \OC\Files\Filesystem::init($user_dir); $rootInfo=OC_FileCache::get(''); $sharedInfo=OC_FileCache::get('/Shared'); $used=$rootInfo['size']-$sharedInfo['size']; - $free=OC_Filesystem::free_space(); + $free=\OC\Files\Filesystem::free_space(); $total=$free+$used; if($total==0) $total=1; // prevent division by zero $relative=round(($used/$total)*10000)/100; diff --git a/lib/public/files.php b/lib/public/files.php index 90889c59ad..2d6775e01f 100644 --- a/lib/public/files.php +++ b/lib/public/files.php @@ -98,7 +98,7 @@ class Files { /** * @param string appid * @param $app app - * @return OC_FilesystemView + * @return \OC\Files\View */ public static function getStorage( $app ) { return \OC_App::getStorage( $app ); diff --git a/lib/public/share.php b/lib/public/share.php index 1db3a0b2c1..7c4ede5e88 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -515,7 +515,7 @@ class Share { $backend = self::getBackend($itemType); // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { - $root = \OC_Filesystem::getRoot(); + $root = \OC\Files\Filesystem::getRoot(); $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; @@ -602,7 +602,7 @@ class Share { } else { if ($itemType == 'file' || $itemType == 'folder') { $where .= ' `file_target` = ?'; - $item = \OC_Filesystem::normalizePath($item); + $item = \OC\Files\Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } @@ -751,7 +751,7 @@ class Share { } else { $childItem['file_source'] = \OC_FileCache::getId($child['file_path']); } - $childItem['file_target'] = \OC_Filesystem::normalizePath($child['file_path']); + $childItem['file_target'] = \OC\Files\Filesystem::normalizePath($child['file_path']); } if (isset($item)) { if ($childItem[$column] == $item) { diff --git a/lib/util.php b/lib/util.php index 557f731522..5cf7657457 100755 --- a/lib/util.php +++ b/lib/util.php @@ -34,7 +34,7 @@ class OC_Util { $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); //first set up the local "root" storage if(!self::$rootMounted) { - OC_Filesystem::mount('\OC\Files\Storage\Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local',array('datadir'=>$CONFIG_DATADIRECTORY),'/'); self::$rootMounted=true; } @@ -46,8 +46,8 @@ class OC_Util { mkdir( $userdirectory, 0755, true ); } //jail the user into his "home" directory - OC_Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); - OC_Filesystem::init($user_dir); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); + \OC\Files\Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); OC_FileProxy::register($quotaProxy); // Load personal mount config @@ -55,7 +55,7 @@ class OC_Util { $mountConfig = include($user_root.'/mount.php'); if (isset($mountConfig['user'][$user])) { foreach ($mountConfig['user'][$user] as $mountPoint => $options) { - OC_Filesystem::mount($options['class'], $options['options'], $mountPoint); + \OC\Files\Filesystem::mount($options['class'], $options['options'], $mountPoint); } } } @@ -64,7 +64,7 @@ class OC_Util { } public static function tearDownFS() { - OC_Filesystem::tearDown(); + \OC\Files\Filesystem::tearDown(); self::$fsSetup=false; } diff --git a/settings/personal.php b/settings/personal.php index 9297f5d91c..54002d87c5 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -25,7 +25,7 @@ if (!isset($sharedInfo['size'])) { } $used=$rootInfo['size']-$sharedSize; if($used<0) $used=0; -$free=OC_Filesystem::free_space(); +$free=\OC\Files\Filesystem::free_space(); $total=$free+$used; if($total==0) $total=1; // prevent division by zero $relative=round(($used/$total)*10000)/100; diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 3e8fd8c1bb..5dcd326880 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -38,8 +38,8 @@ class Test_Cache_File extends Test_Cache { } //set up temporary storage - OC_Filesystem::clearMounts(); - OC_Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); + \OC\Files\Filesystem::clearMounts(); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Temporary',array(),'/'); OC_User::clearBackends(); OC_User::useBackend(new OC_User_Dummy()); diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index b402b86af1..af3620f570 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -20,6 +20,8 @@ * */ +use \OC\Files\Filesystem as Filesystem; + class Test_Filesystem extends UnitTestCase { /** * @var array tmpDirs @@ -42,64 +44,64 @@ class Test_Filesystem extends UnitTestCase { } public function setUp() { - OC_Filesystem::clearMounts(); + Filesystem::clearMounts(); } public function testMount() { - OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('',OC_Filesystem::getInternalPath('/')); - $this->assertEqual('some/folder',OC_Filesystem::getInternalPath('/some/folder')); + Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); + $this->assertEqual('/',Filesystem::getMountPoint('/')); + $this->assertEqual('/',Filesystem::getMountPoint('/some/folder')); + $this->assertEqual('',Filesystem::getInternalPath('/')); + $this->assertEqual('some/folder',Filesystem::getInternalPath('/some/folder')); - OC_Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/')); - $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('/some/',OC_Filesystem::getMountPoint('/some/')); - $this->assertEqual('/',OC_Filesystem::getMountPoint('/some')); - $this->assertEqual('folder',OC_Filesystem::getInternalPath('/some/folder')); + Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); + $this->assertEqual('/',Filesystem::getMountPoint('/')); + $this->assertEqual('/some/',Filesystem::getMountPoint('/some/folder')); + $this->assertEqual('/some/',Filesystem::getMountPoint('/some/')); + $this->assertEqual('/',Filesystem::getMountPoint('/some')); + $this->assertEqual('folder',Filesystem::getInternalPath('/some/folder')); } public function testNormalize() { - $this->assertEqual('/path', OC_Filesystem::normalizePath('/path/')); - $this->assertEqual('/path/', OC_Filesystem::normalizePath('/path/', false)); - $this->assertEqual('/path', OC_Filesystem::normalizePath('path')); - $this->assertEqual('/path', OC_Filesystem::normalizePath('\path')); - $this->assertEqual('/foo/bar', OC_Filesystem::normalizePath('/foo//bar/')); - $this->assertEqual('/foo/bar', OC_Filesystem::normalizePath('/foo////bar')); + $this->assertEqual('/path', Filesystem::normalizePath('/path/')); + $this->assertEqual('/path/', Filesystem::normalizePath('/path/', false)); + $this->assertEqual('/path', Filesystem::normalizePath('path')); + $this->assertEqual('/path', Filesystem::normalizePath('\path')); + $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo//bar/')); + $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo////bar')); if (class_exists('Normalizer')) { - $this->assertEqual("/foo/bar\xC3\xBC", OC_Filesystem::normalizePath("/foo/baru\xCC\x88")); + $this->assertEqual("/foo/bar\xC3\xBC", Filesystem::normalizePath("/foo/baru\xCC\x88")); } } public function testHooks() { - if(OC_Filesystem::getView()){ + if(Filesystem::getView()){ $user = OC_User::getUser(); }else{ $user=uniqid(); - OC_Filesystem::init('/'.$user.'/files'); + Filesystem::init('/'.$user.'/files'); } OC_Hook::clear('OC_Filesystem'); OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook'); - OC_Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); + Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); $rootView=new \OC\Files\View(''); $rootView->mkdir('/'.$user); $rootView->mkdir('/'.$user.'/files'); - OC_Filesystem::file_put_contents('/foo', 'foo'); - OC_Filesystem::mkdir('/bar'); - OC_Filesystem::file_put_contents('/bar//foo', 'foo'); + Filesystem::file_put_contents('/foo', 'foo'); + Filesystem::mkdir('/bar'); + Filesystem::file_put_contents('/bar//foo', 'foo'); $tmpFile = OC_Helper::tmpFile(); file_put_contents($tmpFile, 'foo'); $fh = fopen($tmpFile, 'r'); - OC_Filesystem::file_put_contents('/bar//foo', $fh); + Filesystem::file_put_contents('/bar//foo', $fh); } public function dummyHook($arguments) { $path = $arguments['path']; - $this->assertEqual($path, OC_Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized + $this->assertEqual($path, Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized } } From 08bb5dbe3a9b2bf502e5c6e0c944867015c3795b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 3 Oct 2012 18:19:45 +0200 Subject: [PATCH 033/262] few more test cases for scanning folders --- tests/lib/files/cache/scanner.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 41286e69d3..1f11b9d01d 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -91,6 +91,13 @@ class Scanner extends \UnitTestCase { $this->assertEqual($cachedDataFolder['size'], -1); $this->assertEqual($cachedDataFolder2['size'], -1); + + $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + + $cachedDataFolder = $this->cache->get(''); + $cachedDataFolder2 = $this->cache->get('folder'); + + $this->assertNotEqual($cachedDataFolder['size'], -1); } function setUp() { From a2785f57d2335d06f3fa9900298343c1d7f9253a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 17:45:47 +0200 Subject: [PATCH 034/262] fix cache scanner test case --- tests/lib/files/cache/scanner.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 1f11b9d01d..e3f47047f5 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -94,10 +94,9 @@ class Scanner extends \UnitTestCase { $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); - $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); - $this->assertNotEqual($cachedDataFolder['size'], -1); + $this->assertNotEqual($cachedDataFolder2['size'], -1); } function setUp() { From 5c6e9518edde10e0c23d0d734d2cc6d161fc15c0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 10 Oct 2012 17:46:29 +0200 Subject: [PATCH 035/262] drop Filesystem::getInternalPath and Filesystem::getStorage in favor of Filesystem::resolvePath --- apps/files_sharing/lib/sharedstorage.php | 86 ++++++++++++------------ lib/files/filesystem.php | 31 --------- lib/files/view.php | 61 ++++++----------- lib/filesystem.php | 22 ------ tests/lib/filesystem.php | 9 ++- 5 files changed, 71 insertions(+), 138 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index e17c4b6e04..e12027a4f2 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -114,16 +114,16 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->mkdir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->mkdir($internalPath); } return false; } public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->rmdir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->rmdir($internalPath); } return false; } @@ -134,8 +134,8 @@ class Shared extends \OC\Files\Storage\Common { \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->opendir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->opendir($internalPath); } return false; } @@ -144,16 +144,16 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->is_dir($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->is_dir($internalPath); } return false; } public function is_file($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->is_file($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->is_file($internalPath); } return false; } @@ -165,8 +165,8 @@ class Shared extends \OC\Files\Storage\Common { $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->stat($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->stat($internalPath); } return false; } @@ -175,8 +175,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filetype($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filetype($internalPath); } return false; } @@ -185,8 +185,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filesize($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filesize($internalPath); } return false; } @@ -227,8 +227,8 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->file_exists($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->file_exists($internalPath); } return false; } @@ -248,8 +248,8 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filectime($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filectime($internalPath); } } } @@ -269,8 +269,8 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->filemtime($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->filemtime($internalPath); } } } @@ -283,8 +283,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->file_get_contents($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->file_get_contents($internalPath); } } @@ -299,8 +299,8 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - $result = $storage->file_put_contents($this->getInternalPath($source), $data); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + $result = $storage->file_put_contents($internalPath, $data); return $result; } return false; @@ -310,8 +310,8 @@ class Shared extends \OC\Files\Storage\Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->unlink($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->unlink($internalPath); } else if (dirname($path) == '/' || dirname($path) == '.') { // Unshare the file from the user if in the root of the Shared folder if ($this->is_dir($path)) { @@ -334,8 +334,9 @@ class Shared extends \OC\Files\Storage\Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - $storage = \OC\Files\Filesystem::getStorage($oldSource); - return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); + list($storage, $oldInternalPath)=\OC\Files\Filesystem::resolvePath($oldSource); + list( , $newInternalPath)=\OC\Files\Filesystem::resolvePath($newSource); + return $storage->rename($oldInternalPath, $newInternalPath); } } else { // Move the file if DELETE and CREATE permissions are granted @@ -349,8 +350,9 @@ class Shared extends \OC\Files\Storage\Common { return $this->unlink($path1); } } else { - $storage = \OC\Files\Filesystem::getStorage($oldSource); - return $storage->rename($this->getInternalPath($oldSource), $this->getInternalPath($newSource)); + list($storage, $oldInternalPath)=\OC\Files\Filesystem::resolvePath($oldSource); + list( , $newInternalPath)=\OC\Files\Filesystem::resolvePath($newSource); + return $storage->rename($oldInternalPath, $newInternalPath); } } } @@ -395,8 +397,8 @@ class Shared extends \OC\Files\Storage\Common { 'mode' => $mode, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->fopen($this->getInternalPath($source), $mode); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->fopen($internalPath, $mode); } return false; } @@ -406,8 +408,8 @@ class Shared extends \OC\Files\Storage\Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->getMimeType($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->getMimeType($internalPath); } return false; } @@ -415,22 +417,22 @@ class Shared extends \OC\Files\Storage\Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->free_space($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->free_space($internalPath); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->getLocalFile($this->getInternalPath($source)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->getLocalFile($internalPath); } return false; } public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { - $storage = \OC\Files\Filesystem::getStorage($source); - return $storage->touch($this->getInternalPath($source), $mtime); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + return $storage->touch($internalPath, $mtime); } return false; } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index f23f3a79e9..841f30c767 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -164,37 +164,6 @@ class Filesystem { return $foundMountPoint; } - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * - * @param string $path - * @return bool - */ - static public function getInternalPath($path) { - $mountPoint = self::getMountPoint($path); - $internalPath = substr($path, strlen($mountPoint)); - return $internalPath; - } - - /** - * get the storage object for a path - * - * @param string $path - * @return \OC\Files\Storage\Storage - */ - static public function getStorage($path) { - $mountpoint = self::getMountPoint($path); - if ($mountpoint) { - if (!isset(self::$storages[$mountpoint])) { - $mount = self::$mounts[$mountpoint]; - self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); - } - return self::$storages[$mountpoint]; - }else{ - return null; - } - } - /** * resolve a path to a storage and internal path * diff --git a/lib/files/view.php b/lib/files/view.php index 230455479c..bffeb434f2 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -68,19 +68,6 @@ class View { return $this->fakeRoot; } - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * - * @param string $path - * @return bool - */ - public function getInternalPath($path) { - if (!isset($this->internal_path_cache[$path])) { - $this->internal_path_cache[$path] = Filesystem::getInternalPath($this->getAbsolutePath($path)); - } - return $this->internal_path_cache[$path]; - } - /** * get path relative to the root of the view * @@ -103,19 +90,6 @@ class View { } } - /** - * get the storage object for a path - * - * @param string $path - * @return \OC\Files\Storage\Storage - */ - public function getStorage($path) { - if (!isset($this->storage_cache[$path])) { - $this->storage_cache[$path] = Filesystem::getStorage($this->getAbsolutePath($path)); - } - return $this->storage_cache[$path]; - } - /** * get the mountpoint of the storage object for a path ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account @@ -136,8 +110,9 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { - return $storage->getLocalFile($this->getInternalPath($path)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + if (Filesystem::isValidPath($parent) and $storage) { + return $storage->getLocalFile($internalPath); } else { return null; } @@ -149,8 +124,9 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - if (Filesystem::isValidPath($parent) and $storage = $this->getStorage($path)) { - return $storage->getLocalFolder($this->getInternalPath($path)); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + if (Filesystem::isValidPath($parent) and $storage) { + return $storage->getLocalFolder($internalPath); } else { return null; } @@ -373,8 +349,10 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - if ($storage = $this->getStorage($path1)) { - $result = $storage->rename($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + if ($storage) { + $result = $storage->rename($internalPath1, $internalPath2); } else { $result = false; } @@ -382,8 +360,8 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - $storage1 = $this->getStorage($path1); - $storage1->unlink($this->getInternalPath($path1 . $postFix1)); + list($storage1, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + $storage1->unlink($internalPath1); $result = $count > 0; } if ($this->fakeRoot == Filesystem::getRoot()) { @@ -454,8 +432,10 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - if ($storage = $this->getStorage($path1 . $postFix1)) { - $result = $storage->copy($this->getInternalPath($path1 . $postFix1), $this->getInternalPath($path2 . $postFix2)); + list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + if ($storage) { + $result = $storage->copy($internalPath1, $internalPath2); } else { $result = false; } @@ -588,8 +568,9 @@ class View { array(Filesystem::signal_param_path => $path) ); } - if ($storage = $this->getStorage($path . $postFix)) { - $result = $storage->hash($type, $this->getInternalPath($path . $postFix), $raw); + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + if ($storage) { + $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); return $result; } @@ -621,9 +602,9 @@ class View { if ($path == null) { return false; } - $internalPath = $this->getInternalPath($path . $postFix); $run = $this->runHooks($hooks, $path); - if ($run and $storage = $this->getStorage($path . $postFix)) { + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); } else { diff --git a/lib/filesystem.php b/lib/filesystem.php index 4189fe36c2..587eb50d9e 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -44,28 +44,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::getMountPoint($path); } - /** - * get the part of the path relative to the mountpoint of the storage it's stored in - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return bool - */ - static public function getInternalPath($path) { - return \OC\Files\Filesystem::getInternalPath($path); - } - - /** - * get the storage object for a path - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $path - * @return \OC\Files\Storage\Storage - */ - static public function getStorage($path) { - return \OC\Files\Filesystem::getStorage($path); - } - /** * resolve a path to a storage and internal path * diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php index af3620f570..6e7b4fb781 100644 --- a/tests/lib/filesystem.php +++ b/tests/lib/filesystem.php @@ -51,15 +51,18 @@ class Test_Filesystem extends UnitTestCase { Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); $this->assertEqual('/',Filesystem::getMountPoint('/')); $this->assertEqual('/',Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('',Filesystem::getInternalPath('/')); - $this->assertEqual('some/folder',Filesystem::getInternalPath('/some/folder')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/'); + $this->assertEqual('',$internalPath); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEqual('some/folder',$internalPath); Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); $this->assertEqual('/',Filesystem::getMountPoint('/')); $this->assertEqual('/some/',Filesystem::getMountPoint('/some/folder')); $this->assertEqual('/some/',Filesystem::getMountPoint('/some/')); $this->assertEqual('/',Filesystem::getMountPoint('/some')); - $this->assertEqual('folder',Filesystem::getInternalPath('/some/folder')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEqual('folder',$internalPath); } public function testNormalize() { From 542869114ad67295d61450e637b15a1f4d3ae209 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 11 Oct 2012 23:06:57 +0200 Subject: [PATCH 036/262] implement getId for the external storage providers --- apps/files_external/lib/amazons3.php | 6 ++++++ apps/files_external/lib/dropbox.php | 6 ++++++ apps/files_external/lib/ftp.php | 4 ++++ apps/files_external/lib/google.php | 7 ++++++- apps/files_external/lib/smb.php | 4 ++++ apps/files_external/lib/swift.php | 7 +++++++ apps/files_external/lib/webdav.php | 4 ++++ 7 files changed, 37 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index a17a70ed38..2f7c8b35be 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -29,12 +29,14 @@ class AmazonS3 extends \OC\Files\Storage\Common { private $s3; private $bucket; private $objects = array(); + private $id; private static $tempFiles = array(); // TODO options: storage class, encryption server side, encrypt before upload? public function __construct($params) { + $this->id = 'amazon::'.$params['key'] . md5($params['secret']); $this->s3 = new \AmazonS3(array('key' => $params['key'], 'secret' => $params['secret'])); $this->bucket = $params['bucket']; } @@ -59,6 +61,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { return false; } + public function getId(){ + return $this->id; + } + public function mkdir($path) { // Folders in Amazon S3 are 0 byte objects with a '/' at the end of the name if (substr($path, -1) != '/') { diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 86dbdab9ca..351a2840d9 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -28,12 +28,14 @@ class Dropbox extends \OC\Files\Storage\Common { private $dropbox; private $root; + private $id; private $metaData = array(); private static $tempFiles = array(); public function __construct($params) { if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['app_key']) && isset($params['app_secret']) && isset($params['token']) && isset($params['token_secret'])) { + $this->id = 'dropbox::'.$params['app_key'] . $params['token']. '/' . $params['root']; $this->root=isset($params['root'])?$params['root']:''; $oauth = new \Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']); $oauth->setToken($params['token'], $params['token_secret']); @@ -81,6 +83,10 @@ class Dropbox extends \OC\Files\Storage\Common { } } + public function getId(){ + return $this->id; + } + public function mkdir($path) { $path = $this->root.$path; try { diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 140a21ffe1..731581dacc 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -32,6 +32,10 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ } } + public function getId(){ + return 'ftp::' . $this->user . '@' . $this->host . '/' . $this->root; + } + /** * construct the ftp url * @param string path diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 51c5d219aa..e4be4de5a0 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -30,6 +30,7 @@ class Google extends \OC\Files\Storage\Common { private $oauth_token; private $sig_method; private $entries; + private $id; private static $tempFiles = array(); @@ -37,6 +38,7 @@ class Google extends \OC\Files\Storage\Common { if (isset($params['configured']) && $params['configured'] == 'true' && isset($params['token']) && isset($params['token_secret'])) { $consumer_key = isset($params['consumer_key']) ? $params['consumer_key'] : 'anonymous'; $consumer_secret = isset($params['consumer_secret']) ? $params['consumer_secret'] : 'anonymous'; + $this->id = 'google::' . $consumer_key . $consumer_secret; $this->consumer = new \OAuthConsumer($consumer_key, $consumer_secret); $this->oauth_token = new \OAuthToken($params['token'], $params['token_secret']); $this->sig_method = new \OAuthSignatureMethod_HMAC_SHA1(); @@ -177,6 +179,9 @@ class Google extends \OC\Files\Storage\Common { } } + public function getId(){ + return $this->id; + } public function mkdir($path) { $collection = dirname($path); @@ -539,4 +544,4 @@ class Google extends \OC\Files\Storage\Common { } -} \ No newline at end of file +} diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index 8fcdd1f722..71c7a91ec9 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -42,6 +42,10 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ } } + public function getId(){ + return 'smb::' . $this->user . '@' . $this->host . '/' . $this->share . '/' . $this->root; + } + public function constructUrl($path) { if(substr($path,-1)=='/') { $path=substr($path,0,-1); diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index 8d402b2521..61f58766e8 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -11,6 +11,7 @@ require_once 'php-cloudfiles/cloudfiles.php'; namespace OC\Files\Storage; class SWIFT extends \OC\Files\Storage\Common{ + private $id; private $host; private $root; private $user; @@ -274,6 +275,8 @@ class SWIFT extends \OC\Files\Storage\Common{ $this->user=$params['user']; $this->root=isset($params['root'])?$params['root']:'/'; $this->secure=isset($params['secure'])?(bool)$params['secure']:true; + + $this->id = 'swift::' . $this->user . '@' . $this->host . '/' . $this->root; if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } @@ -289,6 +292,10 @@ class SWIFT extends \OC\Files\Storage\Common{ } } + public function getId(){ + return $this->id; + } + public function mkdir($path) { if($this->containerExists($path)) { diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 7c61d06a01..6ed93e9035 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -56,6 +56,10 @@ class DAV extends \OC\Files\Storage\Common{ $this->mkdir(''); } + public function getId(){ + return 'webdav::' . $this->user . '@' . $this->host . '/' . $this->root; + } + private function createBaseUri() { $baseUri='http'; if($this->secure) { From 141ff806c6cfbd349ffa232502a89a620882c409 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 11 Oct 2012 23:17:59 +0200 Subject: [PATCH 037/262] fix namespace problems for external storage backends --- apps/files_external/lib/amazons3.php | 4 +- apps/files_external/lib/dropbox.php | 4 +- apps/files_external/lib/ftp.php | 7 +-- apps/files_external/lib/google.php | 12 ++--- apps/files_external/lib/smb.php | 5 +- apps/files_external/lib/swift.php | 69 ++++++++++++++-------------- apps/files_external/lib/webdav.php | 32 ++++++------- apps/files_external/tests/config.php | 2 +- 8 files changed, 65 insertions(+), 70 deletions(-) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 2f7c8b35be..832127d3e7 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -20,10 +20,10 @@ * License along with this library. If not, see . */ -require_once 'aws-sdk/sdk.class.php'; - namespace OC\Files\Storage; +require_once 'aws-sdk/sdk.class.php'; + class AmazonS3 extends \OC\Files\Storage\Common { private $s3; diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 351a2840d9..0f7593162e 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -20,10 +20,10 @@ * License along with this library. If not, see . */ -require_once 'Dropbox/autoload.php'; - namespace OC\Files\Storage; +require_once 'Dropbox/autoload.php'; + class Dropbox extends \OC\Files\Storage\Common { private $dropbox; diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 731581dacc..dea44728f3 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -26,7 +26,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } - //create the root folder if necesary + //create the root folder if necessary if (!$this->is_dir('')) { $this->mkdir(''); } @@ -38,7 +38,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ /** * construct the ftp url - * @param string path + * @param string $path * @return string */ public function constructUrl($path) { @@ -74,7 +74,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ }else{ $ext=''; } - $tmpFile=OCP\Files::tmpFile($ext); + $tmpFile=\OCP\Files::tmpFile($ext); \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); if($this->file_exists($path)) { $this->getFile($path,$tmpFile); @@ -82,6 +82,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ self::$tempFiles[$tmpFile]=$path; return fopen('close://'.$tmpFile,$mode); } + return false; } public function writeBack($tmpFile) { diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index e4be4de5a0..141fc619e3 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -20,10 +20,10 @@ * License along with this library. If not, see . */ -require_once 'Google/common.inc.php'; - namespace OC\Files\Storage; +require_once 'Google/common.inc.php'; + class Google extends \OC\Files\Storage\Common { private $consumer; @@ -62,7 +62,7 @@ class Google extends \OC\Files\Storage\Common { $tempStr .= '&' . urlencode($key) . '=' . urlencode($value); } $uri = preg_replace('/&/', '?', $tempStr, 1); - $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $httpMethod, $uri, $params); + $request = \OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $httpMethod, $uri, $params); $request->sign_request($this->sig_method, $this->consumer, $this->oauth_token); $auth_header = $request->to_header(); $headers = array($auth_header, 'GData-Version: 3.0'); @@ -129,7 +129,7 @@ class Google extends \OC\Files\Storage\Common { private function getFeed($feedUri, $httpMethod, $postData = null) { $result = $this->sendRequest($feedUri, $httpMethod, $postData); if ($result) { - $dom = new DOMDocument(); + $dom = new \DOMDocument(); $dom->loadXML($result); return $dom; } @@ -248,7 +248,7 @@ class Google extends \OC\Files\Storage\Common { $this->entries[$name] = $entry; } } - OC_FakeDirStream::$dirs['google'.$path] = $files; + \OC_FakeDirStream::$dirs['google'.$path] = $files; return opendir('fakedir://google'.$path); } @@ -407,7 +407,7 @@ class Google extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index 71c7a91ec9..dfba3105ec 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -6,10 +6,10 @@ * See the COPYING-README file. */ -require_once 'smb4php/smb.php'; - namespace OC\Files\Storage; +require_once 'smb4php/smb.php'; + class SMB extends \OC\Files\Storage\StreamWrapper{ private $password; private $user; @@ -70,6 +70,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ /** * check if a file or folder has been updated since $time + * @param string $path * @param int $time * @return bool */ diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index 61f58766e8..4b3f38166d 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -6,10 +6,10 @@ * See the COPYING-README file. */ -require_once 'php-cloudfiles/cloudfiles.php'; - namespace OC\Files\Storage; +require_once 'php-cloudfiles/cloudfiles.php'; + class SWIFT extends \OC\Files\Storage\Common{ private $id; private $host; @@ -18,15 +18,15 @@ class SWIFT extends \OC\Files\Storage\Common{ private $token; private $secure; /** - * @var CF_Authentication auth + * @var \CF_Authentication auth */ private $auth; /** - * @var CF_Connection conn + * @var \CF_Connection conn */ private $conn; /** - * @var CF_Container rootContainer + * @var \CF_Container rootContainer */ private $rootContainer; @@ -38,7 +38,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * translate directory path to container name - * @param string path + * @param string $path * @return string */ private function getContainerName($path) { @@ -48,8 +48,8 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * get container by path - * @param string path - * @return CF_Container + * @param string $path + * @return \CF_Container */ private function getContainer($path) { if($path=='' or $path=='/') { @@ -62,15 +62,15 @@ class SWIFT extends \OC\Files\Storage\Common{ $container=$this->conn->get_container($this->getContainerName($path)); $this->containers[$path]=$container; return $container; - }catch(NoSuchContainerException $e) { + }catch(\NoSuchContainerException $e) { return null; } } /** * create container - * @param string path - * @return CF_Container + * @param string $path + * @return \CF_Container */ private function createContainer($path) { if($path=='' or $path=='/' or $path=='.') { @@ -92,8 +92,8 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * get object by path - * @param string path - * @return CF_Object + * @param string $path + * @return \CF_Object */ private function getObject($path) { if(isset($this->objects[$path])) { @@ -110,7 +110,7 @@ class SWIFT extends \OC\Files\Storage\Common{ $obj=$container->get_object(basename($path)); $this->objects[$path]=$obj; return $obj; - }catch(NoSuchObjectException $e) { + }catch(\NoSuchObjectException $e) { return null; } } @@ -135,8 +135,8 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * create object - * @param string path - * @return CF_Object + * @param string $path + * @return \CF_Object */ private function createObject($path) { $container=$this->getContainer(dirname($path)); @@ -157,7 +157,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * check if container for path exists - * @param string path + * @param string $path * @return bool */ private function containerExists($path) { @@ -166,15 +166,15 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * get the list of emulated sub containers - * @param CF_Container container + * @param \CF_Container $container * @return array */ private function getSubContainers($container) { - $tmpFile=OCP\Files::tmpFile(); + $tmpFile=\OCP\Files::tmpFile(); $obj=$this->getSubContainerFile($container); try{ $obj->save_to_filename($tmpFile); - }catch(Exception $e) { + }catch(\Exception $e) { return array(); } $obj->save_to_filename($tmpFile); @@ -188,15 +188,15 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * add an emulated sub container - * @param CF_Container container - * @param string name + * @param CF_Container $container + * @param string $name * @return bool */ private function addSubContainer($container,$name) { if(!$name) { return false; } - $tmpFile=OCP\Files::tmpFile(); + $tmpFile=\OCP\Files::tmpFile(); $obj=$this->getSubContainerFile($container); try{ $obj->save_to_filename($tmpFile); @@ -211,8 +211,7 @@ class SWIFT extends \OC\Files\Storage\Common{ $fh=fopen($tmpFile,'a'); fwrite($fh,$name."\n"); } - }catch(Exception $e) { - $containers=array(); + }catch(\Exception $e) { file_put_contents($tmpFile,$name."\n"); } @@ -223,20 +222,20 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * remove an emulated sub container - * @param CF_Container container - * @param string name + * @param CF_Container $container + * @param string $name * @return bool */ private function removeSubContainer($container,$name) { if(!$name) { return false; } - $tmpFile=OCP\Files::tmpFile(); + $tmpFile=\OCP\Files::tmpFile(); $obj=$this->getSubContainerFile($container); try{ $obj->save_to_filename($tmpFile); $containers=file($tmpFile); - }catch(Exception $e) { + }catch(\Exception $e) { return false; } foreach($containers as &$sub) { @@ -258,13 +257,13 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * ensure a subcontainer file exists and return it's object - * @param CF_Container container - * @return CF_Object + * @param \CF_Container $container + * @return \CF_Object */ private function getSubContainerFile($container) { try{ return $container->get_object(self::SUBCONTAINER_FILE); - }catch(NoSuchObjectException $e) { + }catch(\NoSuchObjectException $e) { return $container->create_object(self::SUBCONTAINER_FILE); } } @@ -526,11 +525,11 @@ class SWIFT extends \OC\Files\Storage\Common{ private function getTmpFile($path) { $obj=$this->getObject($path); if(!is_null($obj)) { - $tmpFile=OCP\Files::tmpFile(); + $tmpFile=\OCP\Files::tmpFile(); $obj->save_to_filename($tmpFile); return $tmpFile; }else{ - return OCP\Files::tmpFile(); + return \OCP\Files::tmpFile(); } } @@ -545,7 +544,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * remove custom mtime metadata - * @param CF_Object obj + * @param \CF_Object $obj */ private function resetMTime($obj) { if(isset($obj->metadata['Mtime'])) { diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 6ed93e9035..73231b6ad8 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -15,7 +15,7 @@ class DAV extends \OC\Files\Storage\Common{ private $secure; private $root; /** - * @var Sabre_DAV_Client + * @var \Sabre_DAV_Client */ private $client; @@ -92,7 +92,7 @@ class DAV extends \OC\Files\Storage\Common{ \OC_FakeDirStream::$dirs[$id][]=$file; } return opendir('fakedir://'.$id); - }catch(Exception $e) { + }catch(\Exception $e) { return false; } } @@ -103,7 +103,7 @@ class DAV extends \OC\Files\Storage\Common{ $response=$this->client->propfind($path, array('{DAV:}resourcetype')); $responseType=$response["{DAV:}resourcetype"]->resourceType; return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file'; - }catch(Exception $e) { + }catch(\Exception $e) { error_log($e->getMessage()); \OCP\Util::writeLog("webdav client", \OCP\Util::sanitizeHTML($e->getMessage()), \OCP\Util::ERROR); return false; @@ -123,7 +123,7 @@ class DAV extends \OC\Files\Storage\Common{ try{ $this->client->propfind($path, array('{DAV:}resourcetype')); return true;//no 404 exception - }catch(Exception $e) { + }catch(\Exception $e) { return false; } } @@ -169,7 +169,7 @@ class DAV extends \OC\Files\Storage\Common{ }else{ $ext=''; } - $tmpFile=OCP\Files::tmpFile($ext); + $tmpFile=\OCP\Files::tmpFile($ext); \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); if($this->file_exists($path)) { $this->getFile($path,$tmpFile); @@ -195,7 +195,7 @@ class DAV extends \OC\Files\Storage\Common{ }else{ return 0; } - }catch(Exception $e) { + }catch(\Exception $e) { return 0; } } @@ -231,12 +231,9 @@ class DAV extends \OC\Files\Storage\Common{ $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ - $response=$this->client->request('MOVE',$path1,null,array('Destination'=>$path2)); + $this->client->request('MOVE',$path1,null,array('Destination'=>$path2)); return true; - }catch(Exception $e) { - echo $e; - echo 'fail'; - var_dump($response); + }catch(\Exception $e) { return false; } } @@ -245,12 +242,9 @@ class DAV extends \OC\Files\Storage\Common{ $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ - $response=$this->client->request('COPY',$path1,null,array('Destination'=>$path2)); + $this->client->request('COPY',$path1,null,array('Destination'=>$path2)); return true; - }catch(Exception $e) { - echo $e; - echo 'fail'; - var_dump($response); + }catch(\Exception $e) { return false; } } @@ -264,7 +258,7 @@ class DAV extends \OC\Files\Storage\Common{ 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0, 'ctime'=>-1, ); - }catch(Exception $e) { + }catch(\Exception $e) { return array(); } } @@ -282,7 +276,7 @@ class DAV extends \OC\Files\Storage\Common{ }else{ return false; } - }catch(Exception $e) { + }catch(\Exception $e) { return false; } } @@ -300,7 +294,7 @@ class DAV extends \OC\Files\Storage\Common{ try{ $response=$this->client->request($method,$path,$body); return $response['statusCode']==$expected; - }catch(Exception $e) { + }catch(\Exception $e) { return false; } } diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index ff16b1c1d8..5af317675c 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -8,7 +8,7 @@ return array( 'root'=>'/test', ), 'webdav'=>array( - 'run'=>false, + 'run'=>true, 'host'=>'localhost', 'user'=>'test', 'password'=>'test', From cfa036eaa916c1adf38fb161a16c50cd050c0a3b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 20 Oct 2012 23:54:37 +0200 Subject: [PATCH 038/262] drop filectime from the filesystem api's --- apps/files_external/lib/amazons3.php | 2 -- apps/files_external/lib/dropbox.php | 1 - apps/files_external/lib/google.php | 2 -- apps/files_external/lib/swift.php | 2 -- apps/files_external/lib/webdav.php | 1 - apps/files_sharing/lib/sharedstorage.php | 22 ---------------------- lib/files.php | 3 +-- lib/files/filesystem.php | 4 ---- lib/files/storage/common.php | 4 ---- lib/files/storage/local.php | 3 --- lib/files/storage/storage.php | 1 - lib/files/view.php | 4 ---- lib/filesystem.php | 7 ------- 13 files changed, 1 insertion(+), 55 deletions(-) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index 832127d3e7..c3fa4651f6 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -115,12 +115,10 @@ class AmazonS3 extends \OC\Files\Storage\Common { $stat['size'] = $this->s3->get_bucket_filesize($this->bucket); $stat['atime'] = time(); $stat['mtime'] = $stat['atime']; - $stat['ctime'] = $stat['atime']; } else if ($object = $this->getObject($path)) { $stat['size'] = $object['Size']; $stat['atime'] = time(); $stat['mtime'] = strtotime($object['LastModified']); - $stat['ctime'] = $stat['mtime']; } if (isset($stat)) { return $stat; diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 0f7593162e..0e82f80668 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -119,7 +119,6 @@ class Dropbox extends \OC\Files\Storage\Common { $stat['size'] = $metaData['bytes']; $stat['atime'] = time(); $stat['mtime'] = (isset($metaData['modified'])) ? strtotime($metaData['modified']) : time(); - $stat['ctime'] = $stat['mtime']; return $stat; } return false; diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 141fc619e3..7ee5b97f8b 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -257,14 +257,12 @@ class Google extends \OC\Files\Storage\Common { $stat['size'] = $this->free_space($path); $stat['atime'] = time(); $stat['mtime'] = time(); - $stat['ctime'] = time(); } else if ($entry = $this->getResource($path)) { // NOTE: Native resources don't have a file size $stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue; // if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue)) // $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue); $stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue); - $stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue); } if (isset($stat)) { return $stat; diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index 4b3f38166d..c3578b0c23 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -500,7 +500,6 @@ class SWIFT extends \OC\Files\Storage\Common{ return array( 'mtime'=>-1, 'size'=>$container->bytes_used, - 'ctime'=>-1 ); } @@ -518,7 +517,6 @@ class SWIFT extends \OC\Files\Storage\Common{ return array( 'mtime'=>$mtime, 'size'=>$obj->content_length, - 'ctime'=>-1, ); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 73231b6ad8..c9785f3eb1 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -256,7 +256,6 @@ class DAV extends \OC\Files\Storage\Common{ return array( 'mtime'=>strtotime($response['{DAV:}getlastmodified']), 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0, - 'ctime'=>-1, ); }catch(\Exception $e) { return array(); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index e12027a4f2..521dfb69f2 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -162,7 +162,6 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { $stat['size'] = $this->filesize($path); $stat['mtime'] = $this->filemtime($path); - $stat['ctime'] = $this->filectime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); @@ -233,27 +232,6 @@ class Shared extends \OC\Files\Storage\Common { return false; } - public function filectime($path) { - if ($path == '' || $path == '/') { - $ctime = 0; - if ($dh = $this->opendir($path)) { - while (($filename = readdir($dh)) !== false) { - $tempctime = $this->filectime($filename); - if ($tempctime < $ctime) { - $ctime = $tempctime; - } - } - } - return $ctime; - } else { - $source = $this->getSourcePath($path); - if ($source) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); - return $storage->filectime($internalPath); - } - } - } - public function filemtime($path) { if ($path == '' || $path == '/') { $mtime = 0; diff --git a/lib/files.php b/lib/files.php index 29322cf2d0..28c8d0b449 100644 --- a/lib/files.php +++ b/lib/files.php @@ -30,13 +30,12 @@ class OC_Files { /** * get the filesystem info - * @param string path + * @param string $path * @return array * * returns an associative array with the following keys: * - size * - mtime - * - ctime * - mimetype * - encrypted * - versioned diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index e4c269257c..94e8a56256 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -478,10 +478,6 @@ class Filesystem { return self::$defaultInstance->file_exists($path); } - static public function filectime($path) { - return self::$defaultInstance->filectime($path); - } - static public function filemtime($path) { return self::$defaultInstance->filemtime($path); } diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 3886a04182..1740584555 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -74,10 +74,6 @@ abstract class Common extends \OC\Files\Storage\Storage { return $permissions; } // abstract public function file_exists($path); - public function filectime($path) { - $stat = $this->stat($path); - return $stat['ctime']; - } public function filemtime($path) { $stat = $this->stat($path); return $stat['mtime']; diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index 66ae5542e3..ccd69e3971 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -66,9 +66,6 @@ class Local extends \OC\Files\Storage\Common{ public function file_exists($path) { return file_exists($this->datadir.$path); } - public function filectime($path) { - return filectime($this->datadir.$path); - } public function filemtime($path) { return filemtime($this->datadir.$path); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index f149c61830..941bc3b077 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -29,7 +29,6 @@ abstract class Storage{ abstract public function isSharable($path); abstract public function getPermissions($path); abstract public function file_exists($path); - abstract public function filectime($path); abstract public function filemtime($path); abstract public function file_get_contents($path); abstract public function file_put_contents($path,$data); diff --git a/lib/files/view.php b/lib/files/view.php index bffeb434f2..58e3ee6f05 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -236,10 +236,6 @@ class View { return $this->basicOperation('file_exists', $path); } - public function filectime($path) { - return $this->basicOperation('filectime', $path); - } - public function filemtime($path) { return $this->basicOperation('filemtime', $path); } diff --git a/lib/filesystem.php b/lib/filesystem.php index 587eb50d9e..9ce75aaf8c 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -306,13 +306,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::file_exists($path); } - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function filectime($path) { - return \OC\Files\Filesystem::filectime($path); - } - /** * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem */ From 1901ac8b17c99eef3ccd99edf877fd0a86737d17 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:13:16 +0200 Subject: [PATCH 039/262] drop depricated is_readable and is_writable --- lib/files.php | 2 +- lib/files/filesystem.php | 14 -------------- lib/files/view.php | 14 -------------- lib/filesystem.php | 7 ------- 4 files changed, 1 insertion(+), 36 deletions(-) diff --git a/lib/files.php b/lib/files.php index 28c8d0b449..ba111bee96 100644 --- a/lib/files.php +++ b/lib/files.php @@ -178,7 +178,7 @@ class OC_Files { $filename=$dir.'/'.$files; } @ob_end_clean(); - if($zip or \OC\Files\Filesystem::is_readable($filename)) { + if($zip or \OC\Files\Filesystem::isReadable($filename)) { header('Content-Disposition: attachment; filename="'.basename($filename).'"'); header('Content-Transfer-Encoding: binary'); OC_Response::disableCaching(); diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 94e8a56256..0dae774feb 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -440,20 +440,6 @@ class Filesystem { return self::$defaultInstance->readfile($path); } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - static public function is_readable($path) { - return self::$defaultInstance->isReadable($path); - } - - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - static public function is_writable($path) { - return self::$defaultInstance->is_writable($path); - } - static public function isCreatable($path) { return self::$defaultInstance->isCreatable($path); } diff --git a/lib/files/view.php b/lib/files/view.php index 58e3ee6f05..a59ad8105d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -195,20 +195,6 @@ class View { return false; } - /** - * @deprecated Replaced by isReadable() as part of CRUDS - */ - public function is_readable($path) { - return $this->basicOperation('isReadable', $path); - } - - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - public function is_writable($path) { - return $this->basicOperation('isUpdatable', $path); - } - public function isCreatable($path) { return $this->basicOperation('isCreatable', $path); } diff --git a/lib/filesystem.php b/lib/filesystem.php index 9ce75aaf8c..ea0a289c8d 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -257,13 +257,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::isReadable($path); } - /** - * @deprecated Replaced by isCreatable(), isUpdatable(), isDeletable() as part of CRUDS - */ - static public function is_writable($path) { - return \OC\Files\Filesystem::is_writable($path); - } - /** * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem */ From 6f1fbf97f7678f7a9a8b2e92d1cdd24fc5710d17 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:27:55 +0200 Subject: [PATCH 040/262] some namespaces fixed for the shared backend --- apps/files_sharing/lib/sharedstorage.php | 25 +++++++----------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 521dfb69f2..e354314cc3 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -37,7 +37,7 @@ class Shared extends \OC\Files\Storage\Common { /** * @brief Get the source file path and the permissions granted for a shared file * @param string Shared target file path - * @return Returns array with the keys path and permissions or false if not found + * @return array with the keys path and permissions or false if not found */ private function getFile($target) { $target = '/'.$target; @@ -52,7 +52,7 @@ class Shared extends \OC\Files\Storage\Common { if (isset($this->files[$folder])) { $file = $this->files[$folder]; } else { - $file = OCP\Share::getItemSharedWith('folder', $folder, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $file = \OCP\Share::getItemSharedWith('folder', $folder, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); } if ($file) { $this->files[$target]['path'] = $file['path'].substr($target, strlen($folder)); @@ -60,13 +60,13 @@ class Shared extends \OC\Files\Storage\Common { return $this->files[$target]; } } else { - $file = OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $file = \OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); if ($file) { $this->files[$target] = $file; return $this->files[$target]; } } - OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, OCP\Util::ERROR); + \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::ERROR); return false; } } @@ -74,13 +74,13 @@ class Shared extends \OC\Files\Storage\Common { /** * @brief Get the source file path for a shared file * @param string Shared target file path - * @return Returns source file path or false if not found + * @return string source file path or false if not found */ private function getSourcePath($target) { $file = $this->getFile($target); if (isset($file['path'])) { $uid = substr($file['path'], 1, strpos($file['path'], '/', 1) - 1); - \\OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); return $file['path']; } return false; @@ -89,7 +89,7 @@ class Shared extends \OC\Files\Storage\Common { /** * @brief Get the permissions granted for a shared file * @param string Shared target file path - * @return Returns CRUDS permissions granted or false if not found + * @return int CRUDS permissions granted or false if not found */ public function getPermissions($target) { $file = $this->getFile($target); @@ -99,17 +99,6 @@ class Shared extends \OC\Files\Storage\Common { return false; } - /** - * @brief Get the internal path to pass to the storage filesystem call - * @param string Source file path - * @return Source file path with mount point stripped out - */ - private function getInternalPath($path) { - $mountPoint = \OC\Files\Filesystem::getMountPoint($path); - $internalPath = substr($path, strlen($mountPoint)); - return $internalPath; - } - public function mkdir($path) { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; From 3ff0772a05c70592360c7b11b280cc4cf45a385e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:31:32 +0200 Subject: [PATCH 041/262] add getCache and getScanner to storage api in order to allow storage backends to overwride caching behaviour --- lib/files/storage/common.php | 50 ++++++------------------- lib/files/storage/storage.php | 70 ++++++++++++++++++----------------- 2 files changed, 48 insertions(+), 72 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 1740584555..de02c0d5d8 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -20,7 +20,7 @@ namespace OC\Files\Storage; * in classes which extend it, e.g. $this->stat() . */ -abstract class Common extends \OC\Files\Storage\Storage { +abstract class Common implements \OC\Files\Storage\Storage { public function __construct($parameters) {} // abstract public function getId(); @@ -123,64 +123,30 @@ abstract class Common extends \OC\Files\Storage\Storage { * deleted together with its contents. To avoid this set $empty to true */ public function deleteAll( $directory, $empty = false ) { - - // strip leading slash - if( substr( $directory, 0, 1 ) == "/" ) { - - $directory = substr( $directory, 1 ); - - } - - // strip trailing slash - if( substr( $directory, -1) == "/" ) { - - $directory = substr( $directory, 0, -1 ); - - } + $directory = trim($directory,'/'); if ( !$this->file_exists( \OCP\USER::getUser() . '/' . $directory ) || !$this->is_dir( \OCP\USER::getUser() . '/' . $directory ) ) { - return false; - } elseif( !$this->is_readable( \OCP\USER::getUser() . '/' . $directory ) ) { - return false; - } else { - $directoryHandle = $this->opendir( \OCP\USER::getUser() . '/' . $directory ); - while ( $contents = readdir( $directoryHandle ) ) { - if ( $contents != '.' && $contents != '..') { - $path = $directory . "/" . $contents; - if ( $this->is_dir( $path ) ) { - deleteAll( $path ); - } else { - $this->unlink( \OCP\USER::getUser() .'/' . $path ); // TODO: make unlink use same system path as is_dir - } } - } - //$this->closedir( $directoryHandle ); // TODO: implement closedir in OC_FSV - if ( $empty == false ) { - if ( !$this->rmdir( $directory ) ) { - - return false; - + return false; } - } - return true; } @@ -209,7 +175,7 @@ abstract class Common extends \OC\Files\Storage\Storage { return $mime; } public function hash($type,$path,$raw = false) { - $tmpFile=$this->getLocalFile(); + $tmpFile=$this->getLocalFile($path); $hash=hash($type,$tmpFile,$raw); unlink($tmpFile); return $hash; @@ -283,4 +249,12 @@ abstract class Common extends \OC\Files\Storage\Storage { public function hasUpdated($path,$time) { return $this->filemtime($path)>$time; } + + public function getCache(){ + return new \OC\Files\Cache\Cache($this); + } + + public function getScanner(){ + return new \OC\Files\Cache\Scanner($this); + } } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 941bc3b077..b1ec0bdb50 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -9,40 +9,40 @@ namespace OC\Files\Storage; /** - * Provde a common interface to all different storage options + * Provide a common interface to all different storage options */ -abstract class Storage{ - abstract public function __construct($parameters); - abstract public function getId(); - abstract public function mkdir($path); - abstract public function rmdir($path); - abstract public function opendir($path); - abstract public function is_dir($path); - abstract public function is_file($path); - abstract public function stat($path); - abstract public function filetype($path); - abstract public function filesize($path); - abstract public function isCreatable($path); - abstract public function isReadable($path); - abstract public function isUpdatable($path); - abstract public function isDeletable($path); - abstract public function isSharable($path); - abstract public function getPermissions($path); - abstract public function file_exists($path); - abstract public function filemtime($path); - abstract public function file_get_contents($path); - abstract public function file_put_contents($path,$data); - abstract public function unlink($path); - abstract public function rename($path1,$path2); - abstract public function copy($path1,$path2); - abstract public function fopen($path,$mode); - abstract public function getMimeType($path); - abstract public function hash($type,$path,$raw = false); - abstract public function free_space($path); - abstract public function search($query); - abstract public function touch($path, $mtime=null); - abstract public function getLocalFile($path);// get a path to a local version of the file, whether the original file is local or remote - abstract public function getLocalFolder($path);// get a path to a local version of the folder, whether the original file is local or remote +interface Storage{ + public function __construct($parameters); + public function getId(); + public function mkdir($path); + public function rmdir($path); + public function opendir($path); + public function is_dir($path); + public function is_file($path); + public function stat($path); + public function filetype($path); + public function filesize($path); + public function isCreatable($path); + public function isReadable($path); + public function isUpdatable($path); + public function isDeletable($path); + public function isSharable($path); + public function getPermissions($path); + public function file_exists($path); + public function filemtime($path); + public function file_get_contents($path); + public function file_put_contents($path,$data); + public function unlink($path); + public function rename($path1,$path2); + public function copy($path1,$path2); + public function fopen($path,$mode); + public function getMimeType($path); + public function hash($type,$path,$raw = false); + public function free_space($path); + public function search($query); + public function touch($path, $mtime=null); + public function getLocalFile($path);// get a path to a local version of the file, whether the original file is local or remote + public function getLocalFolder($path);// get a path to a local version of the folder, whether the original file is local or remote /** * check if a file or folder has been updated since $time * @param int $time @@ -51,5 +51,7 @@ abstract class Storage{ * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed. * returning true for other changes in the folder is optional */ - abstract public function hasUpdated($path,$time); + public function hasUpdated($path,$time); + public function getCache(); + public function getScanner(); } From 01594b8610ce4f08e28010994d9cbecda4c52e35 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 00:54:34 +0200 Subject: [PATCH 042/262] remove chroot from filesystem api --- lib/files/filesystem.php | 10 ---------- lib/filesystem.php | 11 ----------- 2 files changed, 21 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 0dae774feb..05dd698ab4 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -281,16 +281,6 @@ class Filesystem { } } - /** - * change the root to a fake root - * - * @param string $fakeRoot - * @return bool - */ - static public function chroot($fakeRoot) { - return self::$defaultInstance->chroot($fakeRoot); - } - /** * @brief get the relative path of the root data directory for the current user * @return string diff --git a/lib/filesystem.php b/lib/filesystem.php index ea0a289c8d..20b5ab2790 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -81,17 +81,6 @@ class OC_Filesystem { \OC\Files\Filesystem::tearDown(); } - /** - * change the root to a fake root - * - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - * @param string $fakeRoot - * @return bool - */ - static public function chroot($fakeRoot) { - return \OC\Files\Filesystem::chroot($fakeRoot); - } - /** * @brief get the relative path of the root data directory for the current user * @return string From 2522c25af726a8487ac13855e8a035b990cd69a4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 02:12:58 +0200 Subject: [PATCH 043/262] use OC_Files::getFileInfo and OC_Files::getDirectoryContent as high level api for the filecache most apps would want to use this api instead of using the cache directly --- lib/files.php | 108 +++++++++++++++++----------------- lib/files/filesystem.php | 73 ++++++++++++++++++----- lib/files/storage/storage.php | 7 +++ tests/lib/files.php | 87 +++++++++++++++++++++++++++ 4 files changed, 204 insertions(+), 71 deletions(-) create mode 100644 tests/lib/files.php diff --git a/lib/files.php b/lib/files.php index ba111bee96..8d402c0001 100644 --- a/lib/files.php +++ b/lib/files.php @@ -41,69 +41,67 @@ class OC_Files { * - versioned */ public static function getFileInfo($path) { - if (($path == '/Shared' || substr($path, 0, 8) == '/Shared/') && OC_App::isEnabled('files_sharing')) { - if ($path == '/Shared') { - list($info) = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT); - }else{ - $info['size'] = \OC\Files\Filesystem::filesize($path); - $info['mtime'] = \OC\Files\Filesystem::filemtime($path); - $info['ctime'] = \OC\Files\Filesystem::filectime($path); - $info['mimetype'] = \OC\Files\Filesystem::getMimeType($path); - $info['encrypted'] = false; - $info['versioned'] = false; + $path=\OC\Files\Filesystem::normalizePath($path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + $cache=$storage->getCache(); + $data = $cache->get($internalPath); + + if($data['mimetype'] === 'httpd/unix-directory'){ + //add the sizes of other mountpoints to the folder + $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + foreach($mountPoints as $mountPoint){ + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; } - } else { - $info = OC_FileCache::get($path); } - return $info; + + return $data; } /** * get the content of a directory - * @param dir $directory path under datadirectory + * @param string $directory path under datadirectory + * @return array */ public static function getDirectoryContent($directory, $mimetype_filter = '') { - $directory=\OC\Files\Filesystem::normalizePath($directory); - if($directory=='/') { - $directory=''; - } - $files = array(); - if (($directory == '/Shared' || substr($directory, 0, 8) == '/Shared/') && OC_App::isEnabled('files_sharing')) { - if ($directory == '/Shared') { - $files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP, array('folder' => $directory, 'mimetype_filter' => $mimetype_filter)); - } else { - $pos = strpos($directory, '/', 8); - // Get shared folder name - if ($pos !== false) { - $itemTarget = substr($directory, 7, $pos - 7); - } else { - $itemTarget = substr($directory, 7); + $path=\OC\Files\Filesystem::normalizePath($directory); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache=$storage->getCache(); + $files=$cache->getFolderContents($internalPath); //TODO: mimetype_filter + + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders + $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $dirLength = strlen($path); + foreach($mountPoints as $mountPoint){ + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $relativePath = trim(substr($mountPoint, $dirLength), '/'); + if($pos = strpos($relativePath, '/')){ //mountpoint inside subfolder add size to the correct folder + $entryName = substr($relativePath, 0, $pos); + foreach($files as &$entry){ + if($entry['name'] === $entryName){ + $entry['size'] += $rootEntry['size']; + } } - $files = OCP\Share::getItemSharedWith('folder', $itemTarget, OC_Share_Backend_File::FORMAT_FILE_APP, array('folder' => $directory, 'mimetype_filter' => $mimetype_filter)); - } - } else { - $files = OC_FileCache::getFolderContent($directory, false, $mimetype_filter); - foreach ($files as &$file) { - $file['directory'] = $directory; - $file['type'] = ($file['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file'; - $permissions = OCP\Share::PERMISSION_READ; - // NOTE: Remove check when new encryption is merged - if (!$file['encrypted']) { - $permissions |= OCP\Share::PERMISSION_SHARE; - } - if ($file['type'] == 'dir' && $file['writable']) { - $permissions |= OCP\Share::PERMISSION_CREATE; - } - if ($file['writable']) { - $permissions |= OCP\Share::PERMISSION_UPDATE | OCP\Share::PERMISSION_DELETE; - } - $file['permissions'] = $permissions; - } - if ($directory == '' && OC_App::isEnabled('files_sharing')) { - // Add 'Shared' folder - $files = array_merge($files, OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT)); + }else{ //mountpoint in this folder, add an entry for it + $rootEntry['name'] = $relativePath; + $files[] = $rootEntry; } } + usort($files, "fileCmp");//TODO: remove this once ajax is merged return $files; } @@ -145,7 +143,7 @@ class OC_Files { set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { exit("cannot open <$filename>\n"); } foreach($files as $file) { @@ -166,7 +164,7 @@ class OC_Files { set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==TRUE) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { exit("cannot open <$filename>\n"); } $file=$dir.'/'.$files; @@ -446,7 +444,7 @@ class OC_Files { $setting = 'php_value '.$key.' '.$size; $hasReplaced = 0; $content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced); - if($content !== NULL) { + if($content !== null) { $htaccess = $content; } if($hasReplaced == 0) { diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 05dd698ab4..b7f8483fbf 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -164,6 +164,43 @@ class Filesystem { return $foundMountPoint; } + /** + * get a list of all mount points in a directory + * + * @param string $path + * @return string[] + */ + static public function getMountPoints($path) { + $path = self::normalizePath($path); + if (strlen($path) > 1) { + $path .= '/'; + } + $pathLength = strlen($path); + + $mountPoints = array_keys(self::$mounts); + $result = array(); + foreach ($mountPoints as $mountPoint) { + if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) { + $result[] = $mountPoint; + } + } + return $result; + } + + /** + * get the storage mounted at $mountPoint + * + * @param string $mountPoint + * @return \OC\Files\Storage\Storage + */ + public static function getStorage($mountPoint) { + if (!isset(self::$storages[$mountPoint])) { + $mount = self::$mounts[$mountPoint]; + self::$storages[$mountPoint] = self::createStorage($mount['class'], $mount['arguments']); + } + return self::$storages[$mountPoint]; + } + /** * resolve a path to a storage and internal path * @@ -173,14 +210,14 @@ class Filesystem { static public function resolvePath($path) { $mountpoint = self::getMountPoint($path); if ($mountpoint) { - if (!isset(self::$storages[$mountpoint])) { - $mount = self::$mounts[$mountpoint]; - self::$storages[$mountpoint] = self::createStorage($mount['class'], $mount['arguments']); + $storage = self::getStorage($mountpoint); + if ($mountpoint === $path) { + $internalPath = ''; + } else { + $internalPath = substr($path, strlen($mountpoint)); } - $storage = self::$storages[$mountpoint]; - $internalPath = substr($path, strlen($mountpoint)); return array($storage, $internalPath); - }else{ + } else { return array(null, null); } } @@ -302,18 +339,22 @@ class Filesystem { /** * mount an \OC\Files\Storage\Storage in our virtual filesystem * - * @param \OC\Files\Storage\Storage $storage + * @param \OC\Files\Storage\Storage|string $class * @param array $arguments * @param string $mountpoint */ static public function mount($class, $arguments, $mountpoint) { - if ($mountpoint[0] != '/') { - $mountpoint = '/' . $mountpoint; + $mountpoint = self::normalizePath($mountpoint); + if (strlen($mountpoint) > 1) { + $mountpoint .= '/'; } - if (substr($mountpoint, -1) !== '/') { - $mountpoint = $mountpoint . '/'; + + if ($class instanceof \OC\Files\Storage\Storage) { + self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); + self::$storages[$mountpoint] = $class; + } else { + self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } - self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } /** @@ -522,15 +563,15 @@ class Filesystem { static public function removeETagHook($params, $root = false) { if (isset($params['path'])) { - $path=$params['path']; + $path = $params['path']; } else { - $path=$params['oldpath']; + $path = $params['oldpath']; } if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new OC_FilesystemView($root); + $fakeRootView = new View($root); $count = 1; - $path=str_replace(OC_App::getStorage("files")->getAbsolutePath(), "", $fakeRootView->getAbsolutePath($path), $count); + $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath(''), "", $fakeRootView->getAbsolutePath($path), $count); } $path = self::normalizePath($path); diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index b1ec0bdb50..853e8ba519 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -52,6 +52,13 @@ interface Storage{ * returning true for other changes in the folder is optional */ public function hasUpdated($path,$time); + + /** + * @return \OC\Files\Cache\Cache + */ public function getCache(); + /** + * @return \OC\Files\Cache\Scanner + */ public function getScanner(); } diff --git a/tests/lib/files.php b/tests/lib/files.php new file mode 100644 index 0000000000..9cb5276845 --- /dev/null +++ b/tests/lib/files.php @@ -0,0 +1,87 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ + +use \OC\Files\Filesystem as Filesystem; + +class Test_Files extends PHPUnit_Framework_TestCase { + /** + * @var \OC\Files\Storage\Storage[] $storages; + */ + private $storages = array(); + + public function setUp() { + Filesystem::clearMounts(); + } + + public function tearDown() { + foreach ($this->storages as $storage) { + $cache = $storage->getCache(); + $cache->clear(); + } + } + + public function testCacheAPI() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $storageSize = $textSize * 2 + $imageSize; + + $cachedData = OC_Files::getFileInfo('/foo.txt'); + $this->assertEquals($textSize, $cachedData['size']); + $this->assertEquals('text/plain', $cachedData['mimetype']); + + $cachedData = OC_Files::getFileInfo('/'); + $this->assertEquals($storageSize * 3, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $cachedData = OC_Files::getFileInfo('/folder'); + $this->assertEquals($storageSize + $textSize, $cachedData['size']); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + + $folderData = OC_Files::getDirectoryContent('/'); + /** + * expected entries: + * folder + * foo.png + * foo.txt + * substorage + */ + $this->assertEquals(4, count($folderData)); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); + $this->assertEquals('substorage', $folderData[3]['name']); + + $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); + $this->assertEquals($imageSize, $folderData[1]['size']); + $this->assertEquals($textSize, $folderData[2]['size']); + $this->assertEquals($storageSize, $folderData[3]['size']); + } + + /** + * @return OC\Files\Storage\Storage + */ + private function getTestStorage() { + $storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $storage->mkdir('folder'); + $storage->file_put_contents('foo.txt', $textData); + $storage->file_put_contents('foo.png', $imgData); + $storage->file_put_contents('folder/bar.txt', $textData); + + $scanner = $storage->getScanner(); + $scanner->scan(''); + $this->storages[] = $storage; + return $storage; + } +} From 33cabcf590401763609570a86f7bc7540dbf1fc5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 22:04:45 +0200 Subject: [PATCH 044/262] postpone the cost of setting up some of the external storage backends untill we actually need it --- apps/files_external/lib/ftp.php | 2 ++ apps/files_external/lib/smb.php | 7 ++---- apps/files_external/lib/streamwrapper.php | 26 ++++++++++++++++++++ apps/files_external/lib/swift.php | 29 +++++++++++++++++++++-- apps/files_external/lib/webdav.php | 23 ++++++++++++++++++ apps/files_external/tests/config.php | 2 +- 6 files changed, 81 insertions(+), 8 deletions(-) diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index dea44728f3..e76eca0be3 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -50,6 +50,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ return $url; } public function fopen($path,$mode) { + $this->init(); switch($mode) { case 'r': case 'rb': @@ -86,6 +87,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ } public function writeBack($tmpFile) { + $this->init(); if(isset(self::$tempFiles[$tmpFile])) { $this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]); unlink($tmpFile); diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index dfba3105ec..4382f63003 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -35,11 +35,6 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ if(substr($this->share,-1,1)=='/') { $this->share=substr($this->share,0,-1); } - - //create the root folder if necesary - if(!$this->is_dir('')) { - $this->mkdir(''); - } } public function getId(){ @@ -54,6 +49,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ } public function stat($path) { + $this->init(); if(!$path and $this->root=='/') {//mtime doesn't work for shares $mtime=$this->shareMTime(); $stat=stat($this->constructUrl($path)); @@ -75,6 +71,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ * @return bool */ public function hasUpdated($path,$time) { + $this->init(); if(!$path and $this->root=='/') { //mtime doesn't work for shares, but giving the nature of the backend, doing a full update is still just fast enough return true; diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/streamwrapper.php index 750bdbaf4d..bc1c95c5e8 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/streamwrapper.php @@ -9,13 +9,29 @@ namespace OC\Files\Storage; abstract class StreamWrapper extends \OC\Files\Storage\Common{ + private $ready = false; + + protected function init(){ + if($this->ready){ + return; + } + $this->ready = true; + + //create the root folder if necesary + if(!$this->is_dir('')) { + $this->mkdir(''); + } + } + abstract public function constructUrl($path); public function mkdir($path) { + $this->init(); return mkdir($this->constructUrl($path)); } public function rmdir($path) { + $this->init(); if($this->file_exists($path)) { $succes=rmdir($this->constructUrl($path)); clearstatcache(); @@ -26,10 +42,12 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{ } public function opendir($path) { + $this->init(); return opendir($this->constructUrl($path)); } public function filetype($path) { + $this->init(); return filetype($this->constructUrl($path)); } @@ -42,16 +60,19 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{ } public function file_exists($path) { + $this->init(); return file_exists($this->constructUrl($path)); } public function unlink($path) { + $this->init(); $succes=unlink($this->constructUrl($path)); clearstatcache(); return $succes; } public function fopen($path,$mode) { + $this->init(); return fopen($this->constructUrl($path),$mode); } @@ -60,6 +81,7 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{ } public function touch($path,$mtime=null) { + $this->init(); if(is_null($mtime)) { $fh=$this->fopen($path,'a'); fwrite($fh,''); @@ -70,18 +92,22 @@ abstract class StreamWrapper extends \OC\Files\Storage\Common{ } public function getFile($path,$target) { + $this->init(); return copy($this->constructUrl($path),$target); } public function uploadFile($path,$target) { + $this->init(); return copy($path,$this->constructUrl($target)); } public function rename($path1,$path2) { + $this->init(); return rename($this->constructUrl($path1),$this->constructUrl($path2)); } public function stat($path) { + $this->init(); return stat($this->constructUrl($path)); } diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index c3578b0c23..55c2c3e0ac 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -17,6 +17,7 @@ class SWIFT extends \OC\Files\Storage\Common{ private $user; private $token; private $secure; + private $ready = false; /** * @var \CF_Authentication auth */ @@ -188,7 +189,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * add an emulated sub container - * @param CF_Container $container + * @param \CF_Container $container * @param string $name * @return bool */ @@ -222,7 +223,7 @@ class SWIFT extends \OC\Files\Storage\Common{ /** * remove an emulated sub container - * @param CF_Container $container + * @param \CF_Container $container * @param string $name * @return bool */ @@ -279,6 +280,15 @@ class SWIFT extends \OC\Files\Storage\Common{ if(!$this->root || $this->root[0]!='/') { $this->root='/'.$this->root; } + + } + + private function init(){ + if($this->ready){ + return; + } + $this->ready = true; + $this->auth = new \CF_Authentication($this->user, $this->token, null, $this->host); $this->auth->authenticate(); @@ -297,6 +307,7 @@ class SWIFT extends \OC\Files\Storage\Common{ public function mkdir($path) { + $this->init(); if($this->containerExists($path)) { return false; }else{ @@ -306,6 +317,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function rmdir($path) { + $this->init(); if(!$this->containerExists($path)) { return false; }else{ @@ -343,6 +355,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function opendir($path) { + $this->init(); $container=$this->getContainer($path); $files=$this->getObjects($container); $i=array_search(self::SUBCONTAINER_FILE,$files); @@ -357,6 +370,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function filetype($path) { + $this->init(); if($this->containerExists($path)) { return 'dir'; }else{ @@ -373,6 +387,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function file_exists($path) { + $this->init(); if($this->is_dir($path)) { return true; }else{ @@ -381,6 +396,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function file_get_contents($path) { + $this->init(); $obj=$this->getObject($path); if(is_null($obj)) { return false; @@ -389,6 +405,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function file_put_contents($path,$content) { + $this->init(); $obj=$this->getObject($path); if(is_null($obj)) { $container=$this->getContainer(dirname($path)); @@ -402,6 +419,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function unlink($path) { + $this->init(); if($this->containerExists($path)) { return $this->rmdir($path); } @@ -415,6 +433,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function fopen($path,$mode) { + $this->init(); switch($mode) { case 'r': case 'rb': @@ -458,6 +477,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function touch($path,$mtime=null) { + $this->init(); $obj=$this->getObject($path); if(is_null($obj)) { return false; @@ -472,6 +492,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function rename($path1,$path2) { + $this->init(); $sourceContainer=$this->getContainer(dirname($path1)); $targetContainer=$this->getContainer(dirname($path2)); $result=$sourceContainer->move_object_to(basename($path1),$targetContainer,basename($path2)); @@ -484,6 +505,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function copy($path1,$path2) { + $this->init(); $sourceContainer=$this->getContainer(dirname($path1)); $targetContainer=$this->getContainer(dirname($path2)); $result=$sourceContainer->copy_object_to(basename($path1),$targetContainer,basename($path2)); @@ -495,6 +517,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } public function stat($path) { + $this->init(); $container=$this->getContainer($path); if (!is_null($container)) { return array( @@ -521,6 +544,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } private function getTmpFile($path) { + $this->init(); $obj=$this->getObject($path); if(!is_null($obj)) { $tmpFile=\OCP\Files::tmpFile(); @@ -532,6 +556,7 @@ class SWIFT extends \OC\Files\Storage\Common{ } private function fromTmpFile($tmpFile,$path) { + $this->init(); $obj=$this->getObject($path); if(is_null($obj)) { $obj=$this->createObject($path); diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index c9785f3eb1..470a80f8cf 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -14,6 +14,7 @@ class DAV extends \OC\Files\Storage\Common{ private $host; private $secure; private $root; + private $ready; /** * @var \Sabre_DAV_Client */ @@ -37,6 +38,13 @@ class DAV extends \OC\Files\Storage\Common{ if(substr($this->root,-1,1)!='/') { $this->root.='/'; } + } + + private function init(){ + if($this->ready){ + return; + } + $this->ready = true; $settings = array( 'baseUri' => $this->createBaseUri(), @@ -70,16 +78,19 @@ class DAV extends \OC\Files\Storage\Common{ } public function mkdir($path) { + $this->init(); $path=$this->cleanPath($path); return $this->simpleResponse('MKCOL',$path,null,201); } public function rmdir($path) { + $this->init(); $path=$this->cleanPath($path); return $this->simpleResponse('DELETE',$path,null,204); } public function opendir($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array(),1); @@ -98,6 +109,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function filetype($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}resourcetype')); @@ -119,6 +131,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function file_exists($path) { + $this->init(); $path=$this->cleanPath($path); try{ $this->client->propfind($path, array('{DAV:}resourcetype')); @@ -129,10 +142,12 @@ class DAV extends \OC\Files\Storage\Common{ } public function unlink($path) { + $this->init(); return $this->simpleResponse('DELETE',$path,null,204); } public function fopen($path,$mode) { + $this->init(); $path=$this->cleanPath($path); switch($mode) { case 'r': @@ -187,6 +202,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function free_space($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}quota-available-bytes')); @@ -201,6 +217,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function touch($path,$mtime=null) { + $this->init(); if(is_null($mtime)) { $mtime=time(); } @@ -209,11 +226,13 @@ class DAV extends \OC\Files\Storage\Common{ } public function getFile($path,$target) { + $this->init(); $source=$this->fopen($path,'r'); file_put_contents($target,$source); } public function uploadFile($path,$target) { + $this->init(); $source=fopen($path,'r'); $curl = curl_init(); @@ -228,6 +247,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function rename($path1,$path2) { + $this->init(); $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ @@ -239,6 +259,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function copy($path1,$path2) { + $this->init(); $path1=$this->cleanPath($path1); $path2=$this->root.$this->cleanPath($path2); try{ @@ -250,6 +271,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function stat($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}getlastmodified','{DAV:}getcontentlength')); @@ -263,6 +285,7 @@ class DAV extends \OC\Files\Storage\Common{ } public function getMimeType($path) { + $this->init(); $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}getcontenttype','{DAV:}resourcetype')); diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index 5af317675c..65127175ad 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -30,7 +30,7 @@ return array( 'root'=>'/', ), 'smb'=>array( - 'run'=>false, + 'run'=>true, 'user'=>'test', 'password'=>'test', 'host'=>'localhost', From 707bd68bb4e77b4184b578699d508750653e2d42 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 21 Oct 2012 22:05:29 +0200 Subject: [PATCH 045/262] automatically scan files when needed --- lib/files.php | 463 +++++++++++++++++++++++--------------------- tests/lib/files.php | 27 ++- 2 files changed, 265 insertions(+), 225 deletions(-) diff --git a/lib/files.php b/lib/files.php index 8d402c0001..a5eec1f2a6 100644 --- a/lib/files.php +++ b/lib/files.php @@ -1,35 +1,36 @@ . -* -*/ + * ownCloud + * + * @author Frank Karlitschek + * @copyright 2012 Frank Karlitschek frank@owncloud.org + * + * 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 . + * + */ /** * Class for fileserver access * */ class OC_Files { - static $tmpFiles=array(); + static $tmpFiles = array(); /** * get the filesystem info + * * @param string $path * @return array * @@ -41,19 +42,25 @@ class OC_Files { * - versioned */ public static function getFileInfo($path) { - $path=\OC\Files\Filesystem::normalizePath($path); + $path = \OC\Files\Filesystem::normalizePath($path); /** * @var \OC\Files\Storage\Storage $storage * @var string $path */ - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); - $cache=$storage->getCache(); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + $data = $cache->get($internalPath); - if($data['mimetype'] === 'httpd/unix-directory'){ + if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder $mountPoints = \OC\Files\Filesystem::getMountPoints($path); - foreach($mountPoints as $mountPoint){ + foreach ($mountPoints as $mountPoint) { $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -66,43 +73,50 @@ class OC_Files { } /** - * get the content of a directory - * @param string $directory path under datadirectory - * @return array - */ + * get the content of a directory + * + * @param string $directory path under datadirectory + * @return array + */ public static function getDirectoryContent($directory, $mimetype_filter = '') { - $path=\OC\Files\Filesystem::normalizePath($directory); + $path = \OC\Files\Filesystem::normalizePath($directory); /** * @var \OC\Files\Storage\Storage $storage * @var string $path */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $cache=$storage->getCache(); - $files=$cache->getFolderContents($internalPath); //TODO: mimetype_filter + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); $dirLength = strlen($path); - foreach($mountPoints as $mountPoint){ + foreach ($mountPoints as $mountPoint) { $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); $relativePath = trim(substr($mountPoint, $dirLength), '/'); - if($pos = strpos($relativePath, '/')){ //mountpoint inside subfolder add size to the correct folder + if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder $entryName = substr($relativePath, 0, $pos); - foreach($files as &$entry){ - if($entry['name'] === $entryName){ + foreach ($files as &$entry) { + if ($entry['name'] === $entryName) { $entry['size'] += $rootEntry['size']; } } - }else{ //mountpoint in this folder, add an entry for it + } else { //mountpoint in this folder, add an entry for it $rootEntry['name'] = $relativePath; $files[] = $rootEntry; } } - usort($files, "fileCmp");//TODO: remove this once ajax is merged + usort($files, "fileCmp"); //TODO: remove this once ajax is merged return $files; } @@ -113,12 +127,11 @@ class OC_Files { // get next subdir to check $dir = array_pop($dirs_to_check); $dir_content = self::getDirectoryContent($dir, $mimetype_filter); - foreach($dir_content as $file) { + foreach ($dir_content as $file) { if ($file['type'] == 'file') { - $files[] = $dir.'/'.$file['name']; - } - else { - $dirs_to_check[] = $dir.'/'.$file['name']; + $files[] = $dir . '/' . $file['name']; + } else { + $dirs_to_check[] = $dir . '/' . $file['name']; } } } @@ -126,170 +139,171 @@ class OC_Files { } /** - * return the content of a file or return a zip file containning multiply files - * - * @param dir $dir - * @param file $file ; seperated list of files to download - * @param boolean $only_header ; boolean to only send header of the request - */ - public static function get($dir,$files, $only_header = false) { - if(strpos($files,';')) { - $files=explode(';',$files); + * return the content of a file or return a zip file containning multiply files + * + * @param dir $dir + * @param file $file ; seperated list of files to download + * @param boolean $only_header ; boolean to only send header of the request + */ + public static function get($dir, $files, $only_header = false) { + if (strpos($files, ';')) { + $files = explode(';', $files); } - if(is_array($files)) { - self::validateZipDownload($dir,$files); + if (is_array($files)) { + self::validateZipDownload($dir, $files); $executionTime = intval(ini_get('max_execution_time')); set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true) { exit("cannot open <$filename>\n"); } - foreach($files as $file) { - $file=$dir.'/'.$file; - if(\OC\Files\Filesystem::is_file($file)) { - $tmpFile=OC_F\OC\Files\Filesystemilesystem::toTmpFile($file); - self::$tmpFiles[]=$tmpFile; - $zip->addFile($tmpFile,basename($file)); - }elseif(\OC\Files\Filesystem::is_dir($file)) { - self::zipAddDir($file,$zip); + foreach ($files as $file) { + $file = $dir . '/' . $file; + if (\OC\Files\Filesystem::is_file($file)) { + $tmpFile = OC_F\OC\Files\Filesystemilesystem::toTmpFile($file); + self::$tmpFiles[] = $tmpFile; + $zip->addFile($tmpFile, basename($file)); + } elseif (\OC\Files\Filesystem::is_dir($file)) { + self::zipAddDir($file, $zip); } } $zip->close(); set_time_limit($executionTime); - }elseif(\OC\Files\Filesystem::is_dir($dir.'/'.$files)) { - self::validateZipDownload($dir,$files); + } elseif (\OC\Files\Filesystem::is_dir($dir . '/' . $files)) { + self::validateZipDownload($dir, $files); $executionTime = intval(ini_get('max_execution_time')); set_time_limit(0); $zip = new ZipArchive(); $filename = OC_Helper::tmpFile('.zip'); - if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) { + if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) !== true) { exit("cannot open <$filename>\n"); } - $file=$dir.'/'.$files; - self::zipAddDir($file,$zip); + $file = $dir . '/' . $files; + self::zipAddDir($file, $zip); $zip->close(); set_time_limit($executionTime); - }else{ - $zip=false; - $filename=$dir.'/'.$files; + } else { + $zip = false; + $filename = $dir . '/' . $files; } @ob_end_clean(); - if($zip or \OC\Files\Filesystem::isReadable($filename)) { - header('Content-Disposition: attachment; filename="'.basename($filename).'"'); + if ($zip or \OC\Files\Filesystem::isReadable($filename)) { + header('Content-Disposition: attachment; filename="' . basename($filename) . '"'); header('Content-Transfer-Encoding: binary'); OC_Response::disableCaching(); - if($zip) { + if ($zip) { ini_set('zlib.output_compression', 'off'); header('Content-Type: application/zip'); header('Content-Length: ' . filesize($filename)); - }else{ - header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); + } else { + header('Content-Type: ' . \OC\Files\Filesystem::getMimeType($filename)); } - }elseif($zip or !\OC\Files\Filesystem::file_exists($filename)) { + } elseif ($zip or !\OC\Files\Filesystem::file_exists($filename)) { header("HTTP/1.0 404 Not Found"); - $tmpl = new OC_Template( '', '404', 'guest' ); - $tmpl->assign('file',$filename); + $tmpl = new OC_Template('', '404', 'guest'); + $tmpl->assign('file', $filename); $tmpl->printPage(); - }else{ + } else { header("HTTP/1.0 403 Forbidden"); die('403 Forbidden'); } - if($only_header) { - if(!$zip) - header("Content-Length: ".\OC\Files\Filesystem::filesize($filename)); - return ; + if ($only_header) { + if (!$zip) + header("Content-Length: " . \OC\Files\Filesystem::filesize($filename)); + return; } - if($zip) { - $handle=fopen($filename,'r'); + if ($zip) { + $handle = fopen($filename, 'r'); if ($handle) { - $chunkSize = 8*1024;// 1 MB chunks + $chunkSize = 8 * 1024; // 1 MB chunks while (!feof($handle)) { echo fread($handle, $chunkSize); flush(); } } unlink($filename); - }else{ + } else { \OC\Files\Filesystem::readfile($filename); } - foreach(self::$tmpFiles as $tmpFile) { - if(file_exists($tmpFile) and is_file($tmpFile)) { + foreach (self::$tmpFiles as $tmpFile) { + if (file_exists($tmpFile) and is_file($tmpFile)) { unlink($tmpFile); } } } - public static function zipAddDir($dir,$zip,$internalDir='') { - $dirname=basename($dir); - $zip->addEmptyDir($internalDir.$dirname); - $internalDir.=$dirname.='/'; - $files=OC_Files::getdirectorycontent($dir); - foreach($files as $file) { - $filename=$file['name']; - $file=$dir.'/'.$filename; - if(\OC\Files\Filesystem::is_file($file)) { - $tmpFile=\OC\Files\Filesystem::toTmpFile($file); - OC_Files::$tmpFiles[]=$tmpFile; - $zip->addFile($tmpFile,$internalDir.$filename); - }elseif(\OC\Files\Filesystem::is_dir($file)) { - self::zipAddDir($file,$zip,$internalDir); + public static function zipAddDir($dir, $zip, $internalDir = '') { + $dirname = basename($dir); + $zip->addEmptyDir($internalDir . $dirname); + $internalDir .= $dirname .= '/'; + $files = OC_Files::getdirectorycontent($dir); + foreach ($files as $file) { + $filename = $file['name']; + $file = $dir . '/' . $filename; + if (\OC\Files\Filesystem::is_file($file)) { + $tmpFile = \OC\Files\Filesystem::toTmpFile($file); + OC_Files::$tmpFiles[] = $tmpFile; + $zip->addFile($tmpFile, $internalDir . $filename); + } elseif (\OC\Files\Filesystem::is_dir($file)) { + self::zipAddDir($file, $zip, $internalDir); } } } + /** - * move a file or folder - * - * @param dir $sourceDir - * @param file $source - * @param dir $targetDir - * @param file $target - */ - public static function move($sourceDir,$source,$targetDir,$target) { - if(OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared')) { - $targetFile=self::normalizePath($targetDir.'/'.$target); - $sourceFile=self::normalizePath($sourceDir.'/'.$source); - return \OC\Files\Filesystem::rename($sourceFile,$targetFile); + * move a file or folder + * + * @param dir $sourceDir + * @param file $source + * @param dir $targetDir + * @param file $target + */ + public static function move($sourceDir, $source, $targetDir, $target) { + if (OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared')) { + $targetFile = self::normalizePath($targetDir . '/' . $target); + $sourceFile = self::normalizePath($sourceDir . '/' . $source); + return \OC\Files\Filesystem::rename($sourceFile, $targetFile); } else { return false; } } /** - * copy a file or folder - * - * @param dir $sourceDir - * @param file $source - * @param dir $targetDir - * @param file $target - */ - public static function copy($sourceDir,$source,$targetDir,$target) { - if(OC_User::isLoggedIn()) { - $targetFile=$targetDir.'/'.$target; - $sourceFile=$sourceDir.'/'.$source; - return \OC\Files\Filesystem::copy($sourceFile,$targetFile); + * copy a file or folder + * + * @param dir $sourceDir + * @param file $source + * @param dir $targetDir + * @param file $target + */ + public static function copy($sourceDir, $source, $targetDir, $target) { + if (OC_User::isLoggedIn()) { + $targetFile = $targetDir . '/' . $target; + $sourceFile = $sourceDir . '/' . $source; + return \OC\Files\Filesystem::copy($sourceFile, $targetFile); } } /** - * create a new file or folder - * - * @param dir $dir - * @param file $name - * @param type $type - */ - public static function newFile($dir,$name,$type) { - if(OC_User::isLoggedIn()) { - $file=$dir.'/'.$name; - if($type=='dir') { + * create a new file or folder + * + * @param dir $dir + * @param file $name + * @param type $type + */ + public static function newFile($dir, $name, $type) { + if (OC_User::isLoggedIn()) { + $file = $dir . '/' . $name; + if ($type == 'dir') { return \OC\Files\Filesystem::mkdir($file); - }elseif($type=='file') { - $fileHandle=\OC\Files\Filesystem::fopen($file, 'w'); - if($fileHandle) { + } elseif ($type == 'file') { + $fileHandle = \OC\Files\Filesystem::fopen($file, 'w'); + if ($fileHandle) { fclose($fileHandle); return true; - }else{ + } else { return false; } } @@ -297,29 +311,29 @@ class OC_Files { } /** - * deletes a file or folder - * - * @param dir $dir - * @param file $name - */ - public static function delete($dir,$file) { - if(OC_User::isLoggedIn() && ($dir!= '' || $file != 'Shared')) { - $file=$dir.'/'.$file; + * deletes a file or folder + * + * @param dir $dir + * @param file $name + */ + public static function delete($dir, $file) { + if (OC_User::isLoggedIn() && ($dir != '' || $file != 'Shared')) { + $file = $dir . '/' . $file; return \OC\Files\Filesystem::unlink($file); } } /** - * checks if the selected files are within the size constraint. If not, outputs an error page. - * - * @param dir $dir - * @param files $files - */ + * checks if the selected files are within the size constraint. If not, outputs an error page. + * + * @param dir $dir + * @param files $files + */ static function validateZipDownload($dir, $files) { - if(!OC_Config::getValue('allowZipDownload', true)) { + if (!OC_Config::getValue('allowZipDownload', true)) { $l = OC_L10N::get('lib'); header("HTTP/1.0 409 Conflict"); - $tmpl = new OC_Template( '', 'error', 'user' ); + $tmpl = new OC_Template('', 'error', 'user'); $errors = array( array( 'error' => $l->t('ZIP download is turned off.'), @@ -332,19 +346,19 @@ class OC_Files { } $zipLimit = OC_Config::getValue('maxZipInputSize', OC_Helper::computerFileSize('800 MB')); - if($zipLimit > 0) { + if ($zipLimit > 0) { $totalsize = 0; - if(is_array($files)) { - foreach($files as $file) { - $totalsize += \OC\Files\Filesystem::filesize($dir.'/'.$file); + if (is_array($files)) { + foreach ($files as $file) { + $totalsize += \OC\Files\Filesystem::filesize($dir . '/' . $file); } - }else{ - $totalsize += \OC\Files\Filesystem::filesize($dir.'/'.$files); + } else { + $totalsize += \OC\Files\Filesystem::filesize($dir . '/' . $files); } - if($totalsize > $zipLimit) { + if ($totalsize > $zipLimit) { $l = OC_L10N::get('lib'); header("HTTP/1.0 409 Conflict"); - $tmpl = new OC_Template( '', 'error', 'user' ); + $tmpl = new OC_Template('', 'error', 'user'); $errors = array( array( 'error' => $l->t('Selected files too large to generate zip file.'), @@ -359,78 +373,80 @@ class OC_Files { } /** - * try to detect the mime type of a file - * - * @param string path - * @return string guessed mime type - */ + * try to detect the mime type of a file + * + * @param string path + * @return string guessed mime type + */ static function getMimeType($path) { return \OC\Files\Filesystem::getMimeType($path); } /** - * get a file tree - * - * @param string path - * @return array - */ + * get a file tree + * + * @param string path + * @return array + */ static function getTree($path) { return \OC\Files\Filesystem::getTree($path); } /** - * pull a file from a remote server - * @param string source - * @param string token - * @param string dir - * @param string file - * @return string guessed mime type - */ - static function pull($source,$token,$dir,$file) { - $tmpfile=tempnam(get_temp_dir(),'remoteCloudFile'); - $fp=fopen($tmpfile,'w+'); - $url=$source.="/files/pull.php?token=$token"; - $ch=curl_init(); - curl_setopt($ch,CURLOPT_URL,$url); + * pull a file from a remote server + * + * @param string source + * @param string token + * @param string dir + * @param string file + * @return string guessed mime type + */ + static function pull($source, $token, $dir, $file) { + $tmpfile = tempnam(get_temp_dir(), 'remoteCloudFile'); + $fp = fopen($tmpfile, 'w+'); + $url = $source .= "/files/pull.php?token=$token"; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FILE, $fp); curl_exec($ch); fclose($fp); - $info=curl_getinfo($ch); - $httpCode=$info['http_code']; + $info = curl_getinfo($ch); + $httpCode = $info['http_code']; curl_close($ch); - if($httpCode==200 or $httpCode==0) { - \OC\Files\Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file); + if ($httpCode == 200 or $httpCode == 0) { + \OC\Files\Filesystem::fromTmpFile($tmpfile, $dir . '/' . $file); return true; - }else{ + } else { return false; } } /** * set the maximum upload size limit for apache hosts using .htaccess + * * @param int size filesisze in bytes * @return false on failure, size on success */ static function setUploadLimit($size) { //don't allow user to break his config -- upper boundary - if($size > PHP_INT_MAX) { + if ($size > PHP_INT_MAX) { //max size is always 1 byte lower than computerFileSize returns - if($size > PHP_INT_MAX+1) + if ($size > PHP_INT_MAX + 1) return false; - $size -=1; + $size -= 1; } else { - $size=OC_Helper::humanFileSize($size); - $size=substr($size,0,-1);//strip the B - $size=str_replace(' ','',$size); //remove the space between the size and the postfix + $size = OC_Helper::humanFileSize($size); + $size = substr($size, 0, -1); //strip the B + $size = str_replace(' ', '', $size); //remove the space between the size and the postfix } //don't allow user to break his config -- broken or malicious size input - if(intval($size) == 0) { + if (intval($size) == 0) { return false; } - $htaccess = @file_get_contents(OC::$SERVERROOT.'/.htaccess'); //supress errors in case we don't have permissions for - if(!$htaccess) { + $htaccess = @file_get_contents(OC::$SERVERROOT . '/.htaccess'); //supress errors in case we don't have permissions for + if (!$htaccess) { return false; } @@ -439,50 +455,53 @@ class OC_Files { 'post_max_size' ); - foreach($phpValueKeys as $key) { - $pattern = '/php_value '.$key.' (\S)*/'; - $setting = 'php_value '.$key.' '.$size; - $hasReplaced = 0; - $content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced); - if($content !== null) { + foreach ($phpValueKeys as $key) { + $pattern = '/php_value ' . $key . ' (\S)*/'; + $setting = 'php_value ' . $key . ' ' . $size; + $hasReplaced = 0; + $content = preg_replace($pattern, $setting, $htaccess, 1, $hasReplaced); + if ($content !== null) { $htaccess = $content; } - if($hasReplaced == 0) { + if ($hasReplaced == 0) { $htaccess .= "\n" . $setting; } } //check for write permissions - if(is_writable(OC::$SERVERROOT.'/.htaccess')) { - file_put_contents(OC::$SERVERROOT.'/.htaccess', $htaccess); + if (is_writable(OC::$SERVERROOT . '/.htaccess')) { + file_put_contents(OC::$SERVERROOT . '/.htaccess', $htaccess); return OC_Helper::computerFileSize($size); - } else { OC_Log::write('files','Can\'t write upload limit to '.OC::$SERVERROOT.'/.htaccess. Please check the file permissions',OC_Log::WARN); } + } else { + OC_Log::write('files', 'Can\'t write upload limit to ' . OC::$SERVERROOT . '/.htaccess. Please check the file permissions', OC_Log::WARN); + } return false; } /** * normalize a path, removing any double, add leading /, etc + * * @param string $path * @return string */ static public function normalizePath($path) { - $path='/'.$path; - $old=''; - while($old!=$path) {//replace any multiplicity of slashes with a single one - $old=$path; - $path=str_replace('//','/',$path); + $path = '/' . $path; + $old = ''; + while ($old != $path) { //replace any multiplicity of slashes with a single one + $old = $path; + $path = str_replace('//', '/', $path); } return $path; } } -function fileCmp($a,$b) { - if($a['type']=='dir' and $b['type']!='dir') { +function fileCmp($a, $b) { + if ($a['type'] == 'dir' and $b['type'] != 'dir') { return -1; - }elseif($a['type']!='dir' and $b['type']=='dir') { + } elseif ($a['type'] != 'dir' and $b['type'] == 'dir') { return 1; - }else{ - return strnatcasecmp($a['name'],$b['name']); + } else { + return strnatcasecmp($a['name'], $b['name']); } } diff --git a/tests/lib/files.php b/tests/lib/files.php index 9cb5276845..d978ac3fd1 100644 --- a/tests/lib/files.php +++ b/tests/lib/files.php @@ -67,10 +67,29 @@ class Test_Files extends PHPUnit_Framework_TestCase { $this->assertEquals($storageSize, $folderData[3]['size']); } + public function testAutoScan() { + $storage1 = $this->getTestStorage(false); + $storage2 = $this->getTestStorage(false); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $storageSize = $textSize * 2 + $imageSize; + + $cachedData = \OC_Files::getFileInfo('/'); + $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); + $this->assertEquals(-1, $cachedData['size']); + + $folderData = \OC_Files::getDirectoryContent('/substorage/folder'); + $this->assertEquals('text/plain', $folderData[0]['mimetype']); + $this->assertEquals($textSize, $folderData[0]['size']); + } + /** + * @param bool $scan * @return OC\Files\Storage\Storage */ - private function getTestStorage() { + private function getTestStorage($scan = true) { $storage = new \OC\Files\Storage\Temporary(array()); $textData = "dummy file data\n"; $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); @@ -79,8 +98,10 @@ class Test_Files extends PHPUnit_Framework_TestCase { $storage->file_put_contents('foo.png', $imgData); $storage->file_put_contents('folder/bar.txt', $textData); - $scanner = $storage->getScanner(); - $scanner->scan(''); + if ($scan) { + $scanner = $storage->getScanner(); + $scanner->scan(''); + } $this->storages[] = $storage; return $storage; } From 56c7ee799cb13f7a4db60663f60b76cdf223614b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 23 Oct 2012 16:34:58 +0200 Subject: [PATCH 046/262] use strtotime on non-nummeric times in oc_filesystem::touch --- lib/files/view.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index a59ad8105d..18d9193035 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,7 +110,7 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); } else { @@ -124,7 +124,7 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFolder($internalPath); } else { @@ -227,6 +227,9 @@ class View { } public function touch($path, $mtime = null) { + if (!is_null($mtime) and !is_numeric($mtime)) { + $mtime = strtotime($mtime); + } return $this->basicOperation('touch', $path, array('write'), $mtime); } @@ -331,8 +334,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -342,7 +345,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -414,8 +417,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1)=\OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list( , $internalPath2)=\OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -550,7 +553,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -585,7 +588,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); From 5a3d6805a2613c4f55daa971e112cc77f17b060f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 24 Oct 2012 15:52:30 +0200 Subject: [PATCH 047/262] cleanup OC_Files a bit --- apps/files/ajax/delete.php | 23 +++--- apps/files/ajax/move.php | 13 +++- apps/files/ajax/newfile.php | 2 +- apps/files/ajax/newfolder.php | 2 +- apps/files/ajax/rename.php | 14 ++-- lib/files.php | 136 ---------------------------------- 6 files changed, 34 insertions(+), 156 deletions(-) diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php index 57c8c15c19..ae6158a05a 100644 --- a/apps/files/ajax/delete.php +++ b/apps/files/ajax/delete.php @@ -12,17 +12,22 @@ $files = isset($_POST["file"]) ? stripslashes($_POST["file"]) : stripslashes($_P $files = explode(';', $files); $filesWithError = ''; -$success = true; -//Now delete -foreach($files as $file) { - if( !OC_Files::delete( $dir, $file )) { - $filesWithError .= $file . "\n"; - $success = false; +if (OC_User::isLoggedIn()) { + $success = true; + + //Now delete + foreach ($files as $file) { + if ($dir != '' || $file != 'Shared' && !\OC\Files\Filesystem::unlink($dir . '/' . $file)) { + $filesWithError .= $file . "\n"; + $success = false; + } } +} else { + $success = false; } -if($success) { - OCP\JSON::success(array("data" => array( "dir" => $dir, "files" => $files ))); +if ($success) { + OCP\JSON::success(array("data" => array("dir" => $dir, "files" => $files))); } else { - OCP\JSON::error(array("data" => array( "message" => "Could not delete:\n" . $filesWithError ))); + OCP\JSON::error(array("data" => array("message" => "Could not delete:\n" . $filesWithError))); } diff --git a/apps/files/ajax/move.php b/apps/files/ajax/move.php index 8b3149ef14..f872783122 100644 --- a/apps/files/ajax/move.php +++ b/apps/files/ajax/move.php @@ -11,9 +11,14 @@ $dir = stripslashes($_GET["dir"]); $file = stripslashes($_GET["file"]); $target = stripslashes($_GET["target"]); - -if(OC_Files::move($dir, $file, $target, $file)) { - OCP\JSON::success(array("data" => array( "dir" => $dir, "files" => $file ))); -} else { +if (OC_User::isLoggedIn() && ($dir != '' || $file != 'Shared')) { + $targetFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file); + $sourceFile = \OC\Files\Filesystem::normalizePath($target . '/' . $file); + if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) { + OCP\JSON::success(array("data" => array( "dir" => $dir, "files" => $file ))); + } else { + OCP\JSON::error(array("data" => array( "message" => "Could not move $file" ))); + } +}else{ OCP\JSON::error(array("data" => array( "message" => "Could not move $file" ))); } diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 4d73970b68..f94d984d5b 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -82,7 +82,7 @@ if($source) { OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); exit(); } - }elseif(OC_Files::newFile($dir, $filename, 'file')) { + }elseif(\OC\Files\Filesystem::touch($dir . '/' . $filename)) { $meta = OC_FileCache::get($dir.'/'.$filename); $id = OC_FileCache::getId($dir.'/'.$filename); OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index 0f1f2f14eb..c36c208455 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -19,7 +19,7 @@ if(strpos($foldername, '/')!==false) { exit(); } -if(OC_Files::newFile($dir, stripslashes($foldername), 'dir')) { +if(\OC\Files\Filesystem::mkdir($dir . '/' . stripslashes($foldername))) { if ( $dir != '/') { $path = $dir.'/'.$foldername; } else { diff --git a/apps/files/ajax/rename.php b/apps/files/ajax/rename.php index 45448279fa..a2b9b8de25 100644 --- a/apps/files/ajax/rename.php +++ b/apps/files/ajax/rename.php @@ -11,10 +11,14 @@ $dir = stripslashes($_GET["dir"]); $file = stripslashes($_GET["file"]); $newname = stripslashes($_GET["newname"]); -// Delete -if( OC_Files::move( $dir, $file, $dir, $newname )) { - OCP\JSON::success(array("data" => array( "dir" => $dir, "file" => $file, "newname" => $newname ))); -} -else{ +if (OC_User::isLoggedIn() && ($dir != '' || $file != 'Shared')) { + $targetFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file); + $sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname); + if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) { + OCP\JSON::success(array("data" => array( "dir" => $dir, "file" => $file, "newname" => $newname ))); + } else { + OCP\JSON::error(array("data" => array( "message" => "Unable to rename file" ))); + } +}else{ OCP\JSON::error(array("data" => array( "message" => "Unable to rename file" ))); } diff --git a/lib/files.php b/lib/files.php index ff9befa89e..7ab7c89201 100644 --- a/lib/files.php +++ b/lib/files.php @@ -252,77 +252,6 @@ class OC_Files { } } - /** - * move a file or folder - * - * @param dir $sourceDir - * @param file $source - * @param dir $targetDir - * @param file $target - */ - public static function move($sourceDir, $source, $targetDir, $target) { - if (OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared')) { - $targetFile = self::normalizePath($targetDir . '/' . $target); - $sourceFile = self::normalizePath($sourceDir . '/' . $source); - return \OC\Files\Filesystem::rename($sourceFile, $targetFile); - } else { - return false; - } - } - - /** - * copy a file or folder - * - * @param dir $sourceDir - * @param file $source - * @param dir $targetDir - * @param file $target - */ - public static function copy($sourceDir, $source, $targetDir, $target) { - if (OC_User::isLoggedIn()) { - $targetFile = $targetDir . '/' . $target; - $sourceFile = $sourceDir . '/' . $source; - return \OC\Files\Filesystem::copy($sourceFile, $targetFile); - } - } - - /** - * create a new file or folder - * - * @param dir $dir - * @param file $name - * @param type $type - */ - public static function newFile($dir, $name, $type) { - if (OC_User::isLoggedIn()) { - $file = $dir . '/' . $name; - if ($type == 'dir') { - return \OC\Files\Filesystem::mkdir($file); - } elseif ($type == 'file') { - $fileHandle = \OC\Files\Filesystem::fopen($file, 'w'); - if ($fileHandle) { - fclose($fileHandle); - return true; - } else { - return false; - } - } - } - } - - /** - * deletes a file or folder - * - * @param dir $dir - * @param file $name - */ - public static function delete($dir, $file) { - if (OC_User::isLoggedIn() && ($dir != '' || $file != 'Shared')) { - $file = $dir . '/' . $file; - return \OC\Files\Filesystem::unlink($file); - } - } - /** * checks if the selected files are within the size constraint. If not, outputs an error page. * @@ -372,55 +301,6 @@ class OC_Files { } } - /** - * try to detect the mime type of a file - * - * @param string path - * @return string guessed mime type - */ - static function getMimeType($path) { - return \OC\Files\Filesystem::getMimeType($path); - } - - /** - * get a file tree - * - * @param string path - * @return array - */ - static function getTree($path) { - return \OC\Files\Filesystem::getTree($path); - } - - /** - * pull a file from a remote server - * - * @param string source - * @param string token - * @param string dir - * @param string file - * @return string guessed mime type - */ - static function pull($source, $token, $dir, $file) { - $tmpfile = tempnam(get_temp_dir(), 'remoteCloudFile'); - $fp = fopen($tmpfile, 'w+'); - $url = $source .= "/files/pull.php?token=$token"; - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_FILE, $fp); - curl_exec($ch); - fclose($fp); - $info = curl_getinfo($ch); - $httpCode = $info['http_code']; - curl_close($ch); - if ($httpCode == 200 or $httpCode == 0) { - \OC\Files\Filesystem::fromTmpFile($tmpfile, $dir . '/' . $file); - return true; - } else { - return false; - } - } - /** * set the maximum upload size limit for apache hosts using .htaccess * @@ -478,22 +358,6 @@ class OC_Files { return false; } - - /** - * normalize a path, removing any double, add leading /, etc - * - * @param string $path - * @return string - */ - static public function normalizePath($path) { - $path = '/' . $path; - $old = ''; - while ($old != $path) { //replace any multiplicity of slashes with a single one - $old = $path; - $path = str_replace('//', '/', $path); - } - return $path; - } } function fileCmp($a, $b) { From 39adadd3e3e50dcf3bf577a22870aaec52f63052 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:30:25 +0200 Subject: [PATCH 048/262] move the cache api from OC_Files to filesystem(view) --- lib/files.php | 92 ------------------------- lib/files/cache/cache.php | 5 ++ lib/files/filesystem.php | 27 ++++++++ lib/files/view.php | 92 +++++++++++++++++++++++++ tests/lib/{files.php => files/view.php} | 23 ++++--- 5 files changed, 138 insertions(+), 101 deletions(-) rename tests/lib/{files.php => files/view.php} (86%) diff --git a/lib/files.php b/lib/files.php index 7ab7c89201..422e7f4ffe 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,98 +28,6 @@ class OC_Files { static $tmpFiles = array(); - /** - * get the filesystem info - * - * @param string $path - * @return array - * - * returns an associative array with the following keys: - * - size - * - mtime - * - mimetype - * - encrypted - * - versioned - */ - public static function getFileInfo($path) { - $path = \OC\Files\Filesystem::normalizePath($path); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $path - */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $cache = $storage->getCache(); - - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); - } - - $data = $cache->get($internalPath); - - if ($data['mimetype'] === 'httpd/unix-directory') { - //add the sizes of other mountpoints to the folder - $mountPoints = \OC\Files\Filesystem::getMountPoints($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; - } - } - - return $data; - } - - /** - * get the content of a directory - * - * @param string $directory path under datadirectory - * @return array - */ - public static function getDirectoryContent($directory, $mimetype_filter = '') { - $path = \OC\Files\Filesystem::normalizePath($directory); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $path - */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); - $cache = $storage->getCache(); - - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); - } - - $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - - //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); - $dirLength = strlen($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $relativePath = trim(substr($mountPoint, $dirLength), '/'); - if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder - $entryName = substr($relativePath, 0, $pos); - foreach ($files as &$entry) { - if ($entry['name'] === $entryName) { - $entry['size'] += $rootEntry['size']; - } - } - } else { //mountpoint in this folder, add an entry for it - $rootEntry['name'] = $relativePath; - $files[] = $rootEntry; - } - } - - usort($files, "fileCmp"); //TODO: remove this once ajax is merged - return $files; - } - public static function searchByMime($mimetype_filter) { $files = array(); $dirs_to_check = array(''); diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5ef49246ea..9b55666f95 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -8,6 +8,11 @@ namespace OC\Files\Cache; +/** + * Metadata cache for the filesystem + * + * don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead + */ class Cache { const NOT_FOUND = 0; const PARTIAL = 1; //only partial data available, file not cached in the database diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b7f8483fbf..d735cf8626 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -609,6 +609,33 @@ class Filesystem { } return $path; } + + /** + * get the filesystem info + * + * @param string $path + * @return array + * + * returns an associative array with the following keys: + * - size + * - mtime + * - mimetype + * - encrypted + * - versioned + */ + public static function getFileInfo($path) { + return self::$defaultInstance->getFileInfo($path); + } + + /** + * get the content of a directory + * + * @param string $directory path under datadirectory + * @return array + */ + public static function getDirectoryContent($directory, $mimetype_filter = '') { + return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); + } } \OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); diff --git a/lib/files/view.php b/lib/files/view.php index 18d9193035..aaca1618ac 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -645,4 +645,96 @@ class View { public function hasUpdated($path, $time) { return $this->basicOperation('hasUpdated', $path, array(), $time); } + + /** + * get the filesystem info + * + * @param string $path + * @return array + * + * returns an associative array with the following keys: + * - size + * - mtime + * - mimetype + * - encrypted + * - versioned + */ + public function getFileInfo($path) { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + $data = $cache->get($internalPath); + + if ($data['mimetype'] === 'httpd/unix-directory') { + //add the sizes of other mountpoints to the folder + $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; + } + } + + return $data; + } + + /** + * get the content of a directory + * + * @param string $directory path under datadirectory + * @return array + */ + public function getDirectoryContent($directory, $mimetype_filter = '') { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $path + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter + + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders + $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $dirLength = strlen($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $relativePath = trim(substr($mountPoint, $dirLength), '/'); + if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder + $entryName = substr($relativePath, 0, $pos); + foreach ($files as &$entry) { + if ($entry['name'] === $entryName) { + $entry['size'] += $rootEntry['size']; + } + } + } else { //mountpoint in this folder, add an entry for it + $rootEntry['name'] = $relativePath; + $files[] = $rootEntry; + } + } + + usort($files, "fileCmp"); //TODO: remove this once ajax is merged + return $files; + } } diff --git a/tests/lib/files.php b/tests/lib/files/view.php similarity index 86% rename from tests/lib/files.php rename to tests/lib/files/view.php index d978ac3fd1..6e7608f596 100644 --- a/tests/lib/files.php +++ b/tests/lib/files/view.php @@ -5,9 +5,11 @@ * later. * See the COPYING-README file. */ +namespace Test\Files; + use \OC\Files\Filesystem as Filesystem; -class Test_Files extends PHPUnit_Framework_TestCase { +class View extends \PHPUnit_Framework_TestCase { /** * @var \OC\Files\Storage\Storage[] $storages; */ @@ -35,19 +37,21 @@ class Test_Files extends PHPUnit_Framework_TestCase { $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); $storageSize = $textSize * 2 + $imageSize; - $cachedData = OC_Files::getFileInfo('/foo.txt'); + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertEquals($textSize, $cachedData['size']); $this->assertEquals('text/plain', $cachedData['mimetype']); - $cachedData = OC_Files::getFileInfo('/'); + $cachedData = $rootView->getFileInfo('/'); $this->assertEquals($storageSize * 3, $cachedData['size']); $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); - $cachedData = OC_Files::getFileInfo('/folder'); + $cachedData = $rootView->getFileInfo('/folder'); $this->assertEquals($storageSize + $textSize, $cachedData['size']); $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); - $folderData = OC_Files::getDirectoryContent('/'); + $folderData = $rootView->getDirectoryContent('/'); /** * expected entries: * folder @@ -74,20 +78,21 @@ class Test_Files extends PHPUnit_Framework_TestCase { Filesystem::mount($storage2, array(), '/substorage'); $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $storageSize = $textSize * 2 + $imageSize; - $cachedData = \OC_Files::getFileInfo('/'); + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('/'); $this->assertEquals('httpd/unix-directory', $cachedData['mimetype']); $this->assertEquals(-1, $cachedData['size']); - $folderData = \OC_Files::getDirectoryContent('/substorage/folder'); + $folderData = $rootView->getDirectoryContent('/substorage/folder'); $this->assertEquals('text/plain', $folderData[0]['mimetype']); $this->assertEquals($textSize, $folderData[0]['size']); } /** * @param bool $scan - * @return OC\Files\Storage\Storage + * @return \OC\Files\Storage\Storage */ private function getTestStorage($scan = true) { $storage = new \OC\Files\Storage\Temporary(array()); From e63e246c4894aa7f72feb550d98747890838af0b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:37:49 +0200 Subject: [PATCH 049/262] fix problem with normalizePath when there was a double leading slash --- lib/files/filesystem.php | 8 ++++---- tests/lib/files/view.php | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d735cf8626..2b51131b20 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -595,14 +595,14 @@ class Filesystem { if ($path[0] !== '/') { $path = '/' . $path; } -//remove trailing slash - if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { - $path = substr($path, 0, -1); - } //remove duplicate slashes while (strpos($path, '//') !== false) { $path = str_replace('//', '/', $path); } +//remove trailing slash + if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') { + $path = substr($path, 0, -1); + } //normalize unicode if possible if (class_exists('Normalizer')) { $path = \Normalizer::normalize($path); diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 6e7608f596..adbed5a18b 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -69,6 +69,9 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($imageSize, $folderData[1]['size']); $this->assertEquals($textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); + + $folderView = new \OC\Files\View('/folder'); + $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); } public function testAutoScan() { From 7ef0ffe8ad8f95b023f95f80e7b91c2a3ee50c67 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 12:43:23 +0200 Subject: [PATCH 050/262] add View->putFileInfo to the filecache api --- lib/files/view.php | 30 ++++++++++++++++++++++++++++-- tests/lib/files/view.php | 7 +++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index aaca1618ac..094a7d92a4 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -663,7 +663,7 @@ class View { $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage - * @var string $path + * @var string $internalPath */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $cache = $storage->getCache(); @@ -700,7 +700,7 @@ class View { $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage - * @var string $path + * @var string $internalPath */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $cache = $storage->getCache(); @@ -737,4 +737,30 @@ class View { usort($files, "fileCmp"); //TODO: remove this once ajax is merged return $files; } + + /** + * change file metadata + * + * @param string $path + * @param array $data + * @return int + * + * returns the fileid of the updated file + */ + public function putFileInfo($path, $data) { + $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $cache = $storage->getCache(); + + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + } + + return $cache->put($internalPath, $data); + } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index adbed5a18b..051ae25162 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -72,6 +72,13 @@ class View extends \PHPUnit_Framework_TestCase { $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); + + $cachedData = $rootView->getFileInfo('/foo.txt'); + $this->assertFalse($cachedData['encrypted']); + $id = $rootView->putFileInfo('/foo.txt', array('encrypted' => true)); + $cachedData = $rootView->getFileInfo('/foo.txt'); + $this->assertTrue($cachedData['encrypted']); + $this->assertEquals($cachedData['fileid'], $id); } public function testAutoScan() { From 8bce661e4ddedb611d5873c578203dfda631ce7e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 13:23:15 +0200 Subject: [PATCH 051/262] add search to the filecache api --- lib/files/cache/cache.php | 21 ++++++++- lib/files/filesystem.php | 2 +- lib/files/view.php | 84 ++++++++++++++++++++++++--------- tests/lib/files/cache/cache.php | 20 ++++++++ tests/lib/files/view.php | 45 +++++++++++++++++- 5 files changed, 146 insertions(+), 26 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9b55666f95..7e0c5cb21f 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -251,7 +251,7 @@ class Cache { */ public function getStatus($file) { $pathHash = md5($file); - $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); + $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); $result = $query->execute(array($this->storageId, $pathHash)); if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { @@ -267,4 +267,23 @@ class Cache { } } } + + /** + * search for files matching $pattern + * + * @param string $pattern + * @return array of file data + */ + public function search($pattern) { + $query = \OC_DB::prepare(' + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' + ); + $result = $query->execute(array($pattern, $this->storageId)); + $files = array(); + while ($row = $result->fetchRow()) { + $files[] = $row; + } + return $files; + } } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 2b51131b20..4031c0c5b8 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -548,7 +548,7 @@ class Filesystem { } static public function search($query) { - return Cache\Cache::search($query); + return self::$defaultInstance->search($query); } /** diff --git a/lib/files/view.php b/lib/files/view.php index 094a7d92a4..ee95cce0c1 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,7 +110,7 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); } else { @@ -124,7 +124,7 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFolder($internalPath); } else { @@ -150,7 +150,7 @@ class View { } public function readdir($handle) { - $fsLocal = new \OC\Files\Storage\Local(array('datadir' => '/')); + $fsLocal = new Storage\Local(array('datadir' => '/')); return $fsLocal->readdir($handle); } @@ -334,8 +334,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -345,7 +345,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -417,8 +417,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = \OC\Files\Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = \OC\Files\Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -553,7 +553,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -588,7 +588,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); @@ -660,26 +660,26 @@ class View { * - versioned */ public function getFileInfo($path) { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } $data = $cache->get($internalPath); if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder - $mountPoints = \OC\Files\Filesystem::getMountPoints($path); + $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subStorage = Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -697,26 +697,26 @@ class View { * @return array */ public function getDirectoryContent($directory, $mimetype_filter = '') { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $directory); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = \OC\Files\Filesystem::getMountPoints($directory); + $mountPoints = Filesystem::getMountPoints($directory); $dirLength = strlen($path); foreach ($mountPoints as $mountPoint) { - $subStorage = \OC\Files\Filesystem::getStorage($mountPoint); + $subStorage = Filesystem::getStorage($mountPoint); $subCache = $subStorage->getCache(); $rootEntry = $subCache->get(''); @@ -748,19 +748,57 @@ class View { * returns the fileid of the updated file */ public function putFileInfo($path, $data) { - $path = \OC\Files\Filesystem::normalizePath($this->fakeRoot . '/' . $path); + $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + list($storage, $internalPath) = Filesystem::resolvePath($path); $cache = $storage->getCache(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); - $scanner->scan($internalPath, \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } return $cache->put($internalPath, $data); } + + /** + * search for files with the name matching $query + * + * @param string $query + * @return array + */ + public function search($query) { + $files = array(); + $rootLength = strlen($this->fakeRoot); + + $mountPoint = Filesystem::getMountPoint($this->fakeRoot); + $storage = Filesystem::getStorage($mountPoint); + $cache = $storage->getCache(); + + $results = $cache->search('%' . $query . '%'); + foreach ($results as $result) { + if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) { + $result['path'] = substr($mountPoint . $result['path'], $rootLength); + $files[] = $result; + } + } + + $mountPoints = Filesystem::getMountPoints($this->fakeRoot); + foreach ($mountPoints as $mountPoint) { + $storage = Filesystem::getStorage($mountPoint); + $cache = $storage->getCache(); + + $relativeMountPoint = substr($mountPoint, $rootLength); + $results = $cache->search('%' . $query . '%'); + foreach ($results as $result) { + $result['path'] = $relativeMountPoint . $result['path']; + $files[] = $result; + } + } + + return $files; + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 177cf1c045..839e06e93f 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -111,6 +111,26 @@ class Cache extends \UnitTestCase { $this->assertEquals(\OC\Files\Cache\Cache::COMPLETE, $this->cache->getStatus('foo')); } + function testSearch() { + $file1 = 'folder'; + $file2 = 'folder/foobar'; + $file3 = 'folder/foo'; + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $fileData = array(); + $fileData['foobar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); + $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); + + $this->cache->put($file1, $data1); + $this->cache->put($file2, $fileData['foobar']); + $this->cache->put($file3, $fileData['foo']); + + $this->assertEquals(2, count($this->cache->search('%foo%'))); + $this->assertEquals(1, count($this->cache->search('foo'))); + $this->assertEquals(1, count($this->cache->search('%folder%'))); + $this->assertEquals(1, count($this->cache->search('folder%'))); + $this->assertEquals(3, count($this->cache->search('%'))); + } + public function tearDown() { $this->cache->clear(); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 051ae25162..fc872ea5e2 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -87,7 +87,6 @@ class View extends \PHPUnit_Framework_TestCase { Filesystem::mount($storage1, array(), '/'); Filesystem::mount($storage2, array(), '/substorage'); $textSize = strlen("dummy file data\n"); - $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); $rootView = new \OC\Files\View(''); @@ -100,6 +99,50 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($textSize, $folderData[0]['size']); } + function testSearch() { + $storage1 = $this->getTestStorage(); + $storage2 = $this->getTestStorage(); + $storage3 = $this->getTestStorage(); + Filesystem::mount($storage1, array(), '/'); + Filesystem::mount($storage2, array(), '/substorage'); + Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + + $rootView = new \OC\Files\View(''); + + $results = $rootView->search('foo'); + $this->assertEquals(6, count($results)); + $paths = array(); + foreach ($results as $result) { + $this->assertEquals($result['path'], Filesystem::normalizePath($result['path'])); + $paths[] = $result['path']; + } + $this->assertContains('/foo.txt', $paths); + $this->assertContains('/foo.png', $paths); + $this->assertContains('/substorage/foo.txt', $paths); + $this->assertContains('/substorage/foo.png', $paths); + $this->assertContains('/folder/anotherstorage/foo.txt', $paths); + $this->assertContains('/folder/anotherstorage/foo.png', $paths); + + $folderView = new \OC\Files\View('/folder'); + $results = $folderView->search('bar'); + $this->assertEquals(2, count($results)); + $paths = array(); + foreach ($results as $result) { + $paths[] = $result['path']; + } + $this->assertContains('/anotherstorage/folder/bar.txt', $paths); + $this->assertContains('/bar.txt', $paths); + + $results = $folderView->search('foo'); + $this->assertEquals(2, count($results)); + $paths = array(); + foreach ($results as $result) { + $paths[] = $result['path']; + } + $this->assertContains('/anotherstorage/foo.txt', $paths); + $this->assertContains('/anotherstorage/foo.png', $paths); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage From 7ad8bf3156a794e47ee223efd2e1cf9191cc8a97 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 18:07:01 +0200 Subject: [PATCH 052/262] move filesystem test case --- tests/lib/files/filesystem.php | 110 +++++++++++++++++++++++++++++++++ tests/lib/files/view.php | 22 +++---- tests/lib/filesystem.php | 110 --------------------------------- 3 files changed, 120 insertions(+), 122 deletions(-) create mode 100644 tests/lib/files/filesystem.php delete mode 100644 tests/lib/filesystem.php diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php new file mode 100644 index 0000000000..363426511b --- /dev/null +++ b/tests/lib/files/filesystem.php @@ -0,0 +1,110 @@ +. + * + */ + +namespace Test\Files; + +class Filesystem extends \PHPUnit_Framework_TestCase { + /** + * @var array tmpDirs + */ + private $tmpDirs=array(); + + /** + * @return array + */ + private function getStorageData() { + $dir = \OC_Helper::tmpFolder(); + $this->tmpDirs[] = $dir; + return array('datadir' => $dir); + } + + public function tearDown() { + foreach ($this->tmpDirs as $dir) { + \OC_Helper::rmdirr($dir); + } + } + + public function setUp() { + \OC\Files\Filesystem::clearMounts(); + } + + public function testMount() { + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); + $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/')); + $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/some/folder')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/'); + $this->assertEquals('',$internalPath); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEquals('some/folder',$internalPath); + + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); + $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/')); + $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/folder')); + $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/')); + $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/some')); + list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); + $this->assertEquals('folder',$internalPath); + } + + public function testNormalize() { + $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('/path/')); + $this->assertEquals('/path/', \OC\Files\Filesystem::normalizePath('/path/', false)); + $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('path')); + $this->assertEquals('/path', \OC\Files\Filesystem::normalizePath('\path')); + $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo//bar/')); + $this->assertEquals('/foo/bar', \OC\Files\Filesystem::normalizePath('/foo////bar')); + if (class_exists('Normalizer')) { + $this->assertEquals("/foo/bar\xC3\xBC", \OC\Files\Filesystem::normalizePath("/foo/baru\xCC\x88")); + } + } + + public function testHooks() { + if(\OC\Files\Filesystem::getView()){ + $user = \OC_User::getUser(); + }else{ + $user=uniqid(); + \OC\Files\Filesystem::init('/'.$user.'/files'); + } + \OC_Hook::clear('OC_Filesystem'); + \OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook'); + + \OC\Files\Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); + + $rootView=new \OC\Files\View(''); + $rootView->mkdir('/'.$user); + $rootView->mkdir('/'.$user.'/files'); + + \OC\Files\Filesystem::file_put_contents('/foo', 'foo'); + \OC\Files\Filesystem::mkdir('/bar'); + \OC\Files\Filesystem::file_put_contents('/bar//foo', 'foo'); + + $tmpFile = \OC_Helper::tmpFile(); + file_put_contents($tmpFile, 'foo'); + $fh = fopen($tmpFile, 'r'); + \OC\Files\Filesystem::file_put_contents('/bar//foo', $fh); + } + + public function dummyHook($arguments) { + $path = $arguments['path']; + $this->assertEquals($path, \OC\Files\Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized + } +} diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index fc872ea5e2..980c5298fb 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -7,8 +7,6 @@ namespace Test\Files; -use \OC\Files\Filesystem as Filesystem; - class View extends \PHPUnit_Framework_TestCase { /** * @var \OC\Files\Storage\Storage[] $storages; @@ -16,7 +14,7 @@ class View extends \PHPUnit_Framework_TestCase { private $storages = array(); public function setUp() { - Filesystem::clearMounts(); + \OC\Files\Filesystem::clearMounts(); } public function tearDown() { @@ -30,9 +28,9 @@ class View extends \PHPUnit_Framework_TestCase { $storage1 = $this->getTestStorage(); $storage2 = $this->getTestStorage(); $storage3 = $this->getTestStorage(); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); - Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + \OC\Files\Filesystem::mount($storage3, array(), '/folder/anotherstorage'); $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); $storageSize = $textSize * 2 + $imageSize; @@ -84,8 +82,8 @@ class View extends \PHPUnit_Framework_TestCase { public function testAutoScan() { $storage1 = $this->getTestStorage(false); $storage2 = $this->getTestStorage(false); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); $textSize = strlen("dummy file data\n"); $rootView = new \OC\Files\View(''); @@ -103,9 +101,9 @@ class View extends \PHPUnit_Framework_TestCase { $storage1 = $this->getTestStorage(); $storage2 = $this->getTestStorage(); $storage3 = $this->getTestStorage(); - Filesystem::mount($storage1, array(), '/'); - Filesystem::mount($storage2, array(), '/substorage'); - Filesystem::mount($storage3, array(), '/folder/anotherstorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + \OC\Files\Filesystem::mount($storage3, array(), '/folder/anotherstorage'); $rootView = new \OC\Files\View(''); @@ -113,7 +111,7 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(6, count($results)); $paths = array(); foreach ($results as $result) { - $this->assertEquals($result['path'], Filesystem::normalizePath($result['path'])); + $this->assertEquals($result['path'], \OC\Files\Filesystem::normalizePath($result['path'])); $paths[] = $result['path']; } $this->assertContains('/foo.txt', $paths); diff --git a/tests/lib/filesystem.php b/tests/lib/filesystem.php deleted file mode 100644 index 6e7b4fb781..0000000000 --- a/tests/lib/filesystem.php +++ /dev/null @@ -1,110 +0,0 @@ -. - * - */ - -use \OC\Files\Filesystem as Filesystem; - -class Test_Filesystem extends UnitTestCase { - /** - * @var array tmpDirs - */ - private $tmpDirs=array(); - - /** - * @return array - */ - private function getStorageData() { - $dir = OC_Helper::tmpFolder(); - $this->tmpDirs[] = $dir; - return array('datadir' => $dir); - } - - public function tearDown() { - foreach ($this->tmpDirs as $dir) { - OC_Helper::rmdirr($dir); - } - } - - public function setUp() { - Filesystem::clearMounts(); - } - - public function testMount() { - Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/'); - $this->assertEqual('/',Filesystem::getMountPoint('/')); - $this->assertEqual('/',Filesystem::getMountPoint('/some/folder')); - list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/'); - $this->assertEqual('',$internalPath); - list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); - $this->assertEqual('some/folder',$internalPath); - - Filesystem::mount('\OC\Files\Storage\Local',self::getStorageData(),'/some'); - $this->assertEqual('/',Filesystem::getMountPoint('/')); - $this->assertEqual('/some/',Filesystem::getMountPoint('/some/folder')); - $this->assertEqual('/some/',Filesystem::getMountPoint('/some/')); - $this->assertEqual('/',Filesystem::getMountPoint('/some')); - list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); - $this->assertEqual('folder',$internalPath); - } - - public function testNormalize() { - $this->assertEqual('/path', Filesystem::normalizePath('/path/')); - $this->assertEqual('/path/', Filesystem::normalizePath('/path/', false)); - $this->assertEqual('/path', Filesystem::normalizePath('path')); - $this->assertEqual('/path', Filesystem::normalizePath('\path')); - $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo//bar/')); - $this->assertEqual('/foo/bar', Filesystem::normalizePath('/foo////bar')); - if (class_exists('Normalizer')) { - $this->assertEqual("/foo/bar\xC3\xBC", Filesystem::normalizePath("/foo/baru\xCC\x88")); - } - } - - public function testHooks() { - if(Filesystem::getView()){ - $user = OC_User::getUser(); - }else{ - $user=uniqid(); - Filesystem::init('/'.$user.'/files'); - } - OC_Hook::clear('OC_Filesystem'); - OC_Hook::connect('OC_Filesystem', 'post_write', $this, 'dummyHook'); - - Filesystem::mount('OC\Files\Storage\Temporary', array(), '/'); - - $rootView=new \OC\Files\View(''); - $rootView->mkdir('/'.$user); - $rootView->mkdir('/'.$user.'/files'); - - Filesystem::file_put_contents('/foo', 'foo'); - Filesystem::mkdir('/bar'); - Filesystem::file_put_contents('/bar//foo', 'foo'); - - $tmpFile = OC_Helper::tmpFile(); - file_put_contents($tmpFile, 'foo'); - $fh = fopen($tmpFile, 'r'); - Filesystem::file_put_contents('/bar//foo', $fh); - } - - public function dummyHook($arguments) { - $path = $arguments['path']; - $this->assertEqual($path, Filesystem::normalizePath($path)); //the path passed to the hook should already be normalized - } -} From c22a723785f80671548b89c543e9163c2fff9264 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 19:07:29 +0200 Subject: [PATCH 053/262] add file permissions cache --- db_structure.xml | 47 +++++++++++++++ lib/files/cache/permissions.php | 85 +++++++++++++++++++++++++++ lib/util.php | 2 +- tests/lib/files/cache/permissions.php | 47 +++++++++++++++ 4 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 lib/files/cache/permissions.php create mode 100644 tests/lib/files/cache/permissions.php diff --git a/db_structure.xml b/db_structure.xml index e0b9dc11e9..e420a9f0e4 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -175,6 +175,53 @@
+ + + *dbprefix*permissions + + + + + fileid + integer + 0 + true + 4 + + + + user + text + + true + 64 + + + + permissions + integer + 0 + true + 4 + + + + id_user_index + true + + fileid + ascending + + + user + ascending + + + + + +
+ *dbprefix*group_user diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php new file mode 100644 index 0000000000..e3fa63c464 --- /dev/null +++ b/lib/files/cache/permissions.php @@ -0,0 +1,85 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +class Permissions { + /** + * get the permissions for a single file + * + * @param int $fileId + * @param string $user + * @return int (-1 if file no permissions set) + */ + static public function get($fileId, $user) { + $query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'); + $result = $query->execute(array($user, $fileId)); + if ($row = $result->fetchRow()) { + return $row['permissions']; + } else { + return -1; + } + } + + /** + * set the permissions of a file + * + * @param int $fileId + * @param string $user + * @param int $permissions + */ + static public function set($fileId, $user, $permissions) { + if (self::get($fileId, $user) !== -1) { + $query = \OC_DB::prepare('UPDATE `*PREFIX*permissions` SET `permissions` = ? WHERE `user` = ? AND `fileid` = ?'); + } else { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*permissions`(`permissions`, `user`, `fileid`) VALUES(?, ?,? )'); + } + $query->execute(array($permissions, $user, $fileId)); + } + + /** + * get the permissions of multiply files + * + * @param int[] $fileIds + * @param string $user + * @return int[] + */ + static public function getMultiple($fileIds, $user) { + $params = $fileIds; + $params[] = $user; + $inPart = implode(', ', array_fill(0, count($fileIds), '?')); + + $query = \OC_DB::prepare('SELECT `fileid`, `permissions` FROM `*PREFIX*permissions` WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); + $result = $query->execute($params); + $filePermissions = array(); + while ($row = $result->fetchRow()) { + $filePermissions[$row['fileid']] = $row['permissions']; + } + return $filePermissions; + } + + /** + * remove the permissions for a file + * + * @param int $fileId + * @param string $user + */ + static public function remove($fileId, $user) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); + $query->execute(array($fileId, $user)); + } + + static public function removeMultiple($fileIds, $user) { + $params = $fileIds; + $params[] = $user; + $inPart = implode(', ', array_fill(0, count($fileIds), '?')); + + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); + $query->execute($params); + } +} diff --git a/lib/util.php b/lib/util.php index 137766d012..a2e0422c97 100755 --- a/lib/util.php +++ b/lib/util.php @@ -86,7 +86,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,00); + return array(4,91,01); } /** diff --git a/tests/lib/files/cache/permissions.php b/tests/lib/files/cache/permissions.php new file mode 100644 index 0000000000..4d47929a3e --- /dev/null +++ b/tests/lib/files/cache/permissions.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Permissions extends \PHPUnit_Framework_TestCase { + function testSimple() { + $ids = range(1, 10); + $user = uniqid(); + + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); + \OC\Files\Cache\Permissions::set(1, $user, 1); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(1, $user)); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user . '2')); + + \OC\Files\Cache\Permissions::set(1, $user, 2); + $this->assertEquals(2, \OC\Files\Cache\Permissions::get(1, $user)); + + \OC\Files\Cache\Permissions::set(2, $user, 1); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + + \OC\Files\Cache\Permissions::remove(1, $user); + $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); + \OC\Files\Cache\Permissions::remove(1, $user . '2'); + $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + + $expected = array(); + foreach ($ids as $id) { + \OC\Files\Cache\Permissions::set($id, $user, 10 + $id); + $expected[$id] = 10 + $id; + } + $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + + \OC\Files\Cache\Permissions::removeMultiple(array(10, 9), $user); + unset($expected[9]); + unset($expected[10]); + $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + + \OC\Files\Cache\Permissions::removeMultiple($ids, $user); + } +} From 6db81afab9d68ccd50c1e164622252e47ae76c2f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 23:05:02 +0200 Subject: [PATCH 054/262] move some stuff to the new api --- apps/files/ajax/list.php | 2 +- apps/files/ajax/newfile.php | 12 ++++++------ apps/files/ajax/newfolder.php | 3 ++- apps/files/ajax/rawlist.php | 2 +- apps/files/ajax/upload.php | 2 +- apps/files/index.php | 2 +- apps/files/settings.php | 2 +- apps/files_encryption/lib/cryptstream.php | 2 +- apps/files_encryption/lib/proxy.php | 10 +++++----- apps/files_sharing/appinfo/update.php | 3 ++- lib/connector/sabre/directory.php | 6 +++--- lib/connector/sabre/node.php | 4 ++-- lib/fileproxy/quota.php | 12 ++++-------- lib/files.php | 2 +- lib/files/filesystem.php | 13 +++++++++++++ lib/files/view.php | 1 - lib/ocs.php | 4 ++-- lib/public/share.php | 15 +++++++++------ lib/search/provider/file.php | 2 +- settings/personal.php | 4 ++-- 20 files changed, 58 insertions(+), 45 deletions(-) diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php index 568fe754c0..92091f4213 100644 --- a/apps/files/ajax/list.php +++ b/apps/files/ajax/list.php @@ -32,7 +32,7 @@ if($doBreadcrumb) { // make filelist $files = array(); -foreach( OC_Files::getdirectorycontent( $dir ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i["date"] = OCP\Util::formatDate($i["mtime"] ); $files[] = $i; } diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index 5f3f3d88f2..38714f34a6 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -65,9 +65,9 @@ if($source) { $target=$dir.'/'.$filename; $result=\OC\Files\Filesystem::file_put_contents($target, $sourceStream); if($result) { - $meta = OC_FileCache::get($target); + $meta = \OC\Files\Filesystem::getFileInfo($target); $mime=$meta['mimetype']; - $id = OC_FileCache::getId($target); + $id = $meta['fileid']; $eventSource->send('success', array('mime'=>$mime, 'size'=>\OC\Files\Filesystem::filesize($target), 'id' => $id)); } else { $eventSource->send('error', "Error while downloading ".$source. ' to '.$target); @@ -77,14 +77,14 @@ if($source) { } else { if($content) { if(\OC\Files\Filesystem::file_put_contents($dir.'/'.$filename, $content)) { - $meta = OC_FileCache::get($dir.'/'.$filename); - $id = OC_FileCache::getId($dir.'/'.$filename); + $meta = \OC\Files\Filesystem::getFileInfo($dir.'/'.$filename); + $id = $meta['fileid']; OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); exit(); } }elseif(\OC\Files\Filesystem::touch($dir . '/' . $filename)) { - $meta = OC_FileCache::get($dir.'/'.$filename); - $id = OC_FileCache::getId($dir.'/'.$filename); + $meta = \OC\Files\Filesystem::getFileInfo($dir.'/'.$filename); + $id = $meta['fileid']; OCP\JSON::success(array("data" => array('content'=>$content, 'id' => $id))); exit(); } diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index c36c208455..e26e1238bc 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -25,7 +25,8 @@ if(\OC\Files\Filesystem::mkdir($dir . '/' . stripslashes($foldername))) { } else { $path = '/'.$foldername; } - $id = OC_FileCache::getId($path); + $meta = \OC\Files\Filesystem::getFileInfo($path); + $id = $meta['fileid']; OCP\JSON::success(array("data" => array('id'=>$id))); exit(); } diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php index e0aa0bdac5..1cd2944483 100644 --- a/apps/files/ajax/rawlist.php +++ b/apps/files/ajax/rawlist.php @@ -15,7 +15,7 @@ $mimetype = isset($_GET['mimetype']) ? $_GET['mimetype'] : ''; // make filelist $files = array(); -foreach( OC_Files::getdirectorycontent( $dir, $mimetype ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir, $mimetype ) as $i ) { $i["date"] = OCP\Util::formatDate($i["mtime"] ); $i['mimetype_icon'] = $i['type'] == 'dir' ? \mimetype_icon('dir'): \mimetype_icon($i['mimetype']); $files[] = $i; diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index b6b8c7f7b4..2a784d6169 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -49,7 +49,7 @@ if(strpos($dir, '..') === false) { for($i=0;$i<$fileCount;$i++) { $target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]); if(is_uploaded_file($files['tmp_name'][$i]) and \OC\Files\Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) { - $meta = \OC_Files::getFileInfo($target); + $meta = \OC\Files\Filesystem::getFileInfo($target); $id = $meta['fileid']; $result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'], 'id'=>$id, 'name'=>basename($target)); } diff --git a/apps/files/index.php b/apps/files/index.php index 192cd2696f..4676ebc602 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -44,7 +44,7 @@ if(!\OC\Files\Filesystem::is_dir($dir.'/')) { } $files = array(); -foreach( OC_Files::getdirectorycontent( $dir ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i['date'] = OCP\Util::formatDate($i['mtime'] ); if($i['type']=='file') { $fileinfo=pathinfo($i['name']); diff --git a/apps/files/settings.php b/apps/files/settings.php index 52ec9fd0fe..30463210f7 100644 --- a/apps/files/settings.php +++ b/apps/files/settings.php @@ -36,7 +36,7 @@ OCP\Util::addscript( "files", "files" ); $dir = isset( $_GET['dir'] ) ? $_GET['dir'] : ''; $files = array(); -foreach( OC_Files::getdirectorycontent( $dir ) as $i ) { +foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i["date"] = date( $CONFIG_DATEFORMAT, $i["mtime"] ); $files[] = $i; } diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index e98013e1f4..c429838264 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -167,7 +167,7 @@ class OC_CryptStream{ public function stream_close() { $this->flush(); if($this->meta['mode']!='r' and $this->meta['mode']!='rb') { - OC_FileCache::put($this->path, array('encrypted'=>true,'size'=>$this->size),''); + \OC\Files\Filesystem::putFileInfo($this->path, array('encrypted'=>true,'size'=>$this->size),''); } return fclose($this->source); } diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index 7b7bafe73e..49fb30ac29 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -59,7 +59,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ * @return bool */ private static function isEncrypted($path) { - $metadata=OC_FileCache_Cached::get($path,''); + $metadata=\OC\Files\Filesystem::getFileInfo($path,''); return isset($metadata['encrypted']) and (bool)$metadata['encrypted']; } @@ -68,14 +68,14 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ if (!is_resource($data)) {//stream put contents should have been converter to fopen $size=strlen($data); $data=OC_Crypt::blockEncrypt($data); - OC_FileCache::put($path, array('encrypted'=>true,'size'=>$size),''); + \OC\Files\Filesystem::putFileInfo($path, array('encrypted'=>true,'size'=>$size),''); } } } public function postFile_get_contents($path,$data) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); $data=OC_Crypt::blockDecrypt($data,'',$cached['size']); } return $data; @@ -113,7 +113,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ public function postStat($path,$data) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); $data['size']=$cached['size']; } return $data; @@ -121,7 +121,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ public function postFileSize($path,$size) { if(self::isEncrypted($path)) { - $cached=OC_FileCache_Cached::get($path,''); + $cached=\OC\Files\Filesystem::getFileInfo($path,''); return $cached['size']; }else{ return $size; diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index e75c538b15..51048bd178 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -10,6 +10,7 @@ if (version_compare($installedVersion, '0.3', '<')) { OC_Group::useBackend(new OC_Group_Database()); OC_App::loadApps(array('authentication')); while ($row = $result->fetchRow()) { + $meta = \OC\Files\Filesystem::getId($path, ''); $itemSource = OC_FileCache::getId($row['source'], ''); if ($itemSource != -1) { $file = OC_FileCache::get($row['source'], ''); @@ -70,4 +71,4 @@ if (version_compare($installedVersion, '0.3.3', '<')) { foreach ($users as $user) { OC_FileCache::delete('Shared', '/'.$user.'/files/'); } -} \ No newline at end of file +} diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 3df85b2bbb..d4f58527d2 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -93,7 +93,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $path = $this->path . '/' . $name; if (is_null($info)) { - $info = OC_Files::getFileInfo($path); + $info = \OC\Files\Filesystem::getFileInfo($path); } if (!$info) { @@ -117,7 +117,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa */ public function getChildren() { - $folder_content = OC_Files::getDirectoryContent($this->path); + $folder_content = \OC\Files\Filesystem::getDirectoryContent($this->path); $paths = array(); foreach($folder_content as $info) { $paths[] = $this->path.'/'.$info['name']; @@ -178,7 +178,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * @return array */ public function getQuotaInfo() { - $rootInfo=OC_FileCache_Cached::get(''); + $rootInfo=\OC\Files\Filesystem::getFileInfo(''); return array( $rootInfo['size'], \OC\Files\Filesystem::free_space() diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index e7e83507ea..2095c956e5 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -95,11 +95,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } /** - * Make sure the fileinfo cache is filled. Uses OC_FileCache or a direct stat + * Make sure the fileinfo cache is filled. Uses the file cache or a direct stat */ protected function getFileinfoCache() { if (!isset($this->fileinfo_cache)) { - if ($fileinfo_cache = \OC\Files\Filesystem::get($this->path)) { + if ($fileinfo_cache = \OC\Files\Filesystem::getFileInfo($this->path)) { } else { $fileinfo_cache = \OC\Files\Filesystem::stat($this->path); } diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index d120f30999..cd9a2f4a19 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -57,7 +57,7 @@ class OC_FileProxy_Quota extends OC_FileProxy{ * @return int */ private function getFreeSpace($path) { - $storage=OC_Filesystem::getStorage($path); + list($storage,)=\OC\Files\Filesystem::resolvePath($path); $owner=$storage->getOwner($path); $totalSpace=$this->getQuota($owner); @@ -65,13 +65,9 @@ class OC_FileProxy_Quota extends OC_FileProxy{ return 0; } - $rootInfo=OC_FileCache::get('', "/".$owner."/files"); - // TODO Remove after merge of share_api - if (OC_FileCache::inCache('/Shared', "/".$owner."/files")) { - $sharedInfo=OC_FileCache::get('/Shared', "/".$owner."/files"); - } else { - $sharedInfo = null; - } + $view = new \OC\Files\View("/".$owner."/files"); + + $rootInfo=$view->getFileInfo('/'); $usedSpace=isset($rootInfo['size'])?$rootInfo['size']:0; $usedSpace=isset($sharedInfo['size'])?$usedSpace-$sharedInfo['size']:$usedSpace; return $totalSpace-$usedSpace; diff --git a/lib/files.php b/lib/files.php index 422e7f4ffe..6a063f216d 100644 --- a/lib/files.php +++ b/lib/files.php @@ -146,7 +146,7 @@ class OC_Files { $dirname = basename($dir); $zip->addEmptyDir($internalDir . $dirname); $internalDir .= $dirname .= '/'; - $files = OC_Files::getdirectorycontent($dir); + $files = \OC\Files\Filesystem::getDirectoryContent($dir); foreach ($files as $file) { $filename = $file['name']; $file = $dir . '/' . $filename; diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 4031c0c5b8..b3c92f3855 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -627,6 +627,19 @@ class Filesystem { return self::$defaultInstance->getFileInfo($path); } + /** + * change file metadata + * + * @param string $path + * @param array $data + * @return int + * + * returns the fileid of the updated file + */ + public static function putFileInfo($path, $data) { + return self::$defaultInstance->putFileInfo($path, $data); + } + /** * get the content of a directory * diff --git a/lib/files/view.php b/lib/files/view.php index ee95cce0c1..e9b583f8ae 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -451,7 +451,6 @@ class View { array(Filesystem::signal_param_path => $path2) ); } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions -// OC_FileCache_Update::update($path2, $this->fakeRoot); Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; diff --git a/lib/ocs.php b/lib/ocs.php index 645380ddba..c6bcd2c06e 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -590,8 +590,8 @@ class OC_OCS { // calculate the disc space $user_dir = '/'.$user.'/files'; \OC\Files\Filesystem::init($user_dir); - $rootInfo=OC_FileCache::get(''); - $sharedInfo=OC_FileCache::get('/Shared'); + $rootInfo=\OC\Files\Filesystem::getFileInfo(''); + $sharedInfo=\OC\Files\Filesystem::getFileInfo('/Shared'); $used=$rootInfo['size']-$sharedInfo['size']; $free=\OC\Files\Filesystem::free_space(); $total=$free+$used; diff --git a/lib/public/share.php b/lib/public/share.php index 7a9a087d1b..dd6c841c99 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -285,10 +285,10 @@ class Share { // If the item is a folder, scan through the folder looking for equivalent item types if ($itemType == 'folder') { $parentFolder = self::put('folder', $itemSource, $shareType, $shareWith, $uidOwner, $permissions, true); - if ($parentFolder && $files = \OC_Files::getDirectoryContent($itemSource)) { + if ($parentFolder && $files = \OC\Files\Filesystem::getDirectoryContent($itemSource)) { for ($i = 0; $i < count($files); $i++) { $name = substr($files[$i]['name'], strpos($files[$i]['name'], $itemSource) - strlen($itemSource)); - if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = \OC_Files::getDirectoryContent($name, '/')) { + if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = \OC\Files\Filesystem::getDirectoryContent($name, '/')) { // Continue scanning into child folders array_push($files, $children); } else { @@ -768,9 +768,10 @@ class Share { if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { $childItem['file_source'] = $child['source']; } else { - $childItem['file_source'] = \OC_FileCache::getId($child['file_path']); + $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']); + $childItem['file_source'] = $meta['fileid']; } - $childItem['file_target'] = \OC_Filesystem::normalizePath($child['file_path']); + $childItem['file_target'] = \OC\Files\Filesystem::normalizePath($child['file_path']); } if (isset($item)) { if ($childItem[$column] == $item) { @@ -881,7 +882,8 @@ class Share { if ($itemType == 'file' || $itemType == 'folder') { $fileSource = $itemSource; } else { - $fileSource = \OC_FileCache::getId($filePath); + $meta = \OC\Files\Filesystem::getFileInfo($filePath); + $fileSource = $meta['fileid']; } if ($fileSource == -1) { $message = 'Sharing '.$itemSource.' failed, because the file could not be found in the file cache'; @@ -1063,7 +1065,8 @@ class Share { } if ($item['uid_owner'] == $uidOwner) { if ($itemType == 'file' || $itemType == 'folder') { - if ($item['file_source'] == \OC_FileCache::getId($itemSource)) { + $meta = \OC\Files\Filesystem::getFileInfo($itemSource); + if ($item['file_source'] == $meta['fileid']) { return $target; } } else if ($item['item_source'] == $itemSource) { diff --git a/lib/search/provider/file.php b/lib/search/provider/file.php index 0d4b332b79..456e12b5ec 100644 --- a/lib/search/provider/file.php +++ b/lib/search/provider/file.php @@ -2,7 +2,7 @@ class OC_Search_Provider_File extends OC_Search_Provider{ function search($query) { - $files=OC_FileCache::search($query, true); + $files=\OC\Files\Filesystem::search($query, true); $results=array(); $l=OC_L10N::get('lib'); foreach($files as $fileData) { diff --git a/settings/personal.php b/settings/personal.php index c73a3dd370..5a267ec284 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -16,8 +16,8 @@ OC_Util::addStyle( '3rdparty', 'chosen' ); OC_App::setActiveNavigationEntry( 'personal' ); // calculate the disc space -$rootInfo=OC_FileCache::get(''); -$sharedInfo=OC_FileCache::get('/Shared'); +$rootInfo=\OC\Files\Filesystem::getFileInfo(''); +$sharedInfo=\OC\Files\Filesystem::getFileInfo('/Shared'); $used=$rootInfo['size']; if($used<0) $used=0; $free=\OC\Files\Filesystem::free_space(); From 7d6da68d532fe1b1299f3a724e70b8ec3960ec8d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 23:25:52 +0200 Subject: [PATCH 055/262] prove some compatibility with the old cache api --- lib/files/view.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/files/view.php b/lib/files/view.php index e9b583f8ae..04b7dca8af 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -712,7 +712,7 @@ class View { $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = Filesystem::getMountPoints($directory); + $mountPoints = Filesystem::getMountPoints($path); $dirLength = strlen($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); @@ -733,6 +733,10 @@ class View { } } + foreach($files as $i => $file){ + $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + } + usort($files, "fileCmp"); //TODO: remove this once ajax is merged return $files; } From 99534271977ef5a4fd35ce119d6627bbcde45096 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 26 Oct 2012 23:26:12 +0200 Subject: [PATCH 056/262] also use new cache api here --- lib/fileproxy/fileoperations.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fileproxy/fileoperations.php b/lib/fileproxy/fileoperations.php index 23fb63fcfb..47ccd8f8c2 100644 --- a/lib/fileproxy/fileoperations.php +++ b/lib/fileproxy/fileoperations.php @@ -29,9 +29,9 @@ class OC_FileProxy_FileOperations extends OC_FileProxy{ public function premkdir($path) { if(!self::$rootView){ - self::$rootView = new OC_FilesystemView(''); + self::$rootView = new \OC\Files\View(''); } return !self::$rootView->file_exists($path); } -} \ No newline at end of file +} From 695405dfeb4da3733df1b1be239a97100f2ce66f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 10:01:20 +0200 Subject: [PATCH 057/262] add permissions data to the results of the cache api --- lib/files/cache/cache.php | 15 +++++++++++++++ lib/files/cache/scanner.php | 3 ++- lib/files/view.php | 12 +++++++++++- tests/lib/files/cache/scanner.php | 2 ++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 7e0c5cb21f..5efc7d67c4 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -286,4 +286,19 @@ class Cache { } return $files; } + + /** + * get all file ids on the files on the storage + * + * @return int[] + */ + public function getAll() { + $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?'); + $result = $query->execute(array($this->storageId)); + $ids = array(); + while ($row = $result->fetchRow()) { + $ids[] = $row['fileid']; + } + return $ids; + } } diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e8f54c34be..0adde1d354 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -66,7 +66,8 @@ class Scanner { $this->scanFile($parent); } } - $this->cache->put($file, $data); + $id = $this->cache->put($file, $data); + Permissions::set($id, \OC_User::getUser(), $data['permissions']); return $data; } diff --git a/lib/files/view.php b/lib/files/view.php index 04b7dca8af..82455d582e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -686,6 +686,8 @@ class View { } } + $data['permissions'] = Cache\Permissions::get($data['fileid'], \OC_User::getUser()); + return $data; } @@ -733,8 +735,16 @@ class View { } } - foreach($files as $i => $file){ + $ids = array(); + + foreach ($files as $i => $file) { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $ids[] = $file['fileid']; + } + + $permissions = Cache\Permissions::getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $files[$i]['permissions'] = $permissions[$file['fileid']]; } usort($files, "fileCmp"); //TODO: remove this once ajax is merged diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index e3f47047f5..34fefc784d 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -106,6 +106,8 @@ class Scanner extends \UnitTestCase { } function tearDown() { + $ids = $this->cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); $this->cache->clear(); } } From fcc92a9f43e75ecdb15adb0e948d45eac119306f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 10:34:25 +0200 Subject: [PATCH 058/262] add searchByMime to new cache api --- lib/files/cache/cache.php | 21 +++++++++++++++++++++ lib/files/filesystem.php | 4 ++++ lib/files/view.php | 25 ++++++++++++++++++++++--- tests/lib/files/cache/cache.php | 3 +++ tests/lib/files/view.php | 3 +++ 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5efc7d67c4..6604525477 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -287,6 +287,27 @@ class Cache { return $files; } + /** + * search for files by mimetype + * + * @param string $part1 + * @param string $part2 + * @return array + */ + public function searchByMime($mimetype) { + if (strpos($mimetype, '/')) { + $where = '`mimetype` = ?'; + } else { + $where = '`mimepart` = ?'; + } + $query = \OC_DB::prepare(' + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' + ); + $result = $query->execute(array($mimetype, $this->storageId)); + return $result->fetchAll(); + } + /** * get all file ids on the files on the storage * diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b3c92f3855..96660a8ce3 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -551,6 +551,10 @@ class Filesystem { return self::$defaultInstance->search($query); } + static public function searchByMime($query) { + return self::$defaultInstance->searchByMime($query); + } + /** * check if a file or folder has been updated since $time * diff --git a/lib/files/view.php b/lib/files/view.php index 82455d582e..0a5a6436c2 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -747,7 +747,7 @@ class View { $files[$i]['permissions'] = $permissions[$file['fileid']]; } - usort($files, "fileCmp"); //TODO: remove this once ajax is merged + usort($files, "fileCmp"); return $files; } @@ -784,6 +784,25 @@ class View { * @return array */ public function search($query) { + return $this->searchCommon('%' . $query . '%', 'search'); + } + + /** + * search for files by mimetype + * + * @param string $query + * @return array + */ + public function searchByMime($mimetype) { + return $this->searchCommon($mimetype, 'searchByMime'); + } + + /** + * @param string $query + * @param string $method + * @return array + */ + private function searchCommon($query, $method) { $files = array(); $rootLength = strlen($this->fakeRoot); @@ -791,7 +810,7 @@ class View { $storage = Filesystem::getStorage($mountPoint); $cache = $storage->getCache(); - $results = $cache->search('%' . $query . '%'); + $results = $cache->$method($query); foreach ($results as $result) { if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) { $result['path'] = substr($mountPoint . $result['path'], $rootLength); @@ -805,7 +824,7 @@ class View { $cache = $storage->getCache(); $relativeMountPoint = substr($mountPoint, $rootLength); - $results = $cache->search('%' . $query . '%'); + $results = $cache->$method($query); foreach ($results as $result) { $result['path'] = $relativeMountPoint . $result['path']; $files[] = $result; diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 839e06e93f..5a8d79b902 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -129,6 +129,9 @@ class Cache extends \UnitTestCase { $this->assertEquals(1, count($this->cache->search('%folder%'))); $this->assertEquals(1, count($this->cache->search('folder%'))); $this->assertEquals(3, count($this->cache->search('%'))); + + $this->assertEquals(3, count($this->cache->searchByMime('foo'))); + $this->assertEquals(2, count($this->cache->searchByMime('foo/file'))); } public function tearDown() { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 980c5298fb..5144fb1caa 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -139,6 +139,9 @@ class View extends \PHPUnit_Framework_TestCase { } $this->assertContains('/anotherstorage/foo.txt', $paths); $this->assertContains('/anotherstorage/foo.png', $paths); + + $this->assertEquals(6, count($rootView->searchByMime('text'))); + $this->assertEquals(3, count($folderView->searchByMime('text'))); } /** From 3437071cf1776288d9239a89b1a6ceb9c5ddbce1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 10:40:27 +0200 Subject: [PATCH 059/262] remove old searchByMime --- lib/files.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/lib/files.php b/lib/files.php index 6a063f216d..28df225580 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,24 +28,6 @@ class OC_Files { static $tmpFiles = array(); - public static function searchByMime($mimetype_filter) { - $files = array(); - $dirs_to_check = array(''); - while (!empty($dirs_to_check)) { - // get next subdir to check - $dir = array_pop($dirs_to_check); - $dir_content = self::getDirectoryContent($dir, $mimetype_filter); - foreach ($dir_content as $file) { - if ($file['type'] == 'file') { - $files[] = $dir . '/' . $file['name']; - } else { - $dirs_to_check[] = $dir . '/' . $file['name']; - } - } - } - return $files; - } - /** * return the content of a file or return a zip file containning multiply files * From 5bfff6c56e8d4d911c7a5265bb5462c7122ca495 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 12:17:35 +0200 Subject: [PATCH 060/262] use absolute paths when resolving mount points --- lib/files.php | 10 ---------- lib/files/cache/permissions.php | 3 +++ lib/files/view.php | 35 ++++++++++++++++++++++++--------- lib/public/share.php | 4 ++-- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/files.php b/lib/files.php index 28df225580..e6b324f062 100644 --- a/lib/files.php +++ b/lib/files.php @@ -249,13 +249,3 @@ class OC_Files { return false; } } - -function fileCmp($a, $b) { - if ($a['type'] == 'dir' and $b['type'] != 'dir') { - return -1; - } elseif ($a['type'] != 'dir' and $b['type'] == 'dir') { - return 1; - } else { - return strnatcasecmp($a['name'], $b['name']); - } -} diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php index e3fa63c464..dd7233abc7 100644 --- a/lib/files/cache/permissions.php +++ b/lib/files/cache/permissions.php @@ -50,6 +50,9 @@ class Permissions { * @return int[] */ static public function getMultiple($fileIds, $user) { + if (count($fileIds) === 0) { + return array(); + } $params = $fileIds; $params[] = $user; $inPart = implode(', ', array_fill(0, count($fileIds), '?')); diff --git a/lib/files/view.php b/lib/files/view.php index 0a5a6436c2..0f9a5feb5d 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -110,6 +110,7 @@ class View { */ public function getLocalFile($path) { $parent = substr($path, 0, strrpos($path, '/')); + $path = $this->getAbsolutePath($path); list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFile($internalPath); @@ -124,6 +125,7 @@ class View { */ public function getLocalFolder($path) { $parent = substr($path, 0, strrpos($path, '/')); + $path = $this->getAbsolutePath($path); list($storage, $internalPath) = Filesystem::resolvePath($path); if (Filesystem::isValidPath($parent) and $storage) { return $storage->getLocalFolder($internalPath); @@ -334,8 +336,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); if ($storage) { $result = $storage->rename($internalPath1, $internalPath2); } else { @@ -345,7 +347,7 @@ class View { $source = $this->fopen($path1 . $postFix1, 'r'); $target = $this->fopen($path2 . $postFix2, 'w'); $count = \OC_Helper::streamCopy($source, $target); - list($storage1, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); + list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); $storage1->unlink($internalPath1); $result = $count > 0; } @@ -417,8 +419,8 @@ class View { $mp1 = $this->getMountPoint($path1 . $postFix1); $mp2 = $this->getMountPoint($path2 . $postFix2); if ($mp1 == $mp2) { - list($storage, $internalPath1) = Filesystem::resolvePath($path1 . $postFix1); - list(, $internalPath2) = Filesystem::resolvePath($path2 . $postFix2); + list($storage, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1); + list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2); if ($storage) { $result = $storage->copy($internalPath1, $internalPath2); } else { @@ -552,7 +554,7 @@ class View { array(Filesystem::signal_param_path => $path) ); } - list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); if ($storage) { $result = $storage->hash($type, $internalPath, $raw); $result = \OC_FileProxy::runPostProxies('hash', $absolutePath, $result); @@ -587,7 +589,7 @@ class View { return false; } $run = $this->runHooks($hooks, $path); - list($storage, $internalPath) = Filesystem::resolvePath($path . $postFix); + list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); if ($run and $storage) { if (!is_null($extraParam)) { $result = $storage->$operation($internalPath, $extraParam); @@ -747,8 +749,23 @@ class View { $files[$i]['permissions'] = $permissions[$file['fileid']]; } - usort($files, "fileCmp"); - return $files; + if ($mimetype_filter) { + foreach ($files as $file) { + if (strpos($mimetype_filter, '/')) { + if ($file['mimetype'] === $mimetype_filter) { + $result[] = $file; + } + } else { + if ($file['mimepart'] === $mimetype_filter) { + $result[] = $file; + } + } + } + } else { + $result = $files; + } + + return $result; } /** diff --git a/lib/public/share.php b/lib/public/share.php index 060f67c9e9..707d5abe44 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -534,7 +534,7 @@ class Share { $backend = self::getBackend($itemType); // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { - $root = \OC_Filesystem::getRoot(); + $root = \OC\Files\Filesystem::getRoot(); $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; @@ -621,7 +621,7 @@ class Share { } else { if ($itemType == 'file' || $itemType == 'folder') { $where .= ' `file_target` = ?'; - $item = \OC_Filesystem::normalizePath($item); + $item = \OC\Files\Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } From dea0d20a9ad0270896e57a7459d6276798658d7c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 12:18:01 +0200 Subject: [PATCH 061/262] fix delete and sort files --- apps/files/ajax/delete.php | 17 +++++++---------- apps/files/ajax/scan.php | 2 ++ apps/files/index.php | 12 ++++++++++++ apps/files_sharing/public.php | 4 ++-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php index ae6158a05a..fdd0c0c491 100644 --- a/apps/files/ajax/delete.php +++ b/apps/files/ajax/delete.php @@ -12,18 +12,15 @@ $files = isset($_POST["file"]) ? stripslashes($_POST["file"]) : stripslashes($_P $files = explode(';', $files); $filesWithError = ''; -if (OC_User::isLoggedIn()) { - $success = true; - //Now delete - foreach ($files as $file) { - if ($dir != '' || $file != 'Shared' && !\OC\Files\Filesystem::unlink($dir . '/' . $file)) { - $filesWithError .= $file . "\n"; - $success = false; - } +$success = true; + +//Now delete +foreach ($files as $file) { + if (($dir === '' && $file === 'Shared') || !\OC\Files\Filesystem::unlink($dir . '/' . $file)) { + $filesWithError .= $file . "\n"; + $success = false; } -} else { - $success = false; } if ($success) { diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php index 5cd9572d7f..91b20fa836 100644 --- a/apps/files/ajax/scan.php +++ b/apps/files/ajax/scan.php @@ -1,5 +1,7 @@ assign('uidOwner', $uidOwner); $tmpl->assign('dir', basename($dir)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); if (isset($_GET['path'])) { $getPath = $_GET['path']; @@ -200,7 +200,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl->assign('uidOwner', $uidOwner); $tmpl->assign('dir', dirname($path)); $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + $tmpl->assign('mimetype', \OC\Files\Filesystem::getMimeType($path)); if ($type == 'file') { $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&file='.urlencode($_GET['file']).'&download', false); } else { From 86be7e88721ada34e7b230a0e5dfb4df546bc38a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 12:23:13 +0200 Subject: [PATCH 062/262] remove last uses of depricated OC_Filesystem --- apps/files_sharing/public.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 143edd23c4..35e7734e2d 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -24,7 +24,7 @@ if (isset($_GET['token'])) { function getID($path) { // use the share table from the db to find the item source if the file was reshared because shared files //are not stored in the file cache. - if (substr(OC_Filesystem::getMountPoint($path), -7, 6) == "Shared") { + if (substr(\OC\Files\Filesystem::getMountPoint($path), -7, 6) == "Shared") { $path_parts = explode('/', $path, 5); $user = $path_parts[1]; $intPath = '/'.$path_parts[4]; @@ -33,7 +33,9 @@ function getID($path) { $row = $result->fetchRow(); $fileSource = $row['item_source']; } else { - $fileSource = OC_Filecache::getId($path, ''); + $rootView = new \OC\Files\View(''); + $meta = $rootView->getFileInfo($path); + $fileSource = $meta['fileid']; } return $fileSource; @@ -102,7 +104,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { if (isset($_GET['path'])) { $path .= $_GET['path']; $dir .= $_GET['path']; - if (!OC_Filesystem::file_exists($path)) { + if (!\OC\Files\Filesystem::file_exists($path)) { header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); @@ -130,7 +132,7 @@ if (isset($_GET['file']) || isset($_GET['dir'])) { $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('owner', $uidOwner); // Show file list - if (OC_Filesystem::is_dir($path)) { + if (\OC\Files\Filesystem::is_dir($path)) { OCP\Util::addStyle('files', 'files'); OCP\Util::addScript('files', 'files'); OCP\Util::addScript('files', 'filelist'); From 0fb707d2c90846c1231cdefac79e9b58c8351c81 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 14:25:15 +0200 Subject: [PATCH 063/262] some more porting of the sharing --- apps/files_sharing/appinfo/update.php | 9 +++++---- apps/files_sharing/public.php | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/files_sharing/appinfo/update.php b/apps/files_sharing/appinfo/update.php index 51048bd178..69c526eae0 100644 --- a/apps/files_sharing/appinfo/update.php +++ b/apps/files_sharing/appinfo/update.php @@ -9,11 +9,12 @@ if (version_compare($installedVersion, '0.3', '<')) { OC_User::useBackend(new OC_User_Database()); OC_Group::useBackend(new OC_Group_Database()); OC_App::loadApps(array('authentication')); + $rootView = new \OC\Files\View(''); while ($row = $result->fetchRow()) { - $meta = \OC\Files\Filesystem::getId($path, ''); - $itemSource = OC_FileCache::getId($row['source'], ''); + $meta = $rootView->getFileInfo($$row['source']); + $itemSource = $meta['fileid']; if ($itemSource != -1) { - $file = OC_FileCache::get($row['source'], ''); + $file = $meta; if ($file['mimetype'] == 'httpd/unix-directory') { $itemType = 'folder'; } else { @@ -69,6 +70,6 @@ if (version_compare($installedVersion, '0.3.3', '<')) { OC_App::loadApps(array('authentication')); $users = OC_User::getUsers(); foreach ($users as $user) { - OC_FileCache::delete('Shared', '/'.$user.'/files/'); +// OC_FileCache::delete('Shared', '/'.$user.'/files/'); } } diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index 35e7734e2d..1fe7311002 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -10,7 +10,8 @@ if (isset($_GET['token'])) { $qry = \OC_DB::prepare('SELECT `source` FROM `*PREFIX*sharing` WHERE `target` = ? LIMIT 1'); $filepath = $qry->execute(array($_GET['token']))->fetchOne(); if(isset($filepath)) { - $info = OC_FileCache_Cached::get($filepath, ''); + $rootView = new \OC\Files\View(''); + $info = $rootView->getFileInfo($filepath, ''); if(strtolower($info['mimetype']) == 'httpd/unix-directory') { $_GET['dir'] = $filepath; } else { From 7891add28655c7f39b388ac0a889b246b23ad934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Sat, 27 Oct 2012 15:26:28 +0200 Subject: [PATCH 064/262] don't call $('#found_versions').chosen(); after opening the history drop-down since no version is selected at the beginning --- apps/files_versions/js/versions.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js index 426d521df8..b9c5468981 100644 --- a/apps/files_versions/js/versions.js +++ b/apps/files_versions/js/versions.js @@ -73,7 +73,6 @@ function createVersionsDropdown(filename, files) { $.each( versions, function(index, row ) { addVersion( row ); }); - $('#found_versions').chosen(); } else { $('#found_versions').hide(); $('#makelink').hide(); From 72aebe3aa3ce51ef47ef6005b528c4d296e208c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Sat, 27 Oct 2012 15:24:01 +0200 Subject: [PATCH 065/262] fix broken paths in versions app --- apps/files_versions/lib/versions.php | 41 +++++++++++++--------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index 47e514d9d7..e83310172a 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -58,10 +58,8 @@ class Storage { public function store($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - - $userHome = \OC_User::getHome($uid); - $files_view = new \OC\Files\View($userHome.'/files'); - $users_view = new \OC\Files\View($userHome); + $files_view = new \OC\Files\View('/'.\OCP\User::getUser() .'/files'); + $users_view = new \OC\Files\View('/'.\OCP\User::getUser()); //check if source file already exist as version to avoid recursions. // todo does this check work? @@ -96,11 +94,12 @@ class Storage { // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval) if ($uid == \OCP\User::getUser()) { - $versions_fileview = new \OC\Files\View($userHome.'/files_versions'); - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); - $matches=glob($versionsFolderName.'/'.$filename.'.v*'); + $versions_fileview = new \OC\Files\View('/'.\OCP\User::getUser().'/files_versions'); + $versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename); + $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath(''); + $matches=glob($versionsName.'.v*'); sort($matches); - $parts=explode('.v', end($matches)); + $parts=explode('.v',end($matches)); if((end($parts)+Storage::DEFAULTMININTERVAL)>time()) { return false; } @@ -110,7 +109,7 @@ class Storage { // create all parent folders $info=pathinfo($filename); if(!file_exists($versionsFolderName.'/'.$info['dirname'])) { - mkdir($versionsFolderName.'/'.$info['dirname'],0750, true); + mkdir($versionsFolderName.'/'.$info['dirname'],0750,true); } // store a new version of a file @@ -129,7 +128,7 @@ class Storage { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $users_view = new \OC\Files\View(\OC_User::getHome($uid)); + $users_view = new \OC\Files\View('/'.\OCP\User::getUser()); // rollback if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) { @@ -152,12 +151,12 @@ class Storage { public static function isversioned($filename) { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC\Files\View(\OC_User::getHome($uid).'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.\OCP\User::getUser().'/files_versions'); - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); + $versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename); // check for old versions - $matches=glob($versionsFolderName.$filename.'.v*'); + $matches=glob($versionsName.'.v*'); if(count($matches)>0) { return true; }else{ @@ -177,22 +176,20 @@ class Storage { * @returns array */ public static function getVersions( $filename, $count = 0 ) { - if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) { list($uid, $filename) = self::getUidAndFilename($filename); - $versions_fileview = new \OC\Files\View(\OC_User::getHome($uid).'/files_versions'); + $versions_fileview = new \OC\Files\View('/'.\OCP\User::getUser().'/files_versions'); - $versionsFolderName = \OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); + $versionsName = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename); $versions = array(); - // fetch for old versions - $matches = glob( $versionsFolderName.'/'.$filename.'.v*' ); + $matches = glob( $versionsName.'.v*' ); sort( $matches ); $i = 0; - $files_view = new \OC\Files\View(\OC_User::getHome($uid).'/files'); + $files_view = new \OC\Files\View('/'.\OCP\User::getUser().'/files'); $local_file = $files_view->getLocalFile($filename); foreach( $matches as $ma ) { @@ -249,10 +246,10 @@ class Storage { list($uid, $filename) = self::getUidAndFilename($filename); $versions_fileview = new \OC\Files\View('/'.$uid.'/files_versions'); - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath(''); + $versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename); // check for old versions - $matches = glob( $versionsFolderName.'/'.$filename.'.v*' ); + $matches = glob( $versionsName.'.v*' ); if( count( $matches ) > \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ) { @@ -263,7 +260,7 @@ class Storage { foreach( $deleteItems as $de ) { - unlink( $versionsFolderName.'/'.$filename.'.v'.$de ); + unlink( $versionsName.'.v'.$de ); } } From 0d3f68cc7a425410e498e9946ab9847348dcdc55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Sat, 27 Oct 2012 15:23:35 +0200 Subject: [PATCH 066/262] fix function documentation --- lib/user.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/user.php b/lib/user.php index 064fcbad96..869984a16e 100644 --- a/lib/user.php +++ b/lib/user.php @@ -369,8 +369,7 @@ class OC_User { * @param $password The password * @returns string * - * Check if the password is correct without logging in the user - * returns the user id or false + * returns the path to the users home directory */ public static function getHome($uid) { foreach(self::$_usedBackends as $backend) { From 2dc1b778b47c7a765b1c4b56aa928c74f7116946 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Sat, 27 Oct 2012 16:24:24 +0200 Subject: [PATCH 067/262] Include copy of Symfony routing component, and don't use composer --- .gitignore | 4 - 3rdparty/bin/composer | Bin 631359 -> 0 bytes .../Component/Routing/Annotation/Route.php | 103 ++++++ .../Component/Routing/CompiledRoute.php | 134 ++++++++ .../Routing/Exception/ExceptionInterface.php | 23 ++ .../Exception/InvalidParameterException.php | 23 ++ .../Exception/MethodNotAllowedException.php | 38 +++ .../MissingMandatoryParametersException.php | 24 ++ .../Exception/ResourceNotFoundException.php | 25 ++ .../Exception/RouteNotFoundException.php | 23 ++ .../Generator/Dumper/GeneratorDumper.php | 39 +++ .../Dumper/GeneratorDumperInterface.php | 45 +++ .../Generator/Dumper/PhpGeneratorDumper.php | 150 +++++++++ .../Routing/Generator/UrlGenerator.php | 176 ++++++++++ .../Generator/UrlGeneratorInterface.php | 37 +++ .../routing/Symfony/Component/Routing/LICENSE | 19 ++ .../Routing/Loader/AnnotationClassLoader.php | 213 ++++++++++++ .../Loader/AnnotationDirectoryLoader.php | 77 +++++ .../Routing/Loader/AnnotationFileLoader.php | 125 +++++++ .../Routing/Loader/ClosureLoader.php | 54 +++ .../Routing/Loader/PhpFileLoader.php | 64 ++++ .../Routing/Loader/XmlFileLoader.php | 224 +++++++++++++ .../Routing/Loader/YamlFileLoader.php | 142 ++++++++ .../Loader/schema/routing/routing-1.0.xsd | 38 +++ .../Routing/Matcher/ApacheUrlMatcher.php | 76 +++++ .../Matcher/Dumper/ApacheMatcherDumper.php | 155 +++++++++ .../Routing/Matcher/Dumper/MatcherDumper.php | 44 +++ .../Matcher/Dumper/MatcherDumperInterface.php | 41 +++ .../Matcher/Dumper/PhpMatcherDumper.php | 293 ++++++++++++++++ .../Matcher/RedirectableUrlMatcher.php | 53 +++ .../RedirectableUrlMatcherInterface.php | 35 ++ .../Component/Routing/Matcher/UrlMatcher.php | 151 +++++++++ .../Routing/Matcher/UrlMatcherInterface.php | 38 +++ .../Symfony/Component/Routing/README.md | 32 ++ .../Component/Routing/RequestContext.php | 250 ++++++++++++++ .../Routing/RequestContextAwareInterface.php | 27 ++ .../Symfony/Component/Routing/Route.php | 312 ++++++++++++++++++ .../Component/Routing/RouteCollection.php | 259 +++++++++++++++ .../Component/Routing/RouteCompiler.php | 128 +++++++ .../Routing/RouteCompilerInterface.php | 29 ++ .../Symfony/Component/Routing/Router.php | 263 +++++++++++++++ .../Component/Routing/RouterInterface.php | 26 ++ .../Symfony/Component/Routing/composer.json | 29 ++ composer.json | 18 - 44 files changed, 4037 insertions(+), 22 deletions(-) delete mode 100755 3rdparty/bin/composer create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Annotation/Route.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/CompiledRoute.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGenerator.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/LICENSE create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcher.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/README.md create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RequestContext.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Route.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RouteCollection.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompiler.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/Router.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/RouterInterface.php create mode 100644 3rdparty/symfony/routing/Symfony/Component/Routing/composer.json delete mode 100644 composer.json diff --git a/.gitignore b/.gitignore index 4ae39ed7fa..4749dea19d 100644 --- a/.gitignore +++ b/.gitignore @@ -54,7 +54,3 @@ nbproject # WebFinger .well-known /.buildpath -3rdparty/autoload.php -3rdparty/composer/ -3rdparty/symfony/ -composer.lock diff --git a/3rdparty/bin/composer b/3rdparty/bin/composer deleted file mode 100755 index 7999bd4ff6875d721d50c01d28e4b371c78d21d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631359 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≧8qj;1nFhbZq$;1^@eeP|dV`PMUV{tW8;o*2-QV2Z#x%+_`46m*e7@&j zKQC!=v&DXl-$n%gTcHV(zxn*{@BH>3z9W4&-yXz)rJro82cK{J=?}f!+bCh|z58$x zHaWK-)8$g%kXV28(b^e4@BPlVhs}qDgAmIaGFqjLJYkLS`S_*(^atLXmmZ`M9L&I( z3wCI6cZek={9YN}g3EjeJ&+yyc$3t8-un23uoJm*=i6j+m(0TA^ND}(Ye9Kmz4Ogw zgzZ+-J z!v1no+W7pElV2LN<#Pw2jlzcG1RL=3H(U5R!=BHtTz}0sIQF;Eg1}x3Vbsqtmg4iJ zZ~NYtdJAU{-UpEXM(Dvi%;m-B2Os#6px7QrxG9a~zZoV?Oy}hDMPL7+cX}u0Z>JLo zL=L_9`Hxpl_nzJ> zTdj`l2mF_3DpWpy>HB~GC!9DB9R#Y%dy^RC(8q0+rap&y7t4LT2!>7Q)j zJAo&K9-m+L&bNNGx3GL0_@7b5MjOenQoLdPtgrgXkM-6LB$KQ^>J3eM^h355^EtEe zalwfRF}VM6wl+$-^4q59@j3I^Z#wQ>IndOzW-^51=nNs5I68dR|6OWn9H=jL$VeZV zVflbD0iP#YpB)?vx6@2m0JS~#=3}fke16iCGoS7xn?K0NWO`$91ixsKiqAK{{6#}= z;6UtU4dl;cJ=;VspFj2otN+#8IM9U8bb=&$k!d@8e&zrChi`P~2NHz_9X8k|JR<}B z$yQ!terrD8_pF6r2r+slCki1!d8Vsqqo~UOTQKf9H~|Med6mzv`opgcdwnqY_Y3sl zPVXA=e5NrBpHF=2heF`;#r=cyT}j3?54V;Z-A!)6K*{zGY;V)}htKyfUJM(v=WnCE z6&$UiizRO7*Q{TBCXal3uU?Y-#lU}Y~1>(&rPZ?R*aZyn?FSJy6wCA`E|7`wrh z_7klNIvz3E$mdJm^ZuX~e(`P45te*sx7j+2Q{Fs)cdOXRw^^%v{`wQIm>Ds5#_nXX zl^?Si%ICX2<{4oJ;PP$sO#<8yeYmvVFX77XvBBf>eXskeYu>M=+i3C3?f^&gi@m#I zH01LKKKgx+d0QpwzNd7ZdiI31#^+<5XFuYt-40ux#Yyc7ww$r%_HpbV zDp}C?(NeaJH&`2dp8V#k!A4^&);<@*m7NZz6e20~u*~1J@!<2z?s+&!UB>x1WaQ+S z<#t1-4WB&@8ZbNzR|_|LtCXf-$xmC|9)7(J6lGCn_Q^FIbfK2o)BvpII^GZ4kX zIm_qC=l<4bd8cl_l}-nAGvCH#cuv>~pTBnedqN!c?K1FucXyk;_`60cJ}2wj;oQP) zGq5=1*utBQz4(0lpM2AGrxW8=O?-?!8kv};_yqY2KjoV~=zu>h1>CR<9>n8Scuh+3 z`NjYFoq^43Y4LU2EuQsyYt(KKC4&80g7{ZPEI!}xr@!|mZ}IL?AlA9Xj)X`AKsA{- z@cH}S{oZeM0Eb2a=(if;kh*4s-@r*`3o!a_nQ-j&u6^$zGrw5&3`qK{@d8?3Kt{S zl<4;h8}pB2r)W^0+`vjYHSy#`dn2jy@3mI^VJdkNNuP$h{jS$cq{f32PvQThQvJ|m zM-G)GC%jC6zP5IDVR>zBrZzh>Gizk=;p7n1rlyj6?n%Z50Vw$Y90cOnTHop=wU_mF zlWi^JT<3R4Q7#gI&@KN|`kQ^r9 zIkB^Q4Pih?)Mis`dJjfQt62g| z5hbvwR5d6Z2)l;7doiFolDu`Ml9)2nCo$7>d#7H*nJ89azBcU{? zfFn?eXb)YfY}t?n_5*l)@T-dr1diQA3VHvCpf&~jq4oeGu`Zw?as{Y01694#>elgS z@2m|Qn^+Q*OCkbHX_tJAv=6AU)`w7S4C{wiA3yrS!-o3Qkz}LM8MIJ`xGS(iw?h#w zCmnQ5yFHzh;1dW7knD|CIhh=_p2ST=Sk)4Yj+Bj2%3>5151k-FQ4L$>eDK+3rc*WL z%p%p;DM!7EcN>H2^+`GG02LG1!VKl1xM=vZQ#Z_gnIiRCQ&O4LrlwB{B&CE4p%TEA zyou@%(Hm{cLs@~8Pp5q#m4$j+2%hdXP3OdPkBBCrNOYorfQ;za-oe^(Lb>pEX_{%X z8v8O7(xyjI9SuB!ILg!A!Od1b?Uv4ba=UpZ>NTn*k1bp{yZG43+U5D>m4(F%YY$yo zIDeK}6qph&0`xklT&t_OcuA(@RB@o`J8Q{_6DN|v?lnw;`r6t#mW;d-94fI^=qT_~^y^wj3nLg1#x=fe^HFw!= zA3|xnJ^<5qpq94Q1vrIK27*jL>zT1M&h9-W z@O%v*Icjc!{M!Dn&f;Cw0#f@0)FdHq4DZu+GI@@9byJ57`9}OY6dbS zDwxRST3`%n9Ercx>7NnVl`|XD<#a|9ja43F->j-ywM1++1{p|obktMLU4TU_Y9&EY z<{9LY)-n05AI1k#Jp}vGh=vH z*RNVkqA%}G%`=2% zb>CAv1y$0cJ*M|wb+blJH2YF9A%ZFcM@U=f7cjXqQ#oxbKYZFm>D2W~`6~H|GN41v z|K$tsIXkPX=G!Su$m*)Mx1Li^;DdPv0Gl4&R*MlVpdlA_b7fz#b7j}$7 zx%`3eZZju7EN4aTZ8(Qr^?ntRtmMMVf}=!Mntn6L#Pn6J#q@)fg&#kCS6%oVwkh+O zhO0}DOy^l$&3oUhZmn7#N84_Gjz?P>t4eM;7^{x%mh9EYqU@rLyR~;tf{s`9k)ssj zeOCD&k|+0#iAPY&2dV69K08aUjHQ%Vg__B%ZvNDeDqC~R);%Ng)mYYMN8&4*{l;pR z?huCkJ?!pb&g}MeH%jL6#Pmr_S$b7)Tao~tMnz7B+LV4f+Zsr^4q%0QlT@}-Kv=P4 zqmQeY8n|alF0z0C9`=$=Y{PXE_)P%^A+<9pEJV}E!5Q5{s!tG-@Q!m$9nJxP1eamv z!`$5R{7Wt^EYF{X)5FM>&=5$_;5FVUr5O>LwW%XzU;{Qqz>7;4;aWa@9)LsqV{#Lj zIRKj%S#e;K!IrFWXi4c*)eg42ID#Wvu~9yPB@HTpsmud*1Sw$P;mmZww*`0lt&LWH zdLT)a0G{fE(MXHT&0Riy{?h!~g~bc==n4)>AaKO#BD=#nSUyw=X~3R#6KFewHp0n| zpaKIX7$I=^%nE+NpQ~4OVHhLI=Fn;)xZ+MAML0=|?1Oeenj47`bWq-WKez^`5xOu6 zgP48V>({}v&GrT;ij8?VJl(;VFaUxB(d%6o6vzQav2qN6-mUe z0yMn0txj);p#tSib$iq65@0>;+}& zT`IR(rI!ND?|~z5%5sY2L4qj(ag9Kq1}vHu>e}R(hG-x55!wUN8f(ae=VlBi5!niZ z%u#^m-FM+VGcln(Ee7vo`;K-by@(6_VWSVFb~xnhW1H7ZR^Ttm768f9gq#Qh9@mt%s()SGD%40-+pPCS59yGULq@XY8 z>}~Bc7Kqw@&Ro!?c}cmr?zV=RMMowyC`b&_q8fl%TKYZk9_Mjs3FEQc_uRT=%V`!y zu8gd0j}v8TWTv`E<-ON8K5OYvlksDG8pT* zPMpNH9uc|yi^~3fhmf>hfZK0Xu5qK!MuG29ldBF6B zUM$ZL=j;X*&zZyQJ3M!g@lCl>liVA&h9W4J$CCA)yv6nH6ba`4G0l;7W*E>+ziq6u0`}Sq8EgZP@;iGbkx{E4?RG1hi^I~;$&S1KWF$>5URA|fBX z8U-gsA0!GXl=ES>E+ZtGCl*r{%MK(u5o+eY)Q+2IDnm#3AF*0c=j$m5b^*#v&jWUA zs^8g?MAH| zcB_L%##ZA7H1n2tfW+Et&O}WZA7|xyJV~%%A^^%UhE%RW$(ly67^YUcyQb1GLjqlN zc_^-q;e5gB2ZRs05ZT-eoS@2>)HBsAysoG70gTq%F00DedhvY8a_dz~ow(Tr88MMO;<1gi z(fwN>QaT^eOhL9s%lecKwr)C&bT(({j`3=^coVHZMTOqndFS9?R4uNi zB3(lSGec#)7L!*;KsC7{vx+(g38e_Lnrvj13@!{YfxRP6-qp3M}RX zwQ7;wS;> zVn%pGxe4#HJ@InfY`|Rr4X}^-2Kh+0q8vPPM{9is66;7ZGeF|;nW+Supmd#|au>pt z<5-C3aya?2Bi-XXGABQ-A}IBU?J~peqaMX2KIl>Bu5{@~+wQ%;gpN*~IPabl=rxcuo5> z7S+bK{@(6E62QG7AFn;pm#4|^847S&q2aotq7d~F5`-G(q<@jI9QJPs6{tDW#z-v_ zp#u8MFW7jKECg%Ap06lMAMl?|&+r>ds0K7s8pGd*m}UGyJjkerCO2@tNk{dpo6I6I zWZ8-Iv%;=Or?#dP^6Pj?gfBk8T<3}2ty z<|7BVXDBU1A@ zZy*f_`bc4H76 zbe*%K(_3$FcOvrn=6vO-4%4Y4spTOsXC_u!t*T?PvYP|7io24kfMYN1evk4Qk+y-eK zteXek;*WOXeU9t43~oTo?uw@y1vk_i4W%I$FAxDUCbr$z0xuSA_ap4?@UT$ zdY&3@M8-&wljKeYV-`U*4SOx3=7Ve=J?RUP3lhMZ%5VcZI|^o~yC={b>-d57m?pA& zQJ^TNZ?137LZe74Y$qy_cdLMbg8`owspZWU$WyhErKTftffysw-w{nKc40imUfXUV zGQmeTP?+5yg&gau`ICJwc5zBRnw7R0Pk5YUIp0g^2Al@gf`E*;Wk;Z|3+KyO5NNrz z3%xXR3OD7TKJG%-wAdIi=ioblVW{DBM;MDHDO`f6lOO_mf0=89ju);6<_cZA-nxaY zvlw%k;Dy1-ko*o2Jlm=mk$NIK;+k|RxBkH3hfn1YkG11?b(o^0zb*Epz4DAns*zkKpe1^034{9`>hFCwCt5JDI5^f4BVI^xPq&D zWp@)}M1OZ~cU59KeFo#qBnI%7B{jp(& zMXLamb2_w-rA$1)LCa0qK+sURV@Kbe7+0kJ)hkY8VNZHh>r+>!=*YH-TiEr)sdTnn zUQ?h1aY2GB>GJQnA*w#=aqyv-wsPc*r!aZXnEJcAqz%X^ipZBC%oOIJE)Z2C#mUET z9DofItCW^3Xc0{Yt2jaqOg+^)Mwr`Nr;RSoXXOJ@E@_11m><^%aO8!h%!i^(-1s+< zGe*2p(Nat3{04?qCY9Gm_MDHq5mR!bRNlO2fIHsX+8JE<#@<>1w_8R?cFczC=avnh_ zQb`$EtH96PX28QH2N+YrX%OdF7Lmik7#mqutcDB$Hard<-{OEoM#AvozJQ{E^-z9_ zMHzIW{mRQ+7mp74Y~A0FW? z>`|pU>jE{*j1UkNc2O*{=)J47TyUcGB`RU8XEs(!mkLRe;mnFMB5h=AEUyUKxrl&#>KNo)vnwxH>-`4BNASRf;P=lwr#EW8%qq6ZkXCn-OEh<&EYa#=p!w+}WW% zR<5%})}a(L`iwFT4V>s~WKA&(B_UV2>K4>hnf+2DV+E3HW;7!hI>3dZ*a;+pLIiOG z(UqlbgkB&cm6Y4F8!5nSKODfIw4GG-uIP(s^s=@qWuS1>b_V_FqwovV-duhW+ZOSr`LA84Uism)cd?G>B6nO^t1^X3Bz|@PIVjB{GHFJrzfpTQO2C}9bj4(CvRub#C36ez}Jnn?~vaygQQ+8!+={#7af<%?+9 z7aKgwspFO^7b1^YTgoUmAc%|UblP1jofSQ1lN=xhE4XzQJg#%EI1U-&eP(%&>ga~! zJ{obsu~(JFigXj?T#f&_w1eQg7J7WgA~tpfVj6!DMSy8z13mMb32s7E1!DoQ$Hok= zHqDa8I`W=3C0a1IB?UVNJ5t(|o;-!-36BZx=)tBPPRe7G9?PXi|BfF65`q?-#B*~C zD{H5hmruV8cMQmwrC*|m4)g60mj1i+})8NCIST<1HV%{4a4@@x&QIlYdicaAMwJ@E>B$S@e-Me8} zCmIq%wtG5~Ev#H`?2; zO43S6bC)-BXWwi?XWt|9gGv!sM%WjMKe!-~G>&pJ2tVDfXP~ug!QJkHpI4KDPSf0R3A)DFi)GGTrgNrD+askTXWU9Bdnn3jL^NBWANejW|_%aj$tKN zW@ctWwuq-IJSzlzQ2A016Lg(3wsc9x!9Zv4# zQPQX$Ert%R=z)72fGA=QscBLu0QT8=+B^!({a>uuE1CF?+9gqR^bEaXp>H1BLfoxJ zd!zteX$bkGu+z*;7ixK@<(%H7a$cPyHZS)&Yvgfmp*U7dx;c}haLC9xqrd+12@B*i z)tj9_d#SWh6{Xc)6{>XLOpLXj2T@Qy9kH9s{A7}3P5)GO&y^~VZfBl>C_S5)ik|e7 zP|-+*#*Lz>Jqdxq(mXT-UMc(JIAuSEP)@C1onuYFr;2i1Hv7&fLJ_ur-`JTbXXKS5TPy{MC z4Qng7a-?HN~WbT&_HS11(2_K0~Q&ZVYN88SYF!Lm|3ojg2S;ErmNg!DW6ou%R57 z*??Xu_bc9=OiybQsXIeJBiI>(C!2EQ`&;9H3Z;2M2>OoX8?#(Y*Bbp9v>vzeGRpv# zZ>n@+rd?;&DQ1A8W~)J>mUb%biTLVFj^rpshGsQrd^~@K3ne->TgU0)^fbpe?gU1` zSRD+|H&DV1R4Os(GKCM%pIt!KhQl!MkkYTwZ(CqKYC|Ifp+)BN-^&x!Je{tAzQp#Cnl5TTHE`G8f6gc+d-!X>jLP+z8}r*MWt($+gv7IR?K8 zlytDjlRViQpHj#yJz;f`qcxiHL}XF4A>G#CNnL%T_dRh*aa%d(49_hcl3yVwfs#WE z@DRuuJyw?p`W2&CR;Yxqzgpp}Y8^??gx9#zcxNTy9i0HoquJZW?Vl|q(v8h~S*UXB>fnj&D#wRY7|M`Z2>Js956+X^5Gw45l~O_raKiAnIcCPV;7l3;+#04# zYp2l+@ul(Rrw!nZ_BM5h8$7pG>o&S{meh9I>+<9*ldaK^t;UfdZR#}~7Dq%GwvE&8 zvTYE0mVU?tOUdrCrl!VSWr{90Q*}F6ZrdtlNN%)_Lk5N&*0>pTGI<5E!n^_m4_j=B z9!jqqBGCtRfOP8d#TjAqU3E;B@iUz~5*A^CGvAyJXevQmhstVZ(yUp8F`7D7Q+dH! z1Y+8k%&5g3VR znI~XBn95DYwzpkC6WX$@+J-4rB&I+W9a4K@>xf1^$adQpct4n6r4=CzZ^-7Fgq786 zvo9A-?o|EM9H%+7xv5jDGxeG0P0eCfMe9eA9;$-lB230;qMpyQs8Y!&y7M4jBXr&H z+!D(nKovK?D(oxA?DjGa*nPrN>o_^Y4QGz5wmou%CVvRkLqbsraNvsFkc4!}yedL- zyzV(w(&c_c&%T7~m!E6`UCQRFdHC$2O>bKV^MX}=v=rqW%f6qj? z%zT?Gj-65H<0u`JH5mpBKPV*kiE~sQOr9bX=smX!0#h2vlcsxJ&jlUfGf{~HBi@0- zk?In}Qdp@bLGLw6AiuF#J1{|;5DLXM?rm*XkQUinwsx;Em;A7|-s=pik(0n65vriM zQlBU&^BU!9@*YY#Pi|u=lhIA1PFY+QH~it#?NFL33~!x@YMvDg2^S^zj3tm{EpH3O z+mazlF}Hn<)*Lc9!gMOk0QuSIE@72=<2F1{GpB` zAa1{U@McR(14yMk*JTfpoTweXdvKVS+yL!%S76y%hSL{OL(qbd-A{u0NI_;3sZH5o z3uHeIExY7%ek)r}AZaT{3u{|CFqs}1ucwo)IQ#$4VZX5ldmkfxH@q0PInLZ{TtmJ> z$*iVh&W%jr(K|Zg3KOC&QXZ<0s@kll^^nec906+fu;EF~Q*2e{uD9Eq2D=jSifv&y zvdE%TEa;W9`9{||{-s{|u$&b&cwHIjwuj|4gk-L8fPk~FL(tIYOkYUK$6iww5GZfi z=v$GEs0eu}2RyJCMk@=7hm{3zXg@<+h@F72SGcyYk#-kLFV_pg%&c|0Ehz*9XHFnB zA=FTSkdVCElP_1et20j#H2yb99ARQX00g7HNEQ_dD6LiutD(3wt+_4{fGC>c^&^A? z^XeG!6dExm5P3Y>kl5Fc;D@GOmV!s7?;~$WvB~QYb&3hPYiUwD zu@}+*(7n`ohlqFaW=av^dNyi%^U5(?hWDTP>x`c!3|qW=ZEY>2+h@VUwvRfxvhGzu z8Mt_5kxmNT(=v?FgNjY9lDVUdRJk){+m`8`Q?xZ@&1vidK+BbFadbk6en?G(5Ee$` z3QRq~^kk+Mo~4AkM%4r>wfKfH`!$q|0uJ0b_O6$0U=Ji4Ip)S*J4)yNuecJ&qYU<@ zhqBs-qqRO9tp!2yw>MhLMAsPMTB%TCxE9nK-h_l~nc4IzW(h>$TFu_gE|1GlfeSb6 z;0J>HxEU0(0?Ox%V8r^1C~A#>lTcOeG|VImyysFkw1S>Ap?VT_Pvu&$a069FJZcLX zy*t1WmJxAbS+YERIj}w)WW~^|zx_d0rXQBL0{*53M+FT|E?_((8u(?u{(Ub!>o%1+ zchT(C%xHDaP6Zg!a8y<)bmjKY9y%SgWw}KpRjDGS&fA0-OSLv?U}@>fup{q$y+&~c z%}a>sZ|CNsKz%t)M`wMk@jG+iETB7Pj{i`$CylgJC=uK_|CP$uuh z3{lm&L?=G@#vsyc%ieG_TfF;56t}kyvE-WV*Ge_D_OLQYgk?wrcHB}g(+U#k+(@JS zEXkd4Ry$42>^?^cE2KSn2nHp0t{7EO-*+Qsmpg#!ro`1mszZ<0eev9+^Bpy8gj%{Y zb^QtIl8a~e8s2QpGifz{-)!`|@SDR+89URaPx|OuXCRw&m*&u6zI%8|mUTgYak?IgN za|c{U>Nz?qDb5Gz>7JgWa40oqG0UGP921i1)xb*jLGHbjv-Fw7d)zQAbLj4&z^Ew| z1wu#qiylGJz!g8t0+GiI?k@3EEwGRKQfs_UL9>bCeV6Pc3uF>Zt;(d*a)?&;uGN7n zqpIWSfzuAuPdsM7`gurHKaT^s31Pu!gZou+2rH=@;dzuuawKvDrl4DiXWWv1di;wX zV#eNTshR~725x7BM~=w4tk+@(nM;?xoIK$*O3e|*sEuS$1B2dYLi?}PJQa_+LpFHv9r}VVYUInkA_VeX!(z`Q5JSEul+Y z->XMludyr>YDiNvU`|oEl#}_sGVMWxcYdP_NMj+ys#c^B+ni>vG+Zp*?9qYdI>x_* z6#QfSyplGQXqDipzy>1WZ(aTIhYceeKuU%oqTubD$&6H@QZA@@dgh2746?>prDKw!*&%sYzk|5SZVMYQlAWS_|m(S4{fx2IoZj&=p{cuUfA zGV@|9eWy6NqP3cSSY3(|ervYITv;2LeA3Sxg#u_Ve!9~R$y{>~!%;Fi2vk2>K}g~H z)>!J1Md3Xd={3k;e)CZc&I7AxG!r-^^*l@td)JXSEb~hFF8c~0EM(*ZDNO_ELaOe> zI+J`7gU#k_q+3;bdz3lqH3rs9Gr)+Rn+y0)i7Inp@xna5Dj78t2WL&B5)6)Tyxv)~ zUQ>cNFn^z(NOGMh{o>jZn$gOl3x%FBOs~p`q@)QhB>f3xiq^6dgh2`13n9*SuBI6K zXn+Q{wl{iRIZ!7~tfyU>8UMZsk^bwZ&wv?CFM*Kt8DjS+a1lr|@3W-W8mR@H_gwut zSM@A)oKqE$KAi49EGy}yR{K5M@V7kOzwsSq2PGQ$tEjN0l7$PgS}QiUGv!?f1hJ78 zS1C&HE>A0R;Hp%XMj%0Kug?|>$d3JHnKo=A!B6$ll48i*QhZVd@Q+t;N&~V~Vraqv z#az1Nw5+A2mC_2l1ljN@2~C!8 zOjMAYIOsaWU!lIpF2ytjCBs3YgH5Wh{PkK#Q4t`gCKztC)!y9d;D1B$S?yh!H8FFC z{Z0$1AiOIQxDMDNbVP2Q3fqcV4*k15-X*g+$_%8KJ%#ZF<9llwyM^i2uYr;}BQ4r5Nkvw16Sa!SeiwZV_ijXY_F;vUU z#6YmUBrIlbjx+^v%D9;}@84&enU>C`6HZQ)xfF;yr56x;^se+(M`Qo?r0aENcD4FB zYezQ8myvI1*gA(TNj6QYw|-=G zLoQ#PBuJjn+3*4(%rH#VdQEYXcx1?LB)5};PH?qymnNGmFT^Qk(;~FY*%9GlMnSMT zut$eu89XZr@uAK1`kP{dKw)n6C*X}?j!F&t@98;mp4m-Dri`DNgI1;?K@Z`7_L+#02Zxauk@gd7`E9-clL zWc~$Y65i!q9Mi0#zXU0J%~kZy_+fPke}f64N`#2LUGeI%Bz_|rj|yg{7-<}L55=l)$A0l{mkz}&1k})# zgSjt)^1GTksxR}LP)J^&u>{$A=tJpB=BDqYz#k`EVyPpcbAZaMLa2AR9~2PSY`rKoPXFAnsJ2&|6=Ctf_X{u>oZeKL@BH?b;37nMYWMr zkr6nUI{c@8%VpjCgRsjirwh1?*WN)LOZ|}JE~&Ps=*wxW(bP^i5f5txa9~n*LuF$U z8B>_sC<^S##?6A8wo{Ome#g|>ci{VR6Gky;Mx2182B)@PJ2rE4=BON6&=)7di^EnVkvE4k$(r0>I$n-akkP3qH<@G78d15E3pFEhn>yqV zAABgI3c^%Px!e2bLkRh&WMjfm7&+Lc)B04r_+B@yv9-;k?W6q4Hef;U;*8~OOpS?& z1x+Q^>`DBeCm%AUPf(+N6{CmD@!QD10lN){UornA(GE}5GI+{TJOuhYjoRNvV;!Q2 z$C-&?5P%xc2cVI-iSD!ec?^gkY8uRy5Y5=%C(h z?ZN-p>Tl!Vfr&o(Y^S`TOzE1BKT=n0iLezF+8cn`Oz>$1mqnCvOmmry0K%@mVMf)K zT5605Ac;lB@RSf5Yvs`p5c4h*a`NpJ!NDX(H~Kt&N7?PnpdO^__ zX}I+OlruG*QY^}Sg?J{VIvgjH+Imp~a(VrEF$;}gDrXD?x)T8)1S6vO64bDnkZvJn zzq(rhlW9{}+ejeN)S!A0Nts5DuovXbUmw;N82J^V8%*?89&qO#k3v^$_wPTvvra(4 zUQ-S0N|EzMMv)&n`%A(^sxexua4}|#CQmiJ>VG`k>hekgH=QgZc6WQn3jh<0UsDoe zcA>)A?*o}mO~4KL>)qPP`6F3|$|uhjLR|X6=g1?;66)pia!7?A3RapFOeBJPPGTo$583fT~9NK+3tdT;i6dfWikWpj7kl9QCjV5n=M7*3I) zm8~&xHp~*k^)`;~RIGZ&9rX7(t>v7OyZTg7TX%Es=(X`Xz%ii`7i5}UN|StPh?VGHelH(v^%5j; z<9w=5B8i#&1p**#Vgs4CNO!r61xZ(S@S`>dvEWNUT8bH5C3DHC33qFok{4XqNt%Wu zzEbk)-GhV#FE)*rXmcu=s{~oB$_js@7pCg5A8V~SYbV58{ng9sgY*|Tg8!5&RuBuk zJJ#8Yas6|QF5Zn|_@b4A=Ob`9is$d>&yWcR-vH9Mwl~_4V}%6qORut9hw4;PcY zuZKxnqTZx2c5;U^a_1q98=VAl!VAJ?2>&!Z<6Dg`&NGd4v}k{WpQY(17SeuZoFdY| zR^vu%LX4QucOwS2%$}~BMbb-OR68DOyd+a29hxw-3R7OXYEMyHMYmFf0p@ z{_SG1ilu16k6T4?tk|nbm2eZ)io76fO9<|-jJ0#IZG8tsm%`?@ly?MM{d2v(q0wsk zLgcFgRev!xBN)=Q#xG@No3u5=c3Eq9wk@k}TbnZIVtf<;8{?6HX&Zu}tf6O=FR`EG zfW^W$`XKn;UyGe?z*N@3#?BsF6$C5vj|)AWq&^WMTf2I<#b zFrFCs!-VOm>H$O>Kb%wLNk8inaj&rXT`(wN+TA7$!B*1<2fF(C4%{n?{Ze)PW^?_@cj9Vr;EZGSyC7}MFwFmRF&If z;2zv5tHZ10Fp|lEJCxnz@w|pF}*w>m)um@6^FZ+TB%K zPr-+qv8`;Du2QG5zYk#GsdkGsGgV?M&jC~~(2=Pb%;kN=wZ!IWbt9v+fMTsBz42?+ zo>ka*v3Vrn-W~Gr{yFkuc55%%!z(pRHCk&D=}A>V=Sc#4*JsjT$j`iPxzoTcvQXK# zdi@ndUUWC>lQ4Pk%Ogdx!4xG!uAf>u&Q1A~SEiHInIo$=S8Kodn!kVbc~i-8e!`LS zcIV{G^G;2joSfaI&ZxlfhlGxaR1lAht2OTPW%>wsJJxU^1boPdKE-T_ug9$~J+icB zVH;37oC3pj%#TJf2Ae}Adr?vn^K6DCpmmRlAK#Oe{p_!?egjK3ujMXoL`%N z^z_1c!Oot zL4m+eG{q}dN9}g27mu^rRMcRPt?wx;CQPIi1xEFKl2J=fpTRb{?=4%T9?*LSq2Q`$ z(->?_lC1ct1%V;A(%1wK`=cnIguXa%eKJ)hBfz8i}}1^ zl)2))(P_gI7qHhW$a!si?yl3_~=600l^c z{K`JbPNYM3Sw-l1gu*x36;_*Cn_iA~b))v93UeZDR|mu9nGSA$(r`c>Hsl^+KJrC^d#nNkFP&1rBWs zS`8qH0%@}pyLp4_qV1CJ#6zl<6;w{0$6~$*|7q=PPlICU!R~J(_F6WAc$NyY?^a9h z0yqVkC#NvV5pzo$HjC^LHLmsgFmmIxJicjYw|y!V?ci77%5jL&-b5O9*a9*Jkf|LS zok#!=9bZ3%4R}5FApDzF62hiGF+LFtsLnXLG8@4X%Tmd!a|*lum*t*|1;GQ-B;cd8 zai1_C*BIXMAPskdBciir#*`yO0F0q2YCPJciG0F%J6$~M4o4f61OIVB{*Sniri6|P}sVfOJ zRiuz*1PyWEMgsWgd!;i)Fxe;&hUUD2iNtGMoUogrfi#PCq)I2U=2~8Y;Y^Yo>Rt z5kr%}hG6k)IV5-iF@WAHc~YLl{gBuqFA+`C)7>V*>?Lbs-FEq8+BYUyM+4M{uM<9ZPoK~fH zM@8~AOa!Fdp&D;_Z%i8&alknmPkYX$8FCWlCy$O4zL|SSWl3ly?8suj^!VL_lf+NN zLOdPRrTWKuXENJX3%&(;__O zWZKCRccj+G02z0dkxD_jUoIdM9Dd-3DrVNIq_=gH3~grDO0cI(xw^zSBX8Fj=UN6K z;_m$n#iM532W*IJ9{%3rQ>d}`Nad@@n8~W7Y+dO%xS}FNEuHZsqB}sX&B&K=IF*fu zXM#ht#KAG)n@b=N{$Df+O?y{~DD&S*uf`O8hF!)(QydGjP=0?W)@#HQDryY9Ow3d0 zCks;5C=*qTnXUDKEa@N5>irl$c@4dX=HZkrK_z4poWf$HVTiEQI`l|YSV?Ba<^r$x zAAatujKPz{ZBLagLtX&0A#R(pAFjLQ$Z-CvBHxY7Xa*9}z8;&5MbynoxNS;`nXi#i zzC=fhx{*){fucDybdr=9LEs+Wr-!>oG%ds)`Nn!SyPa=kfD@F zwvs_BXC>Kx5Vs7D=Ct;TGEQe*G|1dEG}#0arX(&}qPiA}843j9tY&#%AT#Q}B@lzA zn$uQEspW zA`Bxdr4BnT{v2QLy*n~h;H7|{tuDH&TzK!6RK%NE+9>ZTWyH|J{%BzQtZXz`oTntc z-MVI#6v7CdA!xnla9dk5pL@VJDF=yLd-)QWF}W5ovW`-!b%1#!GB4aLtnoig-3S+{ zOdYR8ag;|mVCl_2-$SMo8aD78amJmDgG+(fVVrNW7Opahg0-NLWEdzu!S_gkS7MvQ+s`d^yA%oMw`u_VqB!jSR2TzOYpX!*{ zQxW8XLLRah)RByC$SFgw4DJOt^mV?3b%(rN2|HbY0vlk^@1{pRGo%+_9ZMFR;y9;+ zi7s)}tVk>nF#%)iDV0;DtH(T*SDzlq=hJTqkFQ)m*8t-g{Hw_oi#NG?nDc}e7+_4{ zeX*0CjGe`G!WaY;E1pQBoaSnCC zOx85oTlFGacuS0Fs~}RaEH*^pFQ<#0CCtgG*j(lvRg6urO;Yh;U)37m39aZwOb-@F zCFVHGtzIKy14mv;*~{36H;9A~!GsbeYWzrYpU4A8Kb);3sCaA)n9Qwlhi7m6)1eZf z043P3_pD!e`H8s%p;TA+s6#MJ%1xh>$CAnWIESK6RE{4sr-#$61T;p;l&)v0zrwL3 zM&o8IU2>nK+t|xv3>wHuO*R(V63Q@$h%JLn+%c@1RJ-fDF^h@-93{{_&pDNQJLc+qB=zG)9ucGuT&{l&&^$9&ki zexU8Zov9dJ!*TdJu2dz>LGcqx?QK$7S^^mt@6M0||c&O_JDw+xL= z|B_=Qvb1qe*CX}vTY!dmx)?%e4iXPi-sWP6uJ`z+MB+>Y~)gc85o*^ z*ykkWYq9-RLbc@x3%g;Oh;{)5$v)B zG{Cg6!yghTvLbf{*Q29yHM>5z3VQjt5=5`tM!Ijf4Zl41!ox)@aNep)#{d_ZqCO;T+;yR;APy(VG{SHZ z_t$|i+%(heF!p>it*P3Mw}(A2qaF-87S7DKxjAjtUIxb&BTi7?4Z$gHz8fo~1Iwf) z+r1kt9Nf|4VIr@2)WV83dp?H(V5fX2llD&xKwTg6ETOp$O2(6chKRwyT+jgwGZjuP zIppK*g^||RcW$5~cn2KkE)-hMkqDBGq4|ESkCB<}qs1_|Og+UQeCBe=6*UH}+Zx{l0xZm9E0j>+(_WE@O^VQ$nV#qp;2dIpJg+#h-=wJZKpr!=$woCQd<2A?=aRC6aHQcV;B@)!>-G z2`4fU0!?&nfq!aer*kXQAV`u;!8p38?n6WrY$M1`&a;{gVfWmDQ))|C*+@{HY|ztx zbKKrVN~g%thm{2?3{GO4$7@F1its3x1)pAvy%9Sxl>VR}XoE-|H!%qIjwOrK2W zhYXp_owC_8VvW$XsAP?>rP#R_D?tG-nUqX^dm}d~<7Hfha`nQRS%q^Fr(|9l5@pj; zEE&*1Y&t8q_p;0B7pW=ByGX&mohC@F*Um_Q67Q$Qx-Kcfak{(-7a~%Ji^{@tm)MVI zm@MdkGX)f3x+06wnrgPeGh2rKq%POg*mMdP92+gnK%~0M3Wq)M*JUP2<5KM^D;%ss zJey>`+C?}sCpfdUnjFY?qofn1vI^LTt_PE$q;jO>6qS%1?_o~ZztIp)0vF+#$l6=q z2`!}!@gCpk<_QSHl0gXdB0H(1(>Y1XMKmbPl$^czSCBvzVKT<3 z*qdQPF9_7{dWtvXz z_B+JXgor32$bve&)Q1z*R|k~I3C`+E9vRJ=xnY&tCT@$eu}Uj6B^Hm23~(ql7=81P z10@NGkW==0go0}&Q8!O$Ye?3X1=M@v%P|B_`EvZ%Xz5}7x{fWKzW4~%F+LV9oLgLb==91wk3i{!b`>+)K?zo5x+<1%YRU~Bm>MfL5Lh=z@Ze9g>MW<-jqcfy z`!3|C$!vpx$R)C5Kb9`%EV@nY$;L18qg_%37LgKi7N%GrSdSF$rTSr#i2SF!2ElE~ z;p~n}!66MWCZt-DxCdL+!V`z#{Ko2o*c0CZKYaIK_U-|LQKSHI1W)UJn#;R#an|hJ zzS$m;t>6I6QLXTO|3rh^MEW<1I0IymUEkW1K%+@h?rUIYRU5MT58J{_D}YE@e#`4e)Rv@TW$ea&*oOh}FETGq3$9x8X$C*32k^F8W&NK9rl>wMcqe z$L2|qmV0;&l0eoix|{Pxktg-6{X&JUDqZnzs#23J9vOOR4YX;sdcX#-N%6W5`d z#3-%h65+vvx}8>mCz6TqKoY!0{UaJyI@m#?7{oFmigdMqYPIXpq=pisVx#ek+~v`& zR3<3J(-|^jik_HB4_JVsSP$U-gWR(QW#8=BQMOCkU~Id?@Np_Rncy33z?7$AoaFwf z8Vspyt!dN}U+gyTixtd5Ry+hYZ}pIiG&y|ZFxSo-Z5SV1SrHS~k))@#Uu}!01$oO! zbReQ~hdE{yufGSnX?)5{6Xot*d~#8GqT@R?vk^;_m)R5jH1V!*+%w9)M)tMWh6-dZ%mv6zB>A+={_01Dv5Z(17q@b|(4fQ}_%w1)^RN z=*UW(DMlG?id4!r4BnY&lW`2!IM+d2N+4of5vi>=8H^8OmTMt4)spG{-Ge#2!h+a^ zUxiUhjk17DvC6=sBbp{NaN3V%e8(#A``)VaIkkT=ziqvQIE0qr-NW`Yd0v86#$kGw z^ETf&4{kShP1IxBMj;3*Ec~h;FSQzdQ?=(Gmq@W*A4B9mD{3X!N15#R0OB!ZkANm& z#c6F}<8Pz=xGxp;8dB#|>}Z;2{&n-_O__@hFLFfFKW}*;DLXMnd2>GY$4kXv548vC z@6fk7fmC&AV!gIBe|kBD-Lp}Tq~DP9D~%ynGQJ1LfaOhW@P(2O9iFWmM;Fd1~CCAq=!K?`s-UbLyJ=49^)mFXB)$YuRKPKNh?O(Ea0AP$IS*= z!fe9fJX&pbbv9gpZtvM|gZwu*qt`fR(S>a{j5S!fjAf?DzpD z$Kbj%7QkWfxRk1#<`=Sr+9{T&g~Q9_6;e)5%W=5;jRrPi>0RTZKpjd?dokY8eS&0{ z+RU{E&c6scaUXctNRZ?C5Ai6Z2Y^;tN00o_5XfOd+2f?EgqW+OY>N2Bl-59Uhy(5R z0?ov*IIQX5$*^P(0?16Tx-tob3sMqT<(wSM`v%ejK&kvArv!P&?uWTYW^=9BgjQkR z6_*khE%9RSvlmk^K3F)Aa0o1hYjpUQFQN{v7R@*eFIlG^b>F^Djkceb)Z4A8H}qVs zOj?_-a;8wGXTWj=`$O9e+f^XWGP)D+4I~Uh*2QBwvLy1gHVMpj7ohF2uJYlFO-6;~5&l6a|+BkD35y zi)6Ntd#!fgC~9&a7bT7zgx)rXc>Vg*MP{RJ7~7|X%=aCf%oc5oQb|{2|Wa7E)hFVu@y3!k~T|mf!Eck(4ABPymwtaUn2U%{VXgnD+ ziDO||=LEAokk!aV`bNOHFmZm_!%9LRL`4EIsW?z~9wMcRF~iV5Xm zQTNE;e9t5U2yo)30_%*z7I#Zl(&&Y)V6WQ6QHL z`ebk1Vk%hR(@EvX=;jIADrq7vS-tJ#EIWWDTUW_ik9ms^K~$z+*;`J{b{APINoA`o z!jZ$C3P=`Bb>0k8WinLgs$;^Mgj;jZl*nuS7P#L6(aF+~iD~b(m?t^|!(uP4?0Z8r zS~g>fjq$^kNrJQt#MyVM4N(F&5YUGuHu5tA((fk@e^gCB2zR{)_7Y{w|UKm>D+V@!d>)s73L0M=r8uOyviMRCz^yMx)5F z#qG|#(*l6;hb~coZK5WaH@Y+(iN;!B`A}0hq54HRe8lSZm1#(gk=V>t%#}IstyUpD zq6+M~7vtYr=p5F4ncZp*RM9zJuL4oo00m9xo&K$;>fbDazfAs8a8=eO zg*lqwzzVDFIo?vrDZ(1*5NFNhLU%?DJ;>)sgM94fp>}so`B}c`h#=3$22%c$FqJMx zwPLcEMFYug8BO_`7UA@@alBGMn*s6LIh7v};Nz^EIcCr4G!b8bs5(o5`(L3@5&0pDM4tD@7Ah_+l=gqEvLulAuV0q% z&Y_mBYNeFrXR=s4?VXaGG6$9=dkTe$NyC9lXBp7SEh3>>5Kg0H1U!SGf_E!r5N$_2 zWnmpmH6A0FJYY@MB?xM6c6JAw95Ya=XApil+Z;CG2M3I4+NF9IAb(Sp3TlvfAaor3 zYqW$4lLu@h@txw63XZfJX?^%v`t57GxUh(~;Ho>pWy;>=;p9>o@_&u!G{&M6Z(q_g zC@`JYh8Rih&8;CfM@;m>-_+i&PwH2!6nf_Xjrxv$>9YdlJw9o}w|AOnNxdt31+%4* zYOCp=;gomTA)9lM2HCAW-PZH!cDW{c?*1tR-t(|OBN{PR#ZMIN#OcQ%3i6-H@!nhj z7=mNsohYiO@^9p(URiVFAD+q8ww@{S5K4I`GDTC`fntgVn)O(nOR+{6!;;WVq4Q`1 zsi?nX*G*fCU$edVH%Q_uKMRl17zfFl;@^daY!st0t!$*Q3yCf{moS~^5QpTCB_i0Hq>;lIR<~ww{ZWl|eltd0HNBYkrc%Lh0LT96|d$zrY8dBBf~VfrU!P0s7~= zm}%3FP=0fx`WVrr?)5JEAEIAzzWtwb~%4#dU>wox>=JT z(WscZE5tBkD@q|E%ojy4FQ`u>DnWKvo4*Ox;z|d8Edo+?E_8@+mDMvSheJZLMv^Tr zf=F-}pyR2@J`h*v9c@ZyV6HKkwNbE8<=Cddei%z5C*o=bt=9Iyj)1@=Z6tw<46#x> ztv=FCTY7FXS_#E8yej1ZAxRniN!kd{^S#aXdf37Z8xj+^9q49P;=cO{0(K8`53M2l z5+HHRmkbD6NA!=KUcq5aIlSVS$VTmi>}m0eDdg)8a2ZLE{;EV6rHTyVNs4_6q;RrK zpP$%XZe$R=8aij&$Yq$3rC`GlYZ}W~d#^)~`EV)+fDQ@ST8&FVgei}bq4HBGW;GP# ztSKv&GQZ6)oVzmSVsPi#)(xCggPT6nJS*uLth9YO&vwY=zqT%}!d#JniA>ed6y#qC z)4^`TWY0{?sLNwP(B@MZSuU=eZ6UHYGuhQHJNAe(+3FOi~ zMVVcS^O(emlZ2Eo56MZPr%W_*#V|-dL1Mu11TorqG3{h-4e=#}&dL#Bb%GF*?9V8u z62RGV94}^7g{mN4%yf#vDL+O((}D0%oseoJ#~C(CUcnp8l`<7kM5nDUlD9=W!X-NG zn9Np3yL`Hr$m={u8&^7M13uvoNMF=Rclx~tt^OV8GHfi9Czb3(T7+qppHpKTt5XWG z7YCm?u59I`fgcjI&v}vo?WfCbR5cRUm15^nGUJ~Oi+Ruy(OvnMrx{d$ipgDG-Uoc- zO3lqn$_M+GZ}YZfUlw*A^cXB)01hx5=#E;{7mLTy5s8Nkp@Sqn)+%7a$Y9g*<+#k z;dWhTT=poGzXRNHi6?r<9*76#VJ6cW14_9jN*E*@bpbQ%@Hm)qNz59?6zQSd{{vV9 z6e>xkmpfBna*5-brWWk2`=UOwN5}!)P|3XruJ&Nq zWDA0!6;$tnCzYu1W$acEuGWbkEmZMgXIjJxB3;7dxZkBNmr_b8)1uUclF8U)=SWoH zV%rgtY7mPusz;I$<9ZFpSuFyrw9PX-dB`Sl>Ja?-)WmKVnLu%86BQl8C(}advoKTG zW1zrhr+1Bg)~trJ_p&A%KPJ|opSabid|Gf~@@61J@U9$1+`Lo|2N}|$T2(P8Mt-mW zBPMiDOBx+Q3<YifhxyLQ}4JHj{6 zEUG9evTsLNtycXU6oDdnDqs~2+I&-wyrvm)K$7WY&dAo~<7?ygg#?D#Y_=Uu00NiD zq*%d0`km>U|3r3%9cFn7;$a!=g#WRIbJPvYNyOiq4+nzhW6i+2Vqw{QiGTyL$~k=|<}tcMqv z36}Zh&K+%3+LUm8z1ig6Yn|9Qr|Vapgqdz{ek(YR>6BsVs6@!8M z(Vt`stEo_2QFbB71e+_q#wJ`^Fr~9Lb%Cf1RFu7J1&piTC0q%ao&BhGUx*yUUN5hY z$m-RyyZ*=I#Pk=)bo^7525+O@64aT7qC<@&q$9!hnO)D(a3rPYtUvW0j>L^+9ddE< zpKaG@I8jqb{UOOc=h zvqUi}X|FUVmTaSvRxFSqpC_s923bAph+C$Z>GI#7JbV27-#2$&t!+@~?tJy~$}mQ6bUMjgS#nGynLGBz zG*A!>jpM!;w5gFydKr?0VVniFfKJ<2>dDAfm`L;56?z^7+%9>eLs52F0&ZVxI zk_Wu-gj!cRZuqdM@2A4FGXKsQB4%PpWuxfjAS9(rq{Zs$+Q!b>U!QEg*j#lf@3#L9 zs#Co_?rZFg4v`aP?*k?$HizdcOj;&r{A0DfC(j-|e^zM^-8wUCvk0a@f)SibLaQ*| z&TseC!>3I!Js$zQL1#P|+#7s0Up@!KZ`ZzkzVWwaTi-&@nId;Nl8Z3K=mIT0d%pJU zMYEx2Q(P*7%(Wn^&>1mHK;$`4J$nu&X|^RKu*0AuY0*T&c?f&HzV@uy+@sNP|5VZp zCeUdnx(=dltUY|(Y>Ol%YZ%KffUnK9wZGKcLF~`FdOIO2km(_TLvzgNRi(su5SjZ( zCabe?7m5_~B{&Jd!Zs^7&3;Y~f2L@NF7jtf+#aJilwAXD)pF#8l0trvsT-vkd}32@weu0B6$2$L|OIKRkl_K zzZfG27%eSdhaX{L%jyY4;qC^Wg_O*Ue#*ak z#gzRaQ=BYtXvr}Uds@ffPe0fZ>&6AW8+!N^8)|e-`C8RvJ#pHPD~xCHBruc}(!|nL z&%O^YVaYC+f51ZY7%0mye=}EMIAXbNpnT(42BXIWSP7#7l|ve}Ack3@;_fY3nak1IgzV8E)mz$?ytB2eiQli4Kx;s7`;kv8g5IGo; zJnP+fZ%9R9{>AaMmEqKtyzqYNue?Wc(XFbkETC=yCo}$EX+>xEVIYO{Z;*f?Tc>Ep z^M9oko!&=mW|q;?(u($1(o~l7+mgnz4 zx+m6!9tK5zDhV=0(NO=(bqUFo&4tE7DHw%o$}XjP=vtFq$oG-=dvZhf)(9Z;XdBN-E8Q3HWC%*)fNB zk=fTfnVwu?2F8FXMRx(ks^oTEES<4vmKFC|yBem~F+&u-!9MXWf*zL;b~IM+I(B*w z@j$DA!c*>Pp`YNn5y4(DQJBUXLULlY|?HLE5eOi3}-`K0nmXJD@y(AG7M4w zxvRJ}8os?d{KM-Xe|PtzB&?&2rRC-JqtL}Q*h+a-m>h0>@GcN;R{s4Ajsm)by@{3n zQkGR;t~yHWw_p@y6d8U+qO{QkF@Zow>H9ZqH$LZ#@iMz4%D z&Y@2mN%Vv%t0uO3LQ09lp>%BE)+C89!3%GlsaXiDh{2viVXQB*nLZftf68`JNW7V= zhQ43&+>+g+*#tjaG%4mW9{GzD5z`qY+@SxGYaYd6w3$Wr8=ph2F0v$g?FNZCs;;f2 zE8N1vI7qquGi)usC{{8Fl%$0}Is5`bb2ub2zL<@^?+uUd;Ss_C&cH7|`|KOCT9$D& zN3+~N@f4}1amv-qdP$6hfV2?DluMdKxXK4x0BjDf^nGpAhzYgTrL`m=qno8%*yKY8 zDLBXmw`M(5>9vF%%?)3lz%iNsK#-g$ccL!=+owoSrUaVk(^et zl7AHixqC|jzEVsL%4JYBoCn8l)ZU>SjMbDpf?!0wDPw-4UrnA;ea!^{Cb|Zw{e;DQ zd60!)-C4Q0{1Ho>-IkTOo(cMNcZz#IA-a`!HF8C^OWeB-0cOSAgkgq!gED+8!wec5 z{kWQxK`}k-H6m`{2H=EqJhpv9li=h2N`wJO;|TA>9%O$7tIsLV$1)yA!R2a*v}nj| zI!7j3La)%^b%-F1rA3B%UD2~Z0gl+;A(AeM5If&Cz_sXyJJ_3??Qlb^w(Eorz}!nl zQ$bB+-T=2GVCoO``VGP)S8wp*4Iyr@b$;{RZ@7Da7->?mFj&g9893kw$XAw60E{N1 z){5eP{(z`~BR>a=&|gGqVtSg9tcnVkZLJ|QEoOK~R#iPQB&w|Gz`h(PFEeISc77f#Z?E80OPC_5liq3D*whNVD14J#Z%c83c%VPa9=KFoAl!lNaG2c6lmR`AgmzES%VNLGK`r zm5QhVuEG1VsmUa#?>&GYIQ>R%Anv~CH#8cVMwkT}9Fd>&avtu92ucd&Zo-A>mhaJp z&WLADV&K@f0jaZ@nWd1qa$>Dy{|IcHKD7S|aTNb*^1qcLA*_ePN1C8H2`u(d7TlJdDC@Swkm^d_VkQ2O@&7Bg9xSioKVMR* z>f_DQz15pHZ+=PadIPdHRY;nInKWZJENTeNh|vxpYAa5z>gAeVehT5ivefb*P#E;uI|2SY)Is!0^X>iN=XY4?b?mAEk?>}T;y9u@+F7#$#A&SW3N zuR3200`Xg^2mmUP+#dPJ!xf+CsN`lxoGUQD&{;_`J$(SUU1&w@e`s$s_|*%tdgHUt z4zMrs*=Hl(I)pGf@JZ=CwWx~!(T68D#)uZ0P!Gi-mqq^BOxb>TI2q0Dp-3y~MeJ_~ zh-xWjky+dJcO6&NjA!Up{`mpS+2})rsV7&P=!<>cC#1^xKo- z1TazM%WZCoN+GK~NFeG7;~MsMvsl(2X`Y=h%P58*v0{ z%h0E=RR^llJX&Us9y(C%_tj#ZE=wDIW+Yz%Sk&VH5_%(FUDept04| zB#NM3Us*^gr>#hjh!?EeQQ)cZ#0j0ZRM5>7m)Ho+CQ5IecuSBE5N5!Rwt|~d;Z07( zdn(E}0ymfw8fzoUKH5xz68qRar4JE2%HcDvi z{#?1G`z)kG!*Gjz8~daJDsTdL!I;C@C0TWXMq9yVD~DjPP7BHa*Wg1iR~!}%7vcfH4Q_N2O}qeQt{ z^=^VD3#9TTo1%=K1;v~N7N@Hpk4?!9&{A>EE@;#7Y+S07NhdBxl7&Lc^Vn243YqRj zIPYFx$3^hOg0jt2D3L}L>BRN_|%yj1N&EQv~X{P z`j(|UR=qjl7Xlnt4C@GI9-~hG7&jQpitJDT_uAUIurho!qN(R8) zT5Knwaeza0*wAQBGZn{WYZ~|`jU~;5xx2I{Q-O;JR}Ib_oe()D7F;_+Hex-id%QcI zzRi{*!5lWFM`T&;8hLL4LO>g^5?D(06&5GeNVk;2IqM zPRx#(9t1^Q3P8@Z5XpNfKPSv%00zLqI*#G%zq0b8tFhK^)>dXD0X_}2wG;#m&CLvs z(&Wz;i-^^2-Y~z-;L+pp;f5r=Y!UeE=x}^GHuM#xT3UQ^{B~NDbpAm6$GeVC*hGa5 zjYB1;K9cyRs3r#{H{|dj1-IXTk&RgQWSzhyv#wGceuO=+oy_9+K3#aQ_3_8J3{5b+ zuqMsk!e$FkW)iBUYph}SX2S|T-kZ*3J;s-kW773Y#Eh;@I)>Z5bCW=nxIp!{TwL6G zmz7DjUPFAQZmPq{DjVoCNPF!KTRO8t+>9wwr|}wX${rBvVeM#qmW6_yxkePSJz#x< zO|pXvi?PK3tJ-jd>zt8xZHA+ONYY@*8Q^;U{mO4weoG(p{V%lm^;n-#parnFqU6cb z7dW+!v*1r2KYX#a^K#>ue&D7UP$D^(%nf{8}YB0yclvi=u6 zOCHoHiqXjJH71WIa(y|u$zCYMgm9LYqok^<)f3)3WVI5$Lf>|eW7@YCKr|5SQjir_ z&}I0`KjT_JvP{yt+#IYNO@69*%(xskw|LTZmb1xHv8Asu5dt!X_jPINKjEeYp#2AT zZwneAWWp){)fCP2F2NkeC-SK86G$vY2Ve#e& z6lS@c&esJKx3v4?XkmeA(M(1GG2M!r2m!5_tfvkEs*8rS#upZmQ!SVkqGK@OrV zWX5f|<4}~b{4U5`+e!v&imdvcb4TmrG2Fy*2`z`#7<~LJZPpNU0SZ1vL4$jx zFQTttP@(;9dJQgj@8wi<(o{E#N@p$b7?&tK^s$@|H9&%Q4t{>#R`F6~@eQtWSgU?) zsh{=o@eXESYtdv>gXNFIA00g(S5Ei;aYJR1+<=_(roVjGSfv2R$N>ZC-dl}v{gY9qyKEGwgV><=rlw~B7#eSbwUVRiHS zUbmQC7p6g}lQS*8hNO!!E|2c>zQZAAR0|?yKcW0)^yS^tb>7eE8x94e*bqVi+c$m; z(mw$FaY0T8YnOQYFG;^B>)|UHBZVkMx6Gu+W2BVY8z1j};45AP2|2Ja*2!$k$6hEC z*+=G7{E!HUMJ83O7+aK{GrEFlTMH%~ifb8MpUg0qPr8~8??VBbk7HL*4_X_JrL!xOMVBCFO4+9b&&8Llwd^@@5NC5AXr z`l`ExBMgTxwJ?yWGMc5sLu>IMNTh8QJkWKB{l@#Y1v5I>C*A_id}9&lINx)K89g56||-bQRCNDooq5 zSP-FMvXvz;!F7%i+xD|8vuO&{AgEGhi4D`6#4#Wm6icYBpi|ILW`wuR9V;O&3wPmk znl7rY+B(e#kltG66D<^KYJFU6Y*#8KWjV8~;~OY|RrRBmMn=Hy(kK9JGwJA~RF17t zx%km_3qq1C?eZw)e^yr{2|3xP{;mJi)ds?t^Q3a^EmG=@;D7WIi5pG6;99=w$C=ld zUicj2!_}3A;M$>Fiky@t0G?gD*57hb9_(fuSix;WXW}@PTXu_8P>W$<9LTJK>1%5=2so6y6{tumhzU@DMwK zfuS+n%1AD9uv3Wj#;uRow#@*$^tW_~w%-gHJCwV1dD@L}&p3#Wb%bZyiraQWSc#b# zZ4f{}7_w==X)P7~lYP)l8K80OL#d>KrJOBU2#*XmqKMPKMuZPJT4Y|bY@|fli`WAu zRzO18W^}G;a&3D%fL5+tiTJ$$6BPn8pUv%k0`{^`A|(gEXuG{NA3-LbFFJ^<@mbO%Jx5$|I7&38D~&~gewFJs^#SUa~MFIJbs!3ZASNKQrk zhMqJPPT11GZ#@SA%~)RwraAfKJ#sIGFA?MM^XKui9&b?pDo;UJB1jzIvX+Ias7e_x zxb%goA=$+=8}tvRI6sChk2_M6r@_!B_ZJgL^~_iyY(HS8d9RWyb|a%VHwbibEonf3 zUKBO$-TDkPOcf#RJ$w@A%VwmjgQ zh^rJA#Y3ef_Pc}xyJPN(%4FJ^!&bqiBT0XONkNhqnA41vVhm-3=#Q$zDn7#eBR<60 zj{%ZR4P9f14+Pw9YQ9_2-*3gR6O5rCcLUmwZb4V#GPWE< zQb-5b#b~tA(-B`5!;N;X48P^!PMv@}^t;d`#MDH7ZM~jlMe%`Y*@jdUT@b0j^&C?A z>`19$VQA0;E3=v28|H|n2bURIB$adIq08d@yk=!;ak^%)6={AZy&5NhL{0<4IT4vw zq@Hg=Cnd?^#;##m+Daw{JzgH{xVkF-T|Uwc!Yyxz8A6uZ2K9#2GC&p!bco70wYV$U z%>1-3GQOBpz6ewFS1@7VR_8(Y1Z)xXMy{3r1i)N5z-vOkh!x0#M|#f~>^28VCiE^3 z^z{Z!jVRe7{oUQ)X^sHhwtPew68pz*lS;Y`q39}Z{EHC5AKDP^-yzHrNHg?%k*z+j z8;kKZO=OQwCMmLIHC}Wcq8Fs^o}+jj^@?c}X&Z@)(Hida(FKzEh)6o^e~W3e&`JNb z|ANuT2Sg=e=w!{5Gb3u|XD3K4EcFyGj;BkmB8x0KUr9bc8gVL2KAYe zh|bUEckq9wv+)>zqcSFXS6KC;u7y`JN}0Lmq6Y>)R9D9H#N+}&qs@4BtDk`G)fNKX z3I|x*AQy;D+AJ;y6X|9G&|*`g1iam&c-V0f;(TJqD9#g&fp{VcbCs+v2BlzqeNolq zk~*SRcD9#Oa>CT!UW>9}G#2cm#3$)p z(G!Vc36WU|j;PW8R{t12>i%olu#x8|EwJ9Jd;mM;6l3)c`ovj$NgBll+UVp4=FdVa z$c;P5FEzizd*X#^+TE4X%|}qDUD6?`r;jpN(hGIwXKxU|F|aRN*iL=hN5=kpJk?{9 z(R=H z-ML>FT0pW@tz=eEsUgcp-HZ<@V9YeG^_OTQN@OwkF_sN@5=h|q}6ySHaKnwocUb99*KA_5FmjiX^dS8jq+e-ZoNRr_XeY~)jJxWj-ZW>dIQaF z9h^-vm;Q8z3c~&6B=Qyqs9L$mY4qDw)oWcd!JLLpRwPv_2BQkxuR$!)9BaI^I0fly zc{+inkCZpT9~!j*W$JGvMB9T`xV|CzkjcGFUHtB^!wqk6h}d@=1;O-Q?cKbaCi%1m zglCs>09b=ppB#+~bX$GIEqkGl%iAjB#&1)dWPyGz3wGTL#a|XNJ4= z5bbWuL;&_rcXSYB_)L_1$|Mb~r>Iyv4?tpQ)H}q*eb_&UOhE%^4NqI*p zrH$W$$ed@qy$Le`G$A>@pCC`+!RS3!BPp)!jo*&W4o_E;cZ?;|1vA}#2q7#owM+Lj)<(D}bisru#jO2wQ-eNuZxanJ zZes*6$meHcCTsF`02^453t2Rm{2K+AyiF1vLV)U?3kj+MOq58cZL)3SA-vw)R^QeK zSku}ibR_Pk#{!1@9o0|WDWQ@)_wHl-9rdVij1T8yj;qnh(TIEN7w)5|=3PX-ZUETV zDliSa*}*k)&|`^K*Sl3HRMF+zq04Fbsqqrw5j%QJx)q*F-Rv4T!Qc+?KtcDTNs>t< zvY9K9+ht~0b4Zpgab$AJ%KJz(eOpc9ilNErvSp%FzO&QXSG;DV5-Ex!6+IU_+gjV; zrmSeoVNh;R(-hfdoCaCqtI6q`Gu%36ywTifPP1Bt-RBUe1GY>yb;UBtwt+eIJ!4l= zP@NFTi)gSWFY^hPwHy3SV1eL1;lRo*jg-{{*mRTFosDlC3EL~v+5VkuCs^~e{xX}u z0SQZMqjLnx5}o+Qd^U|wHxWG`iLsb@^v)gn$}&*y+*`Q|uSyKu zS;&o!neUPxR9bvBQ;)SSV)i=-k$gmGwkc$(?ndG7$24i!Zb4ut-*84VmEdl78(Q+7 zWDTsa7ifVMwh}!9+1gQOQ+9^3%^V8&OM2&%J)w^MLdf52ztDxg4&aLRW3OZgjUDEK zKXcv;N`I$cM2@7PsGt~b67HUMAnRA%TwQpl5%WtY2qr@7Y`zq>uu;i59=8w}RC4*f zMhd6vVIQGXExqA3DdFEmtql^PW$UYDSFja5S0wC+ADj}#5yi1=8z!iO@Cu*Wh8QMe zWvezHcEDn`UFcowOZa(@PSpQz;|}X(x$hmC6KR!uEb5gy#M%q&Erh_EXm9A?xaR-T zOAx5SZhz&?8$Du#1xSV;u_3!SdfY}lzOXy>LRfa_Sl0uj7x5<-9f+WRpz znmCkO2IJzS@tVcl_&N4lE~v9Y4@te!KjV(dSFS`$itk@)W92HMgS(6;3C>+tD|hXO z@h%Q}A^bH9E|wy3JEHj7X?>|d-ZZ*$v+9$rB~imCdDw0c?pTs8VnJ~!SH50doy?!| z@DVj&TW6fz?9n<#7ufLJ!4prF4djd+6W>7TjPV?-iun`53{_6X7OY8iKx6^0yf7h# zyxw7Yc=3ma{(jv0ZZ!M{E>T>0t(QLz^KPX9s)I|K><8YGNKfvv;5~BC9na5Z<8T$q znx>@No5-~djsSy~p%t#6?9ji>ynKVUvXsc`6QHA};r$r&AHgHdgCj+PeV`033wT9G zyY#|@+;pU^1@Eo&UcfPaqrcM9_e%dp51;gQ7eAlk0Q1HrI!t!YX56#EO(5f$?|5pa zV%+kB+U4NsSnR$tEXn##QiQ9uGNOy%BEKzgfq^=ndV24u+^BYjTcvbo?wlT6MZzvq zz7r9BN7igGH3aduYxwq*fY>4?E2!_IcQpC{XLS$5#9kRZ+k?;&+#Q;=9+u?VY&M-e zw+r-u=hS5cN0HAAB<3JHa>VZ=JC-y6|6S{yoZ;BO`$7NDPhRXi-2BV>!_Cbv#=8eo zIX}y25#FzmL|?&1G#(ock0t~MDeLPA_?1$ew9Q=g1r^m9+)YI4p@b$dgYHWyV*o@W zQY*S_x^;IVT=%nFbzuxa{P6;_f1b-NnpZLTX#fK`=22quCTHon@-bWn$z2#hoDr_9Vdb%FBF zs!*)v8@<~%d$$JLo454xHm!sn^n^-cZRE}@PN#TSCAmydh??7gdCd+|zWgQKV0u`7 z*(t21WqI1c9ePHB_TvbFXJrgmi&f8E|$J&On^s=h1*}sBNSq4Kbx<*3q|9^ zn-V)ZdL;XRVkB_5Pn^&q<=p&W`n@gC`0t8+cXVJHr|{6B$rrv=R-b1_dl zbTOcyb-Ay~SQ|ZOKXGN1AE-IQgqUw|E3V&@8;G*qmC0f}fBdd@bL+c1uW#M?X6@nQ zo}@Xo^~o2gd{yG%$(z092fdrJHsOySso&BYVfL;42RSK;w%!q2z2y zwg>+P(Qhv`rE@rluHqAvwu=grd6~Q{mCEE(SjxazK}x4F24IEbcg&cC0)2Ua<0fgq zXS)~i=e!i*^b-6{=MVmQfa}tkAY5LZy+MY_7&Bi46qq#EsbCL=7yzg#jOXLSx2vlm z;T3S^#yXiD`lh5amgU5PnWE-|{UD^&fhNOY4^J@eJZdUMhjmZCL#-O8HKj#sAC9U@ zH~z_RR_V!0Smkp&Bi1V&C4{MTl2j5Q#o@?AmotjU{57Q}0EsliuLQ}0V_34*WI&o- zEv4v=Wb*?W`W{5O-Mb4RjW$g->Iaz;=_7eKGY zhm)@hCa#;_`LdZ$QaMYm!w%RJ64YBKkMsOM-Xt*DQKudhVJ$R_I3N!TXFOA$(XeU5 zCHi^?2#urRaR{Go$R%6ClwIPdRwEz+r@|okqsiYib5Pz$Ye)Pv(RQqdh=%{<3EX$I*h$Vn^ zZVs z;Z6`fnK#Ydp*CrCcOel2K5IM9=Niw|ry$wc zNhIu^i`#mo4)LdpMvG<3wO6oas{kI+f7H?3{tlulV+))q636=+Ou8C-s5rFIva5AW zQ=3oLGCRLC+bjvoFk*UgG>`{xyv|G8b2VO9Zaxqr7SAfs8eGH~Z_~x4mYhY(-hFNd z%w5{)J>e@*{4l6w)LVAxg_qOyfL3r7LA{l0_TDRS>G)DEk9S~1>bT{cGYIkA!46+t z$k}1S(dt|+YdEb`^8B}Ag!BM=Fm1S@ow9~2*N7OBEA)a2*5r(=4Y(PDID<6P%7tPV z=4*Q=A)~YUUp`(tI~Mi8$N}5w3MapVad`nyEWbR2%~>l`?Vn!^`1ltT1zw!!`b2Ty zO%)>HlO1Ii&s#HtX#lIzlxmXjq(SSVCyjr%Z_VcieBkeug&bzr_2fGC%dXdARoE-J z!K7hu6(Of|?&g9Nqj9&MzolJuZ3#XzW`8NG#QW#3-Jt5oMOd7;$HVl{;g3Yh#~U~} zGuek{V7&KS_WgNYMl>*M9=B46A1t`FF!S|(MJ_wh^o7Yg5tFwVfW*mUaRpdW{D_@o zcY>n~N9p!f)pX$bA;U`OsevWBMer{=T}lqgT^+o6ht3@ire6nxAxYO~jFX@o- z?@d(VWacCD2r%+5JDC$}IR#32cdjY0xXa+^X&(NHnT1&OrOpSGiPghK#*Ih+sryf7hOABu_}c! z&mz;16GI>SYt#$0M0dFA0Z;k4S`HayRYNmk2VlKx@eyBrG;0`v>ml4)^l;E$HGVZf z_G?9~9_%Au64V6TK7y59O`ovD8`B6MEwBWmtrHwv?hVh*Y0G${>s<4H&DhlQkraZB zfGmxBzJgHHlyW}Hbn+`f9%-Gh82U^cfA;A|@d8TluXLtP|IWGTzmi*}5yiF>cWMijtM4 z+QEMntxJ@nxYcFVp&)nEsi-*EU{3s|EkKI&_p_A9J5!D+?P`>;97m4TuBYN@1ie=*Lx;o9gSmGWL9tiazAgfzU zUJ>ob-MB=F_=Lbr$U2G3Os5!kZho4*-Tl9xf6kvDZzxv48n_5-bTXbFj1QUmC{yIS zCuDUqD0d}d9{M$*Y5vo6AefgaM`TU)kC)ogKh+h6|djnu8$Ca4ec!X(Enq zWy!~1;q%-X!_OTeFj~B3W0W2vcc_Zj$RE&O*fd*uGo8MJO8KtXN-OZ_s}8B*&0H-- zwADZqeY^l&v_eiAhqRMCPKk!pld(E>ex1QSSlz<5-|L&a8l=vS)nPl(-Qy0&Qyfjs z7k&>{U=3i^%Ybzg7pHQGe=8XE(|i=h(1lYzrh0`(ei<%#yx98g%hz8nKghC7{N#s} z@f{ne%iAmOCWprd`%HSjkpI4BtYgU!=GA}IfLF}lnhnXJeL~D@xdj1EYT30of72pW zY;7U`P(J}7^Z;+#{spC~OHbVz;ob$A@+!Pt=LEE7!LJ(oc#cOatFfrR47oJ3%(ED> z{2MW!GqOp-PGwrH;J>{{?ku1)^L2%!ve{eu8GL*YnI2`Uw=jlBbvk7gO}=LD%4BUm z9F7Th8jcR(q{xF`cW|nLcMzZLo~jzJN%|C`+r35_Y5hR$lToa<%Z;?Kc}9+fKje0= z#4y{>ac)IrM@a=BFo%~Y=&0Ee^PqmwQb)1aK;B%iz81KT()0?$Hrw%^IGt9Rl%eg) zFq=cSHcBKh>$R>7AY4hZF3&cke3syOfHen_$Of^{&Oz9aYDTMBKwDg};y$a)8o(Mj zIBdzGQ_uEfYfwnLy~FLM@!p_6MN;nh{7`o+P3CC!O%3`>U+J69{=lR-C4Gu`VTv^L z>S9dUtE7y0gkl{n6lN;~B3ij^Dbr<5j-xEsjv%oXPH{jsE75~C2eFl5=6N+FQdFI4SRc)h%`!1o1Q zX;DzWfTdcyc*lqFtGLmwWCRqaq*oxhFAt1#gfPqukA?D5g3rJ?Ec&lxfQHuY)QSH} z28htA2@*fyR@+56EM)wX8qp<67osQYy8`J}b4P~u)kg`X<6p@DLA(#i`a;JZh5r>$ zK;@D-5`$weiBtEk7>0^swZwC*{jX$z^^Juf_oK=kmiOvX@BT2*wn7g5Dzqm-^sz=0 zZ|1*rGQeCPrGY>fuh}=z9FuLTbL=c}*6Up!uf{VTC{}=18yD<%%+z zoAqtk*_h_89HP9q3k^fd99-+8-FKt?@%F>R$p|NFSPG|>Y-pdoE)id0wm%V?l z(kXj)zJC<8h&jht(l7HyWsQ;Ph}ERbEchNV$daQ!)oD7SIKnQoh*547(p8%HKjVi` z2983hHMqtc8^|@HH$OkJ5ZCR9d*QD?%N1wJV*T4vXBh0NbE^hnpEYo9wOASv@N!2H~SUP5I@4@zTbum4{!w@C`QacG9xt7x%4qNe8XfL(8^8$rWGX-8O{Sf z$bHuOnwJv1-_?xOa@5P%8BLXU8wTgbu1qhM&|l$0?3Ewmle#4fS&9e^o#KOHrsMRK zaD2jY`htz>uWEyk-t!UwR28_Zrk+D!ArriW8R z<#73vEl-BxSNW19O1yz=6P6+AI)*S|Ia!h=-~>lASs}^wfV4Blxu3!SWLD-54~-#9IIh36 zEPfIe*)!Tmxptsf5%-{GVx+=O=g*@j$fGmE?2tIoFq6*jT|4vjX|xyY_-w@*-sj2{ zB-(7euBY03#ejatG2%};#W-ohLD|bo`&=~iSCD=OID?bucy|nmTZwph(Ce3TRL*I< zonqPVGse9*RLWdlAFrh|7%PNffX=okJ;{mUu_Mn#JuX>8z6u90WgSUen+a~H68u6- zi2?9SttROLp{QuC5&GWqXB}>92IX_-9xvYVeiZSefEgace_7PllQxQnUtH z*rz0gm5l&E&!ndUOUp?zz27bOe)_4`|AYP;qJ~z;S`=L)lVP$*S^LN(ReVbpqw*7Y zp%nPrD}VU$|9o7&#e}x~l^^imymMKME+PP%1ZaxE{%c6yUrP2>B-Bz&qJ@QmZhS#< z)Ynp1KGdV;m~JCuY*;r$4M{{?Db8A@a3bRt=&`CzUs!6YgwUbF5HV-3#7$&|+{PKy zy`ynhIK+Tcy)auZysa_v;qG z9ArDOZ71)c)yBl5U|(PSn*LySR@_#8~wC5 znV;qgrM{uaO_rp}aemD~>W8AVwYgk}nYZWfiWV!!&Sai?%pMz*7oN&Bcm~`~P$3l7 z0H7s{fi!xxX~0Eobk)k@AYx;utre;lv|g-JI@&G*Q>=JFa4xZ9mihH<25morF?u*= z-j=SNrC0UM32xM=$8R0yC!yIKZJfLHmhB7#3a3sUmcX_0$EUcZD!*;ovAiyuBVaGO zL<}~4Cy64I00`e5pPqiO&nUe9&HB!(wT;au&!1s&G=h;w?WeYonM_#|oZf+BULKEs zIKkCRs2DdYa=V`r&F!ynIg7kC!8zztz26(n_Aox| z5zJs?i<+1&Hq0^l_7E@`da#}H_7G$Qd;!pb_Vq{4K$;5n%LNjeCIf2kzazP z`gh^q@t!W&DaZo?7!n#hf=@#%e?)mVtFT~|Rjf9yI3v@bnDRgy%b)-d2&u~?R@W9~ zh57fB)7=9&&73!O;e6`#apl=ze-*)6_-o|BK>4&|WD#mL$eNVj>RUFtIw(1@>U+EU@?fdn7 zJGjyB@C_vSppTIA2dmE!ZNIts6er=99}KqS61`hE5yt@Z2g@rrsXYe?Jg}pgurh7w z3+V^xm@HHNVhgNKtGJIusDtSYcD|>vT<#5ffB4^G9pCOfUtfC$2z*>SFV_D00+h~? zbFz!Mdd|>fM7%CZ!8UREXk*QrZnS!KHrcDTdT`=w(3dienm^!xLIoUBYV+xfR#NSa z-;T}>PglXjE^>OG3s>8MWZhnHsxG?Zc%RZEvL?Q1o89=d*z9J(1!gyj&6rvRc&sf4 z_>3=?Nxwy_l>b!42yr?w^-)FJsD4~L+UKg&DpRMDkc)IE6u1maP2zCU^JZ~ap+0mX z{&O8vHiSK{)zGwH?1I-ywuHIo>aW2x8h!wp#T7X#!PS^A66+Joe*~Io&+%1huEQ>2 zfPh8>w%| zk*Xy%lKyZWD<2m{kw?B5VX|ZM7p0IxH{TLVxMkQ4FoY+aYFsOKU=z)DxCZ)df5QBF zj+<(-1FJQwqdtTxY}|nkeFa8ckA;ZwDpqXU{`N0HZrbyjJ5;g{=Ogb1MU-J9WC$RQ zJnLLsqiyDL!Hf!csf&xnrdepDNyMx_nf?a%)ew#60^g5~3Rf#TvMHGNyT5 zV>&(+X}EMcMMNvmi*wi)o*i2ERv{3q@f4lfi_6!>l+MNahKuA6VOdHg4w+e8u8}9x zEf=N`rhJKmiRHwS3eDrF#$Y+fW!5prP7Y48$`pIop<%RC@|Mc8ODyx87WgOjucZ16 z`bYpg!HZZtd-LAE+x^j%GCJb zL-c)GBGDFX!Y@6TX$kXNtAv zTU4@3DH;{vB8yj-=?VM?`MzJJ3U1PZVNZeF_=v6s!Ohb=?oW4tWR?-10e>Ng0m;D6 zn0`YIh71qvNR}nhcc7oqLkFKBxNkmSI&mmnJMTyEK{C^k8P>cvlose9aie0KzhC+7 z%5Uity#Iw3zaHyXyZ-vg(-&(SJFgx-ee(F>i?yAX8&74_Nx)#6`*+Z{P{JN2Yj1z@ zevIo3v8Ut`CW#o7I~yB#jHC8_mb8dT1>bI|egY-J{DO98YbU$|h~vk%AZ+Y|HOVj4 z=HOxs+hAoOjFAp9E8uq%In$+{DRJK*6&RdScTUtYn@jpTIHr(@=)rGZ>YfCavfX2-LSumJXgZj4&S#*m*|6qCqe=yDwN@>iY0=lj5;1v@OnPg<> zGlngJ0c5c!l~dN;L&o>(>Pw#@9hgnSNF}bR3*FkL?ABRFK~QtI{kpx(#-t^NQ(jLX z=bzHF8VZf1v;eS}W$q*#^glBSe3n=^f~Iw7*{2_#!R6Tlm?AodrvlcWZ@%CO zhy#RKVsk>?L8dT2$dCd0I9G9Ug8Lxl>V!K#48Q;Wd$}um2rh<>f)xTA2iI`Bm{gJa zlv6uz&L)R@JAXeL&pzOmLK!|}3FXQELY~lTNKAJ$Mn+Jn@LQZb(6a~9jCk0AdYrmq z_MKA*$Q}4Pu{VsXjWIHe@Jq;|@ecPztYgh(VgWQkk{Y~vm>$@lsB)fPZl52EqZBKN5dqaqo9XbEF zW`8}K9&L_i5dAju>Rq8?kcPfjvfjFV2o8_-iCM9#Ziqc%>@DEgnuGQ|n%TaFy@Qm` z^~^|T35J+iqY7ZY6RAQoG>#)VT9NEbh-#1g6B@BhtuzY9Je|{oHbaMf?moA z&hWze)pz#5a-;9{l>sj2YD7lac0d>qT0F%42fi>7E~Mq~m!w{^D7m28nCX*wW8r1i zSa@sVj_v8ezh@yjmK7rJjAtU9G#Ef;NkEaRHVXTQhX*BOsaPlmmDnRG96NN%Z1v?s z#s>tZC@!GaxmT@MLL`OE2~sbs7-%j(s_d-WqI(Gs6>)l%6LrBE#%`mhD|h^4qcF~j zWL6PtBM#K1EM<;2-4rhUV8S@ok}$|aGJu|wUKkSPGVNaKmoU`(mY^X6sLKmS(dR9S zP}7(ok?{t4D-vu*VnV;h%H`^)dm{ZW_i%is%GS?D@cC#UFTT6~)XTN;9ih#TkbvBE zT$d}B%n%!DIi##jKjaJI>IhwuVU+ep+EQ_uHhb>y(!w&va`8=VX7kxeych@0RasZ3 zuX!g)iZ*4Ev~sm|WJ(BeZcp~WiNH%ab4>cp%&_LhjPU`NsFbBsPh5&XS<0+VWc%lD z2g`z=Cwqh8Jpd2mG86(>@ijEw5-r~!j850pTQDEc-vglVU(kcg6Nh18_k5H{Q;A8T zmK)+a+%9Ahi#ZKZ9#DqlfQf8lLQUn2k%&}jUmM)np|-QL1A8y*(gZaCFcUSI3KKB7 zC9UXb#$4Q%MTBZ>sFaOf&|D>g;<)}8YG(Eo>R$X-a*bgAnx#?dpV0CrM*Qwk%tb|| zn~K^}(f=0fX9FrRVGxLA1hOBDKL7py){J_BP5WGJcB`+&F~8^*FeahO{-3zyW@m3q zz1oLp9Y6s_xB!51;sKMvgPXKq{k|O|$U|lk>mY2P<|EQcx{w?>6d zX;1)b$ZEC`v?^zemT~1`1?$UV9jx?+Cb{DRa86GtA1&5N8b|By&pOJ4k$UZNqgo4N zpd4~Vb}^VjrA5abDiB8e&*u_>y)LpB$E1Cy{NXN-w$f=GLQmZ?xSfYmuCBt^osTzB zcyc&7h4E{=p4uRyGShMmXYAm-w22epFBCFs=Tr5N1sO?bY#=qcuS&PPO16+jZnhjc z!ldO;(uFn$gTkg6rX) zRS{hqV9jd4K*?01U`m{h0zkS5V@2iGfb}ndAFp@q$zZDZrc8R^OFI!=3mZPaFSkCL zM{NE!J?kBv%};ydV=gScQ^bl}#A*!vh0f9YfWsm^gom$yn#`oYG2=b7DFlyVgGZ0j zK+6pvm?uTO_#kF_zNBB|CN8q|_vI2)Uim-;E;*7>k+J-YX%ki1Pu36^ta~=7)J3bvWTGc0G0v&-TV})2Zi9drU2Bj4e1+a%;|K3Mt8Ug(4NX zQxhMUmIduCQ=lYa0^YNs=8e(E@#bb} z!VASG;3ODEu>2LREoJ=5lWHOGMiW56bo&rWszy_*Xeucv#+Pw}>?mPhXe8Kzgk)DX zhQh+N8hU@nlGiCrS}P=b4nPd2W|vv(ZJJ*KgAEg+Xvttoro9yiCT;~HL7vqlKQ);o z?M3)Yyo;coT{sZ}{wwTA#&(I5GC|>HFhZC|nUfT9)qN29(V+0DnG;d>Qr_*81LK#I zcl*Jzpy!>-v134Z)ge=-xPKx>pvd}E^Fl3L7GcgiFNdTcYH8spxAXIA{#J_HLxTYW zN^5}U&Zq^Dx7Clhm2T~^(QTFQ?_qCTMNp0F?~#_^0W0zg^1N_rK$P>I3l}G9SZi|L zO~DN+R+S+t(;(O8MDD57LT9>PfLT#H(n%P&nZ&;;n-@|6DG{&-&2vkQY(`0dNmI*u zG(9`q!vXG7RhtYaIDq4xOl2Orwn#>#s7qg9cTq%_?sVH)f_Mn3WvRlo(qHXu^;cv= zn!6=PoPkoWS*FN;A%0nWwFy{3Z6eyZ%dO5_y$tv-;}0ORx$@M7XwSaDT@M9?B}H^= zttD>^28sVfWs`~)g@Q;Afb5?|8X&#}cLE~e$``%g{_)!P2LK5xgS{LM*^M34A*Kip z0!sc3Kfk66KePq$jQ3?Yp)WB>vO0^bAx8#vfh`a3iwBgiE$#q)HHq^_UAYW7kg!Yk zle#OEoC6$q6jv>yIIJPjgJj~{usEo*`QdncGPrm5F1pMTmPDsPdQ0*5quDV+{OjIj!5vm{d~C`MJtT`Y_6_WF2)fL8sdfyOZ+nkn?Ku!Km}+4%2g6YTjV z!K*4iMu&JO|H_TFG(;5~r}cq^P>-V2i0+?((NGlfM~NOP@N0Mwtf1qvTcXuEtDf8P zanQS1t^Hg=n=!6R^{n@chR0VBzOE`<#5-IFkQYFV{woJ3!CtX6sf4w1eDaWieqm{f zrd9aF*=Z^VmxrPWGpBqHQ9-g0)8=h!0~e&%nd#A zU9>x#grZF2;RzNf7u@c6(6@|eLcpu~Bn0@KcjFHpmCP}+u9d<>Yz|rkd^{d3C}y!2 znsGQdI=m&H4rXKZKfu`m*N!x;eZ>;j5Mmvkt|7YE=KLPB1jIfJJ82s-DprRieTxXm z(|I5Dy$%tG>gL`D5*tvO;bU5-GPJnptd6j?f}0ctgf{^ib&%NnBe|mxYdNWfs9mr| zK3;)U@=qz18{-gT6fJu-gMq`l>BA~maf<*XqG@w zj_;3$Hey9!Soc5-3G^gX7k4`4_wyO>IBc8$m`wE)Rt7~>P zau!@ymPyDYnw823G0}4Y9$9h_=F#nRO2h*CI%!#7B$#J#aHd>nw~4GhPs%prG#B}% zfQ##RD)xXl$x-m!m*DhcyGT^=bU%oMKhLITCoUrsM%3Ci(P~ zrkPGIh_3Vt+sMEQ&8N~j1&`C1waOXGG6IpL2(j6EQJN>B?en`PSR(aRVBSUpZsb=?Zz?vvxgn&QkP zwp~Mk#aI165(eGp<~y9X;vB`4?>38ISGy zsMP@=#MZ4fJtPgp=5lhmcfWU6@b5L}ThJ#YP^2s?!o1xUuz8yqYKi=BSF;zLnOG3& zj485F24V6fkl7hY$z4bmMz3Z?0aw zRqV#b0IAExUuGo_HkGpELUiol|3tw5^H6aq;&-bbw9Kj!n3iUn3 zm=H2)OXiE;ge=C@zcybq^t)ER77G*0neF-}ru63vnbJp-W2{&(k=1%W8vUS;YB7(0 zkj-;_<%Y7EXYt4#Ce#wLZ=Q+QTuoldfG|hSJQ}}HO#q&G6h+|6VW_{g9Qq^jhtBEFall#8kE7d zLUd+%VU~^p-`+~A_8U&L(= z8k2xA7`=ZRJ|ag9HDq;E!VyuQny)Ob(W|%@P=aP;`-6v@-#-{^@BMi1_HREf_xjpOh>Y=`b zuRF^AE-(ALP!=nyAZ}E@LAYr4L?koN)-N>11o^26q9w;-9Y>1JbCq8n;>$Yu zv-B?=8D2;p%krXrvkf^P9umBK1&4q!fqubIgCu~?z)gO*t3l}!t0|Go?O^P(ycODF zb(cWZw6J_bgVab)@7>itKzaI|0x0~V0AY_BZDApn;`dsM-^+{p?v9pEJ?_`~8*7^{ z?jb3LtPyFma9QZL&pW;$43KL}wcg$2n~h9P4Lgf9ut@OqG!PKKge0k)0=it#fej4( z^$2mE*qFTCyK%?V&lQxr0hH*C+|k=QKujn0g_nD52jCbMYE9;}h;NBMG!F5lL~i#$wR#1RMX+^UTv1cc#y6mVy9$htqMrzPn1otl(FaVp2w80f6(L7=s%DVJSrxQKYB zdtG@;g&|>{L~k&zA@!2C*kVIE?DWn208%8$x1JP6e6wd^Pu^l1j4>`A8bI*6mM15Q z@pb|hSkb^CQx;(0Rnk44yxT-;Ne0eYojj5=5C}B9pLE9}$zv#DFz|E0j@2%KVwv(? zXeR-e<&wux#K*wz{@bT=i9;w(kK%S-MSseMtKy*2#=7zhv0rH;!$)fyk0T#c+QlL-8cjBuOxn^_OUBWqSyr=V$*m^noOn`>ycX(RGSvD6@H3OfzOkcr9|u~ z6iK>ck>pV(L^+rX&xTq90lyW}r=tMtRI0CEXeLz}cmZ5idRElZVeknSB^jVFHK4_t zTHa}J1a5?{Bc#lvqJ(9=97M)ai&z;dgv*veaM~M&&^Sxrj)5`|vzgVnT6K0?h7)@} z(RWR3TJunay|jy3X}63hV#BR9sUSfkDIZ3gR7>;~k0J00&&8UO3XgW3oSs96u6 zKHYhQM1X&OzVT#jQ?;$AY>B0ziVk$M)m`MA;L(L+_?kr3vW_LK8jv0p7M8$N^zV); z&ctXpJW{Yf_}73)$`1R+bp;Afft<#Muow5HL`QNB$ttJR2{JM$wL+dn0cs;x1mpAo zV?{3TME4Z0JXdbaF@_oA{<(1hblu!t~)LbzEWu z+T?8~-OECfJTGQhD7#m&kgi!6TV&|06Wk%Ri^17D60@`HG0H|Iu)R%q8ynhRXTwmD zQ#G)&>>fP|K~U;Z0X0QHr#R!YamJaCirA;lCx2)xxrZtajvO$&|6U+;x&M%nrht;? z@@Erx8vZdJlr{DMP68-fd}NafvChXX!F;l9{t3CLDO%?siZE zmx4Xj90A+`U*V-g*Mhc@Seo33r$ZyFMfn-g?wv?`nTWM7(VbEvj3~B3A)iIY2}%j_ ziubbRzpPb`oeSoM4pnd%N{2>oUyE@Pie15E4xqZ)1DR?i;Hl4}(4;@ZZ4B!z!^x5r z-2hCqKm?;Dvk^}=-|(x{`Xz2H*qwNCtayi?pe3n>l%O%y#<9t%*+vpQJ0ME<9GqWM zNiwY{w1P!4ubpVsp%4hW6du3+UTiSGVR8-ak zE}&A-=B zwAw1~o$lSCb7}>5c$mI`Srpo7UBl09&y^3GC=*D^&?=z|O2Mj^!wJoNUE-k!&% zz?&!2<2}0)Ht5*a-(tx6E4MuY^c*%3g=l$Ie&=$j6@E*y^&Q>Oh&v9V61U(R2GOR} z#>I1MhvOq`P~EuQvy14SJzv|{c)me(fa|em;FNB~p1BmIF0>udie|-zU>c_j-^`}( z#>cpu&Qq>qIHU*EJ%&iDP97Y5FbY&VyFl>ghX1zS zNQ@lul!_2ZWfE$Ejq~>oSJt1GD#bDhs)YTu2DXJtUFND3XtPn}1vY;35+Rogi2P)5&-4DT7x|^(>!h zrHK-)aW_GGj80XwqaAa3jF8uSRzbN&$uQxQIv4d#x$>rMT}FR{WX)7JldYcn{0VP1 z=gn?GYm-Q4x$A8sq(Kj*g3`AAh?n*;@g3E3{Z~2#aE{d%>>$ytx3KNT1dsyRdcfV)!=qj=5F z0j2QCf_I{7z1WEMn?u&tJWY}pf>6)~()60~BaO4GVv2QzD@}SE1cd_SY#nh;g9|w$msOK<>W)$l~INR zk0oEhtKZ}Lcj&dr%h4IGWt!#hvIv!=EHCCd8SP69hUchTQrB~crX=SjRV=&>+!Y|= zEHCMRiwZU+bZYJwBU!V_)QlZ@pT6XmtwCgYYpn0fk#ey$<8`aB1P&7IDn)k!Px_j( zCw=zTE0ASvH^Hm5QibuUh4ctsLnu}PUt|V1I69#6)|voWGhVj}%U_JMoOsS@2{itS znDXD=W(7;3#U?;y?J7hMm8~5h(hGyG_U{ZB(KA#wPV($)|UMC4WVr{C5XLp{*u3W$h{~n;N6-R5Rg` zz!SxZ$1Qh2FW0+iTLxN+ zGj&$8WznW|1rp6bVW+xOF!&w@)qU3?XKa-4*ZOZJ$2gfU32ty^5l_sYz_={_MdE_l zh(GM;zNCxZL^^5QImR&H?EP@AA5a`q3HP9loDv+K;1wFjDg&zq z=Lf-=VP&xchE$&Qxc7a=G+EY?Xjp+2_ zi_whRjuV7!iTb5*oXXqb-elGUC8;6IE_Qj^q~cbi<&riHvq&=_l#zgdwrXK~u@d$U zny_eBFOkhVq9j(Cjo*%Ogoby^QD8JX+wcOc4r$vM%43AlHwLnYm&}$>A4aSa2H_Q| zLty!Q0A9QUd{)YUH+Jx<$nJ=fDa~QC-sZvR-lK!@?mLvQaR;AsA~9B1U8Ifoo=%S6 z5e;+E);VrD#e;kXa;1%+?GR;TOD~}L$38d<@mafXC$ssfUR#L+vU>04>*bHiaiMQ$ z1#E#1F#d|1Bf+b$x8$u%9pymW7D1}AY%-x9B|)MpPYb%{Fj6%;lcPDXCS#Y#B_S^} z4C+p0gGbzbgW$HT3104*)fXtU(!={0J z;ZhJ7!%0gCl){!?)YB%vWx$0jHGPx<(^M_~G`)g9lZBj*zL4^_t3v#pDvo@% zH4Z-ssenxKnZB{W=n6Wf5&$#PikK60+w+9tBmSwr!gpGQ>WarfsCxqCN(Cl$ z>}a*1V7XHx(IK@NBGMaFy}!{cKkJnftSxN%p8zbK2oAikYw-5S)eH9z?;Me|@v=t)Q{Iit~BUd)5`7;aAt4V_vaao!y*bWe9tZH9d6mZk{ zw(YO_|83BT2Chw~{+=cp65q*t-FgVEm8ePCKI@rcj5`qEaq$})_u_&vc`eKuOTcrO z)h3aR2{H&&^srr)sLvK7l(Ngk=;T0JP^LEF8HZ$^EE1T~e|h}w7;zpU`7snTg!%Mn z6ZDY%X>vT?Lv9VZ&weL_v5VUnxzqW7931Dm=i_of3>P?;O8hMZi!lweaeFIjn_z#( z;IdX7G><~ct|aujRyMOeRDgIZkZE0oF|=^QMN&mo0(+s{mfdGvG$|)@!6G&r$z)(5 zosyE_86I_~8(6^FB{K+`lXJpc)vOh{0!uXig8r)XGm%Cbqu@>XSESLz9iz-tP6FE6 z3#Vd)C$+E?X<5&~Dhp6%6@=q;MbBDQTNgpXS#lPK&cE7(laLP?DAI$?MiDkI*VYRS zY-KxROkdHxqgdcm`Et9DU@fF)hYHX`q%p5CKq~Oju^QP3=Hqn(#Cn8YI|obePu?TO zOJ`72kun&?+F;vEN`Q*Vy16BO1ehJvKECh}LX`0c!pL%h!>`N-Q3BG2#MB$%UI$A= zm2!gZ1td<3*g?ICwhrAc7H+Fa6ffYGttKlj_&*jBYj$Db;|T+<-SBy;EhSW)pNw}W zZzm9lkdZ%b-ym7HZ>;uKR#tBJwr`+6d-`~L`xvyAmtGY# z^CF*0F}Bl2uNy1ZZgkO%6bz$HsH&cd3lP@OQ6uYPz?T!%M{dX|2*mOkLA`jDoGcxQ z*@EIQL z%|^$&2a>_WnY_6)+2^92a_Lm>rj|Xy(YYPC1DK5y`L2-L>JLBupO4G8J|f1pzw!ek zZOhhlG6bQ$u6FVE<=s;`64j%mV+*!#A1i6Qw<=|wAI*6Fh^)?4Wkr%3 z(V3vChpdr^sHK@`{sf@x@a>9eRPc+#h}TGaE0!&%q0cRAu;G*~5W$74SY$WdSJ#BJ zRelCPer0uiXg+>tcVxqLufOI2sUg=k1Jw0jY4nNSk|mo3vEiatSfxEjyGsgn8|u1> zj6*+)tBeOAsnu>jhL`aL9E-7CEw48Vh0p&nJ;qdf`Qnk>8ydL{ES@?b>4lS9m^?hL zajg_7AUN_-N>9{D0xUl1O4p~l5>2F zX_T{_m)_E%(B*VL51F1q4N}8LDB9en?fyqT^JXHSm6S^zqhV}*xWdVs7ZON=fBDDgY zD_xm+9yJhsj6RlFDP5JrTdb4jlx$XLC%8Ms+r}QhH--+u!!Vaf<5)Hfyqq?=8EuwV z&aJjj9q{PR_A;4~*OETe!&Q253Oyk6pt#==OVj%yuS391xMw`t7sug?0WxJH;o|R> zYx=0!m$0xz;TX#5k8xSq(wb~7PONG$jf|(cjJ4DhxuMFtsyre-bd}Q=Y*~FC{UOGh z4>c`#yEpuu$ZGISxUPUFt>CMkP`d8D5L4d!ac#@c)bMU-xq)Lf?+OTIZ@NWM0j%0* z8-&yvYA%dGK*m+eO~>IRMvAiLpgpXq3Iz#tXt)@cYFnseMf6pdz`C=V{^!PQ;nnySoR)$=PexEwqI^57fA5Z!ii zgm@ueJAAm-tJY?B0n-kTP1KF?{`d!^$YZbu?2@gA!~Yl!|8aNthu87v&dTuh%{%eA z{Dg``JqRm0Q>h@tsYUr>=T@o)1lZ>Ya3Oy~5b3cpP}QohG4%tyjM}IUwQz9iCuK!V zYHclJ4V)ay1OZnr@^_|xY1MRw`1EyfZ9gshr(VI$3nninbtVTkuKS~-0CkN)=@2?_Y;w?Px3 z=--hj#tE<^?nb*2E$7Y4nLB8*eGV8bDT}k0Du362X=U;16|`7mE11vVQn<`l6Zc-#$!_hrcO8iVsz|Yh5hW$= zbBr5o8}uXPXc1Iea4SwF)usIsQ*1UP3PF5ym68jNYQ+tik^^q{j?UoG_A@Z1?3W2 zRve*yUX*Ao-ZcZBdCiIm4ehb zw!2;7!0r~UEf+Md1o)b3=4+=6jCLyrkj$f82!>*jCndNjoml79xZq5)F0XWgRfa)w zEHv)PY?l@@#K|C&C#}Pl3e7=7%;`R#c_7snYI zYo88nGdMwxj#W?-mc>mUM-|s;SU~X(M zWl)U+%Pj`Z&*5BJXmr%#QV)%&bG%PoEh^-^;qIPTb*Wnk+OA>+Ip<&i_Qc=Sq7k%E z0QvW2LtUL$k|;k__x?HEVZR7YMYR+M2M>8;zxU`3!r%@k@5a5)SMFX3s@1RNyEHo0 z%+W+$(}tP)aww*fxSTalvM}(Q7;bDIBdJq{Aismb_A2N|(XP~Igx24AJnGB2X2T%dblgmdK1a-uCfp}?P5r6-6aGn;waSV2Xs55D+hm%M#pf$PUYSX z&EDlfeFl&>VdiSuMyM-t$pDf@1R623@+A|~PdZ-dFMVt-o1tynwnzzOiFRxNGH+`O zge=bVy+}9pDVlT>@fg9janMQCjnpoTfKC}UYf?UeLzdD+sZM!hD=AlBJwt)gI%WJF z>2u80(1(bwI<3zeB*JcV>$?pG*&Xjg*s5L|nRAhG`?3X&n`66^%Trao zKW8KhlV5fA&|24AIu9`vLMzx+Cy$ z4;LaLWe65(q^o1*+|wTR`VmGex%hr|#)vv!7@G@R6W?9D;;WI%-3~UZi(PCMAbqHA zaHOfyT4P=@*sZKK)rOhtPl)-`K zLpNcbIn=~r)MY`W?Kun6B}Vq?>rvZ4sJ|o&{#;MlwXXK!3ryDfuuhk&QpsywD_Wh| zWQ{jXq0I&ivtTh1Rzu@O-H%C^l_eg?Y~U^dUP%u%$X7XWu&OIkzO{G=FgbFj5+~_{ z=p)dExh`GBNi2^nN&^0%@65+Nh8j(AgH`owj!cW-+>xV zGOiBVRd}OINwQT8=4Y4as@yJ3_lg_Pi#p7_coUwEI94m>2zW6B(8iw4c@0bfC6>jIU(G|YPy{(pN(=qgbJK&`l!O92|N=U-1w0BFQ5EG6e=K?Tn>Wnuc zvNnq(6{ONP7Rb46ZgD!aof1v-iul1|~9 z3Q`741MV&av0aCOZ#lm%L{?p=bHXZJZ$9`EaZ>I%?f(R#3dDAcuS1D$mwB3ZNpEtG zOp}wHiUdHfQ8$&MD3T6#YXPwkh|Ro_i9B)uKM1zBB-5vEgohroPd%`Fs6&p&;vND! z;+M3w6k6!!Sq<(DL}Z|(;21)|4hwy!^W{sTQY6>OZW200};S6RS1Nd6r^Nw~aUkmgsVOlFD)A`2-yXKb?YwawOK zJ-m!qO%VR`@W_MT3=p08mf@baFiCUn3Uids6~?~nQKz4qYa-5UT5=-!JSIUB!5Yif zDU~VyMkH0sY3HbT^L5fQg7j&d?O<2s7+!0PT(h*8E?{=s@cvj#Uz|4DpCFV<_ZWx6 z{ORIEng`1llj+BN6uzr-A}}*&FAH22Hx04 z(Y0P&p>??naLrE+C#O%5Ujgc%bt!ANcIj*Nl0n??Zwwx+Zr|)J_ip0H)^~S$uWvoL zv;1JNy?N`W?Ew-vXuWL=<7UD+y_K8FJo-5>PUz0br@H~Mp=H?^NCv1!ELOs54DsK@ zi|ymI+k0(`^jAVBI-^f_52ylEn^%HkF@m-=aM<9?l+zz3a{GVKe|k)UCjh-5$LzmB zv3x-HAnVA$U}1{9gbdenA>O+Q?7zNs=bN>Mk9#sN6}7@YO_^_Gdr+a<;*>IIaF3lF zQFJ6_5MM9J!Qr}^V`!JD$N&n$Sy+%3!;Ca?I-YO{#8r#z3X=ae5DVRK_V`w2{b{O%{@N}+LrzwgI~)03aJ_ik;k zthlTW{bVyPRZU2OyRz7K3NVPNAx{Nzn>92F7eBrHIC-im)goWa1UXbQjWcoQs8lumQzU@$( z`RKA2>>cNhM~_Ck2l0l3rn5Em%98Gcn1_lK_S?ArvH+Q?fAQ*eufhvB--Mghabt^Q zL9r2G9&#j!``LTq9P;0oS*jN_dSa=@%TT=1AuCi~hbn}IWfZ^Gtzs9iD+%$fh~hgf zqU@umrffT*bZk%NPst_72M2+Ox>-PmZ+$rusH8!rS%ypB`57I~H3+20#Rx|v+a|>c zf-KMIBw63g7mC=LQMiv_E((C2H}!R}S`JaGx-N2L&0&3w2!{i?vQlVBgen2!VBoCU zBV^u<6;S+B0bx-D<%1r)B>{3x|1~@FgX>>w7Ea<)_=yd0{IT}}DbmF_+%3j(qyrLu zc-0ayh&`-)lUp2!VGF)y?bxgY<{A?7FI#t^IMC(lm<6jWds2!B7F} zc4U}iicXin=5ewMseU1ZCAe@`V9eUO5GJENkz-uc8Qwf53%QS2+?lol_^CUc@*WW< zRg~jhJM_w?9*Pu7IH*NliR1I>ba!<4c>F%aE;;MmI%$PeTk9GmX5#el{dn({?wbNc zKhVfQAyo!f&!OoGJUs#SuYMtf`XLm??1ksYFu}o76eAt(&DRtOvD`GC(6UB%q@}V!$)NSHc$E`MQGRVt9Qy>rH7O7krbKKT&{FPL~ zdS&&b>^ive^n)luc?~Gz_>hoSwL$4Qpn&L3LP?)a_b0nCo;2kA>OaC^GG1;8PKlX)@9ak`Z-;W8i!o;_kxx~jRj#C1M;cpIi!G$Sh9|O_3vYe34wuoS+F}!|f zxFWgt@>s&^Pp6O?qdoZy31a-~iPW8gD?r5+f-TctNwOrX%4Gj735Ch{)X`(^RPPq+ z6jZ2nU5^^Oiuh`b8#pl}_YT}5ycrk(P%6(L**bOFWD}0h*r)TZ<&$jL#&_nJyDu(N z-_rwQ$Y~cjM8*BT=46sy8lWPNyYGS+%S*ZNQXtn9?@^O7o)ZL5rjK~6Y}|$Fi&Q&4oOxrTY27gE68j|W9X>lN8)yC{x&-MX?eRk|Bx3TbTqNV^iV zZu%c$T{(BhxKt;=AM`ioe~nD7Zjs@A{tYt)W3w~JEF3bMWV4p27nThppUh!0>D?Us zz?~}0TzU#Z5%8C)X$;Il>=gEc@KOBS#!3~}k6`|Zx~7EDy**X@Rl$S4RuZdJ2w^$F zLP}xD6**GW_O;LyP3-kN?36U;$ZUr$?15!_bBELY-thPycH~sG|KhVg-@K|Lt@(uYRn^c6`x~Zv}#DP!zDU zc$~KEBAx~&8V`?X|0DbGrW9-);wN~-qa~h17>AUJ=uiIP)PUY7+p{SaN^rZD|4NMn z9PHD-wSXFXd9n7UE=6r@q)fX=$<%o7>NRNI5qGuev|)jP-K8EOm>xNj=v{Y)sWk?P{eFU+Qr)E> z92od?PARNri@_GsVO~IOP8=#?c-W!0XxW+}IC5~`vW*I8CU%p3NGakpK zNFP0rPk{u4K5V{t_|=oAPhR|Ohrgb#K@qzv3B0mz8;|h*_s#cTt-W}NFZU`{9zI?F zM!r?5Jzjf-TA!nqi>JUnF>)6rblmEOVE86R!nl^z)e>qTf8$a0`^F=Ddow;ARlgE` zd>3|2QbbX0Cl+PdnbV6Qn-Gp+)^k}VoCalkAMkc#`F;<0Mn(~E ziyjv|FfsKAyUF@ugp(GEgs=^Ed0!h0nr3;6^46l+1*&6ACXpS@vbX}tX7ig_0zgXk z?K+YIdcHGaxb6;LBt<>PW%$!~lF{$@7!wbkVV(pPSo#`}5vvq)ew1HMy!L>`GhZz` zh|wTccIbGk-5_Rv9{`h0j25f#U8m3La0O9mA$-X~?qCI0Sp+?>QRtC z^GKSmsioXT93oO<`xR|1O@-*5jk#dV`@!C`BcuWrnkFjKheHJVshKUYE>dPv3zVh| zgWRgK+)V3&lC>JH_Gh-}r}@l54{vknqkNHR7249Pjfy!iaUn;KOmxWTz)Us$Vi!+>1I@|RQs%Pli-!Ra^0Lbn;i3z zsp&401cA20=c@-RFTO$GFw&v(IO!Lf2EV-gW%to9Vg&qh_zOINM<>5roc?lghvDGJ z0*y%UF|_-s|OEcUhriEX2^fw)KjG_nE?SJl*7 zs%Xf3M@+bvZ3*j~E<|YzT|m|DXXhGG{Y4eKRQhb!M1VRM0e*19jWgc^vt@8EVT|R% zL8v_#Fpzz*zb@=fR)iLIda7hesV|aE+332<$!23*V|XVL z62Bm|nb=WI6W)!nC=@h@#P^$lSj2EO$4BL{UYbWCcWWW6+!G#N+H~q)IKX0oqGMTyEH@Ri3&M6385m3FJGieDDc0U)FWMjJnt!B7#fSP3++{(FBQJi;U9c%fHE5xrW6ORQmjHcR;D%RAoZB zZ|=MgjhMIJcnL9UteE?c<>JZ;7fPp%-ElJHKTq;#p+_>VSZ1n~ihDu%oR%S~Q1L&+ zf{|*a11Lk1{c+g@vgWz@>z^-9zp)kluYaB%@lS{vD?RboA5wKOL8uL}xUiZJeiarB zwgD9d2!lhsS?Awg+~Fp$NU*6mjy?gpp^2X+o|^29<=xjB3g;G;ESoIYoY7G zM5Qhzw7mN1H+S65QkppdoW;_MKB?hA)sPM?=oe>X?0V;|_YDDAywd^rv-8o=&HnNBF6gQcL)_8ddXkOlz z{FK9%M6Z#EUhnmT+En*(I6?{B?%_0AT9O!WyVG= zm=)NJ9G7hr`m-ITd?_CSe?yzX99K?n0wtj-`VfPB4!pwysUy0>OP36CAng+A^ed>; z?6O71Mn7Q_qrW-xus!MmN0|a83#V-%3@MiC*yOC&LNlMBzvktMNJlG78f0dFBWXnH z3PTp@R^6ID03{3O3N=T&|5HBgQ5$2;i4IGT7La7MK+=S7eu=;KSAXUtxYOK-=CRL1 zsO~qn0=7aexvLFhbAR?Ja;1FA)mv@TG%`u^LZmIxX8wev6c0pIl)~+o{{em7Gl@zy zyQW&rpM+rp%E8%a`dZ&)viW8eFnrai4Iz?rJU%sL5hydKAW?d`9?A??e{?k=Egr~* zr9}|~*p!Z1Uab<~<@sE<%2%hL0wX$h(nAm8h037VPOED8iTOse>WJv@Bf;Aa~fr zMsyxcZL8Ti=RW(WbFNRqNmQR}>gBMXpTCd*Mh{3A`Sh9n?g#TimDZozjri6I{MSEo z!NqDT>n`#O$f8<^CS10)No~s_A2nV6KXF=d(Oxz8Ro~y5#Gv%ygSX|IqSsi8v1O1E zo{V3g*g6qogPMoAh|MxwqpLxWX%##jp49~bfav|3`lt&u7SfWR4nK%rxNZj#@as+I&WaG47Ll`Usr z@q^jnE!B$g^HFHt<>AAxX?Yc(IF#yXn@gVSN=+WmtGr5dvL4qYu_cb&8?=!)_dicvHU;py(>u-Mf3jhD>uW>2^D-uqFJG3N| zVbWN}>;=v@aq?p3SGWucC7?6Symv22Ybn>D@ni<>x%a;KUzKZY3g3}TYVTbAI9wiE zfSpm4fZN9azOrIMai-N8451VI;xc007J9@bx zjyofFbMpg?Q2E#N0N}*H-;t;E*uRci5f*?Q-`p6*t?|(aFTBpJ^Dq9Ydi2@RS$&73~&&0*3H%`~eqjLyNvytXT( z*Ra+z&}u-$&2A2e$h1<4hafh_nxitiXao|ZP_yRUKCHyPSE*vpLLbR+Q7bkX3E0$c zH&;7umH4JCAS$Ru@z$kC@q(!`?Lf3uoifFL&AuR;t-c7_mP}Ll%^nso1y3R}{Qd^}aeVZ}im0yN2zMIRd4e9rGl)*XlXIdmfdrtCR8ZSP~*dv}V5hr6;geBX#QX zo<&D7ZdP=Z2GOc-$97$#RoDc=iv1w+^@|FWt<6=LdS;BM)t4zAmBC|pxIbBsOR~}R z=m9*tjoVwb^E#=CL(LK1(^$S%C@69g1Xh*9PN{y!M1UNm?jjhvTWP_F(5o9g_yCgJ z+35LiLW}U6Dc)_u9L$w>KAg@vwrRO1G^9a(XU5 zlQDsSU0jI)=P~T9_FD^bGzA))-n8aG&<{*-GHDjDIQ&ekSfT2mfC$c^j@8x~-A=k| zy)OlgGoSaBXeDA;3GO0yAeaj6nDbLN{Ed8IR_Vq)<)%;wvGwz0CVYR_8+}p z*LTOH5rBQ|(C?0DFu@%6&&!X5Ln1Q8YOq>k2O^*d&0Jo0&r%lb&wpoZGHO?H| zI^ecZY(wsY2u#&n68+c2u$WB?V3y#tF)EO*#e^4Km#(I#iHq7AABYA%^}zt|6br)W zLjvFW+6Ohla^v$Cwmod&6P1WnRO^EsxJ9#G45LOLEa1sYyq!FA3v~gG1&lVS9LhBq zkj@QWu_cPH=M;PI=97WArthFqH;)J;sw~PO;uMWK_)`JB2ET0MBS_-p@Bxyu9{n`C zI!ls7fVmXENx5Mnj z%OG|kRk!ZM2*-4G$=&RM*g7SgqKx#4A9JuOP}^v=+IQl$;}`f0E#I*vth|Uw`QLMJ z3W#l#nyouAf-6^V@Eb1A61!>p0A%auu~xzrS@UyT5rcuLIqtnV*MOWiOn^CDnCQ_m60x{sCh z99exx##pxJxLSfkZHAi_T3M=)ne56!eOq*nIRYn<=lPJ-8$KgGgyKsW5h+kPWV_fv z3_pzc-jn25`=3I2k!6pP6)u2dj;S2{!bRF)MXb}g!#m?GpKQ#_Uf-(C&W^UB6?)r# zkW&@YZb#fg{TMXVPB$L!;f|KA#=<6j2f;CyJ!@5qu0K?U8l z-%_u*Ip>gbe!H%oFhY8>7NBXVHV4l2^duOmH3v!=^_;O9=Be%+h}jjFRYk`fY&-XQ z;70gbYmun31_0-?J57HDj3Ho8CHh#Dy#zTj)aM*L8fr?S9XPgmN z*N+pRM6Dhu^LF@Z;D{P6)q3Duvkw>gZNCy&b=4ktyPkDO!VBjPv98(+FMOfb2wLS2 z?SVGuoHCEJRO^9L;vVOYuvF`TQ-wy(1y$ATfmQ-2=YlHLdf?3QXJsmtYCUiud>W}a z7oDip10`ZP=R%2ET~N9cGnJ^5l0Xx;hL&ZFgUKsK`|4&dk2(x+ys#~X(ci;0#eH4b z0*8~R$3fNff*|5W{;7A0ut2)(W04!emD@$*C#oWt=H@A@iqkFPs$91p1!+fum^5{1 z6&^J6`^t*L-9gXbb8tN!0C*q-8@_}N3gOv6hEarsT}~L6(ZtD`QGXj}wR4o`xOFWo zu|JAfqmmYuN`+jgn4-kP0aRm}5sxYz__oGC`EC&u3x*mv9Xe7+)7R{&n8+Q?bbNiy z3ZFZg7E<&z*Ih#cNLO4>lOptEERrk1pA8sNm*?0#0UX5R0@dYS8 z7;u8HH@vdk>}v3O{AP5%>hV2t$)H>$RmIS3(>dO5?NbS0&f}KkBo`|`sGmYD6*{{v z>Jkj4^`2giZK?{KZ^-ns@@&~uAH)EtAR%2rQIOZ++<|f@#G5PB{aRbN)=|~hxKEt@ z@O87$u(hHr1g@Rb%628G_c%|-*$GMlmsC(Htu=>w6`OGFQq6MD0OH_r$}WmKP~|oE zC2uB&j_1UZn>|T&tvvM3{4{f#F965mDo{wa2WLvI&N%=pyOJJLYf8dIj7(WlBmeFM z49!;oCM=G_rdMvyA=bWv{8gaWpYz1+>^xWCnv%(z0%>o?g$zX>wJ2a$9_B7H%ERZw z)$!TI>Ew8{Om8z*ztU`m$@=1>%`N0^mK@z?2|WrKiWvAkE!=v&^=GFKO6Spl* z@Z|3yUK6JIU`63QRl}vF#wvrs+hd5<&Y2ExzC`3k7i4+-fIJPq{#u<`6p`Uq53j5K ziB&gg@}4P~{&y_ih6}&Na5|Q1`^IxXL_OPcBp8ari?QHf#&e5ZF*&+al~iJUF{UF6 z<4eoGnC0A|f-Ew4d29x6%`%hJ%Pc>J)&UOXdhn9kUDli^31|88k9vSrSYKqN41#NhV^`E3cLtgmP>l@0q2t{eo z6v~2%eSv^hHNh$nM;s*u#hRYTNKr&Cab2{!oDvs)CcI+_Nm~3p&}+JNc z)C1I4nT*FpnxvvPFXG52oZ6!=vYy5ltER6-F<@JKN`>aqpLIVJYQ0#wyl1n_=*F3Q zqg`r`QPp^(!KZwh>Rf?Fd;wtAw~Ld7pb^s$hE#LFZhkCe>xjHKYjXbQh80L&#M?}v zT9U0pMpCjPvp`hJP=()#ug3pc8AeN;DaNtjcyqk}cUVcBX16|yz>VXcbdLm3nlz(q zWbj#BW?+9b+RmqcyMD{~Y*)#1mh*6dJGt0VRF@GqxA!-s!jyNsR03P$&t_KY5^K$b_T(YLesNtfnd{>T%^mh>;?EvYG_{mk)&i@= zz5RUzJ0N?j--RB^JUXlc&lPyYGrr^YuJH^2SuZ<(wM$EKWj)~*aH z6sKJIZ}Jwr;yG!DyF#hdVXE<=*X1QX0xLt7*I-)-K%f8laOE%eSN_lH3rUuQ1eqX} zw6P2;Iy^@cD+NCu*h92w@XW^`?UGWFs=yp(8Kwf%YNl2+Q2pNGroB>0804NoaQm_* zpAeKa!947W@-?Y>0~Gu&uIA&HJMTf2f#UzYlqLoT9L`NBj7FdT`Zxc*i1S%qMSQ5} zQ2xr4Y6!_f3TXfF=mLRxqw}M8yQA6U6lO$ICz-!!zv)j>?Ns#k&IIq3y$j{lp|2aZ zT@xUpO%7suFc8a%v4F`1lVD}w)xH<0ae(dhVx!;7v? zE;K1e2YdvuA>$t$54=%xym%kx2tt~5Y=KY3%2;GY=w=A^V!88j3pG*7*Gm~n#rrM4^r&&X> zYE)=qczArg%yHq;3I3N#fpMK+y)3YrQcsy7U%XpcTa$}@`|5K0)wg^DeU?%YKRf^F zeDd~uK+ppM#>HZ)8tH>dKKGJQx54EVTnK&rpsj|w#Mq`79r!`Eq6SR&m4}51B%%x- zb=gF+MUwu|@}veBTgv&$XcGWxw8}pFjLoQb9lH3kDJYCHO61K0SDrnWc9y>|@x1yP zj1}C-{z#tH*CbP=)BMrAon(K#Z7j4Bt~G^-L?dbC{nb`u|BATWV@WC5nkKZm07Bo; zs(WVRZWlKix%$fH8Us%W45}_Z8-+_Zq*i;jCWzlnXmW!25)@+0@>e3XT&+u1DV)$R z0vur?r!pwAUl~&RH$f{cflyWg0=0^=7CIF159n4TT^i*&DIo2y9rmBbIE%l+yKNsf zbm^>n+;c~1FKOqoD$4IavZo}a$cK&zSY>sFvvOpw@&P|zk)-@C{2Dv_)94)yYLSIb zv7yb3OxNl>#N|u~pDR#HN!l?VSt}_7o9h=?C(kd(ho_IPE?^SLA$5q4ki}I%vwe=O z?}9>MYL`=nDcq*sM*1XISH-m5aL0sb5aUejs#{?&jf9jz)_h~O`s zp-6Cr%5deRA1MwWU@M1dwkOu}w^y%Y?TkZ`{asjNxD*;+K*Of`%~r+|-U*x?z7`2A zp(|pU$%~A5&Os}1pii+7qNk(L#U)-g9lV8*oK0ZDosNGR;nBLILwFdD2QS|Z4hJu< zUc;|7;DN+sHkz)2Agi}-??~8{ykg6iF-}5@<56rJC=-(Ce za)=Xr!2Se?iO%={zEpk{Guu1%FrC%b8CGX)dIE83FO^>ydlUy`SPDWi9* zVBM))@>q6i=8wC=1-F91?`v|6~Zt8LK6noIqQ`^qtVpeRj zlWF3FB%}VZ)S*A|LVOi&+;ECdrm!Cz&fW4{nVs6+8BkHMe>yoJ=pBfV$A#3axAKtM z4rjmLzH_cEI3i`0;q!E2>;*Esvex(UB|eJJ6r!UhR|!X$Lku6alVj!K1>SiXJ)L}u zEMl$%e865A@R2&&=-z7iJ<_$Ku@8ECdLtJ0!QCC5!L$Fye`=2(LZvCZ$UtV@K|C)1MI>MfL) z4QJK03g=oj?zEPYUbpP{HF8>yux>Cn1;{5G2;VlDEs$3gjj&MbBA1i%7W<$E1o;8C znZ~Xp9*c+^ss`ZU*3w})JlrI)GR%l>+@bqbggKjAHtM#r1wIP27xhd)`$)uW$O z+bWwBAs{0YDvj2*OP<_=4)CRy;xMy`n|gH*Q&gs7{4iH`9MNq>O+L+?Y02LSSvZ1= zbYY1RdP|$H+!WLn-{9qTJouxpxA#qt)Ltitjl>>(?`@`1!H%kC+L^&{r(JErh@T&n zz;iurNhB-DmkE-!8UXEc{Z~B1p%14{<@RjQVA-xi1d9`gbyF0b)^__!bGWEK_|)!d zi~RA2RPrEg<(EQC695Pg66?w?-Zg#N!?(43$GV=?f$JyDhxZZ-_*PlqRf$IxeJ^N< zm5f9SsB3#=s8GigoIaO?huS26fY@>zBq?)W2{Gnx>>w`3=N5MAT6TeMxeyAKb-Fc< zp&SsWUKtI%4-fIY9eT~B(wXYV-|2^53ULK4VI?=~8GEVHwf8V@Nyxm?WueV{H36QC z-j+c|9>%=D#hIBiN0#%m!=D`y5TRQbP$$WPH;1H%0NbZ#1_`y?Wixd%0hq&4>$>h1 z{4EG3_Lf3&x3ejDJ#YMru(}g&6Q$sL>TMp|Q#Ii_v_pq3vspjKCeKPhSj*f#d52|% z&Qg&GHz`9LIL#0RrMpv<>htnR7kYDHw*8P9cA-;>^uNyFv#H!=nE6B&wwHw@b_5Md zR@#KZR1(elAQZVWqB+Zp4S}LiDVwgP%Ih+0G6=@LULp(yZ`=byAJS!^jvCJSe%{yn zrVeI1V}!3b?b@1P>m=3_SYj*6--nORvp(}oV>4AeRvvccKM)=@an^M)$Z0J3geP)k zY;5WKBd0)3{4Cl%i`IvU@kbiIPsN6WSGxwU!x4UfTU9J3jYW8j$p0B!&a>>&jA(>L z5Q2FB29Gx$ZSHMuKRMXie7do_z6AnD7(#s8-B{n-eu7W1{gOTt)lePh9~%OQ>F6x~ zIP@`PRLeepxo$Jh9qp(L0ODN&@Sj&EGdt}h&oPRQ~@dyOVNS<3^5+FSMLHRLD@9d zrX-Kg`(V)4ZS-&p!5+WQ`CFZzB?89od-E9Y?UuOeo+<+FmtP9_uRbn#fMZxm2Pq)C zlGWxtXyG0N6{(()EjoCT$n*`~GQNLj0BU@+4vd=70ho8EhaMcpF}<;d%=UE0d_N$G?FG{2OhP=$LLJ%*wIAG{^=2;1zEQgBZq0=}qB1Q$;w0#lQ5UT( zDwz+&na0pU_@)(9c-kg?p^`DzghPD}O-}nDc5$xzfn!MKN{y8+3UoW_cEkJRSY%6) zbR4dV$hf@Db1b5-*49FknzpSR7P#%L%VM*#s$GAM)##u$a)-`2L@3rP32OLHu44Kl z&92UMVJX$^4$?t>sqyhOkQ0!>LoCpunseb-IOxTJwtHiIz<(s7-5L~^2$9725U0X9 z%BOP-b3pT%#TRqP+FFCz?UuSQK6<~-`_9>jC&3YqLUz49VWjnPNQGMs2N#ozZUTxy zTgxmA9CbT8shdP_WaN=^nOhwqB}hG;IQJ(aUkS%~l!vXL_4PSectsqQ>j%^_Vm{Vz z;K;e$0*fs&=!5}*j#l)cl&mDdsU#*;KO;Ih+X}9mL$yu-)6rW*EDOpAyzUl(&W1-< zQ$C%O1=)+bCQ|oAL>yEGz@LjZW&mMsjoSlnZqQtGPi`+eOF1UL`9N^Z^XvkL;7KLU z;e8!f7)Pu(Kc#PhRCs(t_ruQ)+7Fs;vjc$;hGMg4mxY~7j&}FIF z4V(us0WlNJ3fuFTEQ8wcr0C~ZRe`#91%$hsm{phClxX30xYP2j+fS$O#^dVPYOmbrl#!sJv%1e1b70*~3?_UbZXSnkkkQWJgk z_Udi3R)t#DE%yvP`qX>F=7R(fv@q}DT&}Hw>lQ1~Rp5SsnB+m?_ zrME1@cDVZeIXAQ+%@X*A68YCOtg7HLiJGHW>k#>q6ySd;&qg{%$4HsD)3)p&fZkhg zs7RrjO+0VNgP8l2ZZCib7_yA%XFW>8&$}Bws2bv>U}=ce%>Olqrogt(&Aqwo(+~z8 z1xFkdR1$#=$5lq&9-SSXIr7+PeL)dYgH1HEvO_Fw0K>SFu^G*p2iq$5=sU0~i8#LUr1@v|ah4c43JghTqH;EQGcq(@O($pY zvs_L%o^C`~CDGDRWTS*c?pEeX!BXQa4|ntVp@ewunH!Js9jL9l5kDjX%Sy^FBO1J%SuwzVo$Han7T= z6QRZ;Xox6A04!`Gz{e326r(*e{c?ni;c#Ripc$zc8r6`IO0F_<>GU!|^Gf3umK4AjH2{M(45+ z+X3m|@aSkVJ+=iMVYyRe)H)xZU7g7*;A5z|cZkEk#F^}C^fSQUqrq1Z^2>;#+3M@b zM-lkDg0v_14qkt;zBk(Z?sR%|?-=>Iu4dHO51C&bVa(GJR)56h zpUx1gynl`@Gf4R~Hn$h$iZf0#co&Ea>yRWM; zaT`1A9o@c$oN_K#o6)b-nR=^o4;Wb_l)Zz^JR7?8iA$t~5h~3MpF%{98OjQw1K{;? z(?e<9KbX!+`tUoL(ojmUdJ2c3w?m2X@1&zhl~`xRWtU*-q8lqyn189tO}nG1D9&pi z_`%uX#d1LQdoNfNIZGWgO*nwU=P|qJP`~S2Sn6!%7%`sr4qlGXZY{mRKJ*f|uzb#v z2<92~V=}=}IamZu=7f4E^*bh>eHCYv{|Ff{k#m8uenSj+(#l~P+$&sTR^ot31~;VE zu@J7FAB~VDIS1HY14b~C`h0%{K*O_ArmFQIRsG>OyDaa)k+2S65W661=pM{zkz5K0SVs}pYCr?^Ntp323ZE^_&2HTGZ#IFp0e!4x`}8rra9nMr!l z*<>TNd9@6st5I2)ZqW5HU_SI2ZOqx3= z`h=}q@JSb3ui4_La4pck1w(i6YOI}p2nZq{Wj1(S)j1*`Tk1$BD6tI{fR*Z%QEMf= zxi09~gH$c$NYe-8OA=(&rMDAKpEO(LxX1)Ts`d?k>H_lNJu6?%4yQkfHL&S%#U0QE zA7f;)_=M8Dv>f~DeS;DOeZV@@vXTvnyxd7#jc%ddp9v>Z=N+*6Xd6pQ2g>fPet+sd z^My<9%IZWZ<6E4*0VfU8uxfzopzuPx77uRI{O{oO4=us@Ae3TYodmiuQVHC3XuYpP zu=3?~x&}=lM&>mvF7i*ket}{j7$*#R0ukjHec@)&B?hhO3e9H;O$=f)5yAqc%d>1M zkj~Qp(=R~XwYr@J!$vW|6X_LXnyAn#YkO~YP-~t=TK{44k|}1gOLutXQ%SRkqvK|` zjie~n?Jx*V$9cSlU}(rnv4g6Ya=(3+xn(ML(Q8!LUWB%_zhmaPPa zxN=5s=NVG0papXUb+aN!mN)}icRLrB-W9a|J3v+V&4tuC0fgT-mVUOXB)=ZedrW{D z0OtV%OopqSY-qzr8lh`uSVgD*f_awRD7CVlv)U~--!4>HIMlhbDWefu_WkFJbAi@874i z3^@M<^1P!$7i!t1PYsZ!t^V-^x!HdR;QwM_Hi5aR1RJqGz7Pu{e?J@6Y#z^}wR1Q{ z+LoTwTTOPmxFJ*@yGG z=)&E;(D>B0nC5YIQJafRvcxP%HnEXe$-A~z18}u%zOMz+*LNfFr+YoJ&(<9M$kBs43NKC34TZI}F} za)D*!+MusW-gnZff4_+e=$)IuZx3f9Qzbq6H_w}%DmPK*TS$G<1BRcq;^&d8{z%j8;RlNO##R!W|r6_1r+u7az zaq}^2B91-PJlNgX*;;?Z4_^R>vg~0Y6+$EVVanEw#VS?tfIt}rAjEM?s&k>%YB>j} zLD*-_KiC5Tfsx3zN+R#!e;Eh~lqy6RP$>bD-<=-5u0Ore)SGVNWX$XhDtYOpr|U6; z2tdlYJG&)|({$|Kq0LZZJdyHFh=SKZD-=t2G#BEdk~-;xwYB^$Tp`t<04wDf^?{mU z)JeP2drBtU+p8R>1p0EoiMvI(d+3KM@{6ZXy&#^qNQ5is7`HlhI&nmhlT%D?j7TTc zzeqEz&EmT-9b+mjObpxxY;g})kjm6sE`P?1ryY60r+Ih|DH=FW0`g3blUON7p>=2{ z87J$>DI5Qg4dX6L#&||TUUSE|B5=#=+Nl|TiiwzxFtv(CP2g*xqBi0{(q zXWrK)kyw&(ZtEh(Ot-4d*N^kak@c@!ZY2gQ50M;X$7Uc-anm3wt&&F}ILSi;yM-&r z!(D!WP*zE9U%HKcERmimKU9+jbJaLegR&ms$t7m}7UW?!`~XMUS@>GfLkec z6gM6Be8_?!0-I8L-}2Gsw0sZIMsr(9eG_rPz1p5njhxI^B+~d?9w5ZygsOqpLyImi z5fKP?bW;UFJs*ybhcf4Mo{f+BE`v=v8_P`jV!ya}4FqUW^S9(TwFP5wBdvQ6WC@NfhGq;<<~Y@}bNrHWsZ>CRwYAYp>Kput%yZ<&xcZ_qCsgV z-*mPGF;Xkh2G)gwnY_~4F+NV#0g8wgkzPl36GV0SkSKYPPaQrGxijg-%$*#I)#t3$-PZ+l`Lkb6MVY z%x=GaT@!oe2_%8nDax9XxFj{onq|t!ZITaJtHc^W^0`oipM6Fox~Ob4&rINokKKrdmQ-5{V zY{^5nK;#}OsmLGRUo0 z4NSunq*T%858qxymU>z8Gz)~JdUjCM;3d;Q>-Ci7+mGU6C9VgKrr7R|fMf;6j>6H|)albRamo*8*@#Ey zv#aUI1Y{F=2M;A@RznluIW0+R1G({jo65qgBrMw7|2hty>f-L8cAurKWU*8^MJz5S zEp>)tc1O64wTv?soGu{+Ljj^zP$TSS;l?to_iap_uGn&uc6B-WQ}t|z(jlP=GV2~3 ztbK!<$K|1i1>4g(5>I@T%>~(4)~tdNpV^V=Bjzo z7?ulIj(ZLmVIJj_GOLN9ixk#`O`Va1*y-pV%^zK<>49AbYNRb@&*TlLDn~B0QLK;L zAz3ieA&7s*_e(!SiF#4cUKlLpplmzIYJn-D6F-Ug?ClsGVDGQAlI{`}O?dF1L>;y} zf^XkmPBRxSe6?$ycDCa)JiKc)qH3dCX4O`U&dN>>-JvVW3(&W(j|1}@qc7Wx8gV}s zd~-kpz7Q7n(#-_J5kJ;vpVsnH_6#|cF64cZAL+4-2f>yRHt1h88Gt;sITSgIok$TG za?_>Hu*`Z?7h;=T_8sC-(@SNzc>rb6=jqKEk4LBKv*m7cP6E*81g7y5&93PaZZ9k@ zaJ~ne{&8BqR|VUD43{4VU2l+YhYnmnSKXaEyJTn6&}+`2D+(P=C77YDJOrj z)>!8ID|!IbcPiHY_NyYR##psfTWzo&S%p>$ERI@TTsh3a$SPVy`(=py{->~R*SXQ# z@r@Y2V-6V_5FUr$y?63!um(0chN{b>4&=R&tngEjc9>xlmC+Jy{$h7Vo~&l&n-s|2 zfdA8CuV~+{#d!hioc#Aqyh}ha1Skf@bb10qi)hC8Xd9-SQ z7UjTFaj-N7E`Fomdn40S$zt|xH>I2#h=QV4K_~Vm7rY8 zF=3ZLmPSb)@8kt3i=3IRlsYU01t%ZGe+N!x?ixKUxG$0=~2U=wH@< zzj5$r`^k4(n~$EN?QcBxM%sFX-Hks!+uYsQLxtaVR@nY_Z+mOwsnqzVs)nJp@%X@j z<+}f;s_QlOu+8*nq6ZN-RAIFF!wxXse0q?fJ*cU&wXweYWaBZZRg=W~S>M`R=a?Qe z0*iQq82%f`v}eRZCNf6%99J{vEv9}Y0$vn_~Wq}Tj&eJbBCU9#0ZG?i;nWvpnmHVD%HKw4xhFCZ|G$; z!nH?!(!UxXh(YVL%n(C8d#-k)o){u(IgeNQUCs6{EbD&yIh+JU+WP zMVi#*;a#prilw7{2T!5izdQJ~E*MQZ!?{fkbX=J#%%Q2?U=K7OH?w1T<-j_Ga||RQ z(>ofVANt=g#Z9e7qrU2Yn7r($FZ2O?|JOv!o_wb|0ekSjzHzYrd{lbBoWE8cdRel# z$|i*-T9r;Y=*l;X?2E#QFP(s}#KG7@rhRf_iJ8K>!Tt_3gqw2doPXfR%yu{pu0CHH zzsO_ozFFSYJxJEv6*fr+p32qFC5j!%W?h;TN^u{vq+y%8Y}(nx=7BKSx=B+bwv0^_ zN9WWrt9?0;Li553!zss4HJRuT@$$tgt5u5FW}Q#eL3AS-cK}0n z(cv!=elIgpIzX9Gk;)jmW~CK;Z4lFIJy1fnhU-^#F=apbc4g)4v?SJiJ_Jrsvdxys zx`_I>H`Q?@i8HZl8E~AK**@Gmw|fAoDN^9@EwVSG8-elV+szg_e$~qW;pii%yCG^G zayNj5%bIIS-$){o`O(w-0h5fz)EZNr4_>~5NE8!hKpVzj5iLj%C8BJiHI9&ugI+55wiW!* zEwVnI3VR7>?>H=yU9GwvhUfyma~YDVJ~OPUT3=!eOQY!&i}=@i|BA_Z59sV;{tTiC z56cjNvyyoD?R0{a2j>6arR$563;U&&d38Hn;o_D?I^r|z*m+-(NmK@sWq9@uXY*&A z4>kFi+?XW71Ex5*-}!#0;Kb<#bkv0{7-#xX0Oru*bo|n20k0Q+V6c7En2Qme2|x@G zriW9qm%xBhH+_N-1CVzP9q!^h=qDW8A((*o-cJspK1m4-7p`OQgISCbvPv3`L4itW z$Xl1b-ZazFhLbF;R5Y8TjbaZLYCYBg?C;7Mqpd@-Pwmv3hO5#mJR>kA|w(h3>UIK-@%I^(cahw#|8O3(3qTeUpSvgZ3tP z5enM2II0feeK|V4qU7KJZFLUoykFTjNBh)3yjZd+X&RsTjv9?>M8991l4*Wsovl+* zB5si`i(Xjf>@VxdBHR)!pDi)%GTUKM(rtw`Pak#RG1Li%30Q)WTFyEj;0o%zf@jNe z1ne~KliBC}eBJ`Q@UM84_C}Y#ADxe;hq%xI`X|?hXUwjO8p*zC)zxke>_F>+&|b(z ziO$>n7r&EcZINu!LG!wL#*rwgE3_T4o?nmpR z0lR9c>|#tE31n>Qg^xvbDXwVAa?D)G@rSuM!o3nkj+;OT7*m5ubO3k$SU-~#2W(L{ z{)=m{F4yiW#cIp*5Cg{VrkL3^haN_tDkg^%-3ocU4I&_A?1_vRk|Q6Zi$6F_v0ap| z_P^-EoMR30ZtBKh`y6l7Nk6vXGVCilLW+db-Z|LWVS9N?rIJ!q3>9x?qi)dpJqHb( zBKIY2Bjg|*&>__#K`#Y#OLLukK?RyL85QR8N6FG5P{Ag}axv7w!(QyM8pz|OJ@~^o zyBbZq@+-O2WsHhh4%YfaG2vE7CfXJq*df~?>z#7zbWva-@OK9c)|9iPX%xZ*ScqOQ zYcRHTV9Tp`)D`0Txhr!AeyP!07N${gx%ni@OUU??x^v|r)F0lhIG=6&=hY$JYcex!%2GWiSjV*0ujG)J)B?}&D54D+_|MG*O8Sk@uhfxt zeH-+w{=h|9zQsS-x)R$3`fyIz&f@tk;6Z=9GxaVRfY|0|m-2^RB*!4&+iK7Cgq%7&p z=vN{wQ`mR2HV`QT4D4ok#jdrs8Y4?D5;<$iO@vhY^y%Hl53QwqaA3l~#E2sU+sOcT zQzZtdoeU@B%vMWD1z%5yY*2NEh}C>dl;4fhap7jjHcYn3DZ=A-OfhmN^zjMb?uCSR zWlX}0VeSPj(+0FG6J3?6vcLgvGQWc4fQPOVn>Umb=Y+2$!eZ6(7$?pg3az=nAPa4# z%sZl7%N2e96Z_q;ML&iRIp!EdmGnJTnpmazoNDqP7<8|Vje zEcl@t@veN)e7ZbiCw%0~0Bw8Vqw7tz8H%KI&RW^yQl4~Tm7ueaD3X}~${viqh;U+C zLtk`~dHj!OOFX}b73@&;L&S`oM4D#koM20HN zO8SHiV|EO4Bb!0}t?+U}Xc}seTOrmCW?>=zUXe;}0O;(wk zLBvoBh;MER0``GZ7NqPp6e@m*n<8<<`61=ka75||PgN z;es<>y7|+|J4Pa{-nK{1Z?Br-^ICkj30X?xe$O4$6?s~eBJ#j7!r-YdoQ770mtZ>t zQyw;k>frKdgEFC%FBD2A1CD}pB3eB@w8n6^Xy#H?Kc}{==C#Nt&#)CP=6<-1nCI!8 zy)z~buv6T<=4)}sqjS8HYb~I<1XBIlnPO*kSG6iYi%2&|@O*syH3lKYV)W1hzdF1t z1rPYCb9`1`YeoIf7png`X!1gZ*x7+!2|dP*FFQ)O;diO;U`uC`)yjJ3CxoLweM^Cm zsSI-EVWVmA%_)P2j0b}UgHLxi9zEOL+uVNgsbJLvk-Ko#S0FxbfzSwq0;pp|bbjV> zXjp;r7i@*c=D>onU05DKQih)ou|36XlC_YsK%p@i$S>2`{!QWGI352!msWM3zgw{F zgJ#5(baScifzAo z1)pjae{5eEo7h+Gt>&KE3Dwmunt}+D%7q z!B<)XTn8HQwl);eb{)2YC!0zmM%pOtr=pMMp=v@0k{yr}uuhyf5v5sIM@&m5lfS;^ zD1>NWM*ir{6djp#CbO(#0E35^MMzdPdFAf&`5?P+19K2sf9rUHd0&4gDk>5^_zTlI z@YhCm->^cPAkiUXxXqpid)vLDiWOed1*kKyQ;2H!b4@e3O8Uvdlp_y1#L#7w-iT_H zI({Q;{fPvK&m=?pv(e}Oab%7xcTPbh-W*q<$(2a-L%W5wc(JMtS$8>C`S_4EK^!b4 zO5;z=3i0R!=NYj{;j!FfzFq%rOQOlPU@O(@!$fqxNu2;}YPQ*E^b_8-m3moqhpxp= znjUh2fej-A@3po@-(x{mIag(;%2|CwZ6&Q+bXAFgnza`d8?vuopJ~=Q!!ABnIDa6a ztDqX3j#%=d?!3+%mvTh6iy$_(W3$V_x4Y|4kmY!56F0KfxAv6a^{0&=H+TVyH&u!w zDdJYDqDF*G?82)xT4c9X0#`}I@>Czy-?h$|kla7E?{c&X%+z!O0~0RViaXWr?_yQ` zetLLuQZ@5EOl_LPH~_E40zFL8lxnoBhx#%V9glNEkl+joNl6uBfN3Hv7@}m8ARu5ou(gpn;8bpw*=O=Ra~QRf zmnRqx4~#`k;g89w%}Hjus?!)TRx~bB>;krLmUYv(bzA~WEE(rF5xd>G(g^m7Ae1>TcoN0$zSxAk9;I$RO3ihy_}>zjR1tM)U=Wo zD-Xx{zKA9W1`aHL9M@jBP0GHN5;(;k30n4vTN*DfPAT8+vV!e=XSg*GohzC_sFjEO zlhM%CzFv1gJ#}MCeRuExs+MSAa21}(5KLWZ_&B!GhM4qHwbM|WT|g}U)wmYP-DQlK z28ty))-sE~q$ys3O>Cr9`1+eV74=I8WCQS(EI6RTgqTR|hSs&S5S5guC!8>^Jrr8@MpG=B zYZAbA1e=go=1dj~yxE(aQP8D`KL~a1@t4{gIQ=S6&@7)HHIbzDs|@uRT{pT}+lF=1 zJuJUu`8VH}>V1WwHe12cTp`*ZE}0;)5`I)01YNLOPYtH0TQ)2^82p6P%w!RMb*dRj zyJBC8qH(jqeFU@ zaK3kVxlA!9S@NN&B9;f3W!X*z-b`@29W%Py0J(xGuhx#M2b?vf!MQa6?Wh%(BZ7JJ zSgak3MiO0^`fvdxtdjUuH)K1u9Vof-OgOwzAM?cJgssL5Z^H4Klv)u_OGyzTy^r8< zW!~72Ot0uD#z`87XR-hmIg59p#IB@Ysjd6Xkn^J!%Pe53ms(hv);{Z#wGq`50-XM~ ztj2LIFdiQ>W1h(pH@p1TfeMOrzXmgI^kyVaHJi)Lu!vEwJQNpa2G>ZIQQPzpbGJZ|u{izyNcdY= zLXyB9_m>Z6e*az$*wYM4wbCp$U;;TgYQ6Fn$<*0XRikbASDz(qp2`$xmbz(BpC%QF zvV~E|3fCoAz@}%*D%#RR)$PntA-KOm+`-0PFMD1=^HSOWzId*Af7}s7Z_f+5;>&@) z_$TzlveA`^g3Pw^KdtRLR=*t=v@JR|Od>FGjW_tqELW}(SgH6Q+cnZ7Erb>EY)W$| z;RH$rKQ^6yMl0(Dm?H~MVR+0ims3m+%G4*iKvmonSrhO)#*}=+K0TB)hv$c<@BT7^ z{|{z^WV8?{jq#bH!X;Xs5sR*jb5^rIdnr}?IQc@66W$WRkA*V89eL~?G*9x*l z3)X5Xl~WeQ^h`HaD48&~?23c=9g<2l>?BMAbYXQ_DS1vWIVHhLcERD$4gyzEO$1(y zEwzoTCE!Ly+##SR{qybf@5ir^csXvFxE`9Zwu)h1LCgRPI0@HinPw5^XAwrBnhGUH zg0@)WUF7AXlypq_QzQUhKR@2oJzt2bC=<+f)BF-r(wH61*)R9iCA&hhdeu?LY?kZ@ zsYPBf(S7U*eSMo_&^!>fv<_MMGRj zS5s3tH%C`C&}&gmIIJ+C)0$Dq-8zHH)xOAuFzOgerpeuwt&Kd}JHMij3dgHUrw_{C zIMSfesUt+^s?CCi#lP(#`oVe{Hkv$u3(3L#r$Oa{X%6OCN0Eli8?) zOa1aQ}ianYzmE`e}zQMo<*jyDqtY*ruO^Ys5*3{A8chQb#2aP51X8HU92i z59z%T-eKOU-6GJ8Msis#O4;=!{is?Aye?H_^i3YC6VW=det;Z;0!d84 zL%NG!#9Qw8$`%P|K%*d+gpbTEaw|7fy^d#B(>0os2*>LuD=Ru0<&W53%ozx6)sPce z!kuZ5K`xSPbj@nGOHY)%q@gRILl|J|kwsd2JDp5^lEw36I=Om%Vrvt8LxV#s`l8El zsxg`&x&>>hWV-NKsOwxcDa#_}y>1?_tbowbai<`Zy+>&#Gt>|O6a2&6t%Py(8o3RV z7bLewyE>%T#Za^f_@)Udp>;fe66Tt&H}atDIf=k$=&;@sHNr_Yl2w$o({(ml@tm*B zlB%ireG4p^k-E%XOOpgg=7upwRItphOf(@*-}vp=jGf=Y-sAFWdM;3Wlo}|y2eS{W zT(_6FBDSK_GErM2Lh9<2CID>CTT)@OjnO1`$B*g?Vs@#ZhD0ef*0uVaD_NzTb?ond zddEm{)-u0LaZ-8Y;WSK|N(5{IR{_*YePP_q?VP!G3uauAz6Na3(XR7E`dqnOrwc8D zg|e;YnMWsfEkcA0;*=}7rac!_w=v(!v4m-(McIsLD^d}Z$M8`0KZ!|TlbT9;jx4H$ zbZhc1M6+6Yyi`qXVXNN%6{Z^3nLW|+bn9g~vD#wuODHorgDSbI`^c4U* zlP+c6JP{@7x$D7+2ZHBI4R1_fojhSOdwSuI50}oPg5(dk?n>O>^DGFof=HE0E>tkikmaad$92sF- z`}yZIz~BD0l@{4p4iNve#n)kK$0 zNCEZA(kp}r9UEb|d9|HL!McLgv6hNBq)K(bf*{`PL-%^wxE3IFH5k$+TyUd%R@)x= zirZ43G{%#G_#ms`8RZ?NpjSw*BsJ9Z-qpng z%pUBbI_f071ssx?i|++RbZTf8Mt5`A=JzxC6o+Cv@`yYpPjf3-ZK&xf5t8Rs7ritm zqj|zWMKY3J5l!}-n-Pw%S>?B7HPrS+(^6sUYIQ3%6lbP9_iH0X+*+c5pfC0VFL4Cw zi_AjYZ^ekpOb95P1q2X7(h1mTZu1`1!?D#4+nJetvh-E;gDk}KnE_)SFd3-}rbOiWu_D=LY%h?9m* zs>L@X_YPAwSDzw;Lw%JO(CsKcn!E+E5tiZI(Nd~Q* z5wFRbu49m-^+$?zYOK0UC)*9EzBH*-1~iFl6`SwstnF}s*XT6nE`G{nfvzDz)H|Y} zDaU0Zi_m)6sc;bL`qiG#pgHlFw7!Q&G1I%1_2O7Zev(H#BrOSs8ryUFM zDRpwt?HGe~@2G5=S)*-%%P{rR{HWV{s^k?XuWV&%h3!uj*;H1pVB9-NEILlj*(c(1 z{g9=aa+Nn3zEEfi$b>(ACBtf|tsBGZ22-?O8>3qO8(P4Gw$f=8UHQ!G=S^Wm3Zehz z>By->QPvR1`BNiLBU_Ct$#>ga_4`r^cR&XkZlQ&CHj|3Jl{*I>k10nr2s6-94P=q& z2C>)wa>2IA*o}fj$YT!j;F!~Nys|>#+qt!9iBmbwN{7>qKW~XckM#(=UX9Vr0SbqJ zMVwsrX^{Hgy$h{NhX_D9?cm|V=>Td@ltN8I2g>Omn@d!+7{2$F zw(6#poiOk7;@YD~)YteKS8ISU{@GnPjU2^32pb@Og9*NY`mPb9;Lxgh+pWIm)0t5? zCk{3~5jwaQdmpTdO~7U=MlhXb&aX!o!x5LF4{FfApdRg~yETFol{jJgn`SVOqR3I7jb;!S_ zw(#?fU6{(YRjKB`tpw(b;*}mmJ$ZQkE%odQlW9sVFKlm64=rwKwu){f09O0y zBD0PkIu-h*a|mc%Jwznzgk_WNrWBPao?-)u(j#1*IKXl+J>cZDw^WA$;XvLY$Bfor z5>hr}e&v%fR!IXPk<47d%-Zr|xgloJga`maXuPbb640f8vUAObkw2C_j@EMDIc6{@ zi#7)6xe%Jxm@J?CM&kS5^j3=e)#%tViuJcdX&%v!>yMi# zHCc7NcXLX?b&qRFAGI6k&aQXHjE`L4)m~#-k$PofDpGwjOD`wdjv$`>89uu>MmC3! zjV_f#BiE->X_v`A4?i*=R{6wZnTEqZz^KB0f!W@K!IHZbN#h3kT3VEwwCIY=?^ZDT z`gtUlyPmu+_<|6(ckP+nZ0zupxr}VR_TVj3n5i{&bw2)2Jh5Pg7A_CRQw0wu>+3V$j z)4~&xhgbu3S+vG-Re>oY2-xp9=#}nrDxp2p4tv;}}&l(bL*(ua18eez8U z=GoE&5Bg1o>a3vbhCl60r8#=`8P;g5`roBhQ-KM<=46R! zUX*GuJW+zz-;5jR^m0=EmZ4)-w@ub+-bIssT~?~h(Plc%>oMcRRDM=yq;b69%qJjD zjIO!`pKd+5h`;L*Bz626Qi*@KQ#hKwIy@Q;v~+KBH9bO>5i8}w*2tkrw^Zb{f{upM z5Y(sik6%;NoAq@(%_dzn0ojni!^gPM5y0gDrmKa*?r4O{i!Jur7HC%o4}ZWB%Rc|- zhr{#n#nmYjtv23Fj4I!ad4r4p^yq;f3?rdsPSBdmD;itUttDtXNwTUz@=IsA`xa&M zIR$$qCIbP%70slF5V-^>WLk~6eWDWg~CLE|Uh2YqKloYb} zJrdc0Kh4EzJi^}LxzyHsWB8!;Rh@Q>qDRX5@ozRLLkLx~+`yd3+9~5)lqq~7fL*lK zao_?%hlKZI+ngE&+a;MCJ@iJpM35UbDmp9jq%gh zYfKYe+q<2He8Syvc`~5`18-FG)EuE@r!TQpm8ropObTLh0BZ!!<<}B%d&~AfW`D96 zokm+UQKRHya z7alsox#R6`|5d%E`?r-Y`?uEyR`j?1bNt_JG`y9ShOJqgu}PE34oZL$ecsafPL+fQ zz0|{?a?`lCE|0wJFM|9NJnd-2=W~fdLK1>74=%1Q4}3s9gJNi3K#I)Ae~e6;<;&i3BM z?!oulKWym3^jLb2S2R;VSCpexo?15-`RP* z{&XGh(c?jfdrmw$XJRT_i|OTbe75XpXzw_`xo1sRkBso**nxl<{xX3~wdh#b(dxZ-4t+c%w9-)8B6WbH~gSOl$DK@bT#Uoh5=m zRx@fT?pH-1P0^@G%BC)+=gLDlt@A|vT0b4`4%wL=Oe(^nl!#Q)UK9x((CYA>f>`|z zXfwFah*$&K8q@|Dpb3QxcSyd(GV&$Z7ML= zB|tFeqGQdR?=F7e`Zw@TIn#Ai8EChBKOVh0#QWzl@nAA7r)iBd)(Odni1)i@*}LkC z;%NKMCN1nU$&86cvPw>AkDk9W3%eA$7_Hi8AW-2$1_3!b7da~RB z-`~_sC+pMKSG-?P5~B>C;zYMhZ92BcxSTT>jp@h04cI{*Gra1DDd(<@N(B{)T~vq3 zl%fmeE+h7j*bigzxE!@8gVffvTb1J?Jn4{0OVu-%ELcmGhzq=Ce z478FCF^^XvgO|+K>h%V%;dzm{WbCrwaDsV0WL3EG8$A1HD4ty*)!)hC8=yE~R|C_) z#y9RS!8FhdTUCAIv$Vv_}4$5TwY$xzFE6>?{8yRphH@r zIx1_i#%KgdCvASV1a|gZHZ|rP5JXnL<|`u~l)jT4kS#SVeciEPw z{@ln_+^FmbD^X#K*ZmhlZa(v!Z z3&maqV{F*iYiqD=o{rB(ldH>ROAuD|0TH9|xN@m=Fmxf6EsLrW7F-k2yXg=(E4HYS zcB$ING}xgBnaUx?YQ3CJ4v(>nt7_QMbL9OkDcs+kOyX!+N(_dgPlDLVB6+ER5Fm}3 zl}@mZj%n8zb~>ELleg!rZALtcTgX5h8~)wF+3~LrsN-tfIQIe@k%BG3K;e(3_zZ>Nc7vlWg|r&d33S79 zXv<2rn#Htzq)QdL7dJjVd%72ph1sWZh+1t8qpF}=`gw$#3bWh2{UP$=1AQ-GZeNYx3*zC>uhXXlzy)cZB z#3|k~;2Pa6f*p%Np^6EVO^vcVsQmdHs8$j+61Oo%Q4d&_L^oC$APP*Xip!9}-xT>@f;@p@6C}#5U+?lLKK$p4DUOjA;BA0xI zPJOb7f$S1zD~@DqI6-2Ma|%l;H(FuORT8or!&Z9lU@Qe>6}N6?Y9% zKa4I9ZKj4P3iT5XCt>j zk+caTwDo|AxZ{MTTOqgy)3N=ny=5ZRN3EO%PY-yxL*iNfU!@X-#@DOx*!D?U|A%Mgpdd`Y=(mjGFdr*32xkFjH^lscS>h? zMnvAXmks6-^GtD09WhmGH5&{d?p4J}Si!qfPT&!`nvNd(;5PL9KA}3F7cIdk-H}zv zrM8P_@8D@E{(P8Q-YeYrDp+vUAH&}*`9BW_>APOG6rr#Kz4%z2>fNl<;|UH_m}^ve zm(GiG6bA>YsBq^-yO&_x_C%w1e0gam5l_&U8td*dOeq!K{WG4J?yOiuI;Ps9(yU&W zGZHPy^v_3=i+7Mf{@=Zg!M#lgcU!UzVFW5PMBWDgy+V3hZkSH>lx1{sMm%(t$oj-7 z18_ETIm~bpmSC{ZTQEjpL z9etusxzem~**byib$-XF1?ph=S9sczvIpe!hn#2ez|By=y^hP1nUEodVOEra_a9YuArIm;K`ye2L1N47EIrh}kh6L(pAu^l^$LXe>^FZs~@zvScJMl=# z(UvYIV?<Dlx`Rx_U}Hz zRF5gNa3OjC)r}E*srFW45(BI+ve0# z7&7qklNv*)9YZVMNbn$jXr=oCan1`v+OQVl_g+(I>LJ}X^bXSfK&<}>8%3P=0PgX!*RL{7RNM> z-ikKEL0qH#YPer1lU+S)+yem1u&D?5?>b#TV%&&wg@;YnLe* z$|I&`F&(o$;5Dj)gU6e@2M0smmO422ZgXn`KRQHG1l119(eeMA$)e&CVc#51u|>GR z`h_S!2!BLcT( zkO2vI{SI4iZvEUT0sr&&S1&QHGIDs}ewTl$E2SzzWjZaYGVb}iqfT4PQTAwD<8;Td zWbGi47oOQU#FV}rz7Jn_OrdI&BsY+mt~CB+pnjh10hkbII(jf6s(lKp+o&07*vWot z(b0PwBZJYzozA9t($B~WhDVIH87P4ZW7F~L@%giQHd-aUS2Yd4EAEYyM-^zDHA|6>GYA}VP%csoWg8TK}_w}%%O2sC0M0|XWdOR?cYXbsjGJR}YO z1!JcSpvtAW_$AsG=kGa+_wL{w90%Aa&1P>W(_`(1E(vxe@Z?C>Cx9c*fGOnuLAL|t zD)*eMWT*frvIw0I-r#|4gcvdskl|1&2N1J+2tME~oY_5$1`oE%!2|-SW24d_>Sv!J zA?B}1M?RngYC;Xlj)+sNAa^+XX?gg}KEap*Jot}oXw91I=f~gU0_FPojH$tfJ66w{ z6`(-15nz<%!4ZK#dr#<<@f#S~6OEvZ6L_o_l#6R-&dFqU$=zOak~lza90y1?!L_iO z5pFWZwUrX|bpe;1ULP}ZH5HD?2$l@H9g~JQboL!yj8_v2eaaZ`a1RP{iVKMvTzgBJ zrC{@0L%kOyMMK2@KOG`7)~m@WQnMW(;6uR3M}-3bxJ@#eO3`h@Y=w`htPPUT++&Q& z{uDQG01e_!{G|!YJu25xn!z=N3vP@e(;~U}h7JC$A!Ob{;f>5zcED&=HV86cZHENI z_#RDH8Ptbi++iv&OS1sE#};|8++JScOQ!@=0>Z0F=EIOhd)$%lls-ozeXV z$lK7RIfmvTp?}cz10s%buLi>(pI>3Eh9#uF&n5kl=E!_;HVV!VI7^)}WO}Q%mW6by zAUutjKAkUUE`k3TlCLTr*~b-7hsRl&n?ElKR<6Xga6tVQ_(#%{T^oS6x_M2n(LJVT z?vhi~mWEg=<~fURJIQ}9rcb8);MW5>mS@zvhlATUG%9`@bdyR%o5 z^LHAga}I&_3q1bcY>YKboysb+ldmONyUwA);ylLZ; zADcDtBnljO68ERy;09${>!eqaw`SKwE)Sse+a7r*?uwIf2`&OGCXkPpSFiA@s(Z2x zR5dTi096+Pc64+y@n*T7=0S6ouY#*fpU=v95TLAGLcKciY=WRv*c>Oc_uo)HvW2a& z6P$Z-@tQ3qIjLva&3y|75+~ZaeYCsx;*x)a8AE+!WiQ|1OyY;bpHorTD5;DG!`Rt0 zN@$0rB0Z)|1rYz&D3raa^~Z$IJMH4h1@nBNqWx=%=-gfElC=iAY$Z(UP;QOo-DRol z?L<<%XZ*L>IS=0I-HMR|Le9TP2K?!x1sYuZP*S>T;{_q^gK5pWp{FI*rj(OC+%z0Y za}4MXOMBZ2l>vaWe;539SqQ=`hiqlBCE_$1YqXEG(-yzY9ICDXvGA=8zQX2!S1BJJP0r5|Py&vxuC9KCO}7>! zA*5_@&_aH94_&I@;hQyGZQ*$itgeS^rH zkwFq^u{WB9RjmQGl*m|ln<%wDH1G9MFsfV%`^&4JezSjPZNODr?)ecLz{3Bx?Rp4j zt1%8qRAtBhkxXW5-$?C;e==>LmUu@D%i#IZX!2^%vDcz4WyyWHe}yM|b^*mbI?!Du z-+~o}V*dsDelJ^1STtRAg;RPxvnGz%Yv*GU16f&QBa7YQ!7FSsaivqi(_TsJZPXh0 zk+nWLCeE9SlZ#bcM&r%Wsyl4)#NUjO&@s~x2_PvOOQfZPzSj7vY71z0*{`7q4}j}~ z-tV72-MP2F_t{|i`Ioc(PZLRqH0rJ0cO^{3% zGB@<>*xCXkBpyYe5M~k_1@H+VMZjMWmI@4?ljrdHtCV6wgxT~HyVpv zDk+igs~Q6BJe}M6#WBT`7D6gIDGsNjWnLAuEDD&Ozh3=v^*-n6!>>(5gGHn%V&T~f zqc0g7Ci8Fv&Vh#5^hee9G?p7D_&!@D7&!ZI_waBnJ8CAlRDHRE{Q-3M?-;c3n=kKb z^ulkxbVrSMYg5h#s4HBLB1X!tsk&6>DB}nB@Bb?4V1YkR;<#w36mqCs`-GQSi<-9n zpQxR4vX^<r_id;< zo5QQa+j)bk}a!4x!{`_W5Q$X6;28^*-jE}<^pij#wW^%x-<uKi&N9 z-wwW8-`sk(yRo*QOeyQ;N>g zc)TXegC|#`k1`O9O&DvoFwcd?vvlrcIjpP+r0q6OgfKC1{#^|T1-FNTXS-XH%^4xB zc(oqKd{~{#-d){4|2G`RxTSG5!+Ir`)DeO_n(8SRPwEi1H@Xc&eeP6sLa2XQrb-$? zQN=^r#XL4Ccoh7Wzv5NWhr?Alm7s?`CvB2V9v3Z)2^oU+o`MHo;j$Q7+*uRXnxDCF z&MGZPJ~{khw}Zj6_d5d8#y2enL515eFLAw?P|&rrKo<-51A^*XpZhgGpW z#9?&x8&3VZx2TmQ5m^}2TD19Od$%sy-N1w0dmCQJ(?O_KN<`mYMmTN6kjEH?>&Py4 zak;X=%tErq;1)x+fC4D79FLIn9Z~Dvfh$6-Ey1eZCJ-k!fSUzv)KU)vogbbLUCj+& zVEGxYNmQ18ajl1(Kmb#Z2Th?XHBHCb;9F+npebj4>0)A@8y5#pD1`qa>GBK#8NO76 zi)X3JQzR6!ghE#Hxt>VBz<>2%8Ci=k3wcvTCC|M^9TkN+y>Ngmq7EgU|7|^r_H%i4 zL$v|kg}a4k)*6jouG#ryV8#>udw$RQYKPVo`q`nT4~1nnIt>t05VrvERD(M0yL@e! zw*JrDw;d-RkGMs~qd-Di#3!l>*>1Z&>k2!E)5Ei(4ep5B(`I9ys460_QP7PTK;Yf0p)kUvhM^_a zGEW}sgK>gJoeJ*lHL*ymS{PV(HiT2~2EgfBB19cAiM9M~W5jetuKm+}SfULmj3DX< z^G{u1zWnkF!hx_Fv6Q6nLAYM=+=!F`!iQsoe@b5wk1@PF@{hCGDXZaAkiivuJZL3x z*=3AFwozZzCvD|VUm+@}FQyn|`>p$G!!Y92S12aDwJr`a?vA0HHHFpB?*=pmH2#W~ zGbrJj!F5v1DZE7}Q$SKI1@?H%PT%vyQ*fuJSJSb0&*j)CRaYA;@|Gs2vLvS)ppcaH_SAj~V~<6+qPMb+tsx-rga3 zR@S=~vA+sVe+!wVxjApO(Dh~!h{7~6w;Z4|%q2LljMgWFvmO%ZVk?9C-!v8Q&qxUj zZyeL=wpywlw(b|mmfIPhY*(~BvDEr>diZWjQc5)rm>U(5dXc%yVD$7iiRfgnJUNep zf(G=t$JYVpJ2?6%Kk`o(KdfO0XR;0^)8>J7>+o{U>2Er|D<{3h`O-WF_3UkWJR*(7 zCzMu3YIr7;pPg**kfHwa_HcR*@>PY@f~SW+%Wxn?<_Twx@-f46?6;lRFnkV$^l_0w zB#z?Jmubm2AY6+jkMt`z2?1e=kUaY<=xe`yfY+s`EBLDWyt_I3^l@mtI6flwGGqxb z3=y%jq+)t$AfA%avKpB4g*t-kbP!LJMn!wI!>qoqT+{-}wB~1MvB0l&yj8VPtbWk* z!5p%qD#Yq?HOiuZ-!1?$gH0*A34_b7V{+&D5TUnNemuu0-r$j+MlM7cs{rg>9RIwf zpEf1n@YNU*vw$qtORJT=lp}hjw=2g_NK>|a)(tP;#yxCh?B34ff5pp?xqV}yL=rt?kmjs z_?#m(L*7{81P3RAo`F90EOO|J6DzLE$9R@*Quc3cZgA&GvkbeE>O|=I`pUn*kPxYY zpVbvnoL#-fLyVVn7J*~Z6xRn&@w5oytCqi6Tb9e3ca{atonP#~`XBvtM~-gy_aE%< zf3dQ^|M~v@m*VvdL9y;I&FapuoW$eG=?i27Z>gIOYOq+)lzYl?|6L9Y#h`gfrEwu% zNj!|QJX(FdI*_-USLg{oz6W3N$;$B|5+uy-tPcK!Aaxx(m`k^&faSq3*7w!H`V5~D zi%aH9{JaIWGpLUY!O`IvId#b&x&-0*0NfWY3hen%M~y@vq# zbJ3g#CA}gTd(fhlaK1k*jS-^_u`2=3L89pj*sYUeNwwoIY*nj^jJF`bWGM^1Z(2CN zn$@ri$bam0FaXKqJic*T0Ut;{BA3Pa5|ksSeWqc+>dH^z2RT*P;n%o<+Z*+@{p%x0 zAd7ub+mf{oEG%Pr=T+sTu?p7!lCU{bt76duI3R;P0%JQyAtST%_UZx7atw_0Bfev` zvQ$b1fkMUC0V7FE=VOSE#+Zr_54s)g>_niy+Wl#24i32rb-nhhSN78I)=* zq6WM00bePWqyaIpIv^Waq``#LFPNL+=BiT2%F4vd_~PQq3fF5A6a&n$>0{9Z6@q&K z<)B;cv>U)QCrFtBRMH6nicuvoI?x6e;=)qPFf|2{bU3P1xdb)?q8*)zr!E82JqIOKwP#veC zUqN6F)Pq=|o>N_pDPRfbDih|R0)i-SdS|iy7B0rD@Tyi}F46h269)%Hh%g4}GStP# z%-J^?7_()oxzID<(GIZ@v>0nf#o_}PqGcjE+nH7ZPE^JaMyxk#_jNUc5Zg+joCTKnyG~)X18Uv zE#!rkBSAK!3-xQm%NwWkm344s_|(b>a%8}CJ3ajQt9Q-}!NlsX-qO=Y)#bJn$C-Z~ zEuzVRaq~i;+gvk+@nRuDAr**)2$Lf>WJOa`gUxH#zzL`p_O$HDS;?^>=c=7cSkERz z<1#V5aSde1qxYF6g1Ca@8LN@Gl8^|RI~glgHUXqGiBQZ{>lILog;&QdK=TVzFR#p< zKfgG&v@$V1zl5E9yjFnod|LE@Apr*D(~g{e)ULpe*H*y~8xD>BbG8-BDPQAXtbCyu;h?^LytnG^lyMaYK?c3T$b8lE)4I|i) z%aCnYg^*z{Qi4L*kj`Wcq|w86vj=9A=WN(ha~D4>YS*$&z{?;h6>uaBV^OJ&7(1Yt zE`FJ}aGQ4^7`+M_{AWAD(kUJA2(*#gL=s{&=L1xOfd*h~zuB5u&osmB(kJQ7_qN2d zZ{T-p_o-aF5CI0BBSIh~6s64=g4lDwl_5me!~R${bRAQH>EbxOJHdNqsFXhm%F4jF z-o*Sv4B^ZluP5L--m1hzOsURErL)0Q)@(m)d~L3U=Fq-^(S5?=Kp=lI1A(v$TgKY( z3LY4H7$(e7nMU&zec!H^tCx0ULx%P!NO6ptzhHEziJiR_m@V?ul0vvW=>0uTCnr|^ zCn`^+bR+WN{;kHmYf%)J8I3o0ppftf4|X_h7f)=04YTiT6Swf3M`LnD5iwJECfWEV zV*B7u^@Qc>0vb)jAdPl4R0q*dAwlbr$rTdw7WFA41YFnj`6LPk56k)2PPr1?6j8|W zZ{9>Mo<-ClBnJ>7zL@3%-BH5f7uMNpSmNM;P^3VQbjes3VDU@8r~wXJ&z_}c3k5^c zA_ys*c{AyW(>$?0r*Y5%_}LlGIr3}(6jSyXnksxhLkR#Sx2-`*rWIwzI-;j|@=!vY zm91z@IvChPv9oO^nUY4(s-NYzGSMG_RTMy_b+Iotp_*tmIWfb-V8jxjw2|Q(4toL@ zgwoErYfFi|F#yHzWjTvUx6_0y=tBtD54~d=WX(Az2UhLiV;VY6B~KA2yKvehmN63{ zl9by^7L=w=pn3~6}HusZT1P+=o(O|v;fz(^N3 zPP`)@Q2G|6huaNd3nF4dhsDsu;E4h^Nc_CZf0HH_MyOM`(d6#cBo9r9E4d#YN*w;( zaT4#wKA2cdkK+uZc<4UFTdgM6PRTKKi0bA|*#EHBN{2ztMv;76Q3i0a@{wu+C=WC& z!I6vmYnVyKzQZTXNv+iG*aU%1-#jS+i106>_XMOd9@6&JkYNq{X}b-IxTJU{_9c*~ z#~%({3Xz9w)_TuWj{!2NY>@E9@k~aFf%%Y;A_cKT&L>m|Vvr2Z_qyrsMF5my|$!p~^`rou-V4+-96_6pt7z1+IwKT+UjU z@F&{x50*j9Hj8!A@GyvfIE_%{JDm-76ZG7otk2<2?a${CMc*;%N<}m!3p?lTvZT+* z*CB~3Vf(;QJRNrlah8GuBBf+2gfQq*%E=9-T&i@L=vdl@TBLPZZ^@)*CF@M{dSgBM3j-i&ch1`xSNwYX_#lvCMfI}*+ynI_RvSm8LkCNd^3Jd-xH zFW(cB7o1w({^&lhki$uhl&x$udAaT+P)-2}R{^!zffmFsyp|GiMTs>`;{rQX2-2zu zclWfgfSARMM^Cf|LnQZb$-w~Rnn!>_X;HndDED#!8xVR4SaS2v#nM}XJ?(z!O%b_f z{j_WG5))mMn9tlD>%br!DDYo|kX+p3XaTue!M%Kt(d##G3^w-^xq)!+Q|=)*S9EM) zK*}X{eBY0Bl)sguqe$*S6u0I&h`InwwEy**e$czlaU_7~1Hz%-T)CBip>4=MOcsjnH35W@V@*Hc zD3KXVfY1j7LcetZLfa?-qI*pM5y{`CxK?;VzocB6oxoP0EP`ppy1-dzy9DGy)1BG_ z^v-1td+v7tDST9}*-J73LoKg{g^43yA)IX=ZNX3yT;?6*~-9Uc2+=)hFIqW<ik}O955JFKz$ny*W0v8-4KBkTsmuo$7Hn#TP7ChfIX5pu9)+^p z(K#p~Id2r3Az8SEf%0wP3D|HaoW5 zeq#B~=Qt5&G1)N1yJ64J*G07Vg*uYOSa(_&8$nn$T1d3(DcJpegRb4Ats2!Hi zAiEp52ap>up!Uzz3NRu1=(RVmo;q0rJ%dur+)KuhG*N&a4`fF}Mq#=ru`{J}PNWpN z@)XQwhu%Q~^d2xv0*?6fq`49&`~-b9dj}gty9{M z0$9>jv5VYTvb}U1g^wL%+t?w#BZ9+FI!Sb|avxH?D*UQFjz~hDGWi~M_!X2=xekun z0oX1@O|Tb0I|*-YyS{a8Y-})V`oKlqS>T73ft9Sb!h>$|etomCwSfz7vLfGgBW(#! zV^Y0CQEA0T5R_1^K}tkDHJFG&(+mzD1Uc-y zjyQn|tPQ;=F}DFYA2Q-vWdp>4&Pxvj^nN&yxn#WZZ^M`gs zhBxk4^<*VuUea~5SqoyMlig}+C0Lt9b`=}A&>r}7`AuDxWaUdL1(H@Hf`Gcesj`mS z5~*cKqqdWvQ^VG2Ot6-%zJd@VoH6Lq1m=M2-S;IdC6>&gaIxWnat%9r7bWF3<_znK z7|kXsq~1ozmE`kMje@NR4gu={iHi%hPa;EwKa9F(FuW&M%X4xX_ShYqJd;)L3}MJw zl!itiH3g-jlf8wZ$}sK}fw6{wTu4zu_oTY<^^t5^MU9uS&8gqg$xC|z7(*}OpZn@D zzsTa4VW|d=yk+CRwo`l@V2uS~_#yHh9@R4m1h;i#OFl??!_f8*_ zxJwt$H|k7#1Y3}P7)rVb=~o07d<4!aXB^jg2lWd)E0YPiWQeu03T;)B!5;I zMO-OG<;D33n>prB$SA)fCIWC9s8+DcqAP*P5qm6mYS@#rh-FtFj#=aV?-z zux(*fspMiMky+?Q{4X%O#44wK`%-5Cu!0J zu4BvznhVkSNZn_(jZjcipp#{KhP_eE+%LS*t`oGlR7t{y(@u-P+jNxAa=~p^!jgAh zgA?S`$$=6XgApW>Ux#3%>cU@hRl2_+GZaoM6G+KKAJes*+0*llGu?J03iOQZ@+*2O zx{19oR#>cWZHRAr2EIZ0f-~C)8z_6rH*jQzP50cE9_vWUYz7pCY)|Cy(~vJ^oy`O?y5r1zMfU1G~mJ)3zQTevhkJux>qg)&b)^E2os z*>l|6O#J1oYrW<6h8vJ~h2?REaO7)rpoLHur6P+slu9N`WV2qAB%((C#OG_0gyKaU zX;l+U;!=9{sIzhf8~8kdDuLEW2T_1jwnPvK#z=Bp_QTEg`bNgju0!F7geNh-c}I=x zRpLsiqQ8Uyd#z$Uy=^(I2GNSMNASQ#gsJ!us>=6^qjDQkThCuoHd{piD}wTMZYYF> z7@p?tw~5_=>(d{yh-cS<$*n1Zmq~lw4TF$l@1vUC8NC zL5^hc%@rjk_r`VxBrHn9c5eEC1cU~nuoTM((z41&;f`T7z_CzLa00XkJA13Q!v4uq5nPaDAC1>DQpV zC~GJf4FkYgu&`>_mCHz6q;3r|K+H@z+2vxYLguU}inwf0pfTuZfroXkGbuk!Gg{z5 zI8@;KhKBl>Kh2~rsn24ikqW3oo^ZesvV@yT5GE~eTwxUr;mnX0lAqBR9XN`23o8L4 zMz3<00&42Fnnbw40ON^q}_>d%YyfK3a+3<(VUc$S_VJQwy;?s z!yDz8aBFU9C{j2u)HiW1^mZK z01aT>Ofycoz=Sg@ZmY)0%66@~y~dPWU`br{Vfj9FuL`&hQ8-{PgIe{%6C8q+$66OjN~)KZ&JRCJQE+Ku zarmj1reukb8>UlmJaNQbH<_IPJZU?@z2b&B-eeKP(kW?agg$T>_LORHL&dT@!Uv~H zd>|I!AYy=qhd~p-)XfP}U6Dj9!xg#0*%+Cw7@7M}1=9mRPWGXKhPg0S7;x~bvP)Via4yLstTAH4;cjy6=wvX|vlSsr6G#-*;5y?w#AXDf3ZgK^ z>;sH1JP@`@S_|V6>Lq?cQE9AD7lS=@O2}P>$NgX;(Q`I3Y0y<&2Q^n*nb7dUM1=J> z6(D|#-twz0R9I2ofl0}sMe|Zj<*9`Qr1fP603ilxgJ*vA<`p$l$_-8vhXh9DfXjS> zlNngztjz21ycL@?nvPI#;HKEmK@QW`qv^SvMnJ4uYWOVTOyGiJQ-!e`#hLKKxm+j{ z+_aLQ0;1qqO=OvSC=|j*SMvCYcG7akC6ZW5#1*#JJ?oc9ogwBfu?rw%0JQAbwYn)> zlLo^mc19ee{w}q~ypLdqQ63>O16Ry51)j7_hQqp8k&#^-L+B-sC+n!X1#?qo_*jvo z^xg$Sk?PX(%y9ZjY)MV;i9`RP5*E(U%WcLY8p``gGC`g(Ympk4AR;rZWyPk>f$%Cc z3dCb~V{ELfEhX-JukZ>@N$#iA!D9=1ZC`|6e-BwDF{Yevlo3t17?mG-`RgX9MdC_!#7&{bmH*T4N_Z zzJp_tUhvIPykZHtF5_TW4zd9PE?Chn$rUg4I@)1QV{^T^mARD|@2GLb3Fu##e;oMk zFrpBRrK>`nSd2>!BEZCup8Y9iUV-#1gmZofHk$hj!Y7mGAKi(MXiTf(%D0BktGY5u#T-90xb0`h>ks9 zIz^4h-aNfxpGR9%5bf+lj=Eq4n zUItA%OC4d#6-ppW-#Fs}E-qq&*ElT`j~J>Gb2ra|yG#3nMCaYD5N zH4iyzjYt=RDf@aKX*R>=S9k@Ay&@r(OdJDnd}RVjCQB&2I7Z?CcqNz7Ir`%of;Xy( z=0#?F%IHi9g4DTB*}hEL>(D)jM(hO%M(Qvb;#f&w0|5lrxe`n0Cytiv5*{CrW)Mw0>0T4*_h8CFIPSp#j;^2-hN%!%usDP$ zHM0_Lc}_!dV;$5mY%~jx*Un9xj71iDeQh+)#$HyEx%+g@<{vCRLna%)a1OWM-NM7LkbO>zCIi*V=}`}2tyo$_2)9E9(MRJcl{f(6Ec8G~WYABqdrD{@03mI$@bC-2EgZzZsz*$5q@`X1N zUKW#gm&lu0G*=>Lv==9`l6sELlDZL)F7>D9N@@~;l#R!lbD0{?ekp_?v)I;Yh4Gien0!2T{>DKpA5&Rfc6nswq+f+N->m}Oz1O5> z+G(e%X`iz;gN1I9LSEM`rE}=xMQnvqfYi@)o-}Yw0_-4kl$12e1l)pixf?>5afxig z=D~EAfg&&CGA}3VNG^u6mg@%#b=;%}yL5RDx?9e|#&5aBs;~R!^}KlbNHAnqN6cWR zO~wf+m?`Oc%8v86T#53mAQXox0o(v2x9hDx%FI$v0A-r216Nak@5};g!%BPaQP|IYajrbF6wCd#)o;fMeTd-U_`y4ev@>8>xXC9fE6R9gd zK`C+h@Vin~ZY1zT>d-(C!AW~8wQH0Wn+YwJr;YOzVWsr8VdzU45GFHa2z7W5Okv<` zG<_x{(|gDEawY~iM+YxS-U4~2!5H}&aFBuhApH`M6XPZaQ-=xxg!N!A1(-5$1Ud@l zXwrd-F2$UHz>J~fDK5LMJ*-G({Ha0Al}B7=$2weR^X6G*>Zg56)7qhG&u{LkZ3+w6 z%dpU(@CD}$efrL%mymEOETmw(#%fqejWP2Z-OspVuD#ku*)evTk z2m%IgJU{AMh19tep2cBz75%yQBReWercxB~gc zslyM!2?pIcXwGxggGdIHjw(p2CHV`nWgt-*_$}>J;9B0sWq3>($D1cAn1K3i-pYtj zkAa}&VjjBc^Wxyf)wZ6`%X61PT2l+&nN=K$IlJu3ybnq)N%ZBBDs%}vy zpNa68WI^gFf2+45zAId zis&564Fn?1%$IDXuM}oOFKbKPE2d}@QLP4sP?JuAJ{Uf`ztal0JP_smgSg~X?JtY~ z4qILwEe2X*mwD!eM5AN|8Jv6vo-^m9j0_osR=48Inm#p@$bh}&i>u6h9bp+hyS9&$ z##R(>T?b|Qoz^u{ChLvd52!{x$ky=OCi=GveaOzHj~B|xN~1fLPZ5^`4vEzunP%iZ zHF|prz}|7hi?p zT~dQ(Ea*7b%U)(9J`1axoYii#ylkIIF-3^4)n=Q`U2nD}=V5Rm=MESuJPcLUS&}#4 zioD*FnRq(gD0Yj zNZeb+He5LI$MoogFvXx%&c~&9&Vpo}xZ&6EX_kZO-kQov?M=^JJ4z4|D9{2Kop5SE zcSWg{Q6?KTgNB%*2nQ^S?r*cfkJ$6>sky$}>pt9C`A zx68rVjOB2cmM9xM=G>TW9>-g1)>}Dq4Js-p<#dCSs_3I7As)P-!gQw3l$eJk*gH_G z2RlK~I$ni$h0#&S8#B7J2VUMbDRS;%> z!(^(_HV!Hqf!0doWf^(@TPZC&VoO=9qYB*rn;{541W9OSji$Tq%`G3K1O#NpwCn1E zpD+hj&ag`kuFlt2TgDVqw~X3-c?lPR~xxy}Gz!8If0Bx->mANi9COyScl9h!HOIbm4~|G$CjN z#O7!O_$&>h%E;O(0{mbJWS+7?GqOTeG5%sF)zSTSi_wasj6ji`1ol!bO&d0?od{CS z3QEv{5QF3zYFw|TL5*3+Zz)a$UPL4B-)8Kg^(yg)js!ji)vn;3K2M;rDjOD+34)MS z5dp<342VZY3$>VFz+*ERiQTyn-x4l6BV}-@?W!IXG0|Sp>n3>n0Fmve7;hoB3+~%1h&mQ?uh2r-V{~njpi_ z6D{L1@fKP&pbB;A5ff3k1PGMqI)OW60mGawL5XJ4RDXg!0PY!}BnV`*Yjsq<(jh|X zaGG?!#j**<{`3kSJNTzCBtBJURhYnKXwbOVEBm`@?(Xk^cyPGT?8-Pg7J35BmaMi0#YrFzkQG;^sWcwhyp( zvOUd2XPd$OVUI z8$pbdZM!_KfkT`pk!&JDd=L`+M}Fg?#M{u-Bj&+0e}G?vO3CDyI8Vf9qM(W|apHyu zEjt?xNB|_*Dix2Q$3WQPW#k#c+XwTTyYsE)?E}#Q+yh$Q#05Lf1D#qr{j)#&vnYE! z2t+^^pfK%lA8=TE21_T3*RgspVW^xAz(V$+A;6zmTIbl51c%S!5Xc6ukZIuzA=1)g z(JS>(9kq?=-wI!+$ z@KJ(Z1Lwk3rX`7ZEM^$-8y=9sB#cfDtsxoNYoB|36e-72&35ud$+makH-mN2Vga%G8}|Up$=t44hm5d2-%872F}&jH=DQ-_u6uc z=S%trcK6$xxQNDou5VOM{Nl#$Y5$F2;R;QK`GvVJU4G%j#N>(P<&>t0b1#d!10#B{ z5{Fu`Y1+D8gZkUyo}ka}NuDILuG#iW)3Yl};|niOEm`9OXt9lZq|-XF%5HOa!>gYN zaGj_u51fcComd{IoOnWt5h+ms9DDR1?ucySMh3bLCj{Yyy*Jyls5^&cn1! zj4h8o@fIcWL^Sc-pa)9g8IR6EEwsD-l)TeVIt zdletV;2nN@b8LC=j@5kA2j)fjd94wL!QUI$cZg5?ZF~v>D-ai$W_ggk0k*+&sI9W` zeeH0W1zWOLmGPD&o)7jdS-4Mo@EY}!**744s zysI|#e`MBtmE8D{cW+ya8(U1o5R9M<2sF#$N#V}BNdbmd6Ss5@V5L{u9-b$eU8HA&XZr>!z;6?Y zPcultiY+I);j>PKVO9=lc%7*+Mty^qR(62)!THYL4_GC5 z%y~Xc&L)o5gcp2uTM#iE_WSg6Pn5f|ySl$!1eV>)mQf2mOZ!Z%9(9g{FP{%9NO;Bc zPgO?V)qQ0AMD!MvhcpM%I1|PUBXyFOqbIeUvw{Ll-sR$=>GjUkjV5~-PJshc)pR`9 zeCm}qx!@~3idg^NNob^H)N`2CWD@jcG@8GAnOV#WyT2+YxqN^zf;+D=OszZso4^I2?}5DH%T=KkXS}SBsS~(l zFulhbXOH6;(?;a*vu)d^AvZ3X#gC&fX?({^?)VKz5yfOvZg>zcU{WCawyX&;H;#fs zV|BXk#g~)S2d~mQ4ZwHTdNq`~huwH+rzIEu6T9hz8EZf&tkcYfPQ(KSa?Uee+|Hb~l~Y-CVowo#o#0Ga;e!gHLgrRe zG(B^+&7PvY1H}8NsP(8u4PX`53B8EKy zZN8caqQ|dqHP?c<9-71!#1opp?ObbHmH~y@Y9^L5e@;BkcMIbTlB$%al29=i69$B! zWyxd6(l|6%CsDhHOSQuz?pkVYOsst}P2N}FT4JRI*J>)1yAM8{FU+GMBZof+GRg+8 zX69h|%F7Fpz;!Vbjm7|KB8!TU2H{kEWpaYf!?d5yV~FC(2IPs|(M94nW>^P%&z0tJ` z`buTLID?1KNkVxlti3n|k%C7#5cYs$b36iv!XmKn*_)7+fC5%i$(8Yj@Ucw4G-*Z~ z_TM#4x1-Zlq8Wf-ktZY0Y+aeuX6IqkT{b&8Zj z{)+AY@|`+rkU9Go_qSKuH!R7UOWG{b9t^Iy^M-VHJJ)d2I1UrU(`ImRG46rG;hHIb zn6H<>A`aYAL+W0woWHQttwt5Ng-G{n1#j8Cb;U>!t?3?mW>=Zi1s+yphyC&Q^yh)O5W|kMVw|l9HwkYdtU>G#3|=JOkyH+gq(sf- z?6M!cOeAvOr!epsBAGJMAEkq!-W;XO?UD?5Lyd3EZ?)Q zX7=o>nsTpJ17A+xRC|i>;nsXLM&!I8K>>)(%NR(aw~|f=4V=)OLXy4x&i zD6`9CJ*6kIp*=#Jf!9xB)uF?}>-ANn(}5BTA-vjl-i-&Ju8*h{oai{+VI&y#ZR;&= zoNEF?B;?#|TnlMHBOp+6;YZY`1xO&B?Jp0_Mx#xlp4e~iHMav?n(Q(zF5OeFM~E?g zE;4b~!`ZZZTO~anA<|_a?h3;SFti=M&|XbfCE2v2VOU6X+K^O)FqYz9ejL$pgS?k| z{)CF(Hmcy=V_JY);T^UMbVY}NFn3)E)~-mEOp*e#o6^@b-IBF;IeLuRj7V$EC zHtsVKLNO8D=b(+Hz0q0?=uoS%r$B`2rJWl)@U{AC95JTsO-=?&w=xXJX&$3EweQ}; z2X=B?(6Fn`ro@p7Y?6iJLOr)-n>BJRh~d2msJMK=8`hQhZ={d8Yqlg0U1%Fw@=2>L z0b{7cFm|V0#Cj93*giNf&}JTumiVJqqBh)BAH-221e$3AHOu%xItb5YOh4CLQ}}{) zZ$$%yp?o(OjkvnOXk!ncCXh&ck56g=#Ce@<+0qL{%#rknc#JGm!z3tEh2dGZQS@o* zbb~fH2)hm5oS$9hC#M4QL$@VSadxKFotk1mowvoJ>Qhfja@69C<@~a|{ZtRU&?M(v zT=8B+e`QLDl=He;4vUne9=Rj?6DhtI9NYu?ugJHLqKg8?5u8bpo>+O=L_S_BC)4r zPK{8O2g53hW|YD7mdFFjEH8k=_!0xKrx7OQ-`B(*xdGWxcSK_5((8!xXMrg@F|naE zkq=;-pa(;Bc|WbZBHg+cMQK3l=5E->%1T_D+eDN3Ou`&X)xUHTnF_b>2?S~^c3o|W z$Vvy3wt|}rxl;2((OC`fVXZ?WKu4SfH`}WbjDN#>J+23UHvP-fbu=Lj7ZmTDQUA+V zNDUb8=l&uHLMMeTOvFB*<}s3d52kPKuY;hSic}hufnl%EugmzbWP8A<>zUWdh41SS z!2QICdYZ8#^WOGM`Wf$q%}0rUN2f!BKz-7CONHQq%B_`jRUcRFSlZw^TtrJUFXRNa z8?g+B0L3ke{+FkO2NSUA835AOkdhFFlLtd0?!>=(`tZ7*aI|HQ@>)79O8!viY^12P zj0A1Om3^jooIDE+uqe!ICOo+dLp%U2tb!X1DvT_A*_cvoGTpR>jTkxO(a$eDNIIR#YC(-W~AnA1a(1@OyPx4iWE1>i8>xda5Pvz(41D5ESNmD5=#P#9KS<>MT zXv%tCpp{HrP>N-CU$OkW`-_4r(`ZmU1ZgBunTeXWHIL#o71?q{ZM>r@$8~Z^GqY3# zMnwFX`e&7s!*d!=F@Y!GWBj^ny)>EVk$E_^dF#Xw0I{A9|DF$j!*IhYh{Ko7Iqon+NDK-SSlb zc}OOEti#Z%a+Dt8e`|HU&cpOlZ@GP{w!C=i9Gs|?=^~e@p8h)nda`ogKl^78h04ow`L`zm!vXW3q$Rw7d9$jmx8`ZlR>5QeR;L zqB=y2oMHu^6^c`oGG&Jspe8H1n6xSk28o2C{&j53@@xtJmYFWC{T(a^Qy!w97Qd-K za5)*Sfe;o5v=0}VJh1mf4o${*YDiy;NN$q?+gGZajq96R_;0Uz)zp$U8faWdwN`D_ zH{@)T*RxFiN7Pz_yuLx%e1HTX&0Ep}^oep)d4B>f1hjTUkr)RBA(~-a-ib+Zr63DN zUz%H-Ub>9ykrytG&kPx!21B2UY})|xsUo5kv*_1wf2~8befiq^C1R`33i@! zqcR8#mhTxLXi+FiDxwQ(X?AT zwd8&WJIh&V?ra?}1x#ZdvISq=^TR|h6=@I&^pQk=4KdL}m4oI!qCj!c!!~YIs%$lG z)KP_Z!|U1>%!~crZHp8|;g&R09ZBHiiei8FdTVuqOAlNrf&J6w&ULhdATtO-URbm- zk`2ZMW090YSZTPEaB}LEl~>0XaM#nzD@)TCaSwd5cLx-jRF&voo#T^oZFZGrfnB?W zI?5@$XBSJ#vz3m`3-2h2M5M-B1pI!BC0xCS~bkvpyx`lXNC^FTswdyc0`lVTBE(>4%v5AO4-U=r<{V&`HwIAEiJza7 z>hnxqclIJe`Eg1g>&@%3Gu>jycWqmqt^oKId4oA0tvq@9si*B@2-l~KR4=}S6i)Tk z8{E+@)Z>fpm2no7*h^|>5n36hkTZO1k8N8J#|>&C%tcYrIbJ|^sk#vHb1R)SCkY^6 zel<%Hy0QRaSOq!O3V|{V@jn!%8*@Q+eB93<#n$t#2uMp}Aw&|_s+K3aVs&`N$#N;Q zckAm2g97s_9xOySX*{ALcjY2R;)<2-gJ0N3qYSSW(k-pOGhSh`c{Zws3yssd0VL0lR5F^9prcnvP%vTqQoNPEQk?$w@TH}b!*lahtq z5t3I^z(AUWWYwx|Z`&_0u23Fnp-<=V+gN&-Grb5eDAd<_h0 zt;%M7$C6NtxIMI|q8gP3zpC`nz1eB(clTIOoKQWLoq+kbSD)9UAU)N%B=K%N6R}5^^jR{1Uf+1k_^I|29MHdT1ewT7Xp$?cL zR*^Nl>0WY&lrHLGH(Qg}ux-a@E=|F%ot=U-MjBSQLf}np;2x;!VxOr_Q%wiQt6IDO z8=Cz%Fcif;?quYmL&0=77N)*SzPvfr~XrcJ3kZbEs0%Elz3qwMb>-`xo4A& zkSX;%3_a6mpFyOpT0An-xh8lHx1-}<%U0rpLnBF(dgd~W9NqN*ZYWN^gvqk?iX_c2 z5Hl?lQn11#kfi_+83z_pLnhC7#GbIG@Z?*QWB3sn5w0U!UurHnLVE5f0d6Qgwd4)a zly4#TFp;vlyGwr-mOuB`d_t10R#g!G#w}FYS@hewNVB={`T)eto zZt zFSCdNs!V?BilVCNHM zB#^Z@h(OQrk&+CyJtXgCp`Ejp0bTQnrw2C!rsJl|;&XvJE>qyhZ;)_d z%Z_eaNNp0mlPx(WVFDq1f9DSGLV+L-;pO<-f4lOyMG&Oz22xk^dJA`4ZjqREt}#!@j+7={nJ7tVSziW1e$#FN zSV52hxVyvXz#}fQ&bOM|0X4mg@-R=)84_Udh-nDKFpDOE`WJju6Inr$Q`%@_ zKeAp6w785vymOR6peWTMqd4xaz(o+*{={1qy1@XjZv!2R&4Ziul{D)zMnzbJ5gb_m zG%B>5rv8+l+2NS~iFiR%PK(cTTiNPqar) z)n0u5asD@YatSW(WlkN^;Ny}L+428{eVmi6Ssp*MXQE`N-$*bDeY{zLAD@S$WquHw zk+fg}E2xN6Je`!JLA)s?AY+2T4M2T}%y9o7p4EsKkXsm*hM?(Mh)33he1JdBRaIRX z5lo)vKCMT&{nBsth4un$DudYy5C*>18!S3zeu(y@^c;kdP`vrdos_O9QE9wbATWQ* z?p!+Z0+Er7xCK1ccB*yNImw-Ygzls}$nvl`h!y7gKK3qd*8TPn|CFV7d_CT3tsaDT z4>NM}uO-uFN+OZ7W&EnF1Xc0K+GgAnzU|8CZiIX}~+A$?gjF zJk~;j1bHctItGXZm)2mkjHqM5cWmWWWHgb3NDyP1 z^W9@pK3Sp&(UAWZOsE-;Eg-pSfI^**LEmxs)A5~j9Rgt?|Ii%4PMG*sw&0p+BB+6BslLzUWEv$=JWPOZ#TvA%mI)Xu~cjvnrGL2?{+Db_Os zS#Rzh)Xc{KBu!8oX`=y8-dD+ML43j6mtW5J?y0j?d~ic%mOEw%hT!NnopdmiG9Cpr zcLA4Ljp1m!6{4n1R!}IH=n^kuYjyEcP;iLVWiQinM5z;&<)Wzzw$D_eS(51&r4zWt z1E7$nrC_CSBQ$Ncyi#auD4d>5T_>_mv`J7S&IWUmRu5n`n>1-$9&?+p7*U;bqzKsQ zB#7&js)|mLqOXT<;`3Cpa54sAv%)@d4$1b#BS>il;73hd)C@ANd*wV_Xu^e~1}Bk? zj@^VXAM5wuXsMFsF!FQl4HBxyGtjiXvtIAQysSU zWU0}qO(nlzOK18{=LHbb^h%IrkOU0|Nc0l3qzvd?_cD@aZ4rv*tV&=$$*B9J99C~B zMxmsjZ4#HHG@mu;v zhT!g8UK0|H4pQE6ty|$(UMk`qR~KzXyrGaeUV-;=Rt^vlN;M^q!>W-VQHH3*-H38HXV z@=CTcM5u&MGZwPAK@+Iro(`AXpv2(+wy_yo(vK7t=edQtkhs(}L?&bb zPO5-2a4oB1R zEUuABeBSjDd*!iMl>Rw)2r$&I(}`~!HVHE!#XuuGod!m&PR~xvT$-F(;Z@w#07yn7 zVxh)SOyUl?DS zTM+9vF~Ly1zds#?Ft87u+*ueiA0}hPYN^8zSIa{kl7U8(imjCI^5+T6=&tjc#?b-k z-cMLFBXTKI7}dng_~PQl@%dzA!f;$ml+R!oo|MA?j8VORL87Jaf?Xj@pH^i_wT<(d3EOP-@5fOvC6mbedNdc;_|(WjLfO z7}wxIJNiulFVW>C{*RJHZ%jz&7|N_rBbnRkjzlG^wBs#MgJT~Q2?J7GJB1L0a7_~9 zDnkv=d&uoC9vaXYFT5rprQR+Pfib^L5TzJI!?Uo zX2?i^1#)%rASA+QeP*1nnCL;WcN&2WYHL>p@q)(;ZTiJQf&~U0va`Hsz?>n7>=C-+ zGiun_4{M}vJpl;uNZeBBfxd+H1hz$UIf{Km0 z(x*Q0HWs2IG(t3BcY;!~1QN`xP~BkOVU0FQ_)l99@a3z>nNC%mH1qF4lv-J4$i+#% zlmb==g725%1NHT=MhGS|)SLW?HBxbVBLr7)T_k@U;-e&ZoKY9tyrB{m0R@XEBc76( zWl_O}g#dt=V_6?PpV3FdSgd?_2hCa#Df`Op-0~4>VTrS|cMYd$U*v+=P<5jH9ITWy zXhQptIA3ehM(SH;+Iv= ztI+F`KaVNKBksT@iQT}4 zy23B(+A;q%J&Pscc^Qqo_h}x(Vo>v?9cwHOwdS4Ucm!G@I|Ag82DiOZgytrw5<^QX zuU?p5QVffg>W$ba)IKme7K>y{H`Wr2nD|iX1QN5VIBCaIzGMDdnsOOpEt1rGN(BkZ zf}5(S^@I8kiavL!tmIOONd;`aiD2J+%9@hmA#v`q9{LQwkM3z6p*2UBqE(Kt)T0Y7 zGLRU_a59)EfmqAUTb7I<#PSvG3ezL+OrO>>a42Wr(y)(QqZ4xMF844tFxzbIhF|$o zbIZx);klRd>IvxONa74uFdb_16(Gd=1B=1EBrSA~BQaULqC1k@@ktmj_o=7f{1i{-dRGBofY~&TQF4}|iNOLGt zpvs{N65fIg<*YM4k8_ea$DOc!vt&6`Oe%?(TcepknzDY@5Yz_qQ3-Eac!=^OA3As1 z3*$<@2@Gnla*W9$xkqr1XnzH4uyEmFD6S04GS0fzP6^AhRLSGeRt{Axo_iFE7BI%b zg@?Y<%99+}LUKjOLQ;pVyr;G~QbP@&jU1;3fgC+4M;Uu}9&s)uBvX4yOSX9q^Kvdod?f|W?6S2Bp)Bug%Z`9#pg#8C+s!cR3A0+z8!6N%B2!ub4GvdZf)ZIB3#Sg+SRP)?L|X#}&OlLt(=VYk zjv`Xqd{90+1^O4aMsdDQ4rx?#t)CrDyD-ez7P|Goty?Vnx3)4PKZzzXKo9jx3~*8y z#9$-Q{kV*!qp6wO7*H~!UFEY(as&mf3)KcXJa8)P-iq+rAky4m=|*j1^NgqgQh@|w zgP@6MB>*YuQ!%dw1zj!4d|^dx?V(yao~YIcJSa}Y1bw)%W7CQ+R#H=FY;1mEYUR@W zU0f#yO4 zbC(NNBx??4MK)a=TaD-qk>^0WiM6mf28vIeX<-W9RM&_Ov=QzF&kUk1wrKS#ZcVqb zwR0Ka%Z7~7H95~BMjOy{1(`ut+ekBnhE8hQHlRB*+hTWeRJu28L|`1m{Tq9tDxR)i zh`t+jT#7AopanPhEb^b1#r_FjOs?*&)|?@FBx}K9m?jEF#n*<}(AW#q2VL6BQD?46 z@IOsnv}}SV^pQ^FMdX*--rru_TU~2xHTFp44oX@qyg$FSdL0wbqZ=ZG6Z|O6iUy3c zZkZ5YZNZ2}t|($o{JYPON`}NRXApFGg0ZS*I7+4|vn8d4cG3h5G&3(SOVm%L>f=a^ z2E`!vKqLY^Z^S}KGO3Wkti~!>B!Yn-+M8i9{5F0~T_tdkty{byJ=I#TxaN9*ieheY zsjH^o`v;~f;tqjYoA@2qS3y7}`XOKu$jFE{{B~M~k)K^{>b6{tnj_1m#9X9#=t7t) z$^k;*z~x^6k%0GC7G>1@(u)$L0c+{ zg6Ui?sYEDB22K-G-g`kNF@l#;#d!}qsix`y5Yh}I?8T@i&1jcM9Zvo(Jh?!i*xvYx z+#fmYf@ZU%#VKH|f+gC4)KOj}ZH^*D+LpGHr;x}sXey}3Tyqi|RUl1D(JiFxJug|a zBNa*K8FU4sI6U?BoT#NhiXvFkpqfygNT(4L9vpNYVl0yz9EOKUX{qDf=EdCTu)l$I zpg{H-&DCo~3J%{|^@S*kQ`uo9VI5!^A@{8vUw!WF9V~hfOS%?R-3()O?;z8HK?*UT zHm+-wv`gCDVh6|WI0_*O)fFmSy6IoxI1+nxB+MfA1*>4RN)<_ht4Lh3QQu|q>z#GX zL`vn3PTWx`d^?V9Q9&a^f@C>l?8*S9jM9@)XBd*fO~oRSr7^B(Dr@_s34Sx0lP!@1 zUwkF~EQy^ehzidp!UV~LVNWUUc;y(N8}_Dka*lz&$~9<%Qfnt;ox0#eyaCd|AcjCT z{9XKY0LjyQUuJ%Dwjkz^rS@jF@AkpYy2>v}f$s8cR2J4mx{nTC(?tep z8FXTqrD)*vOf_i_f$V=UG$iOMXc0;v6VWOQ!X64oofMCsU4yepHVik%9UdHDVb2f6}<^UNOOodtRsF53Cfzg zPDoXiFP5aNxhvEDbImnLw4oQN*u!bPF5altF7Ct?*02RrQnk`*2zD;qPYKtpW!)%W z;GQ|GVc6cv30;~m)Ht#a?kpXrhg|u7BGCf4BdQT}s@O z!>d0uqxDji*>h%^RGLM|MVf`5P9e2Ci7><$_G2lfr07E@H&CF5Gpk}nJ^%cQSq_iE_5EX3Y z9DU+bL38$)z9yMS5@)Tyrn}nlEfjKrj>Q@fjeSJ9LfVi*Q;PADPIIK)q04-!LWj8m za8V1BB%)cu6e<2ybIrNTW_Yns1w?#itdx5}l_f@Z$yNe!Uh+5?Pr9%xQ=QhgSWQkd zZnQ|$w{AJAtLN6{>K?SlO+*csQUfk;!1zpePQ=x(x-+b+oPNb9BLRAkS)naY;}9Q@ zyF>Cu8cgkFATqdU;7v$&$4q8fH;KT?4P96zHg00RFzNc7koDFu!k8IZhQn_vDPa%j zBN@Upc6|)>v45bS3d1V0f|><%`E23tAdNW)T*he;Yr$+xpu(!EU5xoLe$=Mu2*kz< zM9bDv)7~(Hu!4!eUC^KalT;);@uz@ZU^j{7b;2$$LbM%|Jz}qdC^xPo?1H*7*&R=b zEoeH~C71EoB0ttFU9hVea73XVhl)i&&@h_c2czjC3oNF?#*vPf^YM7nm>|-4JM4E> zXPbBgmm7>Rllc`y)SJ_V%zF|hB zN8SDv6HWJ2lR?>DY@~6Kq)OoZ)wb^CnswJfM?$%%^TRCle&5HIYTEfwzi;OzU?4`s z^yi>NAb@Mag_g@2;9wsTr_k0g2pkOf!uZQmE4Y9c*?Dl76tcb+XG{zSOI$FaL$hdDnxHmV zcoQWE78sJmDHU+^i#rCZUsO6E4Q zB_r*1vLBbNk6RuX3Dg50au@mEAV%c;cr-{7GMOx!ZXt>R%R!Szwjy>X5H__NH{nK) z=P60IX?&QSp7cIc6Nqu4R3Wx!x+SdBY7Xtl7+wzT%lvEXS@e(QyKM z`IdUD;;;A5X2~6uRPzEI1IAsa4X7HnIdn7Lj zRiBsC!WFO(n$pg^k^v^1ww9E&N9m%gW0x3C`mWfpi1Z{BS9-OP;1c6;bsTD4!s z&tl6KcsS$cv6Z*-6*e+3+bUUl7^iQCAi zi46_O38|7>kbb_mn|U}HQ%>}NIvtv@ujo+gM))J`!o`XovQOWElK3<2SQ;E`-)QXG zymr_bNShH;*&MLae_H*D?3BYbn;2P0A_1_1j*zvXal<^8i8LT?QehfC9!`u?@y|pjjX%F$IaGEQxbH zUy_AG@L5t49a)f7DOR&J%sdQr7-X+uM+v+_2+jcxuJ5TT{l-e7b_4C&bI`4!NZLy1 z*CHB{`3e9~NvA|=-)){$mz2z{70XaB=`T`5zM-U}gb30(Nw_PphZU86+{z|0QWubq zI!{Ph2olj9g;+s;m7hO}sy&{T+LkCnLwFDeg`1%WtjSw<5`d~HVzy;aGrm#mf#dSj z(JvDhaT1Ur%ZU}KginY2s1OU?mmu2CL(({Do+aUMkH zLgBC&ra*$bdpdDvg@v|rUJJ^q{G%5UI1ZhV1A&<^96B7?13?teq_MTaLA8ptH=d87 z21ywcu{$_FkP8QKpg0=IU1RM_r~`g%9FUaA^vv^l)o{fZxucTB0tMbL76A_)o8>>6b%JZ*}tl9T-*niv@S(BnH zeIC0@dzZfzkhX!iiA1UL5(2((e*?Ul&(2lEkjC-xTMh8wCNvY)AlZZ@EOS#M@~ z0{O|N*c3Bx;o0h5$EJe?$_#(I;g56ET0a zT(oI%Osf^7D;_?LgVeZ$22ssK30fsEi}iYCb8m0AJvKUe9o_G*jlc{TMf$X1u)!$) z!zCgZ z7Eo9d_gH)GV1*X$KEcWk*2LHi!X_x8=AU&UtNU7Y@nHK}bLT*Fxa`n#GvsN{k!W8m z8+i({?p7bQ;$OTw>skxl-)gpQ&>y6TV=>;ky}qZ8X-={mC4yaPCjjZA;yN|c05&k| zI~GN@+FI95O|)g{xe-(bnyA&Uk4SE_`Kj@R5NC$lWOJyXfXL((cW<3`IlZIQRlmK; zqbEa*nL!l0#MuE3W;j|kB5AN_y;49cy9{%|Emt1RN9*E{7TZDF$O#88-x{o0?iI7MFqxyV8Zoic++$PMn&_mmR!7J6%Js%g?lSN1x`Yui zq_BWZ0U_kXL4|qW=~hf}RzVCMM0|U7E8$9S<{U_66C*p1b8!H19?4>OG^AB|{+c{F z*H(HaGm5nG3cX3JQP1fgz%t7lbg=0**E$feefFLLrb$lEofviGc(X zPg@dnA@gP0m6p)8T+na2k1f|oLwB$Z1)ASdbv%5Q1}1Nt)}F9FWRbkpjONbU+;b2| zG?|X~sAgqGF`^@y^nquZ6H!fYpQxOJ9$Vd3y$s8PlSMR1>!em{3Nl*-$sc8e)C6TC z#X2N_Bw9YUmdB%bJk&z)4(VB7tNv#y+h6;%x%Vtv8IBn*NYQ40VZY2D@Uz%%sG8K2 zHf%-{TrJeELsNpEAfh1VD08G=Dg^#Pg~*2^m0A^?tA9rAFe2deCz_#Fl!S7%1bJ^* zT{t0_;ah6aXH3mr!!8rLrX0z3-*IAeA=9`m&PKFXHX(4;3PI;*f--1z9r9ldw$h~I zHpK8@SWd}VlNxh05zj1dSoW&QVzEfP`kF+O+5B++gWFaBS4Xfn#7_gGP%uYLivOfy zr+Uy8xxXw%$Yq|2rK7BZVc^tbCB)i-sRP>XPM8%ltGd5YzgpmJeN zB2lemIdK)Weg0MvseUJ*#&BB@+PP{v=;BZ(5cZB;GgOx#c!c^vse&}f4AJ!A`?fsG zm@p7$Qo%+fdfhmvfDe=PL`YWzK)_$hD4-+cadzOHh8ZP|nBs1&aNh?AhyyKvtp%}omL>&`Jj$U9v>}#y1Z%|!Zg;taLna?lEws%i zCGYiA#NTiexWIwc1n5hitNjZ_o8px9cz9XkY=0avsp!@a)AMW{%gona;43txKS6QNXFlcM3k2km(zA7+01Ao8Smp|6oPbWlqC1 z*ySu`YC*3afm1?NE`t)z!zAz;d2QkRCe^Tfm+tK!gO&5GbkFB1;EU6J9vvwLW%c29 zGuN%yD~DN35>~W=7A&-{15#a=YVmFe&Er*T8fMWUVUZ<^Sm<4mo5z$Cj%-48#*5e_ z_pShDNqkd`841K2N2K6T<;hgJL?jnfq!foa=ZU>#+coXLro<*UUp$?qFq7;=ENqL) zZPGFap7b(91CS#tbcUsBShj80-0?wZnvm&`=YeN!7Wa%HECz>k^wzq`>4m8YT=jH0 zW@<*Jbh{YQI%hU(>_4IZkxEJVII7s+EG^sun%PR_R2JKQOfkhG2F6A4@K)o7(`5H? zX|QM7gbv%l&>s;_6*vw`h6`i}Uf4Dy!&9_85KYf%eqE` z4CIHz7hruW;Z0tTpCpFUa(W7&09z&&RGg!g0u8WI?2t`LH~5m5BrM54p*OJoO8qvB zZ}fn&+>^Orv5bhB>qaKFAm+rX|gu#gop=;0O$An z8F=Y{2%OPP*0PbXM{zR>nbudgL8)?HGJB0%ml<{h7qhMCZ!M|c6&il`I;}lWeq%kf@4x;1_>2SflDA$NcxiER_^IKEtyRnm zVN8Dy&(`JYqd@DaECk+Guq~FoGj%i|kJihZ8MKRnT zD7aH7Cx&0T?C7459}cnocqX(b4~#^#=2b%WpJ*UZpaAOML@SpH1Z2n8>xk z-)S2YrEL^InHVlWV~?_pb%1GcyZ{y+Wk)wLERVA7;Zb3X`Nr}s<(u&~h_}-UhoS7! z`0!ku%c=OaKGAGDcvBN$;`!Bpo)TdYxSBux4NUcRdzJGv)!LFag*c`zF(2UdR%1h6 zU5dR;>Gwcu=T{pomN{>(``eDZagwmn%**G6Sfy$EE)u}LpK(HC6%jv`0sDH2ZS%VU zY+vzM(PF=cxp^_nH6!;GhwHbwX#zJ=Qd^6xHIP3heP7ay2w8C6W?C*lq3vK3WG{VP z(#*@C`~o135XDVq7`%4hRNL)c?>p0d-BIJ-2@mva*{L1fKMt{Ls>Fy|BbJooa_qO_*sSM)Ex z8bJD0zzlt8BXcv8n1-iDo|WFoNu(2P?u!vM z3qeO$1{UP8$g+hCB2CP4SXi7;EG+D=9T0@Y@h^!rV9>c(0VblkvDny-xL(|<*LM%# z(v{l#*H>E;3l~9Gpe%Xf0BM7-;=pKg+a$aqxa`eW2K1|7>E|2UYpqohH$nLMtp;cupHfx}MELpiDKyxB^^Stb zH4kn$8kpCxE$?aXU{@YD*Ivi|m_LnSOE~U~!+U!;MvTg0u^BfYiDZ1CebCe%uzunb zdFtKhlHIy-(|iEOspSR=%Do7ptVgk)m;1QscEK4IAg?vdE=H^7pC8FLW-+Q8Xo=1Y z89jS?QvpxG$pP5`48lHCsY6b~O;-ihTdS>us`@99qZyuE7?HfS0w=9QD$!w!XF$+| zmXy#3b&KIl0q?V`ZrAr#t*REPGyFPf4K68cw`xs7;hvPr+5!A5IPHY(L!hC_sZ+O` zHCI{P-Q8kJzrAJwKe?$W$B$%l8^%HeSnQ6a^G#f9;l3b216`T$0y_e**}7v6B6YXH zA%KQ;H&%Q$Bb6m_8Mf7PjAdAGqH@|bG{JF<(Yv}7A_mmcm;;or~#tW#YQZcpdaO zu-|G71RzsU!X12-TOIJ+6IAmmLHt%Zc+D*AhEX?lDi`=~>aCGx>-y+MbA9ym)5C2n zYPVMrSMxaoK}NI9pacdQamVQ<4qAc!S+L$7DTg01jPDnv4m>7QVw#xFkaD|Hy^O!% zix-C{C#wtvNq$!@To}7}acpr>Bp;C60X&PH>Nx3F0zFm+l%jEVkwoNw`T3u*U@R(; zk;)uI4Yq7}LlbvxJyMG=J0VO1Gm1Z8(RfZ%@n!su}rb;3h)m{ z9k!FhrYf{X*YQLVrqE@W!$IpbppG)vEAlfC{;}t$R2KIzM{!IUv77?cX+$l=n0-Jq zG%gWa)pmt_Q2b>yOF7;PPowVRXyUJAJOf6eg<*t=DCOV0Aat8+wXzBOh!kbQMmeSi z#f=>W2FtmAfqcRgQ`)pEHRu*xk9blg*D92bGY-u^1YzSv)b)7^?IcG!8tk^u^g}dc zWM-t5Yk(mhkP`U;j+pKss3RI59Sn;PeU=@hBn;X0Q{Im3peH)cFBAo{YW)xmHl0k` zhm!P*Tj;OjaV4~w{cT<_$I9zp9ct{Ddzc7bKn0Eu_uPJjQxULR5 ztE=%))LnIi&}hJ=MV!DUb_E8qlSPnZbgFL*(QU#zkLeDnEE`nI1IdcRp-Hr?KN?tT z?36k}LV=!4x*kV>&Q@D=+;9X;irfkOQIza?2$(1MXxhVE>oxa_Dy1+K20~r0V|%1v zpRj1zSgdIZ$aWp{hwva+X%w97xuSWENJQD$ICJ`RrS=SN?P!DQ3!Rls2NpPuYX`&F z3o)K4ka=M=47kI2#~w!$s2&srPc1dPUO}e*H1om1F(;5uaJ%iYicIT2gmLL>215yFmeS_C8l zD#AI0CK5hjS>D2lj_k;;EDxa4GQ8i*19CPgeqA28nio?6tj;UnP$b981&Uma0Nb>RV6+%Oo3f7O3i)jR7J-# z88e*laigCrO1hZc)#U62@xKiZG!_XrdHAO)dyLfzQzb}TAGH@3I-!Fkb}T;=$2R-1 z7Hl#OvLoJHlVt@}UO-JoXDZh@n@v4(=R-G)d1v*F0^Fe6vds>k|AF0hYxr~l$ne^! zs?=f+rE*-eMB@SfkLxq>N&#r7hh%j|Ou*1U`=}Bvri9ICuyz?tZ`#GDCZR7&jRvsyaOQ}o zk#XK3+N)gX9c-(~3O?ch)o?~YGH+wjHA!)8(^)AyVY!FD2ST*~_hE{(_ltwcDctCb z$g`=*u}ZXHQi*~zS~z-Tc%iumLIzqebi_8m9pK^ix+UrCE4k$m#>?z+EZatUT<-jB z)vvFvWA|6LbD^fWcIK*vN2Gbq+k0XNFoe@4oxP4MK+ z*cf61Hk*jU2LX`PdsRDFs_cEJW7XODfeaP1s;Nvq>`AqxDj({ceuyKDQ~F^K6f<2cSww|ONNRw!SOFp7y}Ndf1v^8}VENN(nr8br z7mWBXgm-mvQAf~A10Ko%N0t5U4-W40Z2m#Qd#iDy@xg)nDq4S#&^B7@4;a|#g$d+8 zKt{4UvKvKe#xf8K$<{jJ0I?GXU(To%dXS^hWMU6^Kt|+iEo`F5@&-D{VH zwOrtf3@$UeSLio}I61e7#TzoQee#q2gVywa@Vi5Q@Z7Jz z^fmwQsek#uer*iDpZb@-^|fL7{N1m8UOxY)uf2%RpIrU?*Pg}abH6_EwMXRn?^*e8 z+2{W(p9}CguuUJq{8V4x%tIgR`;CjuIe+%;zK=ZgV-J12udg3Z{#||g?7xH0NAX{U zzt8FSkM#9@j6d<`pM77(4Yquaam^<3Hf0@3Z(X`8(Iw_wGom-CD;p87m(2J%a!K zJ^Yvaonw25hHawY?>~eWL=f8>z<;>Xhtk9new=yt-Uamh-gBSq zJAJNi|0Dm;dw=>HAL;Ac{5y{UrguQ6U*9@&uJ4-<4?d08htF){$2s&3kC!@Uf@y>bw6N9)A4| zltzL6*MIunG8_NybMojb@9q!1{S04j{yEBSeh2^D`*lc)%a_0M?%v<}=G6E9`tb1Z z8<4JjfBL`UpSPcR9#DE~Ke733R{CRB+LB7&{21H%2ugnb>UZ`ZSp;~`;_c^u>R0f1 z@5eX!aqlf4ht2mdzW$NL!^imS>qN@kPyQp6efy!qXZY*z8RF>h86xT4qX6Tr-}%Hl z&*I1De`*N-?*Huk;bZTj{N1TPyZgx9kH3BK+w)(%_aAa>m*2Zvzjt@)+fw?>zp(N@ zit?KR3x}}(BZrUu8h+Ubzs`p5{S^Rv?;96?zOV1v=P?{W{P3A~zkBiP&*SS?{|+Dg z(zBGt`+xfB-@NeIU;5WS2F~C634DG8&;FOUzVUZ4?oZwP{WJgc^S}H(eEsgH-nzZ_ zshj_Zzo~FO{h$5T-QRlsp?3)W;bXg%bA7KL9zM2(&&!wJ`MbcvJHL#74j=n{Jh}VH zJ$!%rk;BJ+S$^%xudn|%{L%N$ZT!0T%18S8?)?Tpe(QzLpvAuZPi+2oe~a~h1BEW% zyDo1YWncRrXGi}nAD?;my?b}?=1>32|M&3l?%}1ofA&j%Rs+)Bx$q>q`{X45ee4|n z{i)~q?=#Qx-xr?7zt?`{u`kQVCzs^or%ubq$A;wNL`^=12l4T1|Ix?3gpa#ZeecZ3 z=fm&JG>{t3PwKK7Fs&O5(~2d_VL??sI0^6MCS1rIlW@^NBe5MSSVfd%^Z zA3>R)V3|#}efU@n??4Vi`1q&q2^Q{7J#rVbyWZaZ_Wl!Z-G20=`-6ASeddMA$NrNa z-+SzZ$NBN87Y6w8qc8NG`!62a|Jc1h1lrELd-b;;?%TZZ8TQD|f#1Uu|24k6{+Z3% z0A^|JBYhxZPVC)heg)4DzjgWTsqeh?y~F)a9PVR!e+SPlfA>0={y!$|zE%Ie6+iqI z${jvKxeHP%nht7VSo$1ig+`U;~^e_MTC*J+bKfZk7DjvV`jqg8xuJ0f7pI7gG z@44S?fBNo^f@42&_=j(O^Wo?Iy7hmrye6d{#t{E8|LIuj@Wk%{(%;9Q;`!nu#$XST zxzN}6^B?^!W2^t`%pd&&^3=7@U-;~&|I^>T``cIFV@3N5^K{|)kN)1Le{=jZi?4k8 zH-F(r&iv787W*wZf@pT}nZ~m=6djxV-$nMFh@16M{fb&1!c!#gvuHOSb z`E8TJ;NBC!+FQT#Fc5PI^fSz7^ZI69-aLXg&)q#Y_*?gW`Y)k|9#JMYTSDZ{M%nRkmde*f^qH-Oi}6MtW@tMDH_!$$8;4nF$! z*5IRG#eb*19f$IL3w2Q1dbsk5#%-GARBlQ8H%IL_npVR_rL#N#bQ5JPtLGe_5b&td+xdC zoO|xM=broZ%YUu^t$*^r?f=o=_@#e`0{`pZ|KLZL{xQV$3cC8G!+$b&_>aH-9p8e_ zb6@@XcYK@u{dW0_zM$Mc$8t+wn_K$o+*dFE#^E>pH!Fbr>)-q*|Iy($ed(|M+^>Aw zH-Ghu7ubQ{_&Z;`zy?0oeE8o(YWt}6_0#XmzaPlIKP3PDu>AXD^6$SU|Nc4o_m}YR z-7Tg0k1kGp%WGQ`-vVlXvGJv^NY_a2rLTVdkhBIneEmn4zNTyhLVqnVKp^znU!D6K zU-^%J65=W_w!%*F}(iLC;tgP{Rlq&%+9GB zWB;Is(xC3|zn`D^p0TlC!0-Qx-#>L`Y^;ml4g9`^-}CtWPW=96V{Gi#@cTdF_owmu z7xDXL{Qg^b$DiLs-Cvo2d4C$P@cYky@7UNDe*Y4F|6M%iPoq9I_TS<6@8I_<`28*X z{&B!);P)ba|9yOa3xB^4zkU4v2!8)Kp8Zq!9mDUJ@%tz6yMy1);rAYXZ{hbEe^GWC zfBy^o{*2+oHoyFBH~2?>-uYuU#{LydFjYUkCj1Cq?%?-_Ud8V}4MhaD=JdLO#W>>% zHHJ|kyj2Bg)MtSC)mPQRySKWy`nUeopZd0+{?o5~@+V&Xe}3`T?|dJ`e{5`XejU5k z-QGI$r?2BIBNG?&d+Sd+J=_tG$cDqM&VFrndS-h4u5E>{Kki^-9p2c3^?Q26Fg}?& z*xC^6+W#!ZGFz|l1uazm{U!U$@81NP{R{ZzkH7!LSb{?=RAQr|&|Pc7YBUb-_kJGHd~ zHvi7C>(?i)UtGL@eFDC+Zj(or`n?;AH+uc88#f+Y$EAkC^7~ypo4KKnKfAE7fLF-V z-Pvqn6CEKgyEg`afcT*B4E}vHR8jx$pc+}Dvo`?Z#`lf=_#eK$iFjhy;uWZLTw8%kk+9E1rGN3G*RNk3b!Y_5 zPcJNCfUp3$dy&J65Bl$o?*q}tnjg7-ea7LP6eEX!<1>Ktg;%a$pMD{be(Ia9Be%uQ zGw`DHZ5C_{eBNGtaP#gP(;^1n@k+C`+k3>sd~lQf+hffphMY%*k=mg*cJ`I#roQ>$ z6)mzo*8I%oLH|}~2jMnjzxXkI`{z*)F>Odb|77fAACZrEy*u`Y;^$_2>D!x3qSkGPLSvI3Tk|eqW@Iet*w}w4+VZfAOBHa#yFR@3vHN?9 z8C%eFQZ}q(-|;c%(t)r4)<E1ttu6oDjg`25H4{mml z|1OQ)!>8M0D`U&}ejESZ!e{>c?8pAE-{QhqfBA%;$Hrjp$`8To6MKL^KZ15%0lfZL zcdRqEH}(k7I#>a;0eNq1du$(N=y`et8y)BI`-c48kZq4&82dDyd-+Aw>5Xj)oCCn? zpf1!Je(vE-YitW|Yk=6r^Id%Eq0E-FSsQzbzkRIw_s0(Lw^+kMNzC5tka? z>c5Wxli%8aw=3^ks8vHddw^OqNCyIs?QY=BCLlTlZC%?Vju*$iIqAy-f!hOI@59X4 zS=5~_{L6Zm#=ZshNGru<5AEz=Oj^JSQx5vn0X|#!yeC*HM&zIGM7=wB{zz)vL`w%_ zM?$?vsD+7m?2~xb6&lsB`LmCbj{t)`Bn>9D_2%Z_#A zKwWa8PI*W5R~$=%K-5<2Z~ z_a|XN%(r^GQ%`12AtB0MXB(#-9%yQwtEZTm@!GdyYxoMzsPy``nI2~}XmeT*HF2sD zu^0U#fx~U;D?DX^R@z&4ySM}h;oI$Ac$vOldLLDJNbn9%N+Zr2|6V=S>fIJop?j)! z*jd0`Sv~Yk60DuNcI8}vU9247CnZX)UqPfmg6oxYq0>qO+y)I>6NZ)d<%&P)FBq+3 zJ5K%EsLPa%!n-0Uei@P75w+dc|Y4{pM~x_NKyl;@1Ndg_g->8aV7=~?Ci z^y8rW-34A`)khAn!!Dq`f9WFL$z4C6Y9Fn^fZD^LZEs%MnA>=xHPfEC)J8r>kR`{) z@Vs)ax(D&O^flJMc6Z_K!s6oX|CiZcp8fl?|L5%2X8+&WZ=U;S z=Dut0^xX8^^4!|o_sxC(-1gkgTyO64bN}+(pPKvAb6=kOH|PGnxu2Z-&*y$_?ic3% z=G^}@_ser%nfpg`U!VKf`ENh}UFZL$^QX^WKL6(VFP;DK^Z)w!zi|F9p8wCz|JCz< z_x!J&|E=@ie&N*%pS!Sm;fF7L@xo7BcJ9y!hi6|Ln!F*Z=VA-}?H;Uw``g z2e1F!>%aQ?|NZ*^_xc~Y^sSe^>(bRrOPB6mdT?p|(#EC7m-a68FMa;f4_*2ca8cP{?qBNO#j2_@1Cj6^k?3m`R>`;?2Xy=+3%lyJlp3)g_#mz68QT&?dQsM zTv4c(<;uU|@MQVQIyxGue{mxQ57dA{RO@8G3VD0YX1FOh0 zx=^{jntjJrYvGzTJr2S%9=uee-7P}OZ!F_dnMrsKH*x>19?0Pp0#CP)PhGF1mh)Y; z2`t$0NWS2LWLyxUNB{BcB5q)?LYCJd7UYGeTy*aB=jYR=6g1lbD1gSlp>czZM+Oep zU-2O|GaHL!Z`a9i)LaK@}pfnK;6 zqdv9K;(eU;DICwzzx%uFaOoo1lqpMNh8>0N`T5v3iJm{hP=zZoIyf!W0GXRBt7sc0 zjnWuwSiym-hP+X+$?t-sOOk*^Ug+VpKjY+sdylTcMjc1o_nLB1Wv8q6!%XOvWq0AdL%sI<2Rrb^ zHSR8~y_H_@g33?{rTVy{9)~591}~4pgQU0BrGOFND);Ddv?yAgUK8~o$!JyNM!=*u z)P=hP{rV#)#BkFJ>XH;zAL9ysQdpM-yw!okvKTMIK!Z_ilXm?A3nIc1kpKLKnL^*} z;=}RdC`8KD&(yBZ*PLb~EohDV>ca@xJ@tWu!id$$o}`f7r_`vEci*|aytwktYV*O; zz17<*%gs0M-@dbG!$-`Q-skP;p*>)*^qDn6N*fRYvE=oEqwGb_)aG5;xd@Or$wSVA>?MEP#2;=Y_I8MUbZ7sJ;miTDQ}5VU%zaRR_?Fy z5%!?)$eyjPEv(&NZQfg2So|zs(xZPAYS>%+xrdX{d=Hi1#UeN_v9@&Y?c2*dKFvbG z8P9T|AuPb~a@w(3U0YOyW|Ak0^=vwiV6D#ypZiyr4u7lzhXkO=mCpZZ=Eu z#B7)33HJl&_fH;Sc`io7Qu)<^5}U3CyW%^khvq@z;sXpr@}NzR{bt)HO_&@IT}w+{ zF16ZuBsVD!Dt6F0;KjFL-Zk8kC!D4a^1LNQectaG zYItQoHd}cCQuQXN8s~*^%*WSi^_5T6&yLT?$4^Mojhz}uw2wRI$7ki~+XxWgL4s|Z zgJ+htjYDiz;aE2cjL*zolrrj4!LeyOZf%kJs@`E~py2CL5Tujy*o@FvI;0$8L!REz9B_Glt+gLtTU(B%dSrM@Bmf}o@qBeeaQN-=C%%Z4}elv5SY{6 z+(r`kM~HXexpZ3da1Tk%$|(V&6#f*C^CKIeZNlNU`Q7$b2itKwM`xs%68k=O z2a)Pfk(-ehO5)Y_BL;>D+#0f5Ay>H3=)97=P;-_w&nw;E0cJ>2f%`Ne2bzp;kLj?P ztg{6@@JPz)FhG>{FbaqeuyjeSomO{O3fM?k2S~GqdFABnmUoPu0b`t3^55hQ=kDgJ zh2CS?)a&mb9AE$%INJk#4Ei3nw>~bUIIm>CX-|2nnw1trl%A`oZ|ea`xrDm{_L2Xo zvvVYcl$vXb6~kyy8p4Rq$!n$Qn>c0ms4Lf(n@*^;`q+X)dOv1yLf%#o$P$ym)z>(M zOd^8e1ts~h^`AQF`%;~`=Cr6F%=^%MOb5*sTAfGW;HgYvC_d`W?F6g-2ynDY! zC5mtL*p~}BFt?za(8JGH7EviF4K5*)`dqxD!%sThK4Xsf7`&Z+WrC~& zTvD(lEPX)-7g7g}D5MfVRs=|a0WRn;-QCxO4VtUMUODxdBBjTbC!TY4Q~b&8`gE-` zVH%Bd9_-nH3w~Ru%Y28a)xO$vhX=esC^Fo2i()yXVPE)UeM9JY{M!m>rypq3JD`Eq z1RB761EZ!`6rxf#DNy#+QPvuAo1nJb={ck&@o0e7p{dN<6jp5Nq^k4yE_0hVW%}yj z?$v98Dwc3c%cj^h;W@op(c@IHXh&QJwr9ju#XRb>H+npwY(=f+D{xhCbwiw`t0B{f<%^3dZ^2D#pGRcNMTB` zT2C>hK-&dPSk=&YRZHX6(-hKK5HKqX_AO>+XJ zue`TqoY-j}h2m^hZ`7xZipdL1fVH`6*yen4j?>j;7%^Mzs}t8R*V>zp_c;Y3KiIYJ zox^voTI4&pk}j+9bbgGSm;g80oKV#dS+dGpm^6S^>+tN>&OMl4S+1R1l7Da3PNAns zsj2!Ypez;$vM#_QX=E@Z|FFJsbbt-urY!&J@2YQ5`E5WEw5yYy(m~6bV#d2*k3bNk zO94!rjBa3Q(ZJywjEC?U({}hACnWEPT&#PDJF>hx*8T~$1aM329;_u~9LC;(RX2;s zNK~!z%}Imdjm|ft0X+m_!?0T%E=-iX1sG&+ZZJBLnsS0KkuH{d9TZX(Au*SdEfTRy z2x1%Adwa2)Y=XC@Umic)OGZ=ZsLyQz5Xcj?Qsd|jGQ`Mz#yf57 z@MupJJ7_%lu(G`kR8R;$r*YVzSVA@@)j%-UeQ%ZvY&PJ2iuZT~E3|&k{ z3_ASM%p0@dCBoNkip5UAXhYgd%GX{q+Tva4fBOC!-phCJ3@bbD#_>=VO$I0ojwq8T zQMf^hI~XQM6O4~RQBnC2rxpTTT#!-*KvyPY9SrJl8ul_tH!=Fc$SiiIc1=f)CPfo| zux^v9w8&><32FIiZ3YV+opk9atr*>R;Ud2ElEeLUEZb2h%Jna5SEFf#Uh@>+%y z`WdWNE5n`_fAXFc4O?TQ#4^rl6>MY_HI^A{Ho6i^^*Y9Jq&=d<(n)Mc8Te7P-~bR5 zf5S+}pi(!Ut-b1{sP~15R8=Lt5z!u?K2=%1c)gio<+4mJ=Ej9M?p%W47Ng%lR0#Q@ z`BHT1OV%|)@=9f+%Mtk7$cWG`G8Q^E&>e-X5Rj>XBO35`P?dl_ZqdIeg{70&OHf(C z(~`@fOl1WwP8RbI>pk(V!YBDI$ueZZ>|rBjufN@>(>LZC$KAmj?ah{LYqV;oPWMik z*LI5A)TsBl}%Ln3Sj5tG# zVNlRR9nv&n^>_f|e@i!;CMVnC`<#S;ic@u}_SyYIy+wnfjups~ZueIDAK;zljvWe; z(AcG8BIu&$Dc4lNCefj(8gd=^ih*|mt|0(Lhu^D5^P@oLI8wSwx9|(r;z0Bs1`&Z` zbW2p8<*#9zBJl0KJ>-S6z24!&jWIoxElpf*DySN#a~5`GnW0*=&GPPJ0N+GfQ49n2 z$=dK$gGGn)&`aPA?%A2rmn#lDwOku_!Q!aE$%ej47l93>d(=h4=>g&q8>PqZQEJda z14VLT3}Ow;v)Hv&!BFWsM))d6K%pGhCdkiS-h})%DLrG8SvT`8CZ>V$y}N290LVjp zlDSFUOq2nWJTb?FtDYUxFuNAHGsl(&6C4$~)pd1dS{G3IRSuv;3)BjId}ey-qIwJr zyQIhL1cz#v#a=e5(n&l4mReShqTs|<6v|-xDq8o-U*hg6_!P2LcraMCq*lI?PMAM6X60~R)6MNzM^O!-S_?StwoG8iqR7exQOKIz7@|4VEy^K$LAdC9q z#k372l&|r!AOJCfElznE;UdfC?1~UyvwJ4EXP+$h)o`j!f!G?s<~q3oL~0^cz=44@ z0vxE7o9f=a15DD1(|VIQzhj5W))wrR6i(_hPr8=?13}Y585LtwdB-^osbE(iYr-9C zS6enf)?v6r`s|)Ku(cJHQdtlfbYO0d*wmPoHXRy@aKX!K60ztFSegBxfU(dLcWYc6 z4hs9!#i6$@5dvy3BFSuv7Xoz{y4CCSJGh0-nst|}jiOhk5Nq=%A^1DEy%awGMZ~;p z_7N6VL3s(7aAvJ!j}j0Ds-(Oj=T!LcB&aPRxST-Jp_sgeU6+&xavl;R`-unZqi})- zzL7NrLIG+7n1hq48L?v(h=?0G)~qDVD&tQP?9V?5BJ!Q67>v=8S zros(R)J)K_@UO#jfNx=w0#7)V`4ena;7JlZ5t@Jj2sfnfW5^}~ikUvZq%t83z zSCF{45O_wbUEtfKQ8x523Vg^TK~1%b%G-k^se4k&5FXZpNuSKD$Jnh0B22x3fj{ADZL zZOcU|njjA*Ok1-}U(%o34G5U+g%PL%q?2jAdVLi_HL5da!*#=?=ij^>I zd9=S{#JAQKa@GFvKp!=}dfHz@ar)x#PIXIncs(bBlRd~2ooiKXSG zdkc5C&aAEu>C^ogiZHs#_--P;W)_5x6NaV#v{q_Urv^nD8lV~-8)AtZ!DHDYJ6D1lTw#E;MsnDTIsl5 z{Su=qQ0~frjxh=V=b~Qj{yzc=7{pVcD3n?qQMdH5N|*q?YnVXnp`NXCKSlC9iy4S- z;3g)`W8}cI9!#dAeBi<55P90w|P_bx8PTOM&n`tmVR!V2_6%iv5lBi@WrpE}(+z&WGJj@@GSc>V} z6n)pWaiMt;`-R53alH^6EcQlMTlv$7GH~!9J;$B40?ri$vu_hKK)>yaxfH(yd(%mb zk<NUh#h$3m?%J)XSjU!qJN8%w< zv>M|u0tynm%^n)?C}m>ssltn5!l(hYQ~Bn#+C+0{`2qGm)x#J9W$2HhD21Y;TN172 z^i5K)h|dzU3Ct4I4#tVhA>o_pYkW5*2NA%GCsvG0@Dire}Wp;7$hOYa}3|EYyVhXh|3 zz_V~f;bL{fT0MfZTu&YH81z%v`MnT7;Htti<)kQ&d&JhbglxGAlISdLYpOnVYJG2g zPnUG_>wB<{3qR|7r>4Belh>f5d=;+sWW8S-y>{v!V6u=vJ3vnNWX_D^KPov@B36uA z#XeTrE2#>_=$OhW!eGT0D$IlI@xXfP153OVL2|JeH@PUMs7iT1CXBh|S-XY_L1L2S zH8D6eS(hY9EDBwgP)#a?xxvn!$!LDl>eZItQt__|8Da=m2La_!EXgUs|}=G(_~MFR)78G{QCQ?-GhU5G_t-f2dcbtK2K-kW(mLQ zr~u1BD1eEV5T9YzMMeN#gRpKQ4i>G}@LojleOF=%;PQDsGp!xK~p6a8^@ zRMD;LpOI@>uan-3#i8=~R(t2b3IvT|-%~l=RP#}V8#*v|_QJ!u-Fbv0q++$&m?B;Z z$vPfz(^XENi}vkF0JxMG$GL!Zf0aY?I>Sy%HBGXu4i*|ocm#U3%N_Js5AcTrh zli8=hA%(Z|^DB4Pki==>4jg5S7Pi8YXBCC5wX+efj#;CQY_@n$i_$>qi~0En3wQ1> zHJ4YGmk1JRFeJ{iMzrbp`pnyRa6ob#$-tyfi?DsW9bF{U7dyR!oz_uL3nL-}JJE)a z_n4#5xN_yn(#oxI;(LYO!fU6k)D-)8`pP+Z=v8Z56<~FywrcaxYX%8YR144$^|vEr zJB_Rmy}rR6ALohziC%D6w-@@y=|AaXZQ}@=MO-fM#T7P$MfA1FNzm=eIsb}8CLFvG z+Lww&EI?c9nY2L+nPesAHn86H&emWCw%~K3EDJh9pQKAps;P0(^~|`aOyT`}jsY9q zRDNpM-w<(;OgYvv%>eu85Gy3Ya^*CHF@vlkqaU@(S+iM^=gLrQjXG9*&ai}h8Ds5< zT2-4QK}H{7dRaI)*y-pcM2$11LA61#om`h?!egQDY&I#JN`y>C+zkZklh@>I*G@PY zXoz5oulJc<#FLi#25G#%cK7~T^WMTcRNi4{@OXe4Oe-4SZL!#ITlbyNoN|SIGibDt z=Ypu0j#Jb!=sJNY9ZyifN9hDr0vjDyXGMnaq!UQOR>w6!Mb_@F>z~y&{VDdN(~VI* zomy}Oi8C!WN^IXkJYvaL%pnl<)b}e^h)fbmF{-NMtDirHGD@CSPfJOG1fw|QZ?}G3@Ho}-GAO=eC{iDvRSU3!zrZm<%-7*sgE`|Tj&igmrX>es+77k(B`t`BGC zr6XI3dSF$q;;Tpfcyk5)4sLa01Q-dAhG&2q3;6t4W_!$50b)f^PXHGo zRKiGTT>&K_O$w*vXX*4pmK|s&TV$o9UNOHHEneq3*LL_@QRmrhf+2Dd9KHKb+TCsk z`73A)c~fWX;0uBsfiv`6iP|BCt;ws#*%0kO>^2H)g0f3Cu-upx!3}E})dGZgQFdhb9HGBi2D~B^_M2 z`82CffMJ7PhJZo!`Vv&jZN&iC4b&~26*OXrhnAol@_qMM7R!4f75(dCrU-4?%nuGK z7JwLj&f^vJ!Zr?^9(%|P+wI_te}usURmoRuB47tLWmI9NoRgsE*^9>dP3-Mst;=Nq z`UsU_2=OcRAOC{N?yX@TBX~D)!mjKPMw-xfxM>bxsgMS(4-!pR!?AT1)kp)SZ}K{_ z>Dyw_kcAXcK~Yu#p;ei5a0d!A*}GjzRII;|j|=MyS>jg|;XG;Xln{!QU?wmkdR)P9 zO%rNxI;((+{jFGLB1e`?6#Td;zKnH}W$NgtczM~kGE5TuBkD?78?rd^WU30DiuD>y zJ8rHIAL-JnXwmpBhj$VvyHNEOAKc~XIsTanvaeIY^tp zSM33Msh!h#%tgCu8d=bFIu?ZbffS9$|LmazY0Bqh#wf~#z7@**92YzQ4*O&SykMA> z$Jnrn!(1`S(fUS*Xr557rpAqXUXmX9Bd`KafA2PYBf5UNS38YN=T2T3KmU>{XwW^j zE9>Z@Ifn@|_kk7?SB<4=gOAa-sNUIkz42Z2(GVr)Z>28%F z^L0Y4LT7`GrAA;{8MO~u$u!ikK9EV04gi@VCL~;{J`gu?>TC`F*6>G_F=HZ5i7c7A@y=`6 z0I#4+%KSwy{zR*{xW9|O=un&Fxju+Y@eO9SEy0OK#ropP+l%{~a_L8-j*BU|t#^Oz z*5oC*lLZB_{~=dMsLxw8f#hqJR}c(DJl$lL`H-{{dw3i?d9RVOOB!bs_Ddwks_*@v zxR}igeW)0O%3u?-!%LTpNFwYQMDw#$lxB%i`C^3vnunC8AxO%5MbV3bMbnNZT_fWz z!@dlvu~H~u(jp`s>|N+a5oR=jhv1f&7m8u>KuA-B$Mi#x)Zu5q zMHjn`X>46eOJMjR{7&9HSyTJ!XQ*r_EE-hd!Yu{*!5^h+sMmVZmQ7XB>Lt%n(QtF~ zf>Y6}NCE!{VYqNCHtOd-_waM;^Y6aaSfAGqXFfi0j+#ema8gR#%Y&lDf}*I~9-ahK zXsR`&SL*0JOpP-oIW$^8Ck=ujHcT(S z6QCU*by6Mhk_Me@YHUCcR~j)`r-umH&NdFxkgzvDeQH4YYcLv!BEA`Jx?VLhp{%H`wcK4R>DFC+#TND+G6OBy_RJD zNZK(1EhZ-c-jOKA;#4po&?!#^VArC1rOau*imU+XI|U;AL5jnMgPMrRbK8J$vsd;d zWFj#)mc)q-jf&wCBbv$dWovkh@0#$v%|MNM;44h5&mBHf)v_#8j%ykdLb;JWXBtkJ-`J((BS4YL_q|ruJYgH2I>lZ9Q zPy}VF4RNFb-Rr02!iCmH0)YaGLLe1Z=^u@|{l z7RW~*y4s?HZTkzCCx<8j?>h=9iLp5kmW{4tUNnK1rSuln6$d#K0YSvNVgt^^W=PEy z*{QFnsyL8xCp+zOLXCG*Ewz)G%u#Sg)Lyea# z1S`f}NJTt^QP~mr14*+h2g?ntRKIR>@(skcb3g*zippuscT$IO}y^G%cFEOzbLc$cL`kLj-=famtaHmIWc2Ppl3G z%>^vjAxt)-I1lT$_h7v-C+5x(SP`ok+~G>xYyH+Ey*auNgPQXmjFg)ih9B2Noz)&d!s;(@-O3Y3(5sr4D#kO9nd~<&%y&-YDzJUmi z_vFgbIozaJ$A!ZBWd>g!b&-2szs}<85%Nv!Kh^JZ_`b1o*w%07@og7-Xt)hqA6&qL z&7+o8zKCzQ^rLU3UuWRPKwRS$&O>lLpW=GHi0k`xT;qq z-J#z=ER2wVIPp^RZcpx2r=nrY8%PPF@_|6#eHZH_w=}Qvc;$)hjdeb3{ zw42z#*p(iZ?99k!NaYE4AaO_X$`CI z-FMwB22siHgV9R4<7A^1`R(MR6j=vn2(X+E3KzrrSg}n{ zFgZ}0856iO+v+AJuRU?(<+u=4tE`6H=`3p=Et$+tVLA+>Tx5)#FX){;!lDja-hu$n z;{>XOb4s#;lg{UQUYeFlX%JwX2iSU;PZJ1H_f$iO?;S#6>ESesm7Q3AC$`{J5-$Q1 zeDoScgDGW;Ygy1k%GzSV=iO85({pnVPxp3D_vF*`E`3^RP9QJM3|unBl*trbyf2`5&IM3ruGxD~i4)Lt$= zUZbr0QXc1cyv!xukkwsq;K0Ph50(bV*Kup*-rEanO(Z$O-7m{v;`;YA*70-w%$3Hu z>t`AdTa%xEm;X#pzR|pTdGg)Y&RoCNXk4FfTz^%{T{$y#=Hq9+r_)0iY*>RKsLOVM zlC^~{*IiC1+hHvtuU6@=C{a;oo|wE;Qx!&yVFDsSR2G+yFscTkr||PGx^WJu!L*#1 zSzo_G`4CkjvSmzK;?lwrCiDb|Qw^Dk$}@@ZC?u*X(VuCZ0rRAR$i?YJ>80m6Y!qa{70AJH5nkem4REE(`{+LqiU=L+y=5W9f8GT`!0 z$Ywk>u<`S1Q==b-ZT-r%a5(1JT14$QnFw96mUT#>GdbY6Q|g2n#9wt*I1yweAZ8#qFqAGBEnc zBc=+b#Ha%Z17!#Tk!3~K#L(;}0$0_pxC#^KD(s8P_}jSr!NeKHXQxWkU{F3u<~Guw z-MzQ;37kA!Yp&eGT_~xgFO(ON(oPPUv&gV<6=twy6(*lKX13OR+}Wo3Ve3A^_3cNL z4Hvy>5e;opLUv&7n;Xx$1Jdb3BeJzI96^~UDIZno3XkxQN zY4j>Y&R38QL|LgY&GG~k21o9ekm9v#wdt6uI%T_b6U(>d)N*9NKPxNFFUXW1xUkA> zcG4r)+^_ZBe8c(D%0q)gp&}SYzaNK~ z)mlX6q5VfEs)B=YSV#7HUMWhZe<}t4Vm@^p?!j+q_PwXAJvlqi)wE5Bp*SKo_b?>~ z+JzTfBPK2c24@tL2THD{kfJ|ruXWhpU&7_>Np)EiROKjaXITMrWm<3+=(-iBTbDnz zyz73q1=@WkI0xlU0xfTv*V@DqcIh%K8MTJO&qDd&lzUn|?|r1S*FrkA>S- zajqm7o6x<`CQOZ@LyVWSJt=#;8UN;^!T4T5A*cWg)&{QXy-}@_yxy01F?;WpUkn-QFbS++B%fGL0=iA3vx8>) z#ySd8Dn;n1RZvn^(^8N1uvvN7y9wWIr0UlGJ%%ewyWk{)iuRD23#Q#MX~;5GAvU@| z*8F2);2O*{TTubWK&E6!kYEZy2tlqI6HI)gxak2-Iu;pIb8pVMI@p!GTRLat^cF?pDkR933Dq*s&MNZ|C3Y+38WWzHyat2p zZmWxem^RERmnB34chcA=2>Xd@sl9pQLRtz z`B2!%VI)L2?IcJ>Dfh=T!JIgCi9;SZR`Gtb(}RIv(z>P@Xi!4>MKSQu++iKL~{A(z-S)3Yby;vYQhwCU8YPyV1& zFk$8g;W&vZtf23ZMSkhtn=7lg*FM|)^!?jQYhkocJeZixaj1pqBkGe+o)rhhX6YGa z!3+vP;X#f1_6oOa?bCW`7DQ z%DDMavY?p|g7)VYdM|7oW-0(Q0Vu)aG>+!Xk1%M4$)}V;Qp#MnLs+Abg-=QH z-NYiKJ`$UgT?=2*sUwG8l*N+gwgN^4gw$j!frutw#G?WRdnPfz?wF3dV@~ayyAYzt zOhX|(P(>P|u=QQ5J>1tQm3PC5&4(?|4e>4#>fn571f}y?FHO{glbsmZYID@DvCveO zR@v-QZC13Q`Oz&Z28)rs{&u5YtDT;leS-skT7Z|uEUn<$jWAkT%nX!#e8Iyv zX>|s}56L(;?Cy9lj7d{wbb^PI{ZA_%d8ll^qm>1-#j3z3>zk9o1>Y(0OT10>atuaN zQ}s~nDeF;0kE@TCgDx#KZi@Ms_PxHZ1`};z0Eoy4uyW}GKGf!6VVYh<9w7Wvh zS?bYtc{L6`-Lq^0HODmwJ6}$xHL#;KrU}B_ z)-Ep-+mB!ug&oh*xNzCYWuBSRHVF-t4^*+zAu_}!rXI&DDjk3NY%AVeEQzVL8)ib` z4{JuusfBpXSvM2W6Sc_VB$*^u7ezOyKBq@k*ZEO6*JaB`1R;udAeW>kb2)tfh-$`tt^Cmfi{hSj9N;zLWFp@5$}CbV#ukzAv}6PK$XIEG@C-1_i#9G6#7!NJ2%3GjRSfJP8VFWI zxWzuFeiyff(y~He-)*tMDH1&=IaZsIM#(GEwIqLRQ>&+;gxKm~HvMIP8OV}wH{~HVW4(~~gIIdhwuIFIKHVSF zO+G~5BjU!+rXB8e5PxG|aN~GTZQ38p3KG;|Nf>BpCp`?<30bl88Qw*Uu7a}JkO+bI zgh2}+aMvz{xBb4|MLSR3zbBm>$Kef}aj6`>th|qhdJa1hErgpb)m7Kp*uY5`BFiNK z4*>wT1$o%PcSOEb5w1W|qoNXwjYqX@E8bx(r?Ht}^N zmZ}zuT#C3HDdFneFPKjFN8U%>Q#BbUD}5+(_yPjwf+rzASlYK+-Ob13C_FKvn-rCa zPVH8BmnbIvZWo_)qJht4-rQIz#DrZVkM<5XP}l46L@mHbsAIWp5u>SM4JodD4VKtY zb?LKRX(F;IryW%?`>bO(;&dcJS_Ow8Ab}L)xPRhRIe@C&R_#E8U>u4rIS17MB?`;}|UI6Tn1zjEEj$($S z!Oo+bRVTBH%A6L7RAzm*j(!`s-6&!zky+Cz`eLRf)EdqD@Cwf0z7p{^66H78D#%Be zD-E*=!Zbj(5n82lZ6t6ueH%om(#UyWkl(3uxX-pU7rp^gxF*Vfn9v5==UFE5eBcI) zX3$j&i6vW{y{oV?F|N{h6~%+bOJ?kR?ZsHgsQqJ#YcR@+6Pt87_dAq5 z526X2dPX``1o0G0rtr;N5l@i|ST!-EgSxUpABZ0mEDUl4HKGD0Y>94UsWY|7+RWve zyg{7f<=W&VKTDTXhFPIx^stC+*X8q_)-n}jY5?9CVMdZg$4;mO5YZ&hi>lHjjzMRR z%QVmFmI#7= z9Jqu&BN3zG$c$V+KJm1()qjk(uyItHA~8SX5KO|`p|lUMy-R%%P(D`ddfbdtWOP~fUt-yh=y9QJtXnIX_6fLA~>8%>_wDP8I?n;1G>s#P0JQA5O(o( z&#BXs6JHSgKjdBuFH~S<{7L&-*#00d;y*X}d~O)D|KamU?70m#WL9^$pdfg2K~doh zK{+_Q7oM~_J1wU2HDonyF)x8!hh?^YDz4~~Z7c7iTIc9YzSh;vsJQc0ZYF_dp7BK9 zlz&e?mh8U0@XMcnFM&ziiVhkM>XewhFF@;}2%5XP}B$1r}k=^HK6u(eC zVHn?ucqx1{Slh@g9ir8kkQy@2DUy~{esPEMFj?;fs~e`O*U+^Wc^$|5ySUz``W}wn z(eC#C9)e9EDdQ6;C}H%an>>0$E--K*Q5Y5C<^=#l_c`MI9)aBAT!e-wOHU{=42M`q zE-NYbBNhM_qH5s3h}`>vgiEwbXljAEfQJw+6cn7pH}*3dh49Wnq6d-l{9#U9y*wpQ zw8HtVGZ>-gYCR02st6mx!bJ83o=xs|_88a-y`AY9A%#^NLIW#Nq(JNtPLPy%Q3ue4 zuuQDV>oV9!v#=-jEPOL`N)w4opq%uu;&O|CXSmveBVd4}MNC-XvJAekoO2W_t6Vj( zC@9<*CqC0RFkS}VTcJuUxA%vIY;xm8trBR0U}7j7F5@nklfNku?+Aq@Czvg6RKeaB>+-pqe9@j*Yj<}$d##;!Xbei+ z$KZFc=3zIBNWmrR0j2%T36noo}xZkJ727!2owx7#=`W3E($l$W4HCbP+1lz+T?4;#ayMJ0zMP;w1l8|P_pt(KL>A0evWvK8L44SH_T239}W2N#1I6w+zXKB zUG8TN9GrSY$S#A-u%oB>0u9hDe22`vs`eOn>{L4J zIX3S0&b3&PLo8sdz#V+As%Xz+MFgkyq@waN!qdbW!l+`!jxEa?c~#sG_-t+n>BbqX z+dH)@_L5&-drjxPomP(mZ%cD2%niqfba&3L; zm7Syjpo5}K_~SZuf+k4h$_9k`CG_+u8z8MsqgB?IK`7PNr?Gxnj(p)*hg#x)7`Rs7 z?i@Vbn-Aeh)Gb0oDi;s~f4pP-h;HEzoAb#&XXzng4Bb{kx=K(6Qv|7}jCL1$)E(^A zX^<_=9PyncS&E9msg?2``llg>X@C5c%_&7-Vvi)3I-=JeY_$xN1~|!FcCudD8mQu0 z7wCj+vNLy~`KTLmA?rK0mls#wS#3hCtlnN(ZoYZ{_MJsF5X5fenFQE|AR*wj_ntKB z3(KpwZ>}sCjEFSDLZkkL&o$P!UOV&t)W;`2#2_OP42Rkvi9!@57ms?Q3UcEe?(X&G z*LxqA${%)EClJU2&fbQN)sQ?4dd^$ih3;mR!_Dm;jyK!f#ttNnoccm{|7mYZz+axS z2JP#I9nRIExm5)1BLg5Yip`Z9dpPS&$uJBbgtywAM~^ipHxc^=i~$MpPtJV?Ip}J)^ z2yqLW6`DL4ohD3?&_Oshf}K3_c2Em)(hD>l3jEf77rra1+nUm55Hvs7bsRv9ptwRu z1Bp2MHskQn9iasO6*jHr4jsf+?>!m8Q29x_=6R|FeN!{X3yevp1{#_as#H*3=oYpT zRM32socEUL9gCaeTOk}d`;p$#;tlAFL=-V1>49&wEb^3|==NvDBinph?0M%2?(>PO zcTBE@Imf2z@**B{%x06<2&MC{EZUKXqPN-Y9Q2VK9O-{CV=Lwe&bVeD>jxd!oM01N zTXwcKTm1qWZGx>pxB(-y*Qoa}Db^-iwGV1IjD7$GBl9D`Wi8_Y+d&c*^}6c6icGzC zcz`Ln*K5l9NNsiT)}UF=JvjY?*ZYTHeZ;US8oDXS^Bq74%hU4JKGL4%HQCM(BZa9q z0Mpf;@m~?45l9>%V{Y7mlN_c~Wmi)k$^yf5nk28JTF9Y^9`bSFbScau?u$T1I?q`I zjqq6$scgDUjw<2>@SSOvfs_CdL56$v3CiN%HXM8Xb_WSCj76*v8q*!&4|hUItq(H(tM!aVQ{4ceF$5^D8+&XS@xs~7+&jKtG!O{*DqI|;Y5KC z0cI?iY91-fI8yLWXG@|;rA<{urbQ`K=#|mi9$F^^7Z~uW`HEBtX1WsG%HS}VxhR-& zSH?(Ns~ibamg#CK!AkT=WxY=CUK{=ZXs};$1m({Dqt0g7ooUo>w)V&i zXd3sdJ3EVJfyJ@eKIk**p?25P$;{6?^9ny=p?X5KI^o&U4`=T@?7&#lDe_=K% z3WGlOaDTDrf_ztn7`UkD0-!=mY@g+sDD&05)Az zUQXGq2V=vlbnexm(DJx>Ns;;rg&uX5$)WFs_0+WRgORFRk%dS%^?m? z>ugB6k_24Pe4;<$VF`y|Dz%c-AJPM{jkT#jvs5aKp^U~AZz5`VSr{VcYFPE~Rs@Y3 zI3Nz88|1Z6w0cxxm(3aB+nch<6!1U8P0pO;V%9I1D7vP;DN)+Fbl*ehc4xPpsHtV1 zu-@B0eDpX-b1zD7CE+_g;bKdrl;~{3EaAn$VhX*OLP6Rjb67rUCj*x}#TXJ_%O>%Zi43dfg#8Gd@)CyC$618mChk2nm zfMNa2Z38hvTCS9bpP={EY!4&h2gb=>sqOT z(@irT&*utZBrY!$eRdvK)M_W^aO+c}m_VOpt%{o%l*WP^%SNPyY=?@y$ugG;hXHLbB>vbfrN6bxH{nPhX)|M7iDA(st z0n#bCP3Pl)#Sc^A0j~Zz^}#yZTF31UxNs*a;!jX!z0QWhPcG@H38(o6ZF3JoY-VI? zub_9nh=vscbA5h3g<#7BU36P@$h_M)(8_E3@4>s|lSH52I-d{8GIRZqd-C)07y(5Z zcojoW&NbG%>w6!pcR%32eYq(>qZm7qRaTG^Tu?QvZWv+sNX`bid&^5tY#w&uvO!^- z8uEZ5dj>m7>-lObi8ZO8TkpMgZh?LX0foO3p5l9A23I69uB{3HFv3?);rb5YsH@R^puo^nPe(pP{Q+x9kv} zqQiZL5{|sDL2!h637(+B02NVGH853wZrsA4P%3=EGhQ1<;05BBWN8Gio>=>C>r~is z_xEJ0AJHGOY(SC{BnL(1R=0L)YHErR!}!A?^zm{&Rqh5wrZs$*nRQ(ZaBR&b#7U>J z8|)8}trw<|lXbAF{GfYdXbNOAxGVK(a2_R2OMMd@B;vYMHLP!fOXzCt5|qRsr)JMG z1}1JyI;N7Zu)Rk1a}Hfui~S6};Z35S)WOsw^cIG1MJL}7*Jm-q1g&!jED|P)5|Y*c z)VV=l&+6!M&51`uC)Z{z&&{4RjSAqX=HoRfjvEyJ;VWIHDtiyBd&{-#}ON z%!TLkMXP+h08e!2eliNdFLQD?HG6G_WpH28nfj`)p*HCWeZbsY8u>obXx+vMpI)!S zgP~B7k6Q>+g5%M6Rglco0?^>0Q7aKv4J~OM?pd+LouLgi*gdu;8qu}B8uF2r3}C0K z$Ux=V7mK%L$aICflCnIwo_4_qSZcS^lQ-@YLM%6TJapM^@04>|JL%dyw>L{*Vnb@w zD7mBNj?Vh*%^;WkfEFWi)h)&uA#X9f8NJ1Y>Me+jl_>PK&5^ws)Kb|AP{CTJB;C`I zl9dshq81Cy%F|+#FL;;Y>0_J*s^Qw^z?cU9YEZJAaTPfPWnVV z8LEKNOdwG!L1(A=lB2H6ipLk@S(QMLtVVcVs1RohnPpvNxs0Z;OWG-Ip!70pMf9Um zhdQvLYJ53PV!tq7g|SZfqt4ZWsR^kqQ5|v&4|*1Kg4v- zsJ;Wv<#8K`0K_&kNE5iP?;g&fJgoBp&o+_0b(P+-67Sj%E471{%f%e|dwfDnY%Nwo#@^25B6*PwS;=oS$tAS@KX+9{|) zTOk4N5E#V;h%}n6KoZn=AA(YCMC8os7npAHC-6k4R0HJVASqcv6cJe!GMAv@o?HcV z@(s-{jGC{gtiOx}l|_s%q**NFu}Z96OcmxzlRH9!S`@g_N2)MIJuMrY__y}E=4Vta3LRW|x8j3CgKHzGJV&tBQlz2())sXC2R9;pZIkc0qzEvYGMkyXt z+OY(W?U3Z~F_GeFjGBb=`r%JMwlC9j#VE%yPKC>hhiRG)OP#_ezDJ_7S6t+>!?QBO^pOM<{PDjd^$1vD~;=W2-E<&lm7d-~|HUie(04+G&+#UV$++Tq_d6970dCF+R7H7EmXgLQ{%&HHs9;j@;u$gk%_% z8AF${)^*5bfre$czXVS%dYmBED+;2DH0zU2iB5ObpmT7i8L~ zc$tBQjWmxXm031MCbwnmZ7^CyV6040eJH{z;*s1=Eq(snhY=+HZW|lRdaC#~qxbj~ ztUjVp(4YuExeN_q)R`qy!B%vOTA)Q%D@htEel=M-sQl7p&LI4)EW#a zDHmrMCs+;?9uNoW>oH@y!3`AbHPOOeHir&WRAU^6uA1iEQa*BC>n0c6t} zp=1s@i%lKWBOo9wYcZ^a=u=9_bIXSgl>7Ajdep&AJsN{wd9CHN0D92BIv90oPFjtatGB=$Baja_C6ewC)RhttJ ze{=MPXcaEeOskJF1?GK_tc_tZL_&H!a`c`q*yw4U;2K*^uHOZ7Wt{5NTp8Zq*j*Yf zBX%!%D`R;cZPYj)2k`&mS1zTzw{2MJ@Oh0>$w9q~C@ ziq0~_k@SLQcIag==OQPYBxVc70I<_(l0E6w>ID>en0077XtD5vZl{Yd>L?2XNbK{bS^sNBgEtFKE%+=#(yZFjp4O5rAk|*t89x6 z02uq7j6rBFz76dbI1BF)>1`M#Y=h^};o1F?eS3G*5 zZ`7)Bq{Cyek^LLXl+lahArvpn{3RPWK~Y0P9AVjo7r}KTJ?p7%FZz(n9)grhoW7-< zwd^!>*jGbLsduLKw1cR9YF0b9wu7Chts|_FaNjFD?a;SgG-=7)vn1lcvCJl@3>QC{ z4NB;FWjn*%+Q#xLoL~-UdRU;e7!gX(#EYX>4a0=#PJjjO#MJZkq19TzMun-hQ^RG9 z191@*su7d}sRAx^FPyq~t2;xqUwh485 zOz!KOfRat+MdIY7DI@waNMpG96-RMoNpJ374_1oF*cDDD=3EkCW zE?4N+)8y~i9~ij%>ZlKC_MXY-pyqQq88GQ39f46n=e1JAR=r?jGe9Knp{@5j*^1Li zUY-z?$*c8pDrBNXtz8TEbs{Q=I09t}teD>;y2)H^bANmn=HpU*DeigYP0{~{TQM;^jX+psSTx2xI2aC|kqGFXNZpCaD|dlP-cl#y_6M9uq9$oijz(i$m1p+?R?d=qqN3SG151uEiejW zsoT_X+9^nQGPom6hle-7U0T^ucc2|4$V z77ERAsTh`cr2x7$(cWn@pArq)ftElROR#l5F5YI;Pck;EK|7}zHzCy@aFvw|Vl1f1 zHZgfSN_t5PMrp6V-KamTPx+L|(5(kW4r3}v%ZQ-VsAOI+_)AtuIyV_Rt_ zhPK?Cgnz&%5sY;Gr2L^|i10i%ISw&6%(^8FVBw6?7~zS264@o&{L(@!Xp-tkjj7#zdnY*sw{1#gpRg`k^hg*LcpsX8a&OaKq1}Qh8i!fM99E=f8ryESsE2&5o5F*J#Y)awuzwBjkhCkJ<~0?dcKc!8!~ zp;-W^e1m2ZJmp)G#!=Wv`9eEY& z=QxaNI{webr-i=cT&geM7KJVfaxxsTNa~pqLp(KfbL2V~;K13DrNQF?^oMd)6nT7{ zJLOY>Izc_2^$mz2_DBQv!Wo&b62wwHPkI4RDlhyd@`C41@^PK!VlPY~WK*Lm0V$;w zbcIzi()3cwirZ&j&KySFuz5qKw^CqwP>C7}Ll zNN2o=G#!+#fZ{Gu@sipBb{9r)SWV1r?xHIK$Sgcw899ACESV>BKnr?)9D1M{O5qCC zgolSvCMl)FNgk9*U3uTC6W3<^R6C%b8PPHn)k8THKP}?O={G2`<82AVac8JWW!TwR zDxmtt{{GIui61mpQ{_pkiyKmT-|L{VcKfS<9n_*j8}OcWwK>VD6NST6kA`vE7nzCu zMa3AYwmP1s1(H_4*+({iUXRpouVLC>MpBuWrb5&i{2D{Gg6h~|I>AZ^Cb84Unhd7= zD=yhpfJ6GO1+?p-aDJOIZF!I+~K+;{O zw2h+SlqiUSm_h=?a44uPN4aXf9dynxkUm4ExTOY66_89P1O+l=7!xh!Y@Alhrl(4^ z7~TD3BrlA{1HyGt*gei)hu0f-_7w$5fRR-QM3jTEB@NBdTDpk57BO{hjvuLc9g< z@-amvzG!_l=Gr{2!pdPEnJm01{Whr1UA@(7-TuCL*xA`?caJUo_+aV%_U2)q+4F88 zy*R7HAB|jF#qEbX7T=l~bdJ0eLK)bYnEA(!A5gmDH2h{H}0&jL~}w&9}Sat(rJ^e8AB_4np(2R?}1_P%I@;&j#;qS*T

J{fW+SfXRq-eaET&qYo^DAbnH>1R3g` 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 diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Annotation/Route.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Annotation/Route.php new file mode 100644 index 0000000000..f60af463f2 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Annotation/Route.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Annotation; + +/** + * Annotation class for @Route(). + * + * @Annotation + * + * @author Fabien Potencier + */ +class Route +{ + private $pattern; + private $name; + private $requirements; + private $options; + private $defaults; + + /** + * Constructor. + * + * @param array $data An array of key/value parameters. + */ + public function __construct(array $data) + { + $this->requirements = array(); + $this->options = array(); + $this->defaults = array(); + + if (isset($data['value'])) { + $data['pattern'] = $data['value']; + unset($data['value']); + } + + foreach ($data as $key => $value) { + $method = 'set'.$key; + if (!method_exists($this, $method)) { + throw new \BadMethodCallException(sprintf("Unknown property '%s' on annotation '%s'.", $key, get_class($this))); + } + $this->$method($value); + } + } + + public function setPattern($pattern) + { + $this->pattern = $pattern; + } + + public function getPattern() + { + return $this->pattern; + } + + public function setName($name) + { + $this->name = $name; + } + + public function getName() + { + return $this->name; + } + + public function setRequirements($requirements) + { + $this->requirements = $requirements; + } + + public function getRequirements() + { + return $this->requirements; + } + + public function setOptions($options) + { + $this->options = $options; + } + + public function getOptions() + { + return $this->options; + } + + public function setDefaults($defaults) + { + $this->defaults = $defaults; + } + + public function getDefaults() + { + return $this->defaults; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/CompiledRoute.php b/3rdparty/symfony/routing/Symfony/Component/Routing/CompiledRoute.php new file mode 100644 index 0000000000..c86c9eca5b --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/CompiledRoute.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * CompiledRoutes are returned by the RouteCompiler class. + * + * @author Fabien Potencier + */ +class CompiledRoute +{ + private $route; + private $variables; + private $tokens; + private $staticPrefix; + private $regex; + + /** + * Constructor. + * + * @param Route $route A original Route instance + * @param string $staticPrefix The static prefix of the compiled route + * @param string $regex The regular expression to use to match this route + * @param array $tokens An array of tokens to use to generate URL for this route + * @param array $variables An array of variables + */ + public function __construct(Route $route, $staticPrefix, $regex, array $tokens, array $variables) + { + $this->route = $route; + $this->staticPrefix = $staticPrefix; + $this->regex = $regex; + $this->tokens = $tokens; + $this->variables = $variables; + } + + /** + * Returns the Route instance. + * + * @return Route A Route instance + */ + public function getRoute() + { + return $this->route; + } + + /** + * Returns the static prefix. + * + * @return string The static prefix + */ + public function getStaticPrefix() + { + return $this->staticPrefix; + } + + /** + * Returns the regex. + * + * @return string The regex + */ + public function getRegex() + { + return $this->regex; + } + + /** + * Returns the tokens. + * + * @return array The tokens + */ + public function getTokens() + { + return $this->tokens; + } + + /** + * Returns the variables. + * + * @return array The variables + */ + public function getVariables() + { + return $this->variables; + } + + /** + * Returns the pattern. + * + * @return string The pattern + */ + public function getPattern() + { + return $this->route->getPattern(); + } + + /** + * Returns the options. + * + * @return array The options + */ + public function getOptions() + { + return $this->route->getOptions(); + } + + /** + * Returns the defaults. + * + * @return array The defaults + */ + public function getDefaults() + { + return $this->route->getDefaults(); + } + + /** + * Returns the requirements. + * + * @return array The requirements + */ + public function getRequirements() + { + return $this->route->getRequirements(); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php new file mode 100644 index 0000000000..5289f525fc --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ExceptionInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * ExceptionInterface + * + * @author Alexandre Salomé + * + * @api + */ +interface ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php new file mode 100644 index 0000000000..4f12469529 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/InvalidParameterException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * Exception thrown when a parameter is not valid + * + * @author Alexandre Salomé + * + * @api + */ +class InvalidParameterException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php new file mode 100644 index 0000000000..470ce52216 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MethodNotAllowedException.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * The resource was found but the request method is not allowed. + * + * This exception should trigger an HTTP 405 response in your application code. + * + * @author Kris Wallsmith + * + * @api + */ +class MethodNotAllowedException extends \RuntimeException implements ExceptionInterface +{ + protected $allowedMethods; + + public function __construct(array $allowedMethods, $message = null, $code = 0, \Exception $previous = null) + { + $this->allowedMethods = array_map('strtoupper', $allowedMethods); + + parent::__construct($message, $code, $previous); + } + + public function getAllowedMethods() + { + return $this->allowedMethods; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php new file mode 100644 index 0000000000..5a523fa559 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/MissingMandatoryParametersException.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * Exception thrown when a route cannot be generated because of missing + * mandatory parameters. + * + * @author Alexandre Salomé + * + * @api + */ +class MissingMandatoryParametersException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php new file mode 100644 index 0000000000..362a0d61f3 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/ResourceNotFoundException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * The resource was not found. + * + * This exception should trigger an HTTP 404 response in your application code. + * + * @author Kris Wallsmith + * + * @api + */ +class ResourceNotFoundException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php new file mode 100644 index 0000000000..4d5f288e7e --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Exception/RouteNotFoundException.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Exception; + +/** + * Exception thrown when a route does not exists + * + * @author Alexandre Salomé + * + * @api + */ +class RouteNotFoundException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php new file mode 100644 index 0000000000..1291bd12d0 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumper.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator\Dumper; + +use Symfony\Component\Routing\RouteCollection; + +/** + * GeneratorDumper is the base class for all built-in generator dumpers. + * + * @author Fabien Potencier + */ +abstract class GeneratorDumper implements GeneratorDumperInterface +{ + private $routes; + + /** + * Constructor. + * + * @param RouteCollection $routes The RouteCollection to dump + */ + public function __construct(RouteCollection $routes) + { + $this->routes = $routes; + } + + public function getRoutes() + { + return $this->routes; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php new file mode 100644 index 0000000000..6f5353caf2 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/GeneratorDumperInterface.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator\Dumper; + +use Symfony\Component\Routing\RouteCollection; + +/** + * GeneratorDumperInterface is the interface that all generator dumper classes must implement. + * + * @author Fabien Potencier + * + * @api + */ +interface GeneratorDumperInterface +{ + /** + * Dumps a set of routes to a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing the generator class + */ + public function dump(array $options = array()); + + /** + * Gets the routes to dump. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRoutes(); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php new file mode 100644 index 0000000000..080dd3a253 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/Dumper/PhpGeneratorDumper.php @@ -0,0 +1,150 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator\Dumper; + +use Symfony\Component\Routing\Route; + +/** + * PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes. + * + * @author Fabien Potencier + * + * @api + */ +class PhpGeneratorDumper extends GeneratorDumper +{ + /** + * Dumps a set of routes to a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing the generator class + * + * @api + */ + public function dump(array $options = array()) + { + $options = array_merge(array( + 'class' => 'ProjectUrlGenerator', + 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', + ), $options); + + return + $this->startClass($options['class'], $options['base_class']). + $this->addConstructor(). + $this->addGenerator(). + $this->endClass() + ; + } + + private function addGenerator() + { + $methods = array(); + foreach ($this->getRoutes()->all() as $name => $route) { + $compiledRoute = $route->compile(); + + $variables = str_replace("\n", '', var_export($compiledRoute->getVariables(), true)); + $defaults = str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)); + $requirements = str_replace("\n", '', var_export($compiledRoute->getRequirements(), true)); + $tokens = str_replace("\n", '', var_export($compiledRoute->getTokens(), true)); + + $escapedName = str_replace('.', '__', $name); + + $methods[] = <<{'get'.\$escapedName.'RouteInfo'}(); + + return \$this->doGenerate(\$variables, \$defaults, \$requirements, \$tokens, \$parameters, \$name, \$absolute); + } + +$methods +EOF; + } + + private function startClass($class, $baseClass) + { + $routes = array(); + foreach ($this->getRoutes()->all() as $name => $route) { + $routes[] = " '$name' => true,"; + } + $routes = implode("\n", $routes); + + return <<context = \$context; + } + +EOF; + } + + private function endClass() + { + return << + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator; + +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\Exception\InvalidParameterException; +use Symfony\Component\Routing\Exception\RouteNotFoundException; +use Symfony\Component\Routing\Exception\MissingMandatoryParametersException; + +/** + * UrlGenerator generates URL based on a set of routes. + * + * @author Fabien Potencier + * + * @api + */ +class UrlGenerator implements UrlGeneratorInterface +{ + protected $context; + protected $decodedChars = array( + // %2F is not valid in a URL, so we don't encode it (which is fine as the requirements explicitly allowed it) + '%2F' => '/', + ); + + protected $routes; + protected $cache; + + /** + * Constructor. + * + * @param RouteCollection $routes A RouteCollection instance + * @param RequestContext $context The context + * + * @api + */ + public function __construct(RouteCollection $routes, RequestContext $context) + { + $this->routes = $routes; + $this->context = $context; + $this->cache = array(); + } + + /** + * Sets the request context. + * + * @param RequestContext $context The context + * + * @api + */ + public function setContext(RequestContext $context) + { + $this->context = $context; + } + + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + + /** + * Generates a URL from the given parameters. + * + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean $absolute Whether to generate an absolute URL + * + * @return string The generated URL + * + * @throws Symfony\Component\Routing\Exception\RouteNotFoundException When route doesn't exist + * + * @api + */ + public function generate($name, $parameters = array(), $absolute = false) + { + if (null === $route = $this->routes->get($name)) { + throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name)); + } + + if (!isset($this->cache[$name])) { + $this->cache[$name] = $route->compile(); + } + + return $this->doGenerate($this->cache[$name]->getVariables(), $route->getDefaults(), $route->getRequirements(), $this->cache[$name]->getTokens(), $parameters, $name, $absolute); + } + + /** + * @throws Symfony\Component\Routing\Exception\MissingMandatoryParametersException When route has some missing mandatory parameters + * @throws Symfony\Component\Routing\Exception\InvalidParameterException When a parameter value is not correct + */ + protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute) + { + $variables = array_flip($variables); + + $originParameters = $parameters; + $parameters = array_replace($this->context->getParameters(), $parameters); + $tparams = array_replace($defaults, $parameters); + + // all params must be given + if ($diff = array_diff_key($variables, $tparams)) { + throw new MissingMandatoryParametersException(sprintf('The "%s" route has some missing mandatory parameters ("%s").', $name, implode('", "', array_keys($diff)))); + } + + $url = ''; + $optional = true; + foreach ($tokens as $token) { + if ('variable' === $token[0]) { + if (false === $optional || !array_key_exists($token[3], $defaults) || (isset($parameters[$token[3]]) && (string) $parameters[$token[3]] != (string) $defaults[$token[3]])) { + if (!$isEmpty = in_array($tparams[$token[3]], array(null, '', false), true)) { + // check requirement + if ($tparams[$token[3]] && !preg_match('#^'.$token[2].'$#', $tparams[$token[3]])) { + throw new InvalidParameterException(sprintf('Parameter "%s" for route "%s" must match "%s" ("%s" given).', $token[3], $name, $token[2], $tparams[$token[3]])); + } + } + + if (!$isEmpty || !$optional) { + $url = $token[1].strtr(rawurlencode($tparams[$token[3]]), $this->decodedChars).$url; + } + + $optional = false; + } + } elseif ('text' === $token[0]) { + $url = $token[1].$url; + $optional = false; + } + } + + if (!$url) { + $url = '/'; + } + + // add a query string if needed + $extra = array_diff_key($originParameters, $variables, $defaults); + if ($extra && $query = http_build_query($extra, '', '&')) { + $url .= '?'.$query; + } + + $url = $this->context->getBaseUrl().$url; + + if ($this->context->getHost()) { + $scheme = $this->context->getScheme(); + if (isset($requirements['_scheme']) && ($req = strtolower($requirements['_scheme'])) && $scheme != $req) { + $absolute = true; + $scheme = $req; + } + + if ($absolute) { + $port = ''; + if ('http' === $scheme && 80 != $this->context->getHttpPort()) { + $port = ':'.$this->context->getHttpPort(); + } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { + $port = ':'.$this->context->getHttpsPort(); + } + + $url = $scheme.'://'.$this->context->getHost().$port.$url; + } + } + + return $url; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php new file mode 100644 index 0000000000..6f2800c27c --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Generator/UrlGeneratorInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Generator; + +use Symfony\Component\Routing\RequestContextAwareInterface; + +/** + * UrlGeneratorInterface is the interface that all URL generator classes must implements. + * + * @author Fabien Potencier + * + * @api + */ +interface UrlGeneratorInterface extends RequestContextAwareInterface +{ + /** + * Generates a URL from the given parameters. + * + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean $absolute Whether to generate an absolute URL + * + * @return string The generated URL + * + * @api + */ + public function generate($name, $parameters = array(), $absolute = false); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/LICENSE b/3rdparty/symfony/routing/Symfony/Component/Routing/LICENSE new file mode 100644 index 0000000000..cdffe7aebc --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2012 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php new file mode 100644 index 0000000000..5f292d4589 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationClassLoader.php @@ -0,0 +1,213 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Doctrine\Common\Annotations\Reader; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Config\Loader\LoaderResolver; + +/** + * AnnotationClassLoader loads routing information from a PHP class and its methods. + * + * You need to define an implementation for the getRouteDefaults() method. Most of the + * time, this method should define some PHP callable to be called for the route + * (a controller in MVC speak). + * + * The @Route annotation can be set on the class (for global parameters), + * and on each method. + * + * The @Route annotation main value is the route pattern. The annotation also + * recognizes three parameters: requirements, options, and name. The name parameter + * is mandatory. Here is an example of how you should be able to use it: + * + * /** + * * @Route("/Blog") + * * / + * class Blog + * { + * /** + * * @Route("/", name="blog_index") + * * / + * public function index() + * { + * } + * + * /** + * * @Route("/{id}", name="blog_post", requirements = {"id" = "\d+"}) + * * / + * public function show() + * { + * } + * } + * + * @author Fabien Potencier + */ +abstract class AnnotationClassLoader implements LoaderInterface +{ + protected $reader; + protected $routeAnnotationClass = 'Symfony\\Component\\Routing\\Annotation\\Route'; + protected $defaultRouteIndex; + + /** + * Constructor. + * + * @param Reader $reader + */ + public function __construct(Reader $reader) + { + $this->reader = $reader; + } + + /** + * Sets the annotation class to read route properties from. + * + * @param string $class A fully-qualified class name + */ + public function setRouteAnnotationClass($class) + { + $this->routeAnnotationClass = $class; + } + + /** + * Loads from annotations from a class. + * + * @param string $class A class name + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When route can't be parsed + */ + public function load($class, $type = null) + { + if (!class_exists($class)) { + throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + + $globals = array( + 'pattern' => '', + 'requirements' => array(), + 'options' => array(), + 'defaults' => array(), + ); + + $class = new \ReflectionClass($class); + if ($class->isAbstract()) { + throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class)); + } + + if ($annot = $this->reader->getClassAnnotation($class, $this->routeAnnotationClass)) { + if (null !== $annot->getPattern()) { + $globals['pattern'] = $annot->getPattern(); + } + + if (null !== $annot->getRequirements()) { + $globals['requirements'] = $annot->getRequirements(); + } + + if (null !== $annot->getOptions()) { + $globals['options'] = $annot->getOptions(); + } + + if (null !== $annot->getDefaults()) { + $globals['defaults'] = $annot->getDefaults(); + } + } + + $collection = new RouteCollection(); + $collection->addResource(new FileResource($class->getFileName())); + + foreach ($class->getMethods() as $method) { + $this->defaultRouteIndex = 0; + foreach ($this->reader->getMethodAnnotations($method) as $annot) { + if ($annot instanceof $this->routeAnnotationClass) { + $this->addRoute($collection, $annot, $globals, $class, $method); + } + } + } + + return $collection; + } + + protected function addRoute(RouteCollection $collection, $annot, $globals, \ReflectionClass $class, \ReflectionMethod $method) + { + $name = $annot->getName(); + if (null === $name) { + $name = $this->getDefaultRouteName($class, $method); + } + + $defaults = array_merge($globals['defaults'], $annot->getDefaults()); + $requirements = array_merge($globals['requirements'], $annot->getRequirements()); + $options = array_merge($globals['options'], $annot->getOptions()); + + $route = new Route($globals['pattern'].$annot->getPattern(), $defaults, $requirements, $options); + + $this->configureRoute($route, $class, $method, $annot); + + $collection->add($name, $route); + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return is_string($resource) && preg_match('/^(?:\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)+$/', $resource) && (!$type || 'annotation' === $type); + } + + /** + * Sets the loader resolver. + * + * @param LoaderResolver $resolver A LoaderResolver instance + */ + public function setResolver(LoaderResolver $resolver) + { + } + + /** + * Gets the loader resolver. + * + * @return LoaderResolver A LoaderResolver instance + */ + public function getResolver() + { + } + + /** + * Gets the default route name for a class method. + * + * @param \ReflectionClass $class + * @param \ReflectionMethod $method + * + * @return string + */ + protected function getDefaultRouteName(\ReflectionClass $class, \ReflectionMethod $method) + { + $name = strtolower(str_replace('\\', '_', $class->name).'_'.$method->name); + if ($this->defaultRouteIndex > 0) { + $name .= '_'.$this->defaultRouteIndex; + } + $this->defaultRouteIndex++; + + return $name; + } + + abstract protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, $annot); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php new file mode 100644 index 0000000000..8097cd67f9 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationDirectoryLoader.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Config\Resource\DirectoryResource; + +/** + * AnnotationDirectoryLoader loads routing information from annotations set + * on PHP classes and methods. + * + * @author Fabien Potencier + */ +class AnnotationDirectoryLoader extends AnnotationFileLoader +{ + /** + * Loads from annotations from a directory. + * + * @param string $path A directory path + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When the directory does not exist or its routes cannot be parsed + */ + public function load($path, $type = null) + { + $dir = $this->locator->locate($path); + + $collection = new RouteCollection(); + $collection->addResource(new DirectoryResource($dir, '/\.php$/')); + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { + if (!$file->isFile() || '.php' !== substr($file->getFilename(), -4)) { + continue; + } + + if ($class = $this->findClass($file)) { + $refl = new \ReflectionClass($class); + if ($refl->isAbstract()) { + continue; + } + + $collection->addCollection($this->loader->load($class, $type)); + } + } + + return $collection; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + try { + $path = $this->locator->locate($resource); + } catch (\Exception $e) { + return false; + } + + return is_string($resource) && is_dir($path) && (!$type || 'annotation' === $type); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php new file mode 100644 index 0000000000..49e1cb2f77 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/AnnotationFileLoader.php @@ -0,0 +1,125 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Loader\FileLoader; +use Symfony\Component\Config\FileLocator; + +/** + * AnnotationFileLoader loads routing information from annotations set + * on a PHP class and its methods. + * + * @author Fabien Potencier + */ +class AnnotationFileLoader extends FileLoader +{ + protected $loader; + + /** + * Constructor. + * + * @param FileLocator $locator A FileLocator instance + * @param AnnotationClassLoader $loader An AnnotationClassLoader instance + * @param string|array $paths A path or an array of paths where to look for resources + */ + public function __construct(FileLocator $locator, AnnotationClassLoader $loader, $paths = array()) + { + if (!function_exists('token_get_all')) { + throw new \RuntimeException('The Tokenizer extension is required for the routing annotation loaders.'); + } + + parent::__construct($locator, $paths); + + $this->loader = $loader; + } + + /** + * Loads from annotations from a file. + * + * @param string $file A PHP file path + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When the file does not exist or its routes cannot be parsed + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $collection = new RouteCollection(); + if ($class = $this->findClass($path)) { + $collection->addResource(new FileResource($path)); + $collection->addCollection($this->loader->load($class, $type)); + } + + return $collection; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'annotation' === $type); + } + + /** + * Returns the full class name for the first class in the file. + * + * @param string $file A PHP file path + * + * @return string|false Full class name if found, false otherwise + */ + protected function findClass($file) + { + $class = false; + $namespace = false; + $tokens = token_get_all(file_get_contents($file)); + for ($i = 0, $count = count($tokens); $i < $count; $i++) { + $token = $tokens[$i]; + + if (!is_array($token)) { + continue; + } + + if (true === $class && T_STRING === $token[0]) { + return $namespace.'\\'.$token[1]; + } + + if (true === $namespace && T_STRING === $token[0]) { + $namespace = ''; + do { + $namespace .= $token[1]; + $token = $tokens[++$i]; + } while ($i < $count && is_array($token) && in_array($token[0], array(T_NS_SEPARATOR, T_STRING))); + } + + if (T_CLASS === $token[0]) { + $class = true; + } + + if (T_NAMESPACE === $token[0]) { + $namespace = true; + } + } + + return false; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php new file mode 100644 index 0000000000..ca49c8fa35 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/ClosureLoader.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Config\Loader\Loader; + +/** + * ClosureLoader loads routes from a PHP closure. + * + * The Closure must return a RouteCollection instance. + * + * @author Fabien Potencier + * + * @api + */ +class ClosureLoader extends Loader +{ + /** + * Loads a Closure. + * + * @param \Closure $closure A Closure + * @param string $type The resource type + * + * @api + */ + public function load($closure, $type = null) + { + return call_user_func($closure); + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + * + * @api + */ + public function supports($resource, $type = null) + { + return $resource instanceof \Closure && (!$type || 'closure' === $type); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php new file mode 100644 index 0000000000..ffd31f9444 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/PhpFileLoader.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Loader\FileLoader; + +/** + * PhpFileLoader loads routes from a PHP file. + * + * The file must return a RouteCollection instance. + * + * @author Fabien Potencier + * + * @api + */ +class PhpFileLoader extends FileLoader +{ + /** + * Loads a PHP file. + * + * @param mixed $file A PHP file path + * @param string $type The resource type + * + * @api + */ + public function load($file, $type = null) + { + // the loader variable is exposed to the included file below + $loader = $this; + + $path = $this->locator->locate($file); + $this->setCurrentDir(dirname($path)); + + $collection = include $path; + $collection->addResource(new FileResource($path)); + + return $collection; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + * + * @api + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'php' === $type); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php new file mode 100644 index 0000000000..5dad9db3fa --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -0,0 +1,224 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\Route; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Loader\FileLoader; + +/** + * XmlFileLoader loads XML routing files. + * + * @author Fabien Potencier + * + * @api + */ +class XmlFileLoader extends FileLoader +{ + /** + * Loads an XML file. + * + * @param string $file An XML file path + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When a tag can't be parsed + * + * @api + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $xml = $this->loadFile($path); + + $collection = new RouteCollection(); + $collection->addResource(new FileResource($path)); + + // process routes and imports + foreach ($xml->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement) { + continue; + } + + $this->parseNode($collection, $node, $path, $file); + } + + return $collection; + } + + /** + * Parses a node from a loaded XML file. + * + * @param RouteCollection $collection the collection to associate with the node + * @param DOMElement $node the node to parse + * @param string $path the path of the XML file being processed + * @param string $file + */ + protected function parseNode(RouteCollection $collection, \DOMElement $node, $path, $file) + { + switch ($node->tagName) { + case 'route': + $this->parseRoute($collection, $node, $path); + break; + case 'import': + $resource = (string) $node->getAttribute('resource'); + $type = (string) $node->getAttribute('type'); + $prefix = (string) $node->getAttribute('prefix'); + $this->setCurrentDir(dirname($path)); + $collection->addCollection($this->import($resource, ('' !== $type ? $type : null), false, $file), $prefix); + break; + default: + throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName)); + } + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + * + * @api + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'xml' === $type); + } + + /** + * Parses a route and adds it to the RouteCollection. + * + * @param RouteCollection $collection A RouteCollection instance + * @param \DOMElement $definition Route definition + * @param string $file An XML file path + * + * @throws \InvalidArgumentException When the definition cannot be parsed + */ + protected function parseRoute(RouteCollection $collection, \DOMElement $definition, $file) + { + $defaults = array(); + $requirements = array(); + $options = array(); + + foreach ($definition->childNodes as $node) { + if (!$node instanceof \DOMElement) { + continue; + } + + switch ($node->tagName) { + case 'default': + $defaults[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); + break; + case 'option': + $options[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); + break; + case 'requirement': + $requirements[(string) $node->getAttribute('key')] = trim((string) $node->nodeValue); + break; + default: + throw new \InvalidArgumentException(sprintf('Unable to parse tag "%s"', $node->tagName)); + } + } + + $route = new Route((string) $definition->getAttribute('pattern'), $defaults, $requirements, $options); + + $collection->add((string) $definition->getAttribute('id'), $route); + } + + /** + * Loads an XML file. + * + * @param string $file An XML file path + * + * @return \DOMDocument + * + * @throws \InvalidArgumentException When loading of XML file returns error + */ + protected function loadFile($file) + { + $internalErrors = libxml_use_internal_errors(true); + $disableEntities = libxml_disable_entity_loader(true); + libxml_clear_errors(); + + $dom = new \DOMDocument(); + $dom->validateOnParse = true; + if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { + libxml_disable_entity_loader($disableEntities); + + throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($internalErrors))); + } + $dom->normalizeDocument(); + + libxml_use_internal_errors($internalErrors); + libxml_disable_entity_loader($disableEntities); + + foreach ($dom->childNodes as $child) { + if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { + throw new \InvalidArgumentException('Document types are not allowed.'); + } + } + + $this->validate($dom); + + return $dom; + } + + /** + * Validates a loaded XML file. + * + * @param \DOMDocument $dom A loaded XML file + * + * @throws \InvalidArgumentException When XML doesn't validate its XSD schema + */ + protected function validate(\DOMDocument $dom) + { + $location = __DIR__.'/schema/routing/routing-1.0.xsd'; + + $current = libxml_use_internal_errors(true); + libxml_clear_errors(); + + if (!$dom->schemaValidate($location)) { + throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($current))); + } + libxml_use_internal_errors($current); + } + + /** + * Retrieves libxml errors and clears them. + * + * @return array An array of libxml error strings + */ + private function getXmlErrors($internalErrors) + { + $errors = array(); + foreach (libxml_get_errors() as $error) { + $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', + LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', + $error->code, + trim($error->message), + $error->file ? $error->file : 'n/a', + $error->line, + $error->column + ); + } + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + + return $errors; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php new file mode 100644 index 0000000000..ee72383435 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/YamlFileLoader.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Loader; + +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\Route; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Yaml\Yaml; +use Symfony\Component\Config\Loader\FileLoader; + +/** + * YamlFileLoader loads Yaml routing files. + * + * @author Fabien Potencier + * + * @api + */ +class YamlFileLoader extends FileLoader +{ + private static $availableKeys = array( + 'type', 'resource', 'prefix', 'pattern', 'options', 'defaults', 'requirements' + ); + + /** + * Loads a Yaml file. + * + * @param string $file A Yaml file path + * @param string $type The resource type + * + * @return RouteCollection A RouteCollection instance + * + * @throws \InvalidArgumentException When route can't be parsed + * + * @api + */ + public function load($file, $type = null) + { + $path = $this->locator->locate($file); + + $config = Yaml::parse($path); + + $collection = new RouteCollection(); + $collection->addResource(new FileResource($path)); + + // empty file + if (null === $config) { + $config = array(); + } + + // not an array + if (!is_array($config)) { + throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $file)); + } + + foreach ($config as $name => $config) { + $config = $this->normalizeRouteConfig($config); + + if (isset($config['resource'])) { + $type = isset($config['type']) ? $config['type'] : null; + $prefix = isset($config['prefix']) ? $config['prefix'] : null; + $this->setCurrentDir(dirname($path)); + $collection->addCollection($this->import($config['resource'], $type, false, $file), $prefix); + } else { + $this->parseRoute($collection, $name, $config, $path); + } + } + + return $collection; + } + + /** + * Returns true if this class supports the given resource. + * + * @param mixed $resource A resource + * @param string $type The resource type + * + * @return Boolean True if this class supports the given resource, false otherwise + * + * @api + */ + public function supports($resource, $type = null) + { + return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION) && (!$type || 'yaml' === $type); + } + + /** + * Parses a route and adds it to the RouteCollection. + * + * @param RouteCollection $collection A RouteCollection instance + * @param string $name Route name + * @param array $config Route definition + * @param string $file A Yaml file path + * + * @throws \InvalidArgumentException When config pattern is not defined for the given route + */ + protected function parseRoute(RouteCollection $collection, $name, $config, $file) + { + $defaults = isset($config['defaults']) ? $config['defaults'] : array(); + $requirements = isset($config['requirements']) ? $config['requirements'] : array(); + $options = isset($config['options']) ? $config['options'] : array(); + + if (!isset($config['pattern'])) { + throw new \InvalidArgumentException(sprintf('You must define a "pattern" for the "%s" route.', $name)); + } + + $route = new Route($config['pattern'], $defaults, $requirements, $options); + + $collection->add($name, $route); + } + + /** + * Normalize route configuration. + * + * @param array $config A resource config + * + * @return array + * + * @throws InvalidArgumentException if one of the provided config keys is not supported + */ + private function normalizeRouteConfig(array $config) + { + foreach ($config as $key => $value) { + if (!in_array($key, self::$availableKeys)) { + throw new \InvalidArgumentException(sprintf( + 'Yaml routing loader does not support given key: "%s". Expected one of the (%s).', + $key, implode(', ', self::$availableKeys) + )); + } + } + + return $config; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd new file mode 100644 index 0000000000..a9554e64df --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Loader/schema/routing/routing-1.0.xsd @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php new file mode 100644 index 0000000000..3003dfdebb --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\Exception\MethodNotAllowedException; + +/** + * ApacheUrlMatcher matches URL based on Apache mod_rewrite matching (see ApacheMatcherDumper). + * + * @author Fabien Potencier + */ +class ApacheUrlMatcher extends UrlMatcher +{ + /** + * Tries to match a URL based on Apache mod_rewrite matching. + * + * Returns false if no route matches the URL. + * + * @param string $pathinfo The pathinfo to be parsed + * + * @return array An array of parameters + * + * @throws MethodNotAllowedException If the current method is not allowed + */ + public function match($pathinfo) + { + $parameters = array(); + $defaults = array(); + $allow = array(); + $match = false; + + foreach ($_SERVER as $key => $value) { + $name = $key; + + if (0 === strpos($name, 'REDIRECT_')) { + $name = substr($name, 9); + } + + if (0 === strpos($name, '_ROUTING_DEFAULTS_')) { + $name = substr($name, 18); + $defaults[$name] = $value; + } elseif (0 === strpos($name, '_ROUTING_')) { + $name = substr($name, 9); + if ('_route' == $name) { + $match = true; + $parameters[$name] = $value; + } elseif (0 === strpos($name, '_allow_')) { + $allow[] = substr($name, 7); + } else { + $parameters[$name] = $value; + } + } else { + continue; + } + + unset($_SERVER[$key]); + } + + if ($match) { + return $this->mergeDefaults($parameters, $defaults); + } elseif (0 < count($allow)) { + throw new MethodNotAllowedException($allow); + } else { + return parent::match($pathinfo); + } + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php new file mode 100644 index 0000000000..4f03b8d393 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php @@ -0,0 +1,155 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher\Dumper; + +/** + * Dumps a set of Apache mod_rewrite rules. + * + * @author Fabien Potencier + * @author Kris Wallsmith + */ +class ApacheMatcherDumper extends MatcherDumper +{ + /** + * Dumps a set of Apache mod_rewrite rules. + * + * Available options: + * + * * script_name: The script name (app.php by default) + * * base_uri: The base URI ("" by default) + * + * @param array $options An array of options + * + * @return string A string to be used as Apache rewrite rules + * + * @throws \LogicException When the route regex is invalid + */ + public function dump(array $options = array()) + { + $options = array_merge(array( + 'script_name' => 'app.php', + 'base_uri' => '', + ), $options); + + $options['script_name'] = self::escape($options['script_name'], ' ', '\\'); + + $rules = array("# skip \"real\" requests\nRewriteCond %{REQUEST_FILENAME} -f\nRewriteRule .* - [QSA,L]"); + $methodVars = array(); + + foreach ($this->getRoutes()->all() as $name => $route) { + $compiledRoute = $route->compile(); + + // prepare the apache regex + $regex = $compiledRoute->getRegex(); + $delimiter = $regex[0]; + $regexPatternEnd = strrpos($regex, $delimiter); + if (strlen($regex) < 2 || 0 === $regexPatternEnd) { + throw new \LogicException('The "%s" route regex "%s" is invalid', $name, $regex); + } + $regex = preg_replace('/\?P<.+?>/', '', substr($regex, 1, $regexPatternEnd - 1)); + $regex = '^'.self::escape(preg_quote($options['base_uri']).substr($regex, 1), ' ', '\\'); + + $hasTrailingSlash = '/$' == substr($regex, -2) && '^/$' != $regex; + + $variables = array('E=_ROUTING__route:'.$name); + foreach ($compiledRoute->getVariables() as $i => $variable) { + $variables[] = 'E=_ROUTING_'.$variable.':%'.($i + 1); + } + foreach ($route->getDefaults() as $key => $value) { + $variables[] = 'E=_ROUTING_DEFAULTS_'.$key.':'.strtr($value, array( + ':' => '\\:', + '=' => '\\=', + '\\' => '\\\\', + ' ' => '\\ ', + )); + } + $variables = implode(',', $variables); + + $rule = array("# $name"); + + // method mismatch + if ($req = $route->getRequirement('_method')) { + $methods = explode('|', strtoupper($req)); + // GET and HEAD are equivalent + if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { + $methods[] = 'HEAD'; + } + $allow = array(); + foreach ($methods as $method) { + $methodVars[] = $method; + $allow[] = 'E=_ROUTING__allow_'.$method.':1'; + } + + $rule[] = "RewriteCond %{REQUEST_URI} $regex"; + $rule[] = sprintf("RewriteCond %%{REQUEST_METHOD} !^(%s)$ [NC]", implode('|', $methods)); + $rule[] = sprintf('RewriteRule .* - [S=%d,%s]', $hasTrailingSlash ? 2 : 1, implode(',', $allow)); + } + + // redirect with trailing slash appended + if ($hasTrailingSlash) { + $rule[] = 'RewriteCond %{REQUEST_URI} '.substr($regex, 0, -2).'$'; + $rule[] = 'RewriteRule .* $0/ [QSA,L,R=301]'; + } + + // the main rule + $rule[] = "RewriteCond %{REQUEST_URI} $regex"; + $rule[] = "RewriteRule .* {$options['script_name']} [QSA,L,$variables]"; + + $rules[] = implode("\n", $rule); + } + + if (0 < count($methodVars)) { + $rule = array('# 405 Method Not Allowed'); + $methodVars = array_values(array_unique($methodVars)); + foreach ($methodVars as $i => $methodVar) { + $rule[] = sprintf('RewriteCond %%{_ROUTING__allow_%s} !-z%s', $methodVar, isset($methodVars[$i + 1]) ? ' [OR]' : ''); + } + $rule[] = sprintf('RewriteRule .* %s [QSA,L]', $options['script_name']); + + $rules[] = implode("\n", $rule); + } + + return implode("\n\n", $rules)."\n"; + } + + /** + * Escapes a string. + * + * @param string $string The string to be escaped + * @param string $char The character to be escaped + * @param string $with The character to be used for escaping + * + * @return string The escaped string + */ + private static function escape($string, $char, $with) + { + $escaped = false; + $output = ''; + foreach (str_split($string) as $symbol) { + if ($escaped) { + $output .= $symbol; + $escaped = false; + continue; + } + if ($symbol === $char) { + $output .= $with.$char; + continue; + } + if ($symbol === $with) { + $escaped = true; + } + $output .= $symbol; + } + + return $output; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php new file mode 100644 index 0000000000..423368b57e --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumper.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher\Dumper; + +use Symfony\Component\Routing\RouteCollection; + +/** + * MatcherDumper is the abstract class for all built-in matcher dumpers. + * + * @author Fabien Potencier + */ +abstract class MatcherDumper implements MatcherDumperInterface +{ + private $routes; + + /** + * Constructor. + * + * @param RouteCollection $routes The RouteCollection to dump + */ + public function __construct(RouteCollection $routes) + { + $this->routes = $routes; + } + + /** + * Gets the routes to dump. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRoutes() + { + return $this->routes; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php new file mode 100644 index 0000000000..fe09e067d7 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/MatcherDumperInterface.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher\Dumper; + +/** + * MatcherDumperInterface is the interface that all matcher dumper classes must implement. + * + * @author Fabien Potencier + */ +interface MatcherDumperInterface +{ + /** + * Dumps a set of routes to a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing the matcher class + */ + public function dump(array $options = array()); + + /** + * Gets the routes to match. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRoutes(); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php new file mode 100644 index 0000000000..fdaad513a1 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php @@ -0,0 +1,293 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher\Dumper; + +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; + +/** + * PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes. + * + * @author Fabien Potencier + */ +class PhpMatcherDumper extends MatcherDumper +{ + /** + * Dumps a set of routes to a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * + * @param array $options An array of options + * + * @return string A PHP class representing the matcher class + */ + public function dump(array $options = array()) + { + $options = array_merge(array( + 'class' => 'ProjectUrlMatcher', + 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', + ), $options); + + // trailing slash support is only enabled if we know how to redirect the user + $interfaces = class_implements($options['base_class']); + $supportsRedirections = isset($interfaces['Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface']); + + return + $this->startClass($options['class'], $options['base_class']). + $this->addConstructor(). + $this->addMatcher($supportsRedirections). + $this->endClass() + ; + } + + private function addMatcher($supportsRedirections) + { + // we need to deep clone the routes as we will modify the structure to optimize the dump + $code = implode("\n", $this->compileRoutes(clone $this->getRoutes(), $supportsRedirections)); + + return <<getIterator(); + $keys = array_keys($routeIterator->getArrayCopy()); + $keysCount = count($keys); + + $i = 0; + foreach ($routeIterator as $name => $route) { + $i++; + + if ($route instanceof RouteCollection) { + $prefix = $route->getPrefix(); + $optimizable = $prefix && count($route->all()) > 1 && false === strpos($route->getPrefix(), '{'); + $indent = ''; + if ($optimizable) { + for ($j = $i; $j < $keysCount; $j++) { + if ($keys[$j] === null) { + continue; + } + + $testRoute = $routeIterator->offsetGet($keys[$j]); + $isCollection = ($testRoute instanceof RouteCollection); + + $testPrefix = $isCollection ? $testRoute->getPrefix() : $testRoute->getPattern(); + + if (0 === strpos($testPrefix, $prefix)) { + $routeIterator->offsetUnset($keys[$j]); + + if ($isCollection) { + $route->addCollection($testRoute); + } else { + $route->add($keys[$j], $testRoute); + } + + $i++; + $keys[$j] = null; + } + } + + if ($prefix !== $parentPrefix) { + $code[] = sprintf(" if (0 === strpos(\$pathinfo, %s)) {", var_export($prefix, true)); + $indent = ' '; + } + } + + foreach ($this->compileRoutes($route, $supportsRedirections, $prefix) as $line) { + foreach (explode("\n", $line) as $l) { + if ($l) { + $code[] = $indent.$l; + } else { + $code[] = $l; + } + } + } + + if ($optimizable && $prefix !== $parentPrefix) { + $code[] = " }\n"; + } + } else { + foreach ($this->compileRoute($route, $name, $supportsRedirections, $parentPrefix) as $line) { + $code[] = $line; + } + } + } + + return $code; + } + + private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null) + { + $code = array(); + $compiledRoute = $route->compile(); + $conditions = array(); + $hasTrailingSlash = false; + $matches = false; + if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?P.*?)\$\1#', $compiledRoute->getRegex(), $m)) { + if ($supportsRedirections && substr($m['url'], -1) === '/') { + $conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true)); + $hasTrailingSlash = true; + } else { + $conditions[] = sprintf("\$pathinfo === %s", var_export(str_replace('\\', '', $m['url']), true)); + } + } else { + if ($compiledRoute->getStaticPrefix() && $compiledRoute->getStaticPrefix() != $parentPrefix) { + $conditions[] = sprintf("0 === strpos(\$pathinfo, %s)", var_export($compiledRoute->getStaticPrefix(), true)); + } + + $regex = $compiledRoute->getRegex(); + if ($supportsRedirections && $pos = strpos($regex, '/$')) { + $regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2); + $hasTrailingSlash = true; + } + $conditions[] = sprintf("preg_match(%s, \$pathinfo, \$matches)", var_export($regex, true)); + + $matches = true; + } + + $conditions = implode(' && ', $conditions); + + $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name); + + $code[] = <<getRequirement('_method')) { + $methods = explode('|', strtoupper($req)); + // GET and HEAD are equivalent + if (in_array('GET', $methods) && !in_array('HEAD', $methods)) { + $methods[] = 'HEAD'; + } + if (1 === count($methods)) { + $code[] = <<context->getMethod() != '$methods[0]') { + \$allow[] = '$methods[0]'; + goto $gotoname; + } +EOF; + } else { + $methods = implode('\', \'', $methods); + $code[] = <<context->getMethod(), array('$methods'))) { + \$allow = array_merge(\$allow, array('$methods')); + goto $gotoname; + } +EOF; + } + } + + if ($hasTrailingSlash) { + $code[] = sprintf(<<redirect(\$pathinfo.'/', '%s'); + } +EOF + , $name); + } + + if ($scheme = $route->getRequirement('_scheme')) { + if (!$supportsRedirections) { + throw new \LogicException('The "_scheme" requirement is only supported for route dumper that implements RedirectableUrlMatcherInterface.'); + } + + $code[] = sprintf(<<context->getScheme() !== '$scheme') { + return \$this->redirect(\$pathinfo, '%s', '$scheme'); + } +EOF + , $name); + } + + // optimize parameters array + if (true === $matches && $compiledRoute->getDefaults()) { + $code[] = sprintf(" return array_merge(\$this->mergeDefaults(\$matches, %s), array('_route' => '%s'));" + , str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)), $name); + } elseif (true === $matches) { + $code[] = sprintf(" \$matches['_route'] = '%s';", $name); + $code[] = sprintf(" return \$matches;", $name); + } elseif ($compiledRoute->getDefaults()) { + $code[] = sprintf(' return %s;', str_replace("\n", '', var_export(array_merge($compiledRoute->getDefaults(), array('_route' => $name)), true))); + } else { + $code[] = sprintf(" return array('_route' => '%s');", $name); + } + $code[] = " }"; + + if ($req) { + $code[] = " $gotoname:"; + } + + $code[] = ''; + + return $code; + } + + private function startClass($class, $baseClass) + { + return <<context = \$context; + } + +EOF; + } + + private function endClass() + { + return << + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\Exception\ResourceNotFoundException; + +/** + * @author Fabien Potencier + * + * @api + */ +abstract class RedirectableUrlMatcher extends UrlMatcher implements RedirectableUrlMatcherInterface +{ + private $trailingSlashTest = false; + + /** + * @see UrlMatcher::match() + * + * @api + */ + public function match($pathinfo) + { + try { + $parameters = parent::match($pathinfo); + } catch (ResourceNotFoundException $e) { + if ('/' === substr($pathinfo, -1)) { + throw $e; + } + + // try with a / at the end + $this->trailingSlashTest = true; + + return $this->match($pathinfo.'/'); + } + + if ($this->trailingSlashTest) { + $this->trailingSlashTest = false; + + return $this->redirect($pathinfo, null); + } + + return $parameters; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php new file mode 100644 index 0000000000..929ae9cc78 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/RedirectableUrlMatcherInterface.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +/** + * RedirectableUrlMatcherInterface knows how to redirect the user. + * + * @author Fabien Potencier + * + * @api + */ +interface RedirectableUrlMatcherInterface +{ + /** + * Redirects the user to another URL. + * + * @param string $path The path info to redirect to. + * @param string $route The route that matched + * @param string $scheme The URL scheme (null to keep the current one) + * + * @return array An array of parameters + * + * @api + */ + public function redirect($path, $route, $scheme = null); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php new file mode 100644 index 0000000000..5ff8070ea0 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\Exception\MethodNotAllowedException; +use Symfony\Component\Routing\Exception\ResourceNotFoundException; +use Symfony\Component\Routing\RouteCollection; +use Symfony\Component\Routing\RequestContext; + +/** + * UrlMatcher matches URL based on a set of routes. + * + * @author Fabien Potencier + * + * @api + */ +class UrlMatcher implements UrlMatcherInterface +{ + protected $context; + protected $allow; + + private $routes; + + /** + * Constructor. + * + * @param RouteCollection $routes A RouteCollection instance + * @param RequestContext $context The context + * + * @api + */ + public function __construct(RouteCollection $routes, RequestContext $context) + { + $this->routes = $routes; + $this->context = $context; + } + + /** + * Sets the request context. + * + * @param RequestContext $context The context + * + * @api + */ + public function setContext(RequestContext $context) + { + $this->context = $context; + } + + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + + /** + * Tries to match a URL with a set of routes. + * + * @param string $pathinfo The path info to be parsed + * + * @return array An array of parameters + * + * @throws ResourceNotFoundException If the resource could not be found + * @throws MethodNotAllowedException If the resource was found but the request method is not allowed + * + * @api + */ + public function match($pathinfo) + { + $this->allow = array(); + + if ($ret = $this->matchCollection($pathinfo, $this->routes)) { + return $ret; + } + + throw 0 < count($this->allow) + ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow))) + : new ResourceNotFoundException(); + } + + protected function matchCollection($pathinfo, RouteCollection $routes) + { + $pathinfo = urldecode($pathinfo); + + foreach ($routes as $name => $route) { + if ($route instanceof RouteCollection) { + if (false === strpos($route->getPrefix(), '{') && $route->getPrefix() !== substr($pathinfo, 0, strlen($route->getPrefix()))) { + continue; + } + + if (!$ret = $this->matchCollection($pathinfo, $route)) { + continue; + } + + return $ret; + } + + $compiledRoute = $route->compile(); + + // check the static prefix of the URL first. Only use the more expensive preg_match when it matches + if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { + continue; + } + + if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { + continue; + } + + // check HTTP method requirement + if ($req = $route->getRequirement('_method')) { + // HEAD and GET are equivalent as per RFC + if ('HEAD' === $method = $this->context->getMethod()) { + $method = 'GET'; + } + + if (!in_array($method, $req = explode('|', strtoupper($req)))) { + $this->allow = array_merge($this->allow, $req); + + continue; + } + } + + return array_merge($this->mergeDefaults($matches, $route->getDefaults()), array('_route' => $name)); + } + } + + protected function mergeDefaults($params, $defaults) + { + $parameters = $defaults; + foreach ($params as $key => $value) { + if (!is_int($key)) { + $parameters[$key] = rawurldecode($value); + } + } + + return $parameters; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php new file mode 100644 index 0000000000..5823d3201b --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcherInterface.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing\Matcher; + +use Symfony\Component\Routing\RequestContextAwareInterface; + +/** + * UrlMatcherInterface is the interface that all URL matcher classes must implement. + * + * @author Fabien Potencier + * + * @api + */ +interface UrlMatcherInterface extends RequestContextAwareInterface +{ + /** + * Tries to match a URL with a set of routes. + * + * @param string $pathinfo The path info to be parsed + * + * @return array An array of parameters + * + * @throws ResourceNotFoundException If the resource could not be found + * @throws MethodNotAllowedException If the resource was found but the request method is not allowed + * + * @api + */ + public function match($pathinfo); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/README.md b/3rdparty/symfony/routing/Symfony/Component/Routing/README.md new file mode 100644 index 0000000000..eb72334d2e --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/README.md @@ -0,0 +1,32 @@ +Routing Component +================= + +Routing associates a request with the code that will convert it to a response. + +The example below demonstrates how you can set up a fully working routing +system: + + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\Routing\Matcher\UrlMatcher; + use Symfony\Component\Routing\RequestContext; + use Symfony\Component\Routing\RouteCollection; + use Symfony\Component\Routing\Route; + + $routes = new RouteCollection(); + $routes->add('hello', new Route('/hello', array('controller' => 'foo'))); + + $context = new RequestContext(); + + // this is optional and can be done without a Request instance + $context->fromRequest(Request::createFromGlobals()); + + $matcher = new UrlMatcher($routes, $context); + + $parameters = $matcher->match('/hello'); + +Resources +--------- + +Unit tests: + +https://github.com/symfony/symfony/tree/master/tests/Symfony/Tests/Component/Routing diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContext.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContext.php new file mode 100644 index 0000000000..fef85b6bb3 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContext.php @@ -0,0 +1,250 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * Holds information about the current request. + * + * @author Fabien Potencier + * + * @api + */ +class RequestContext +{ + private $baseUrl; + private $method; + private $host; + private $scheme; + private $httpPort; + private $httpsPort; + private $parameters; + + /** + * Constructor. + * + * @param string $baseUrl The base URL + * @param string $method The HTTP method + * @param string $host The HTTP host name + * @param string $scheme The HTTP scheme + * @param integer $httpPort The HTTP port + * @param integer $httpsPort The HTTPS port + * + * @api + */ + public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', $scheme = 'http', $httpPort = 80, $httpsPort = 443) + { + $this->baseUrl = $baseUrl; + $this->method = strtoupper($method); + $this->host = $host; + $this->scheme = strtolower($scheme); + $this->httpPort = $httpPort; + $this->httpsPort = $httpsPort; + $this->parameters = array(); + } + + /** + * Gets the base URL. + * + * @return string The base URL + */ + public function getBaseUrl() + { + return $this->baseUrl; + } + + /** + * Sets the base URL. + * + * @param string $baseUrl The base URL + * + * @api + */ + public function setBaseUrl($baseUrl) + { + $this->baseUrl = $baseUrl; + } + + /** + * Gets the HTTP method. + * + * The method is always an uppercased string. + * + * @return string The HTTP method + */ + public function getMethod() + { + return $this->method; + } + + /** + * Sets the HTTP method. + * + * @param string $method The HTTP method + * + * @api + */ + public function setMethod($method) + { + $this->method = strtoupper($method); + } + + /** + * Gets the HTTP host. + * + * @return string The HTTP host + */ + public function getHost() + { + return $this->host; + } + + /** + * Sets the HTTP host. + * + * @param string $host The HTTP host + * + * @api + */ + public function setHost($host) + { + $this->host = $host; + } + + /** + * Gets the HTTP scheme. + * + * @return string The HTTP scheme + */ + public function getScheme() + { + return $this->scheme; + } + + /** + * Sets the HTTP scheme. + * + * @param string $scheme The HTTP scheme + * + * @api + */ + public function setScheme($scheme) + { + $this->scheme = strtolower($scheme); + } + + /** + * Gets the HTTP port. + * + * @return string The HTTP port + */ + public function getHttpPort() + { + return $this->httpPort; + } + + /** + * Sets the HTTP port. + * + * @param string $httpPort The HTTP port + * + * @api + */ + public function setHttpPort($httpPort) + { + $this->httpPort = $httpPort; + } + + /** + * Gets the HTTPS port. + * + * @return string The HTTPS port + */ + public function getHttpsPort() + { + return $this->httpsPort; + } + + /** + * Sets the HTTPS port. + * + * @param string $httpsPort The HTTPS port + * + * @api + */ + public function setHttpsPort($httpsPort) + { + $this->httpsPort = $httpsPort; + } + + /** + * Returns the parameters. + * + * @return array The parameters + */ + public function getParameters() + { + return $this->parameters; + } + + /** + * Sets the parameters. + * + * This method implements a fluent interface. + * + * @param array $parameters The parameters + * + * @return Route The current Route instance + */ + public function setParameters(array $parameters) + { + $this->parameters = $parameters; + + return $this; + } + + /** + * Gets a parameter value. + * + * @param string $name A parameter name + * + * @return mixed The parameter value + */ + public function getParameter($name) + { + return isset($this->parameters[$name]) ? $this->parameters[$name] : null; + } + + /** + * Checks if a parameter value is set for the given parameter. + * + * @param string $name A parameter name + * + * @return Boolean true if the parameter value is set, false otherwise + */ + public function hasParameter($name) + { + return array_key_exists($name, $this->parameters); + } + + /** + * Sets a parameter value. + * + * @param string $name A parameter name + * @param mixed $parameter The parameter value + * + * @api + */ + public function setParameter($name, $parameter) + { + $this->parameters[$name] = $parameter; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php new file mode 100644 index 0000000000..38443a88b7 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RequestContextAwareInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * @api + */ +interface RequestContextAwareInterface +{ + /** + * Sets the request context. + * + * @param RequestContext $context The context + * + * @api + */ + public function setContext(RequestContext $context); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Route.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Route.php new file mode 100644 index 0000000000..548568334d --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Route.php @@ -0,0 +1,312 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * A Route describes a route and its parameters. + * + * @author Fabien Potencier + * + * @api + */ +class Route +{ + private $pattern; + private $defaults; + private $requirements; + private $options; + private $compiled; + + private static $compilers = array(); + + /** + * Constructor. + * + * Available options: + * + * * compiler_class: A class name able to compile this route instance (RouteCompiler by default) + * + * @param string $pattern The pattern to match + * @param array $defaults An array of default parameter values + * @param array $requirements An array of requirements for parameters (regexes) + * @param array $options An array of options + * + * @api + */ + public function __construct($pattern, array $defaults = array(), array $requirements = array(), array $options = array()) + { + $this->setPattern($pattern); + $this->setDefaults($defaults); + $this->setRequirements($requirements); + $this->setOptions($options); + } + + public function __clone() + { + $this->compiled = null; + } + + /** + * Returns the pattern. + * + * @return string The pattern + */ + public function getPattern() + { + return $this->pattern; + } + + /** + * Sets the pattern. + * + * This method implements a fluent interface. + * + * @param string $pattern The pattern + * + * @return Route The current Route instance + */ + public function setPattern($pattern) + { + $this->pattern = trim($pattern); + + // a route must start with a slash + if (empty($this->pattern) || '/' !== $this->pattern[0]) { + $this->pattern = '/'.$this->pattern; + } + + return $this; + } + + /** + * Returns the options. + * + * @return array The options + */ + public function getOptions() + { + return $this->options; + } + + /** + * Sets the options. + * + * This method implements a fluent interface. + * + * @param array $options The options + * + * @return Route The current Route instance + */ + public function setOptions(array $options) + { + $this->options = array_merge(array( + 'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler', + ), $options); + + return $this; + } + + /** + * Sets an option value. + * + * This method implements a fluent interface. + * + * @param string $name An option name + * @param mixed $value The option value + * + * @return Route The current Route instance + * + * @api + */ + public function setOption($name, $value) + { + $this->options[$name] = $value; + + return $this; + } + + /** + * Get an option value. + * + * @param string $name An option name + * + * @return mixed The option value + */ + public function getOption($name) + { + return isset($this->options[$name]) ? $this->options[$name] : null; + } + + /** + * Returns the defaults. + * + * @return array The defaults + */ + public function getDefaults() + { + return $this->defaults; + } + + /** + * Sets the defaults. + * + * This method implements a fluent interface. + * + * @param array $defaults The defaults + * + * @return Route The current Route instance + */ + public function setDefaults(array $defaults) + { + $this->defaults = array(); + foreach ($defaults as $name => $default) { + $this->defaults[(string) $name] = $default; + } + + return $this; + } + + /** + * Gets a default value. + * + * @param string $name A variable name + * + * @return mixed The default value + */ + public function getDefault($name) + { + return isset($this->defaults[$name]) ? $this->defaults[$name] : null; + } + + /** + * Checks if a default value is set for the given variable. + * + * @param string $name A variable name + * + * @return Boolean true if the default value is set, false otherwise + */ + public function hasDefault($name) + { + return array_key_exists($name, $this->defaults); + } + + /** + * Sets a default value. + * + * @param string $name A variable name + * @param mixed $default The default value + * + * @return Route The current Route instance + * + * @api + */ + public function setDefault($name, $default) + { + $this->defaults[(string) $name] = $default; + + return $this; + } + + /** + * Returns the requirements. + * + * @return array The requirements + */ + public function getRequirements() + { + return $this->requirements; + } + + /** + * Sets the requirements. + * + * This method implements a fluent interface. + * + * @param array $requirements The requirements + * + * @return Route The current Route instance + */ + public function setRequirements(array $requirements) + { + $this->requirements = array(); + foreach ($requirements as $key => $regex) { + $this->requirements[$key] = $this->sanitizeRequirement($key, $regex); + } + + return $this; + } + + /** + * Returns the requirement for the given key. + * + * @param string $key The key + * + * @return string The regex + */ + public function getRequirement($key) + { + return isset($this->requirements[$key]) ? $this->requirements[$key] : null; + } + + /** + * Sets a requirement for the given key. + * + * @param string $key The key + * @param string $regex The regex + * + * @return Route The current Route instance + * + * @api + */ + public function setRequirement($key, $regex) + { + $this->requirements[$key] = $this->sanitizeRequirement($key, $regex); + + return $this; + } + + /** + * Compiles the route. + * + * @return CompiledRoute A CompiledRoute instance + */ + public function compile() + { + if (null !== $this->compiled) { + return $this->compiled; + } + + $class = $this->getOption('compiler_class'); + + if (!isset(self::$compilers[$class])) { + self::$compilers[$class] = new $class; + } + + return $this->compiled = self::$compilers[$class]->compile($this); + } + + private function sanitizeRequirement($key, $regex) + { + if (is_array($regex)) { + throw new \InvalidArgumentException(sprintf('Routing requirements must be a string, array given for "%s"', $key)); + } + + if ('^' == $regex[0]) { + $regex = substr($regex, 1); + } + + if ('$' == substr($regex, -1)) { + $regex = substr($regex, 0, -1); + } + + return $regex; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCollection.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCollection.php new file mode 100644 index 0000000000..b3289d337c --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCollection.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * A RouteCollection represents a set of Route instances. + * + * When adding a route, it overrides existing routes with the + * same name defined in the instance or its children and parents. + * + * @author Fabien Potencier + * + * @api + */ +class RouteCollection implements \IteratorAggregate +{ + private $routes; + private $resources; + private $prefix; + private $parent; + + /** + * Constructor. + * + * @api + */ + public function __construct() + { + $this->routes = array(); + $this->resources = array(); + $this->prefix = ''; + } + + public function __clone() + { + foreach ($this->routes as $name => $route) { + $this->routes[$name] = clone $route; + if ($route instanceof RouteCollection) { + $this->routes[$name]->setParent($this); + } + } + } + + /** + * Gets the parent RouteCollection. + * + * @return RouteCollection The parent RouteCollection + */ + public function getParent() + { + return $this->parent; + } + + /** + * Sets the parent RouteCollection. + * + * @param RouteCollection $parent The parent RouteCollection + */ + public function setParent(RouteCollection $parent) + { + $this->parent = $parent; + } + + /** + * Gets the current RouteCollection as an Iterator. + * + * @return \ArrayIterator An \ArrayIterator interface + */ + public function getIterator() + { + return new \ArrayIterator($this->routes); + } + + /** + * Adds a route. + * + * @param string $name The route name + * @param Route $route A Route instance + * + * @throws \InvalidArgumentException When route name contains non valid characters + * + * @api + */ + public function add($name, Route $route) + { + if (!preg_match('/^[a-z0-9A-Z_.]+$/', $name)) { + throw new \InvalidArgumentException(sprintf('The provided route name "%s" contains non valid characters. A route name must only contain digits (0-9), letters (a-z and A-Z), underscores (_) and dots (.).', $name)); + } + + $parent = $this; + while ($parent->getParent()) { + $parent = $parent->getParent(); + } + + if ($parent) { + $parent->remove($name); + } + + $this->routes[$name] = $route; + } + + /** + * Returns the array of routes. + * + * @return array An array of routes + */ + public function all() + { + $routes = array(); + foreach ($this->routes as $name => $route) { + if ($route instanceof RouteCollection) { + $routes = array_merge($routes, $route->all()); + } else { + $routes[$name] = $route; + } + } + + return $routes; + } + + /** + * Gets a route by name. + * + * @param string $name The route name + * + * @return Route $route A Route instance + */ + public function get($name) + { + // get the latest defined route + foreach (array_reverse($this->routes) as $routes) { + if (!$routes instanceof RouteCollection) { + continue; + } + + if (null !== $route = $routes->get($name)) { + return $route; + } + } + + if (isset($this->routes[$name])) { + return $this->routes[$name]; + } + } + + /** + * Removes a route by name. + * + * @param string $name The route name + */ + public function remove($name) + { + if (isset($this->routes[$name])) { + unset($this->routes[$name]); + } + + foreach ($this->routes as $routes) { + if ($routes instanceof RouteCollection) { + $routes->remove($name); + } + } + } + + /** + * Adds a route collection to the current set of routes (at the end of the current set). + * + * @param RouteCollection $collection A RouteCollection instance + * @param string $prefix An optional prefix to add before each pattern of the route collection + * + * @api + */ + public function addCollection(RouteCollection $collection, $prefix = '') + { + $collection->setParent($this); + $collection->addPrefix($prefix); + + // remove all routes with the same name in all existing collections + foreach (array_keys($collection->all()) as $name) { + $this->remove($name); + } + + $this->routes[] = $collection; + } + + /** + * Adds a prefix to all routes in the current set. + * + * @param string $prefix An optional prefix to add before each pattern of the route collection + * + * @api + */ + public function addPrefix($prefix) + { + // a prefix must not end with a slash + $prefix = rtrim($prefix, '/'); + + if (!$prefix) { + return; + } + + // a prefix must start with a slash + if ('/' !== $prefix[0]) { + $prefix = '/'.$prefix; + } + + $this->prefix = $prefix.$this->prefix; + + foreach ($this->routes as $name => $route) { + if ($route instanceof RouteCollection) { + $route->addPrefix($prefix); + } else { + $route->setPattern($prefix.$route->getPattern()); + } + } + } + + public function getPrefix() + { + return $this->prefix; + } + + /** + * Returns an array of resources loaded to build this collection. + * + * @return ResourceInterface[] An array of resources + */ + public function getResources() + { + $resources = $this->resources; + foreach ($this as $routes) { + if ($routes instanceof RouteCollection) { + $resources = array_merge($resources, $routes->getResources()); + } + } + + return array_unique($resources); + } + + /** + * Adds a resource for this collection. + * + * @param ResourceInterface $resource A resource instance + */ + public function addResource(ResourceInterface $resource) + { + $this->resources[] = $resource; + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompiler.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompiler.php new file mode 100644 index 0000000000..72ececc5ca --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompiler.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * RouteCompiler compiles Route instances to CompiledRoute instances. + * + * @author Fabien Potencier + */ +class RouteCompiler implements RouteCompilerInterface +{ + /** + * Compiles the current route instance. + * + * @param Route $route A Route instance + * + * @return CompiledRoute A CompiledRoute instance + */ + public function compile(Route $route) + { + $pattern = $route->getPattern(); + $len = strlen($pattern); + $tokens = array(); + $variables = array(); + $pos = 0; + preg_match_all('#.\{([\w\d_]+)\}#', $pattern, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); + foreach ($matches as $match) { + if ($text = substr($pattern, $pos, $match[0][1] - $pos)) { + $tokens[] = array('text', $text); + } + $seps = array($pattern[$pos]); + $pos = $match[0][1] + strlen($match[0][0]); + $var = $match[1][0]; + + if ($req = $route->getRequirement($var)) { + $regexp = $req; + } else { + if ($pos !== $len) { + $seps[] = $pattern[$pos]; + } + $regexp = sprintf('[^%s]+?', preg_quote(implode('', array_unique($seps)), '#')); + } + + $tokens[] = array('variable', $match[0][0][0], $regexp, $var); + + if (in_array($var, $variables)) { + throw new \LogicException(sprintf('Route pattern "%s" cannot reference variable name "%s" more than once.', $route->getPattern(), $var)); + } + + $variables[] = $var; + } + + if ($pos < $len) { + $tokens[] = array('text', substr($pattern, $pos)); + } + + // find the first optional token + $firstOptional = INF; + for ($i = count($tokens) - 1; $i >= 0; $i--) { + $token = $tokens[$i]; + if ('variable' === $token[0] && $route->hasDefault($token[3])) { + $firstOptional = $i; + } else { + break; + } + } + + // compute the matching regexp + $regexp = ''; + for ($i = 0, $nbToken = count($tokens); $i < $nbToken; $i++) { + $regexp .= $this->computeRegexp($tokens, $i, $firstOptional); + } + + return new CompiledRoute( + $route, + 'text' === $tokens[0][0] ? $tokens[0][1] : '', + sprintf("#^%s$#s", $regexp), + array_reverse($tokens), + $variables + ); + } + + /** + * Computes the regexp used to match the token. + * + * @param array $tokens The route tokens + * @param integer $index The index of the current token + * @param integer $firstOptional The index of the first optional token + * + * @return string The regexp + */ + private function computeRegexp(array $tokens, $index, $firstOptional) + { + $token = $tokens[$index]; + if ('text' === $token[0]) { + // Text tokens + return preg_quote($token[1], '#'); + } else { + // Variable tokens + if (0 === $index && 0 === $firstOptional && 1 == count($tokens)) { + // When the only token is an optional variable token, the separator is required + return sprintf('%s(?P<%s>%s)?', preg_quote($token[1], '#'), $token[3], $token[2]); + } else { + $nbTokens = count($tokens); + $regexp = sprintf('%s(?P<%s>%s)', preg_quote($token[1], '#'), $token[3], $token[2]); + if ($index >= $firstOptional) { + // Enclose each optional tokens in a subpattern to make it optional + $regexp = "(?:$regexp"; + if ($nbTokens - 1 == $index) { + // Close the optional subpatterns + $regexp .= str_repeat(")?", $nbTokens - $firstOptional); + } + } + + return $regexp; + } + } + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php new file mode 100644 index 0000000000..5c988adafb --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RouteCompilerInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +/** + * RouteCompilerInterface is the interface that all RouteCompiler classes must implements. + * + * @author Fabien Potencier + */ +interface RouteCompilerInterface +{ + /** + * Compiles the current route instance. + * + * @param Route $route A Route instance + * + * @return CompiledRoute A CompiledRoute instance + */ + public function compile(Route $route); +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/Router.php b/3rdparty/symfony/routing/Symfony/Component/Routing/Router.php new file mode 100644 index 0000000000..eadb2231e1 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/Router.php @@ -0,0 +1,263 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Config\ConfigCache; + +/** + * The Router class is an example of the integration of all pieces of the + * routing system for easier use. + * + * @author Fabien Potencier + */ +class Router implements RouterInterface +{ + protected $matcher; + protected $generator; + protected $defaults; + protected $context; + protected $loader; + protected $collection; + protected $resource; + protected $options; + + /** + * Constructor. + * + * @param LoaderInterface $loader A LoaderInterface instance + * @param mixed $resource The main resource to load + * @param array $options An array of options + * @param RequestContext $context The context + * @param array $defaults The default values + */ + public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, array $defaults = array()) + { + $this->loader = $loader; + $this->resource = $resource; + $this->context = null === $context ? new RequestContext() : $context; + $this->defaults = $defaults; + $this->setOptions($options); + } + + /** + * Sets options. + * + * Available options: + * + * * cache_dir: The cache directory (or null to disable caching) + * * debug: Whether to enable debugging or not (false by default) + * * resource_type: Type hint for the main resource (optional) + * + * @param array $options An array of options + * + * @throws \InvalidArgumentException When unsupported option is provided + */ + public function setOptions(array $options) + { + $this->options = array( + 'cache_dir' => null, + 'debug' => false, + 'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', + 'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator', + 'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper', + 'generator_cache_class' => 'ProjectUrlGenerator', + 'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', + 'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher', + 'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper', + 'matcher_cache_class' => 'ProjectUrlMatcher', + 'resource_type' => null, + ); + + // check option names and live merge, if errors are encountered Exception will be thrown + $invalid = array(); + $isInvalid = false; + foreach ($options as $key => $value) { + if (array_key_exists($key, $this->options)) { + $this->options[$key] = $value; + } else { + $isInvalid = true; + $invalid[] = $key; + } + } + + if ($isInvalid) { + throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('\', \'', $invalid))); + } + } + + /** + * Sets an option. + * + * @param string $key The key + * @param mixed $value The value + * + * @throws \InvalidArgumentException + */ + public function setOption($key, $value) + { + if (!array_key_exists($key, $this->options)) { + throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); + } + + $this->options[$key] = $value; + } + + /** + * Gets an option value. + * + * @param string $key The key + * + * @return mixed The value + * + * @throws \InvalidArgumentException + */ + public function getOption($key) + { + if (!array_key_exists($key, $this->options)) { + throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key)); + } + + return $this->options[$key]; + } + + /** + * Gets the RouteCollection instance associated with this Router. + * + * @return RouteCollection A RouteCollection instance + */ + public function getRouteCollection() + { + if (null === $this->collection) { + $this->collection = $this->loader->load($this->resource, $this->options['resource_type']); + } + + return $this->collection; + } + + /** + * Sets the request context. + * + * @param RequestContext $context The context + */ + public function setContext(RequestContext $context) + { + $this->context = $context; + + $this->getMatcher()->setContext($context); + $this->getGenerator()->setContext($context); + } + + /** + * Gets the request context. + * + * @return RequestContext The context + */ + public function getContext() + { + return $this->context; + } + + /** + * Generates a URL from the given parameters. + * + * @param string $name The name of the route + * @param mixed $parameters An array of parameters + * @param Boolean $absolute Whether to generate an absolute URL + * + * @return string The generated URL + */ + public function generate($name, $parameters = array(), $absolute = false) + { + return $this->getGenerator()->generate($name, $parameters, $absolute); + } + + /** + * Tries to match a URL with a set of routes. + * + * Returns false if no route matches the URL. + * + * @param string $url URL to be parsed + * + * @return array|false An array of parameters or false if no route matches + */ + public function match($url) + { + return $this->getMatcher()->match($url); + } + + /** + * Gets the UrlMatcher instance associated with this Router. + * + * @return UrlMatcherInterface A UrlMatcherInterface instance + */ + public function getMatcher() + { + if (null !== $this->matcher) { + return $this->matcher; + } + + if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) { + return $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context, $this->defaults); + } + + $class = $this->options['matcher_cache_class']; + $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']); + if (!$cache->isFresh($class)) { + $dumper = new $this->options['matcher_dumper_class']($this->getRouteCollection()); + + $options = array( + 'class' => $class, + 'base_class' => $this->options['matcher_base_class'], + ); + + $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); + } + + require_once $cache; + + return $this->matcher = new $class($this->context, $this->defaults); + } + + /** + * Gets the UrlGenerator instance associated with this Router. + * + * @return UrlGeneratorInterface A UrlGeneratorInterface instance + */ + public function getGenerator() + { + if (null !== $this->generator) { + return $this->generator; + } + + if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) { + return $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->defaults); + } + + $class = $this->options['generator_cache_class']; + $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']); + if (!$cache->isFresh($class)) { + $dumper = new $this->options['generator_dumper_class']($this->getRouteCollection()); + + $options = array( + 'class' => $class, + 'base_class' => $this->options['generator_base_class'], + ); + + $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources()); + } + + require_once $cache; + + return $this->generator = new $class($this->context, $this->defaults); + } +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/RouterInterface.php b/3rdparty/symfony/routing/Symfony/Component/Routing/RouterInterface.php new file mode 100644 index 0000000000..961342bf09 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/RouterInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Routing; + +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\Matcher\UrlMatcherInterface; + +/** + * RouterInterface is the interface that all Router classes must implements. + * + * This interface is the concatenation of UrlMatcherInterface and UrlGeneratorInterface. + * + * @author Fabien Potencier + */ +interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface +{ +} diff --git a/3rdparty/symfony/routing/Symfony/Component/Routing/composer.json b/3rdparty/symfony/routing/Symfony/Component/Routing/composer.json new file mode 100644 index 0000000000..8d29398b24 --- /dev/null +++ b/3rdparty/symfony/routing/Symfony/Component/Routing/composer.json @@ -0,0 +1,29 @@ +{ + "name": "symfony/routing", + "type": "library", + "description": "Symfony Routing Component", + "keywords": [], + "homepage": "http://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.2" + }, + "suggest": { + "symfony/config": "self.version", + "symfony/yaml": "self.version" + }, + "autoload": { + "psr-0": { "Symfony\\Component\\Routing": "" } + }, + "target-dir": "Symfony/Component/Routing" +} diff --git a/composer.json b/composer.json deleted file mode 100644 index 7916b15cb9..0000000000 --- a/composer.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "description": "ownCloud gives you universal access to your files/contacts/calendar through a web interface or WebDAV.", - "homepage": "http://owncloud.org", - "license": "AGPL-3.0+", - "support": { - "email": "owncloud@kde.org", - "irc": "irc://irc.freenode.org/owncloud", - "forum": "http://forum.owncloud.org/", - "issues": "https://github.com/owncloud/core/issues" - }, - "require": { - "php": ">=5.3.2", - "symfony/routing": "2.0.*" - }, - "config": { - "vendor-dir": "3rdparty" - } -} From 56e9ce44c3ac18d6183a8959c690c6e3269bc79e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 17:02:05 +0200 Subject: [PATCH 068/262] add a way to recalucale the size of a folder in the cache --- lib/files/cache/cache.php | 25 +++++++++++++++++++++++++ tests/lib/files/cache/cache.php | 11 +++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 6604525477..734890329a 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -308,6 +308,31 @@ class Cache { return $result->fetchAll(); } + /** + * get the size of a folder and set it in the cache + * + * @param string $path + * @return int + */ + public function calculateFolderSize($path) { + $id = $this->getId($path); + $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); + $result = $query->execute(array($id, $this->storageId)); + $totalSize = 0; + while ($row = $result->fetchRow()) { + $size = (int)$row['size']; + if ($size === -1) { + $totalSize = -1; + break; + } else { + $totalSize += $size; + } + } + + $this->update($id, array('size' => $totalSize)); + return $totalSize; + } + /** * get all file ids on the files on the storage * diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 5a8d79b902..57a154d295 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -99,6 +99,17 @@ class Cache extends \UnitTestCase { $this->assertEqual($value, $cachedData[$name]); } } + + $file4 = 'folder/unkownSize'; + $fileData['unkownSize'] = array('size' => -1, 'mtime' => 25, 'mimetype' => 'foo/file'); + $this->cache->put($file4, $fileData['unkownSize']); + + $this->assertEquals(-1, $this->cache->calculateFolderSize($file1)); + + $fileData['unkownSize'] = array('size' => 5, 'mtime' => 25, 'mimetype' => 'foo/file'); + $this->cache->put($file4, $fileData['unkownSize']); + + $this->assertEquals(1025, $this->cache->calculateFolderSize($file1)); } function testStatus() { From 79d0ac21ccc65d12b6643ab525d45977644873e8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 27 Oct 2012 18:05:40 +0200 Subject: [PATCH 069/262] delete child entries when a folder gets removed from cache --- lib/files/cache/cache.php | 12 +++++++++--- lib/files/cache/scanner.php | 16 ++++++++++++++++ tests/lib/files/cache/cache.php | 6 +++++- tests/lib/files/cache/scanner.php | 9 +++++++-- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 734890329a..cba48e4dbe 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -231,9 +231,15 @@ class Cache { * @param string $file */ public function remove($file) { - $pathHash = md5($file); - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $query->execute(array($this->storageId, $pathHash)); + $entry = $this->get($file); + if ($entry['mimetype'] === 'httpd/unix-directory') { + $children = $this->getFolderContents($file); + foreach($children as $child){ + $this->remove($child['path']); + } + } + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + $query->execute(array($entry['fileid'])); } /** diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 0adde1d354..7062888d74 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -107,4 +107,20 @@ class Scanner { } return $size; } + + /** + * update the folder size and the size of all parent folders + * + * @param $path + */ + public function correctFolderSize($path) { + $this->cache->calculateFolderSize($path); + if ($path !== '') { + $parent = dirname($path); + if ($parent === '.') { + $parent = ''; + } + $this->correctFolderSize($parent); + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 57a154d295..4f22e9bd1d 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -82,7 +82,7 @@ class Cache extends \UnitTestCase { $file1 = 'folder'; $file2 = 'folder/bar'; $file3 = 'folder/foo'; - $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/folder'); + $data1 = array('size' => 100, 'mtime' => 50, 'mimetype' => 'httpd/unix-directory'); $fileData = array(); $fileData['bar'] = array('size' => 1000, 'mtime' => 20, 'mimetype' => 'foo/file'); $fileData['foo'] = array('size' => 20, 'mtime' => 25, 'mimetype' => 'foo/file'); @@ -110,6 +110,10 @@ class Cache extends \UnitTestCase { $this->cache->put($file4, $fileData['unkownSize']); $this->assertEquals(1025, $this->cache->calculateFolderSize($file1)); + + $this->cache->remove('folder'); + $this->assertFalse($this->cache->inCache('folder/foo')); + $this->assertFalse($this->cache->inCache('folder/bar')); } function testStatus() { diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 34fefc784d..34d38c4273 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -89,14 +89,19 @@ class Scanner extends \UnitTestCase { $cachedDataFolder = $this->cache->get(''); $cachedDataFolder2 = $this->cache->get('folder'); - $this->assertEqual($cachedDataFolder['size'], -1); - $this->assertEqual($cachedDataFolder2['size'], -1); + $this->assertEqual(-1, $cachedDataFolder['size']); + $this->assertEqual(-1, $cachedDataFolder2['size']); $this->scanner->scan('folder', \OC\Files\Cache\Scanner::SCAN_SHALLOW); $cachedDataFolder2 = $this->cache->get('folder'); $this->assertNotEqual($cachedDataFolder2['size'], -1); + + $this->scanner->correctFolderSize('folder'); + + $cachedDataFolder = $this->cache->get(''); + $this->assertNotEqual($cachedDataFolder['size'], -1); } function setUp() { From fba7be1194fd31da2cb71c56d0cd8e6ab1c1ff49 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 28 Oct 2012 11:26:31 +0100 Subject: [PATCH 070/262] add filesystem watcher to detect updates --- lib/files/cache/cache.php | 8 ++- lib/files/cache/watcher.php | 70 +++++++++++++++++++++++++ tests/lib/files/cache/watcher.php | 86 +++++++++++++++++++++++++++++++ tests/lib/files/view.php | 2 + 4 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 lib/files/cache/watcher.php create mode 100644 tests/lib/files/cache/watcher.php diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index cba48e4dbe..138a5e6e63 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -234,7 +234,7 @@ class Cache { $entry = $this->get($file); if ($entry['mimetype'] === 'httpd/unix-directory') { $children = $this->getFolderContents($file); - foreach($children as $child){ + foreach ($children as $child) { $this->remove($child['path']); } } @@ -325,7 +325,9 @@ class Cache { $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); $result = $query->execute(array($id, $this->storageId)); $totalSize = 0; + $hasChilds = 0; while ($row = $result->fetchRow()) { + $hasChilds = true; $size = (int)$row['size']; if ($size === -1) { $totalSize = -1; @@ -335,7 +337,9 @@ class Cache { } } - $this->update($id, array('size' => $totalSize)); + if ($hasChilds) { + $this->update($id, array('size' => $totalSize)); + } return $totalSize; } diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php new file mode 100644 index 0000000000..f04ca9b465 --- /dev/null +++ b/lib/files/cache/watcher.php @@ -0,0 +1,70 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +/** + * check the storage backends for updates and change the cache accordingly + */ +class Watcher { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var Cache $cache + */ + private $cache; + + /** + * @var Scanner $scanner; + */ + private $scanner; + + /** + * @param \OC\Files\Storage\Storage $storage + */ + public function __construct(\OC\Files\Storage\Storage $storage) { + $this->storage = $storage; + $this->cache = $storage->getCache(); + $this->scanner = $storage->getScanner(); + } + + /** + * check $path for updates + * + * @param string $path + */ + public function checkUpdate($path) { + $cachedEntry = $this->cache->get($path); + if ($this->storage->hasUpdated($path, $cachedEntry['mtime'])) { + if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + $this->scanner->scan($path, Scanner::SCAN_SHALLOW); + $this->cleanFolder($path); + } else { + $this->scanner->scanFile($path); + } + $this->scanner->correctFolderSize($path); + } + } + + /** + * remove deleted files in $path from the cache + * + * @param string $path + */ + public function cleanFolder($path) { + $cachedContent = $this->cache->getFolderContents($path); + foreach ($cachedContent as $entry) { + if (!$this->storage->file_exists($entry['path'])) { + $this->cache->remove($entry['path']); + } + } + } +} diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php new file mode 100644 index 0000000000..a7076d9b0b --- /dev/null +++ b/tests/lib/files/cache/watcher.php @@ -0,0 +1,86 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +class Watcher extends \PHPUnit_Framework_TestCase { + + /** + * @var \OC\Files\Storage\Storage[] $storages; + */ + private $storages = array(); + + public function setUp() { + \OC\Files\Filesystem::clearMounts(); + } + + public function tearDown() { + foreach ($this->storages as $storage) { + $cache = $storage->getCache(); + $ids = $cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $cache->clear(); + } + } + + function testWatcher() { + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('', array('mtime' => 10)); + + $this->assertTrue($cache->inCache('folder/bar.txt')); + $this->assertTrue($cache->inCache('folder/bar2.txt')); + + $this->assertFalse($cache->inCache('bar.test')); + $storage->file_put_contents('bar.test', 'foo'); + $updater->checkUpdate(''); + $this->assertTrue($cache->inCache('bar.test')); + $cachedData = $cache->get('bar.test'); + $this->assertEquals(3, $cachedData['size']); + + $cache->put('bar.test', array('mtime' => 10)); + $storage->file_put_contents('bar.test', 'test data'); + + $updater->checkUpdate('bar.test'); + $cachedData = $cache->get('bar.test'); + $this->assertEquals(9, $cachedData['size']); + + $cache->put('folder', array('mtime' => 10)); + + $storage->unlink('folder/bar2.txt'); + $updater->checkUpdate('folder'); + + $this->assertTrue($cache->inCache('folder/bar.txt')); + $this->assertFalse($cache->inCache('folder/bar2.txt')); + } + + /** + * @param bool $scan + * @return \OC\Files\Storage\Storage + */ + private function getTestStorage($scan = true) { + $storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $storage->mkdir('folder'); + $storage->file_put_contents('foo.txt', $textData); + $storage->file_put_contents('foo.png', $imgData); + $storage->file_put_contents('folder/bar.txt', $textData); + $storage->file_put_contents('folder/bar2.txt', $textData); + + if ($scan) { + $scanner = $storage->getScanner(); + $scanner->scan(''); + } + $this->storages[] = $storage; + return $storage; + } +} diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 5144fb1caa..8ff03963e4 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -20,6 +20,8 @@ class View extends \PHPUnit_Framework_TestCase { public function tearDown() { foreach ($this->storages as $storage) { $cache = $storage->getCache(); + $ids = $cache->getAll(); + \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } From b07672821bcdc1ce31e169d691cf9a94ad5fad21 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 28 Oct 2012 11:43:45 +0100 Subject: [PATCH 071/262] check for changes when using the cache api --- lib/files/view.php | 6 ++++++ tests/lib/files/view.php | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/files/view.php b/lib/files/view.php index 0f9a5feb5d..c5e470b438 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -672,6 +672,9 @@ class View { if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); } $data = $cache->get($internalPath); @@ -711,6 +714,9 @@ class View { if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); } $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 8ff03963e4..fa562cb15c 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -146,6 +146,23 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(3, count($folderView->searchByMime('text'))); } + function testWatcher() { + $storage1 = $this->getTestStorage(); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + + $rootView = new \OC\Files\View(''); + + $cachedData = $rootView->getFileInfo('foo.txt'); + $this->assertEquals(16, $cachedData['size']); + + $rootView->putFileInfo('foo.txt', array('mtime' => 10)); + $storage1->file_put_contents('foo.txt', 'foo'); + clearstatcache(); + + $cachedData = $rootView->getFileInfo('foo.txt'); + $this->assertEquals(3, $cachedData['size']); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage From 8a6bb7965d96b1c4297da8f5dbc9644fec7aeb0f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 2 Nov 2012 22:25:33 +0100 Subject: [PATCH 072/262] add Cache::move --- lib/files/cache/cache.php | 29 +++++++++++++++++++++++++++-- tests/lib/files/cache/cache.php | 26 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 138a5e6e63..9d13b56104 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -242,6 +242,32 @@ class Cache { $query->execute(array($entry['fileid'])); } + /** + * Move a file or folder in the cache + * + * @param string $source + * @param string $target + */ + public function move($source, $target) { + $sourceId = $this->getId($source); + $newParentId = $this->getParentId($target); + + //find all child entries + $query = \OC_DB::prepare('SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `path` LIKE ?'); + $result = $query->execute(array($source . '/%')); + $childEntries = $result->fetchAll(); + $sourceLength = strlen($source); + $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ? WHERE `fileid` = ?'); + + foreach ($childEntries as $child) { + $targetPath = $target . substr($child['path'], $sourceLength); + $query->execute(array($targetPath, md5($targetPath), $child['fileid'])); + } + + $query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ?, `parent` =? WHERE `fileid` = ?'); + $query->execute(array($target, md5($target), $newParentId, $sourceId)); + } + /** * remove all entries for files that are stored on the storage from the cache */ @@ -296,8 +322,7 @@ class Cache { /** * search for files by mimetype * - * @param string $part1 - * @param string $part2 + * @param string $mimetype * @return array */ public function searchByMime($mimetype) { diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 4f22e9bd1d..9c469aa937 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -149,6 +149,32 @@ class Cache extends \UnitTestCase { $this->assertEquals(2, count($this->cache->searchByMime('foo/file'))); } + function testMove() { + $file1 = 'folder'; + $file2 = 'folder/bar'; + $file3 = 'folder/foo'; + $file4 = 'folder/foo/1'; + $file5 = 'folder/foo/2'; + $data = array('size' => 100, 'mtime' => 50, 'mimetype' => 'foo/bar'); + + $this->cache->put($file1, $data); + $this->cache->put($file2, $data); + $this->cache->put($file3, $data); + $this->cache->put($file4, $data); + $this->cache->put($file5, $data); + + $this->cache->move('folder/foo', 'folder/foobar'); + + $this->assertFalse($this->cache->inCache('folder/foo')); + $this->assertFalse($this->cache->inCache('folder/foo/1')); + $this->assertFalse($this->cache->inCache('folder/foo/2')); + + $this->assertTrue($this->cache->inCache('folder/bar')); + $this->assertTrue($this->cache->inCache('folder/foobar')); + $this->assertTrue($this->cache->inCache('folder/foobar/1')); + $this->assertTrue($this->cache->inCache('folder/foobar/2')); + } + public function tearDown() { $this->cache->clear(); } From 72c38686449a8887d8441377a11f0bfc910bc31f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:42:26 +0100 Subject: [PATCH 073/262] add resolvePath to filesystem view api --- lib/files/view.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/files/view.php b/lib/files/view.php index 709e374d86..e3f9b762f7 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -101,6 +101,16 @@ class View { return Filesystem::getMountPoint($this->getAbsolutePath($path)); } + /** + * resolve a path to a storage and internal path + * + * @param string $path + * @return array consisting of the storage and the internal path + */ + public function resolvePath($path) { + return Filesystem::resolvePath($this->getAbsolutePath($path)); + } + /** * return the path to a local version of the file * we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed From 706bb3ccd654f76c0a6c5b7874fcc1e288b13f54 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:47:00 +0100 Subject: [PATCH 074/262] move ETag generation to storage backends --- lib/connector/sabre/node.php | 16 +--------------- lib/files/filesystem.php | 10 ++++++++++ lib/files/storage/common.php | 16 ++++++++++++++++ lib/files/storage/storage.php | 8 ++++++++ lib/files/view.php | 15 +++++++++++++++ 5 files changed, 50 insertions(+), 15 deletions(-) diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index ebc9e53962..d0ab0c2498 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -210,27 +210,13 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr return $props; } - /** - * Creates a ETag for this path. - * @param string $path Path of the file - * @return string|null Returns null if the ETag can not effectively be determined - */ - static protected function createETag($path) { - if(self::$ETagFunction) { - $hash = call_user_func(self::$ETagFunction, $path); - return $hash; - }else{ - return uniqid('', true); - } - } - /** * Returns the ETag surrounded by double-quotes for this path. * @param string $path Path of the file * @return string|null Returns null if the ETag can not effectively be determined */ static public function getETagPropertyForPath($path) { - $tag = self::createETag($path); + $tag = \OC\Files\Filesystem::getETag($path); if (empty($tag)) { return null; } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 76a188e412..ed2814211f 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -654,6 +654,16 @@ class Filesystem { public static function getDirectoryContent($directory, $mimetype_filter = '') { return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter); } + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + static public function getETag($path){ + return self::$defaultInstance->getETag($path); + } } \OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index e22264d0da..f471752d1f 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -267,4 +267,20 @@ abstract class Common implements \OC\Files\Storage\Storage { public function getOwner($path) { return \OC_User::getUser(); } + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + public function getETag($path){ + $ETagFunction = \OC_Connector_Sabre_Node::$ETagFunction; + if($ETagFunction) { + $hash = call_user_func($ETagFunction, $path); + return $hash; + }else{ + return uniqid('', true); + } + } } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 1f5c935629..bb1ba16984 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -63,4 +63,12 @@ interface Storage{ public function getScanner(); public function getOwner($path); + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + public function getETag($path); } diff --git a/lib/files/view.php b/lib/files/view.php index e3f9b762f7..a54c3ee356 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -866,4 +866,19 @@ class View { return $files; } + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + public function getETag($path){ + /** + * @var Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = $this->resolvePath($path); + return $storage->getETag($internalPath); + } } From e7bed5ddabea5a3841d4a08082badaec025ed242 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 17:59:08 +0100 Subject: [PATCH 075/262] allow creating Cache objects with only the storage id instead of the whole storage object --- lib/files/cache/cache.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 9d13b56104..dba026a611 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -19,24 +19,25 @@ class Cache { const SHALLOW = 2; //folder in cache, but not all child files are completely scanned const COMPLETE = 3; - /** - * @var \OC\Files\Storage\Storage - */ - private $storage; - /** * @var array partial data for the cache */ private $partial = array(); + /** + * @var string + */ private $storageId; /** - * @param \OC\Files\Storage\Storage $storage + * @param \OC\Files\Storage\Storage|string $storage */ - public function __construct(\OC\Files\Storage\Storage $storage) { - $this->storage = $storage; - $this->storageId = $storage->getId(); + public function __construct($storage) { + if($storage instanceof \OC\Files\Storage\Storage){ + $this->storageId = $storage->getId(); + }else{ + $this->storageId = $storage; + } } /** From 3f644fe70c8451ab1ab877c4dd97f34366548b70 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 18:07:30 +0100 Subject: [PATCH 076/262] fix calculateFolderSize for non existing files --- lib/files/cache/cache.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index dba026a611..83d3585bb5 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -348,6 +348,9 @@ class Cache { */ public function calculateFolderSize($path) { $id = $this->getId($path); + if($id === -1){ + return 0; + } $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); $result = $query->execute(array($id, $this->storageId)); $totalSize = 0; From 15b8a3f98757f220db190c1e9489d5888b2b1015 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 18:10:54 +0100 Subject: [PATCH 077/262] move correctFolderSize from Scanner to Cache --- lib/files/cache/cache.php | 16 ++++++++++++++++ lib/files/cache/scanner.php | 16 ---------------- lib/files/cache/watcher.php | 2 +- tests/lib/files/cache/scanner.php | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 83d3585bb5..7c6bba4fad 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -340,6 +340,22 @@ class Cache { return $result->fetchAll(); } + /** + * update the folder size and the size of all parent folders + * + * @param $path + */ + public function correctFolderSize($path) { + $this->calculateFolderSize($path); + if ($path !== '') { + $parent = dirname($path); + if ($parent === '.') { + $parent = ''; + } + $this->correctFolderSize($parent); + } + } + /** * get the size of a folder and set it in the cache * diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 7062888d74..0adde1d354 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -107,20 +107,4 @@ class Scanner { } return $size; } - - /** - * update the folder size and the size of all parent folders - * - * @param $path - */ - public function correctFolderSize($path) { - $this->cache->calculateFolderSize($path); - if ($path !== '') { - $parent = dirname($path); - if ($parent === '.') { - $parent = ''; - } - $this->correctFolderSize($parent); - } - } } diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php index f04ca9b465..d6039d9945 100644 --- a/lib/files/cache/watcher.php +++ b/lib/files/cache/watcher.php @@ -50,7 +50,7 @@ class Watcher { } else { $this->scanner->scanFile($path); } - $this->scanner->correctFolderSize($path); + $this->cache->correctFolderSize($path); } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index 34d38c4273..f784a82dad 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -98,7 +98,7 @@ class Scanner extends \UnitTestCase { $this->assertNotEqual($cachedDataFolder2['size'], -1); - $this->scanner->correctFolderSize('folder'); + $this->cache->correctFolderSize('folder'); $cachedDataFolder = $this->cache->get(''); $this->assertNotEqual($cachedDataFolder['size'], -1); From 5a173b901f90dba3465847cde4477be9994a1341 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 20:47:40 +0100 Subject: [PATCH 078/262] fix Scanner->scan setting the filesize to 0 for files --- lib/files/cache/scanner.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 0adde1d354..eb947a2d53 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -101,9 +101,9 @@ class Scanner { } } } - } - if ($size !== -1) { - $this->cache->put($path, array('size' => $size)); + if ($size !== -1) { + $this->cache->put($path, array('size' => $size)); + } } return $size; } From fedff3eafe73a3eafbc1bc7af364297e8135d086 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:12:40 +0100 Subject: [PATCH 079/262] add cache updater --- lib/files/cache/updater.php | 71 ++++++++++++++++++ tests/lib/files/cache/updater.php | 116 ++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 lib/files/cache/updater.php create mode 100644 tests/lib/files/cache/updater.php diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php new file mode 100644 index 0000000000..fb9783023e --- /dev/null +++ b/lib/files/cache/updater.php @@ -0,0 +1,71 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +/** + * listen to filesystem hooks and change the cache accordingly + */ +class Updater { + + /** + * resolve a path to a storage and internal path + * + * @param string $path + * @return array consisting of the storage and the internal path + */ + static public function resolvePath($path) { + $view = \OC\Files\Filesystem::getView(); + return $view->resolvePath($path); + } + + static public function writeUpdate($path) { + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = self::resolvePath($path); + $cache = new Cache($storage); + $scanner = new Scanner($storage); + $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); + $cache->correctFolderSize($internalPath); + } + + static public function deleteUpdate($path) { + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = self::resolvePath($path); + $cache = new Cache($storage); + $cache->remove($internalPath); + $cache->correctFolderSize($internalPath); + } + + /** + * @param array $params + */ + static public function writeHook($params) { + self::writeUpdate($params['path']); + } + + /** + * @param array $params + */ + static public function renameHook($params) { + self::deleteUpdate($params['oldpath']); + self::writeUpdate($params['newpath']); + } + + /** + * @param array $params + */ + static public function deleteHook($params) { + self::deleteUpdate($params['path']); + } +} diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php new file mode 100644 index 0000000000..8059418dc1 --- /dev/null +++ b/tests/lib/files/cache/updater.php @@ -0,0 +1,116 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\Files\Cache; + +use \OC\Files\Filesystem as Filesystem; + +class Updater extends \PHPUnit_Framework_TestCase { + /** + * @var \OC\Files\Storage\Storage $storage + */ + private $storage; + + /** + * @var \OC\Files\Cache\Scanner $scanner + */ + private $scanner; + + /** + * @var \OC\Files\Cache\Cache $cache + */ + private $cache; + + private static $user; + + public function setUp() { + $this->storage = new \OC\Files\Storage\Temporary(array()); + $textData = "dummy file data\n"; + $imgData = file_get_contents(\OC::$SERVERROOT . '/core/img/logo.png'); + $this->storage->mkdir('folder'); + $this->storage->file_put_contents('foo.txt', $textData); + $this->storage->file_put_contents('foo.png', $imgData); + $this->storage->file_put_contents('folder/bar.txt', $textData); + $this->storage->file_put_contents('folder/bar2.txt', $textData); + + $this->scanner = $this->storage->getScanner(); + $this->scanner->scan(''); + $this->cache = $this->storage->getCache(); + + if (!self::$user) { + if (!\OC\Files\Filesystem::getView()) { + self::$user = uniqid(); + \OC\Files\Filesystem::init('/' . self::$user . '/files'); + } else { + self::$user = \OC_User::getUser(); + } + } + + Filesystem::clearMounts(); + Filesystem::mount($this->storage, array(), '/' . self::$user . '/files'); + + \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); + \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); + \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); + + } + + public function tearDown() { + $this->cache->clear(); + Filesystem::tearDown(); + } + + public function testWrite() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + Filesystem::file_put_contents('foo.txt', 'asd'); + $cachedData = $this->cache->get('foo.txt'); + $this->assertEquals(3, $cachedData['size']); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); + + $this->assertFalse($this->cache->inCache('bar.txt')); + Filesystem::file_put_contents('bar.txt', 'asd'); + $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get('bar.txt'); + $this->assertEquals(3, $cachedData['size']); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); + } + + public function testDelete() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + $this->assertTrue($this->cache->inCache('foo.txt')); + Filesystem::unlink('foo.txt', 'asd'); + $this->assertFalse($this->cache->inCache('foo.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); + } + + public function testRename() { + $textSize = strlen("dummy file data\n"); + $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + + $this->assertTrue($this->cache->inCache('foo.txt')); + $this->assertFalse($this->cache->inCache('bar.txt')); + Filesystem::rename('foo.txt', 'bar.txt'); + $this->assertFalse($this->cache->inCache('foo.txt')); + $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + } +} From d4858527c2fae4b58c5a9bc1c3aae9ada0ee7b24 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:35:30 +0100 Subject: [PATCH 080/262] fix rename parameter order --- apps/files/ajax/rename.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/files/ajax/rename.php b/apps/files/ajax/rename.php index a2b9b8de25..470ee635a2 100644 --- a/apps/files/ajax/rename.php +++ b/apps/files/ajax/rename.php @@ -11,9 +11,9 @@ $dir = stripslashes($_GET["dir"]); $file = stripslashes($_GET["file"]); $newname = stripslashes($_GET["newname"]); -if (OC_User::isLoggedIn() && ($dir != '' || $file != 'Shared')) { - $targetFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file); - $sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname); +if (($dir != '' || $file != 'Shared')) { + $targetFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname); + $sourceFile = \OC\Files\Filesystem::normalizePath($dir . '/' . $file); if(\OC\Files\Filesystem::rename($sourceFile, $targetFile)) { OCP\JSON::success(array("data" => array( "dir" => $dir, "file" => $file, "newname" => $newname ))); } else { From 46071fed80c7375edf4788578776a6b313b6dca3 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:35:40 +0100 Subject: [PATCH 081/262] fix quota proxy --- lib/fileproxy/quota.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index b359b9ae02..a8219191bf 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -22,7 +22,7 @@ */ /** - * user quota managment + * user quota management */ class OC_FileProxy_Quota extends OC_FileProxy{ @@ -39,10 +39,8 @@ class OC_FileProxy_Quota extends OC_FileProxy{ return $this->userQuota[$user]; } $userQuota=OC_Preferences::getValue($user, 'files', 'quota', 'default'); - $userQuota=OC_Preferences::getValue($user,'files','quota','default'); if($userQuota=='default') { $userQuota=OC_AppConfig::getValue('files', 'default_quota', 'none'); - $userQuota=OC_AppConfig::getValue('files','default_quota','none'); } if($userQuota=='none') { $this->userQuota[$user]=0; @@ -59,8 +57,12 @@ class OC_FileProxy_Quota extends OC_FileProxy{ * @return int */ private function getFreeSpace($path) { - $storage=OC_Filesystem::getStorage($path); - $owner=$storage->getOwner($path); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); + $owner=$storage->getOwner($internalPath); $totalSpace=$this->getQuota($owner); if($totalSpace==0) { From 41a61bc637c3d60efc5abe81c39fc726fd78cd1d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 8 Nov 2012 21:36:13 +0100 Subject: [PATCH 082/262] fix undefined index when loading files app --- apps/files/index.php | 4 +--- apps/files/templates/part.list.php | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/files/index.php b/apps/files/index.php index cdb88ab83f..4e5f4cd93a 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -66,9 +66,7 @@ foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { $i['extension']=''; } } - if($i['directory']=='/') { - $i['directory']=''; - } + $i['directory'] = $dir; $files[] = $i; } diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php index 4b5ac32567..9c9d9926e5 100644 --- a/apps/files/templates/part.list.php +++ b/apps/files/templates/part.list.php @@ -18,7 +18,7 @@ $name = str_replace('%2F', '/', $name); $directory = str_replace('+', '%20', urlencode($file['directory'])); $directory = str_replace('%2F', '/', $directory); ?> -

' data-permissions=''> + ' data-permissions=''>
From cbcd9ba84ada830d91a6f1d7bee0ac59762835ed Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 15 Nov 2012 00:57:30 +0100 Subject: [PATCH 083/262] allow storage backends to implement custom permission management --- lib/files/cache/permissions.php | 36 ++++++++++++++------- lib/files/storage/common.php | 14 ++++++--- lib/files/storage/storage.php | 5 +++ lib/files/view.php | 6 ++-- tests/lib/files/cache/permissions.php | 45 ++++++++++++++++----------- tests/lib/files/cache/scanner.php | 3 +- tests/lib/files/cache/watcher.php | 3 +- tests/lib/files/view.php | 3 +- 8 files changed, 76 insertions(+), 39 deletions(-) diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php index dd7233abc7..d0968337f0 100644 --- a/lib/files/cache/permissions.php +++ b/lib/files/cache/permissions.php @@ -9,6 +9,22 @@ namespace OC\Files\Cache; class Permissions { + /** + * @var string $storageId + */ + private $storageId; + + /** + * @param \OC\Files\Storage\Storage|string $storage + */ + public function __construct($storage){ + if($storage instanceof \OC\Files\Storage\Storage){ + $this->storageId = $storage->getId(); + }else{ + $this->storageId = $storage; + } + } + /** * get the permissions for a single file * @@ -16,7 +32,7 @@ class Permissions { * @param string $user * @return int (-1 if file no permissions set) */ - static public function get($fileId, $user) { + public function get($fileId, $user) { $query = \OC_DB::prepare('SELECT `permissions` FROM `*PREFIX*permissions` WHERE `user` = ? AND `fileid` = ?'); $result = $query->execute(array($user, $fileId)); if ($row = $result->fetchRow()) { @@ -33,7 +49,7 @@ class Permissions { * @param string $user * @param int $permissions */ - static public function set($fileId, $user, $permissions) { + public function set($fileId, $user, $permissions) { if (self::get($fileId, $user) !== -1) { $query = \OC_DB::prepare('UPDATE `*PREFIX*permissions` SET `permissions` = ? WHERE `user` = ? AND `fileid` = ?'); } else { @@ -49,7 +65,7 @@ class Permissions { * @param string $user * @return int[] */ - static public function getMultiple($fileIds, $user) { + public function getMultiple($fileIds, $user) { if (count($fileIds) === 0) { return array(); } @@ -72,17 +88,15 @@ class Permissions { * @param int $fileId * @param string $user */ - static public function remove($fileId, $user) { + public function remove($fileId, $user) { $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); $query->execute(array($fileId, $user)); } - static public function removeMultiple($fileIds, $user) { - $params = $fileIds; - $params[] = $user; - $inPart = implode(', ', array_fill(0, count($fileIds), '?')); - - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` IN (' . $inPart . ') AND `user` = ?'); - $query->execute($params); + public function removeMultiple($fileIds, $user) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*permissions` WHERE `fileid` = ? AND `user` = ?'); + foreach($fileIds as $fileId){ + $query->execute(array($fileId, $user)); + } } } diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index f471752d1f..cf6fe64a4f 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -57,19 +57,19 @@ abstract class Common implements \OC\Files\Storage\Storage { public function getPermissions($path){ $permissions = 0; if($this->isCreatable($path)){ - $permissions |= \OCP\Share::PERMISSION_CREATE; + $permissions |= \OCP\PERMISSION_CREATE; } if($this->isReadable($path)){ - $permissions |= \OCP\Share::PERMISSION_READ; + $permissions |= \OCP\PERMISSION_READ; } if($this->isUpdatable($path)){ - $permissions |= \OCP\Share::PERMISSION_UPDATE; + $permissions |= \OCP\PERMISSION_UPDATE; } if($this->isDeletable($path)){ - $permissions |= \OCP\Share::PERMISSION_DELETE; + $permissions |= \OCP\PERMISSION_DELETE; } if($this->isSharable($path)){ - $permissions |= \OCP\Share::PERMISSION_SHARE; + $permissions |= \OCP\PERMISSION_SHARE; } return $permissions; } @@ -259,6 +259,10 @@ abstract class Common implements \OC\Files\Storage\Storage { return new \OC\Files\Cache\Scanner($this); } + public function getPermissionsCache(){ + return new \OC\Files\Cache\Permissions($this); + } + /** * get the owner of a path * @param string $path The path to get the owner diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index bb1ba16984..73dcb8fe36 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -64,6 +64,11 @@ interface Storage{ public function getOwner($path); + /** + * @return \OC\Files\Cache\Permissions + */ + public function getPermissionsCache(); + /** * get the ETag for a file or folder * diff --git a/lib/files/view.php b/lib/files/view.php index a54c3ee356..e516a4fed6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -701,7 +701,8 @@ class View { } } - $data['permissions'] = Cache\Permissions::get($data['fileid'], \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); return $data; } @@ -759,8 +760,9 @@ class View { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; } + $permissionsCache = $storage->getPermissionsCache(); - $permissions = Cache\Permissions::getMultiple($ids, \OC_User::getUser()); + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); foreach ($files as $i => $file) { $files[$i]['permissions'] = $permissions[$file['fileid']]; } diff --git a/tests/lib/files/cache/permissions.php b/tests/lib/files/cache/permissions.php index 4d47929a3e..56dbbc4518 100644 --- a/tests/lib/files/cache/permissions.php +++ b/tests/lib/files/cache/permissions.php @@ -9,39 +9,48 @@ namespace Test\Files\Cache; class Permissions extends \PHPUnit_Framework_TestCase { + /*** + * @var \OC\Files\Cache\Permissions $permissionsCache + */ + private $permissionsCache; + + function setUp(){ + $this->permissionsCache=new \OC\Files\Cache\Permissions('dummy'); + } + function testSimple() { $ids = range(1, 10); $user = uniqid(); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); - \OC\Files\Cache\Permissions::set(1, $user, 1); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(1, $user)); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(2, $user)); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user . '2')); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user)); + $this->permissionsCache->set(1, $user, 1); + $this->assertEquals(1, $this->permissionsCache->get(1, $user)); + $this->assertEquals(-1, $this->permissionsCache->get(2, $user)); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user . '2')); - \OC\Files\Cache\Permissions::set(1, $user, 2); - $this->assertEquals(2, \OC\Files\Cache\Permissions::get(1, $user)); + $this->permissionsCache->set(1, $user, 2); + $this->assertEquals(2, $this->permissionsCache->get(1, $user)); - \OC\Files\Cache\Permissions::set(2, $user, 1); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->permissionsCache->set(2, $user, 1); + $this->assertEquals(1, $this->permissionsCache->get(2, $user)); - \OC\Files\Cache\Permissions::remove(1, $user); - $this->assertEquals(-1, \OC\Files\Cache\Permissions::get(1, $user)); - \OC\Files\Cache\Permissions::remove(1, $user . '2'); - $this->assertEquals(1, \OC\Files\Cache\Permissions::get(2, $user)); + $this->permissionsCache->remove(1, $user); + $this->assertEquals(-1, $this->permissionsCache->get(1, $user)); + $this->permissionsCache->remove(1, $user . '2'); + $this->assertEquals(1, $this->permissionsCache->get(2, $user)); $expected = array(); foreach ($ids as $id) { - \OC\Files\Cache\Permissions::set($id, $user, 10 + $id); + $this->permissionsCache->set($id, $user, 10 + $id); $expected[$id] = 10 + $id; } - $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + $this->assertEquals($expected, $this->permissionsCache->getMultiple($ids, $user)); - \OC\Files\Cache\Permissions::removeMultiple(array(10, 9), $user); + $this->permissionsCache->removeMultiple(array(10, 9), $user); unset($expected[9]); unset($expected[10]); - $this->assertEquals($expected, \OC\Files\Cache\Permissions::getMultiple($ids, $user)); + $this->assertEquals($expected, $this->permissionsCache->getMultiple($ids, $user)); - \OC\Files\Cache\Permissions::removeMultiple($ids, $user); + $this->permissionsCache->removeMultiple($ids, $user); } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index f784a82dad..c53da92727 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -112,7 +112,8 @@ class Scanner extends \UnitTestCase { function tearDown() { $ids = $this->cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $this->storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $this->cache->clear(); } } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index a7076d9b0b..0125dd843b 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -23,7 +23,8 @@ class Watcher extends \PHPUnit_Framework_TestCase { foreach ($this->storages as $storage) { $cache = $storage->getCache(); $ids = $cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index fa562cb15c..a173094b1c 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -21,7 +21,8 @@ class View extends \PHPUnit_Framework_TestCase { foreach ($this->storages as $storage) { $cache = $storage->getCache(); $ids = $cache->getAll(); - \OC\Files\Cache\Permissions::removeMultiple($ids, \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache->removeMultiple($ids, \OC_User::getUser()); $cache->clear(); } } From 5569f07e8d68716f01267c9f41e5f0be299cc67a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 15 Nov 2012 22:04:48 +0100 Subject: [PATCH 084/262] add OC_FilesystemView alias for compatibility --- lib/filesystemview.php | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 lib/filesystemview.php diff --git a/lib/filesystemview.php b/lib/filesystemview.php new file mode 100644 index 0000000000..37e2a737e0 --- /dev/null +++ b/lib/filesystemview.php @@ -0,0 +1,8 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ + +class OC_FilesystemView extends \OC\Files\View {} From 288ecf318cbb742b2c6a40d6c6afedfafb3cafd4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 15 Nov 2012 22:08:08 +0100 Subject: [PATCH 085/262] add getFileInfo and getDirectoryContent to OC_Files for compatibility --- lib/files.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/files.php b/lib/files.php index e6b324f062..3abc8c4aaf 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,6 +28,14 @@ class OC_Files { static $tmpFiles = array(); + public function getFileInfo($path){ + return \OC\Files\Filesystem::getFileInfo($path); + } + + public function getDirectoryContent($path){ + return \OC\Files\Filesystem::getDirectoryContent($path); + } + /** * return the content of a file or return a zip file containning multiply files * From 54240140b10f2d718753445b656c9607967d7c64 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 16 Nov 2012 12:14:29 +0100 Subject: [PATCH 086/262] fix incorectly merged smb.php --- apps/files_external/lib/smb.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php index bf0d780d27..a4b2338e3b 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/smb.php @@ -35,6 +35,7 @@ class SMB extends \OC\Files\Storage\StreamWrapper{ if(substr($this->share, -1, 1)=='/') { $this->share = substr($this->share,0,-1); } + } public function getId(){ return 'smb::' . $this->user . '@' . $this->host . '/' . $this->share . '/' . $this->root; From 3358bface5c20aeb4ad41dc1edffb895bc24af71 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 16 Nov 2012 12:24:28 +0100 Subject: [PATCH 087/262] fix incorectly merged versions.php --- apps/files_versions/lib/versions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php index b365f45679..7fe3d5549e 100644 --- a/apps/files_versions/lib/versions.php +++ b/apps/files_versions/lib/versions.php @@ -189,7 +189,7 @@ class Storage { $i = 0; - $files_view = new \OC\Files\View('/' \OCP\User::getUser() . '/files'); + $files_view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files'); $local_file = $files_view->getLocalFile($filename); foreach( $matches as $ma ) { From 40fae0acbf2e84782c273a82eb10a2ed9fdf8162 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 18 Nov 2012 14:10:28 +0100 Subject: [PATCH 088/262] fix outdated permissions cache use in scanner --- lib/files/cache/scanner.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index eb947a2d53..404029ee2e 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -19,12 +19,18 @@ class Scanner { */ private $cache; + /** + * @var \OC\Files\Cache\Permissions $permissionsCache + */ + private $permissionsCache; + const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; public function __construct(\OC\Files\Storage\Storage $storage) { $this->storage = $storage; - $this->cache = new Cache($storage); + $this->cache = $storage->getCache(); + $this->permissionsCache = $storage->getPermissionsCache(); } /** @@ -67,7 +73,7 @@ class Scanner { } } $id = $this->cache->put($file, $data); - Permissions::set($id, \OC_User::getUser(), $data['permissions']); + $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); return $data; } From 77fdb16b7cb97f4e68949baf6796ef0e290b03f5 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 22 Nov 2012 00:22:27 -0500 Subject: [PATCH 089/262] Remove incorrect extra parameter for init() call --- lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util.php b/lib/util.php index 89fbcd05cd..c79afe1957 100755 --- a/lib/util.php +++ b/lib/util.php @@ -52,7 +52,7 @@ class OC_Util { } //jail the user into his "home" directory \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); - \OC\Files\Filesystem::init($user_dir, $user); + \OC\Files\Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); $fileOperationProxy = new OC_FileProxy_FileOperations(); From b76d1afe193fae3bf94aed9a95e270b452e62eb8 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 22 Nov 2012 00:44:48 -0500 Subject: [PATCH 090/262] Create public function initMountPoints() for initializing a specified user's mount points --- lib/files/filesystem.php | 53 ++++++++++++++++++++++++++++------------ lib/util.php | 16 ------------ 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index ed2814211f..cee3cd883b 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -229,35 +229,50 @@ class Filesystem { self::$defaultInstance = new View($root); //load custom mount config - if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { + self::initMountPoints(); + + self::$loaded = true; + + return true; + } + + /** + * Initialize system and personal mount points for a user + * + * @param string $user + */ + public static function initMountPoints($user = '') { + if ($user == '') { + $user = \OC_User::getUser(); + } + // Load system mount points + if (is_file(\OC::$SERVERROOT.'/config/mount.php')) { $mountConfig = include 'config/mount.php'; if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); } } - if (isset($mountConfig['group'])) { foreach ($mountConfig['group'] as $group => $mounts) { - if (\OC_Group::inGroup(\OC_User::getUser(), $group)) { + if (\OC_Group::inGroup($user, $group)) { foreach ($mounts as $mountPoint => $options) { - $mountPoint = self::setUserVars($mountPoint); + $mountPoint = self::setUserVars($user, $mountPoint); foreach ($options as &$option) { - $option = self::setUserVars($option); + $option = self::setUserVars($user, $option); } self::mount($options['class'], $options['options'], $mountPoint); } } } } - if (isset($mountConfig['user'])) { - foreach ($mountConfig['user'] as $user => $mounts) { - if ($user === 'all' or strtolower($user) === strtolower(\OC_User::getUser())) { + foreach ($mountConfig['user'] as $mountUser => $mounts) { + if ($user === 'all' or strtolower($mountUser) === strtolower($user)) { foreach ($mounts as $mountPoint => $options) { - $mountPoint = self::setUserVars($mountPoint); + $mountPoint = self::setUserVars($user, $mountPoint); foreach ($options as &$option) { - $option = self::setUserVars($option); + $option = self::setUserVars($user, $option); } self::mount($options['class'], $options['options'], $mountPoint); } @@ -265,10 +280,16 @@ class Filesystem { } } } - - self::$loaded = true; - - return true; + // Load personal mount points + $root = OC_User::getHome($user); + if (is_file($root.'/mount.php')) { + $mountConfig = include $root.'/mount.php'; + if (isset($mountConfig['user'][$user])) { + foreach ($mountConfig['user'][$user] as $mountPoint => $options) { + self::mount($options['class'], $options['options'], $mountPoint); + } + } + } } /** @@ -277,8 +298,8 @@ class Filesystem { * @param string $input * @return string */ - private static function setUserVars($input) { - return str_replace('$user', \OC_User::getUser(), $input); + private static function setUserVars($user, $input) { + return str_replace('$user', $user, $input); } /** diff --git a/lib/util.php b/lib/util.php index c79afe1957..25fdcef1ae 100755 --- a/lib/util.php +++ b/lib/util.php @@ -58,8 +58,6 @@ class OC_Util { $fileOperationProxy = new OC_FileProxy_FileOperations(); OC_FileProxy::register($quotaProxy); OC_FileProxy::register($fileOperationProxy); - // Load personal mount config - self::loadUserMountPoints($user); OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $user_dir)); } @@ -71,20 +69,6 @@ class OC_Util { self::$fsSetup=false; } - public static function loadUserMountPoints($user) { - $user_dir = '/'.$user.'/files'; - $user_root = OC_User::getHome($user); - $userdirectory = $user_root . '/files'; - if (is_file($user_root.'/mount.php')) { - $mountConfig = include $user_root.'/mount.php'; - if (isset($mountConfig['user'][$user])) { - foreach ($mountConfig['user'][$user] as $mountPoint => $options) { - \OC\Files\Filesystem::mount($options['class'], $options['options'], $mountPoint); - } - } - } - } - /** * get the current installed version of ownCloud * @return array From 208c6fd966dd5f9f387cdd1b4f030a2723144347 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Thu, 22 Nov 2012 10:21:48 +0100 Subject: [PATCH 091/262] fixing namespace --- lib/files/filesystem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index cee3cd883b..9e8ce3ec18 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -281,7 +281,7 @@ class Filesystem { } } // Load personal mount points - $root = OC_User::getHome($user); + $root = \OC_User::getHome($user); if (is_file($root.'/mount.php')) { $mountConfig = include $root.'/mount.php'; if (isset($mountConfig['user'][$user])) { From e6cf082fe07e4e33c883bd5f9aaa0cc72b082741 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 22:44:43 +0100 Subject: [PATCH 092/262] emit a hooks during the filesystem scan --- lib/files/cache/scanner.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 404029ee2e..e650a220f5 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -14,6 +14,11 @@ class Scanner { */ private $storage; + /** + * @var string $storageId + */ + private $storageId; + /** * @var \OC\Files\Cache\Cache $cache */ @@ -29,6 +34,7 @@ class Scanner { public function __construct(\OC\Files\Storage\Storage $storage) { $this->storage = $storage; + $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); $this->permissionsCache = $storage->getPermissionsCache(); } @@ -62,6 +68,7 @@ class Scanner { * @return array with metadata of the scanned file */ public function scanFile($file) { + \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($file !== '') { $parent = dirname($file); @@ -85,6 +92,7 @@ class Scanner { * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ public function scan($path, $recursive = self::SCAN_RECURSIVE) { + \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_folder', array('path' => $path, 'storage' => $this->storageId)); $this->scanFile($path); $size = 0; From 186c9e77e89dcd057a311ed08df9e1bb9e13ea8f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 23:02:43 +0100 Subject: [PATCH 093/262] add Cache->getIncomplete for use in background scanning --- lib/files/cache/cache.php | 19 +++++++++++++++++++ tests/lib/files/cache/cache.php | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 7c6bba4fad..b52c0f4067 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -402,4 +402,23 @@ class Cache { } return $ids; } + + /** + * find a folder in the cache which has not been fully scanned + * + * If multiply incomplete folders are in the cache, the one with the highest id will be returned, + * use the one with the highest id gives the best result with the background scanner, since that is most + * likely the folder where we stopped scanning previously + * + * @return string|bool the path of the folder or false when no folder matched + */ + public function getIncomplete(){ + $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1'); + $query->execute(array($this->storageId)); + if($row = $query->fetchRow()){ + return $row['path']; + }else{ + return false; + } + } } diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index 9c469aa937..e9105cd5ab 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -175,6 +175,23 @@ class Cache extends \UnitTestCase { $this->assertTrue($this->cache->inCache('folder/foobar/2')); } + function testGetIncomplete() { + $file1 = 'folder1'; + $file2 = 'folder2'; + $file3 = 'folder3'; + $file4 = 'folder4'; + $data = array('size' => 10, 'mtime' => 50, 'mimetype' => 'foo/bar'); + + $this->cache->put($file1, $data); + $data['size'] = -1; + $this->cache->put($file2, $data); + $this->cache->put($file3, $data); + $data['size'] = 12; + $this->cache->put($file4, $data); + + $this->assertEquals($file3, $this->cache->getIncomplete()); + } + public function tearDown() { $this->cache->clear(); } From 8687e0d346e7dad6890982c1a7b08befd8998aeb Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 21 Nov 2012 23:18:58 +0100 Subject: [PATCH 094/262] add Scanner->backgroundScan --- lib/files/cache/scanner.php | 10 ++++++++++ tests/lib/files/cache/scanner.php | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index e650a220f5..3c83b6528a 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -121,4 +121,14 @@ class Scanner { } return $size; } + + /** + * walk over any folders that are not fully scanned yet and scan them + */ + public function backgroundScan() { + while ($path = $this->cache->getIncomplete()) { + $this->scan($path); + $this->cache->correctFolderSize($path); + } + } } diff --git a/tests/lib/files/cache/scanner.php b/tests/lib/files/cache/scanner.php index c53da92727..6d26150d82 100644 --- a/tests/lib/files/cache/scanner.php +++ b/tests/lib/files/cache/scanner.php @@ -104,6 +104,28 @@ class Scanner extends \UnitTestCase { $this->assertNotEqual($cachedDataFolder['size'], -1); } + function testBackgroundScan(){ + $this->fillTestFolders(); + $this->storage->mkdir('folder2'); + $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); + + $this->scanner->scan('', \OC\Files\Cache\Scanner::SCAN_SHALLOW); + $this->assertFalse($this->cache->inCache('folder/bar.txt')); + $this->assertFalse($this->cache->inCache('folder/2bar.txt')); + $cachedData = $this->cache->get(''); + $this->assertEquals(-1, $cachedData['size']); + + $this->scanner->backgroundScan(); + + $this->assertTrue($this->cache->inCache('folder/bar.txt')); + $this->assertTrue($this->cache->inCache('folder/bar.txt')); + + $cachedData = $this->cache->get(''); + $this->assertnotEquals(-1, $cachedData['size']); + + $this->assertFalse($this->cache->getIncomplete()); + } + function setUp() { $this->storage = new \OC\Files\Storage\Temporary(array()); $this->scanner = new \OC\Files\Cache\Scanner($this->storage); From 810563ae8aa5884a101cc64226c4f8c3c897132e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 Nov 2012 12:44:31 +0100 Subject: [PATCH 095/262] don't redefine inherited functions as abstract --- lib/files/storage/common.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index cf6fe64a4f..9978cea571 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -23,18 +23,12 @@ namespace OC\Files\Storage; abstract class Common implements \OC\Files\Storage\Storage { public function __construct($parameters) {} - abstract public function getId(); - abstract public function mkdir($path); - abstract public function rmdir($path); - abstract public function opendir($path); public function is_dir($path) { return $this->filetype($path)=='dir'; } public function is_file($path) { return $this->filetype($path)=='file'; } - abstract public function stat($path); - abstract public function filetype($path); public function filesize($path) { if($this->is_dir($path)) { return 0;//by definition @@ -46,8 +40,6 @@ abstract class Common implements \OC\Files\Storage\Storage { public function isCreatable($path) { return $this->isUpdatable($path); } - abstract public function isReadable($path); - abstract public function isUpdatable($path); public function isDeletable($path) { return $this->isUpdatable($path); } @@ -73,7 +65,6 @@ abstract class Common implements \OC\Files\Storage\Storage { } return $permissions; } - abstract public function file_exists($path); public function filemtime($path) { $stat = $this->stat($path); return $stat['mtime']; @@ -97,7 +88,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $handle = $this->fopen($path, "w"); return fwrite($handle, $data); } - abstract public function unlink($path); public function rename($path1,$path2) { if($this->copy($path1,$path2)) { return $this->unlink($path1); @@ -111,7 +101,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $count=\OC_Helper::streamCopy($source,$target); return $count>0; } - abstract public function fopen($path,$mode); /** * @brief Deletes all files and folders recursively within a directory @@ -180,7 +169,6 @@ abstract class Common implements \OC\Files\Storage\Storage { unlink($tmpFile); return $hash; } - abstract public function free_space($path); public function search($query) { return $this->searchInDir($query); } @@ -222,7 +210,6 @@ abstract class Common implements \OC\Files\Storage\Storage { } } } - abstract public function touch($path, $mtime=null); protected function searchInDir($query,$dir='') { $files=array(); From 8ce5e0d30d874bf59a81aa01202a497ea4cb8492 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 22 Nov 2012 13:14:39 +0100 Subject: [PATCH 096/262] don't throw fatal error in updater cache if setup failed for some reason --- tests/lib/files/cache/updater.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 8059418dc1..b2eccf9130 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -61,7 +61,9 @@ class Updater extends \PHPUnit_Framework_TestCase { } public function tearDown() { - $this->cache->clear(); + if($this->cache){ + $this->cache->clear(); + } Filesystem::tearDown(); } From ad706229f5dbc6382ade61493e9f100a2dc07293 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 Nov 2012 00:17:18 +0100 Subject: [PATCH 097/262] explicitly sort files when using getFolderContents --- lib/files/cache/cache.php | 14 +++++++------- tests/lib/files/view.php | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index b52c0f4067..6b93673097 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -33,9 +33,9 @@ class Cache { * @param \OC\Files\Storage\Storage|string $storage */ public function __construct($storage) { - if($storage instanceof \OC\Files\Storage\Storage){ + if ($storage instanceof \OC\Files\Storage\Storage) { $this->storageId = $storage->getId(); - }else{ + } else { $this->storageId = $storage; } } @@ -87,7 +87,7 @@ class Cache { if ($fileId > -1) { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` - FROM `*PREFIX*filecache` WHERE parent = ?'); + FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `fileid` ASC'); $result = $query->execute(array($fileId)); return $result->fetchAll(); } else { @@ -364,7 +364,7 @@ class Cache { */ public function calculateFolderSize($path) { $id = $this->getId($path); - if($id === -1){ + if ($id === -1) { return 0; } $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); @@ -412,12 +412,12 @@ class Cache { * * @return string|bool the path of the folder or false when no folder matched */ - public function getIncomplete(){ + public function getIncomplete() { $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1'); $query->execute(array($this->storageId)); - if($row = $query->fetchRow()){ + if ($row = $query->fetchRow()) { return $row['path']; - }else{ + } else { return false; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index a173094b1c..ecfc803dc2 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -55,20 +55,20 @@ class View extends \PHPUnit_Framework_TestCase { $folderData = $rootView->getDirectoryContent('/'); /** * expected entries: - * folder * foo.png * foo.txt + * folder * substorage */ $this->assertEquals(4, count($folderData)); - $this->assertEquals('folder', $folderData[0]['name']); - $this->assertEquals('foo.png', $folderData[1]['name']); - $this->assertEquals('foo.txt', $folderData[2]['name']); + $this->assertEquals('foo.png', $folderData[0]['name']); + $this->assertEquals('foo.txt', $folderData[1]['name']); + $this->assertEquals('folder', $folderData[2]['name']); $this->assertEquals('substorage', $folderData[3]['name']); - $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); - $this->assertEquals($imageSize, $folderData[1]['size']); - $this->assertEquals($textSize, $folderData[2]['size']); + $this->assertEquals($imageSize, $folderData[0]['size']); + $this->assertEquals($textSize, $folderData[1]['size']); + $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); $folderView = new \OC\Files\View('/folder'); From 8fb4dfd2eabcc267725d3c151d93644d6f28f010 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 Nov 2012 00:20:46 +0100 Subject: [PATCH 098/262] use background scanner --- apps/files/ajax/scan.php | 97 +++++++++++++++++++++++++--------------- apps/files/js/files.js | 38 +++++++--------- 2 files changed, 76 insertions(+), 59 deletions(-) diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php index 91b20fa836..53ae4f5ff0 100644 --- a/apps/files/ajax/scan.php +++ b/apps/files/ajax/scan.php @@ -1,45 +1,70 @@ send('success', true); +OC_Hook::connect('\OC\Files\Cache\Scanner', 'scan_folder', 'ScanListener', 'folder'); +OC_Hook::connect('\OC\Files\Cache\Scanner', 'scan_file', 'ScanListener', 'file'); + +$absolutePath = \OC\Files\Filesystem::getView()->getAbsolutePath($dir); + +$mountPoints = \OC\Files\Filesystem::getMountPoints($absolutePath); +$mountPoints[] = \OC\Files\Filesystem::getMountPoint($absolutePath); +$mountPoints = array_reverse($mountPoints); //start with the mount point of $dir + +foreach ($mountPoints as $mountPoint) { + $storage = \OC\Files\Filesystem::getStorage($mountPoint); + error_log('scanning mp '.$mountPoint); + ScanListener::$mountPoints[$storage->getId()] = $mountPoint; + $scanner = $storage->getScanner(); + if ($force) { + $scanner->scan(''); } else { - OCP\JSON::success(array('data'=>array('done'=>true))); - exit; - } -} else { - if($checkOnly) { - OCP\JSON::success(array('data'=>array('done'=>false))); - exit; - } - if(isset($eventSource)) { - $eventSource->send('success', false); - } else { - exit; + $scanner->backgroundScan(); } } + +$eventSource->send('done', ScanListener::$fileCount); $eventSource->close(); + +class ScanListener { + + static public $fileCount = 0; + static public $lastCount = 0; + + /** + * @var \OC\Files\View $view + */ + static public $view; + + /** + * @var array $mountPoints map storage ids to mountpoints + */ + static public $mountPoints = array(); + + /** + * @var \OC_EventSource event source to pass events to + */ + static public $eventSource; + + static function folder($params) { + $internalPath = $params['path']; + $mountPoint = self::$mountPoints[$params['storage']]; + $path = self::$view->getRelativePath($mountPoint . $internalPath); + self::$eventSource->send('folder', $path); + } + + static function file() { + self::$fileCount++; + if (self::$fileCount > self::$lastCount + 20) { //send a count update every 20 files + self::$lastCount = self::$fileCount; + self::$eventSource->send('count', self::$fileCount); + } + } +} diff --git a/apps/files/js/files.js b/apps/files/js/files.js index bb80841055..f95bfa2bf8 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -602,12 +602,8 @@ $(document).ready(function() { }); }); - //check if we need to scan the filesystem - $.get(OC.filePath('files','ajax','scan.php'),{checkonly:'true'}, function(response) { - if(response.data.done){ - scanFiles(); - } - }, "json"); + //do a background scan if needed + scanFiles(); var lastWidth = 0; var breadcrumbs = []; @@ -676,27 +672,23 @@ $(document).ready(function() { resizeBreadcrumbs(true); }); -function scanFiles(force,dir){ +function scanFiles(force, dir){ if(!dir){ - dir=''; + dir = ''; } - force=!!force; //cast to bool - scanFiles.scanning=true; - $('#scanning-message').show(); - $('#fileList').remove(); - var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force,dir:dir}); - scanFiles.cancel=scannerEventSource.close.bind(scannerEventSource); - scannerEventSource.listen('scanning',function(data){ - $('#scan-count').text(t('files', '{count} files scanned', {count: data.count})); - $('#scan-current').text(data.file+'/'); + force = !!force; //cast to bool + scanFiles.scanning = true; + var scannerEventSource = new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force,dir:dir}); + scanFiles.cancel = scannerEventSource.close.bind(scannerEventSource); + scannerEventSource.listen('count',function(count){ + console.log(count + 'files scanned') }); - scannerEventSource.listen('success',function(success){ + scannerEventSource.listen('folder',function(path){ + console.log('now scanning ' + path) + }); + scannerEventSource.listen('done',function(count){ scanFiles.scanning=false; - if(success){ - window.location.reload(); - }else{ - alert(t('files', 'error while scanning')); - } + console.log('done after ' + count + 'files'); }); } scanFiles.scanning=false; From c47bf9bbcefb0640c24ab0aa6ee79f4c52222b45 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 24 Nov 2012 16:42:54 -0500 Subject: [PATCH 099/262] Add checks for storage object --- apps/files/ajax/scan.php | 15 +-- lib/files/view.php | 221 +++++++++++++++++++++------------------ 2 files changed, 127 insertions(+), 109 deletions(-) diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php index 53ae4f5ff0..391b98608b 100644 --- a/apps/files/ajax/scan.php +++ b/apps/files/ajax/scan.php @@ -20,13 +20,14 @@ $mountPoints = array_reverse($mountPoints); //start with the mount point of $dir foreach ($mountPoints as $mountPoint) { $storage = \OC\Files\Filesystem::getStorage($mountPoint); - error_log('scanning mp '.$mountPoint); - ScanListener::$mountPoints[$storage->getId()] = $mountPoint; - $scanner = $storage->getScanner(); - if ($force) { - $scanner->scan(''); - } else { - $scanner->backgroundScan(); + if ($storage) { + ScanListener::$mountPoints[$storage->getId()] = $mountPoint; + $scanner = $storage->getScanner(); + if ($force) { + $scanner->scan(''); + } else { + $scanner->backgroundScan(); + } } } diff --git a/lib/files/view.php b/lib/files/view.php index e516a4fed6..468808566a 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -671,39 +671,41 @@ class View { * - versioned */ public function getFileInfo($path) { + $data = array(); $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ list($storage, $internalPath) = Filesystem::resolvePath($path); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } else { - $watcher = new \OC\Files\Cache\Watcher($storage); - $watcher->checkUpdate($internalPath); - } - - $data = $cache->get($internalPath); - - if ($data['mimetype'] === 'httpd/unix-directory') { - //add the sizes of other mountpoints to the folder - $mountPoints = Filesystem::getMountPoints($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); } + + $data = $cache->get($internalPath); + + if ($data['mimetype'] === 'httpd/unix-directory') { + //add the sizes of other mountpoints to the folder + $mountPoints = Filesystem::getMountPoints($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + + $data['size'] += $rootEntry['size']; + } + } + + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); } - - $permissionsCache = $storage->getPermissionsCache(); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); - return $data; } @@ -714,75 +716,79 @@ class View { * @return array */ public function getDirectoryContent($directory, $mimetype_filter = '') { + $result = array(); $path = Filesystem::normalizePath($this->fakeRoot . '/' . $directory); /** * @var \OC\Files\Storage\Storage $storage * @var string $internalPath */ list($storage, $internalPath) = Filesystem::resolvePath($path); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); - } else { - $watcher = new \OC\Files\Cache\Watcher($storage); - $watcher->checkUpdate($internalPath); - } - - $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - - //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders - $mountPoints = Filesystem::getMountPoints($path); - $dirLength = strlen($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $relativePath = trim(substr($mountPoint, $dirLength), '/'); - if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder - $entryName = substr($relativePath, 0, $pos); - foreach ($files as &$entry) { - if ($entry['name'] === $entryName) { - $entry['size'] += $rootEntry['size']; - } - } - } else { //mountpoint in this folder, add an entry for it - $rootEntry['name'] = $relativePath; - $files[] = $rootEntry; + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } else { + $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher->checkUpdate($internalPath); } - } - $ids = array(); + $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter - foreach ($files as $i => $file) { - $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache(); + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders + $mountPoints = Filesystem::getMountPoints($path); + $dirLength = strlen($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = Filesystem::getStorage($mountPoint); + if ($subStorage) { + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$file['fileid']]; - } - - if ($mimetype_filter) { - foreach ($files as $file) { - if (strpos($mimetype_filter, '/')) { - if ($file['mimetype'] === $mimetype_filter) { - $result[] = $file; - } - } else { - if ($file['mimepart'] === $mimetype_filter) { - $result[] = $file; + $relativePath = trim(substr($mountPoint, $dirLength), '/'); + if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder + $entryName = substr($relativePath, 0, $pos); + foreach ($files as &$entry) { + if ($entry['name'] === $entryName) { + $entry['size'] += $rootEntry['size']; + } + } + } else { //mountpoint in this folder, add an entry for it + $rootEntry['name'] = $relativePath; + $files[] = $rootEntry; } } } - } else { - $result = $files; - } + $ids = array(); + + foreach ($files as $i => $file) { + $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $ids[] = $file['fileid']; + } + $permissionsCache = $storage->getPermissionsCache(); + + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $files[$i]['permissions'] = $permissions[$file['fileid']]; + } + + if ($mimetype_filter) { + foreach ($files as $file) { + if (strpos($mimetype_filter, '/')) { + if ($file['mimetype'] === $mimetype_filter) { + $result[] = $file; + } + } else { + if ($file['mimepart'] === $mimetype_filter) { + $result[] = $file; + } + } + } + } else { + $result = $files; + } + } return $result; } @@ -802,14 +808,18 @@ class View { * @var string $internalPath */ list($storage, $internalPath) = Filesystem::resolvePath($path); - $cache = $storage->getCache(); + if ($storage) { + $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); - $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + if (!$cache->inCache($internalPath)) { + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); + } + + return $cache->put($internalPath, $data); + } else { + return -1; } - - return $cache->put($internalPath, $data); } /** @@ -843,29 +853,32 @@ class View { $mountPoint = Filesystem::getMountPoint($this->fakeRoot); $storage = Filesystem::getStorage($mountPoint); - $cache = $storage->getCache(); - - $results = $cache->$method($query); - foreach ($results as $result) { - if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) { - $result['path'] = substr($mountPoint . $result['path'], $rootLength); - $files[] = $result; - } - } - - $mountPoints = Filesystem::getMountPoints($this->fakeRoot); - foreach ($mountPoints as $mountPoint) { - $storage = Filesystem::getStorage($mountPoint); + if ($storage) { $cache = $storage->getCache(); - $relativeMountPoint = substr($mountPoint, $rootLength); $results = $cache->$method($query); foreach ($results as $result) { - $result['path'] = $relativeMountPoint . $result['path']; - $files[] = $result; + if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) { + $result['path'] = substr($mountPoint . $result['path'], $rootLength); + $files[] = $result; + } + } + + $mountPoints = Filesystem::getMountPoints($this->fakeRoot); + foreach ($mountPoints as $mountPoint) { + $storage = Filesystem::getStorage($mountPoint); + if ($storage) { + $cache = $storage->getCache(); + + $relativeMountPoint = substr($mountPoint, $rootLength); + $results = $cache->$method($query); + foreach ($results as $result) { + $result['path'] = $relativeMountPoint . $result['path']; + $files[] = $result; + } + } } } - return $files; } @@ -881,6 +894,10 @@ class View { * @var string $internalPath */ list($storage, $internalPath) = $this->resolvePath($path); - return $storage->getETag($internalPath); + if ($storage) { + return $storage->getETag($internalPath); + } else { + return null; + } } } From d3e37fa157faa59598e92a9aa02c6bbf818b60e0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 23 Nov 2012 16:23:52 +0100 Subject: [PATCH 100/262] remove fileatime from common storage backend --- lib/fileproxy.php | 2 +- lib/files/storage/common.php | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/fileproxy.php b/lib/fileproxy.php index 2f81bde64a..52ec79b4bd 100644 --- a/lib/fileproxy.php +++ b/lib/fileproxy.php @@ -36,7 +36,7 @@ * The return value of the post-proxy will be used as the new result of the operation * The operations that have a post-proxy are: * file_get_contents, is_file, is_dir, file_exists, stat, is_readable, - * is_writable, fileatime, filemtime, filectime, file_get_contents, + * is_writable, filemtime, filectime, file_get_contents, * getMimeType, hash, fopen, free_space and search */ diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 9978cea571..c891d0c3ad 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -69,10 +69,6 @@ abstract class Common implements \OC\Files\Storage\Storage { $stat = $this->stat($path); return $stat['mtime']; } - public function fileatime($path) { - $stat = $this->stat($path); - return $stat['atime']; - } public function file_get_contents($path) { $handle = $this->fopen($path, "r"); if(!$handle) { From 709aacfa0fef29692bff231f09625db5ba0bef6f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 24 Nov 2012 23:41:39 +0100 Subject: [PATCH 101/262] change behaviour of Filesystem::getMountPoint when a mountpoint is passed as path without trailing slash --- lib/files/filesystem.php | 8 +------- tests/lib/files/filesystem.php | 2 +- tests/lib/files/view.php | 12 ++++++++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 9e8ce3ec18..4e3eb1989b 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -144,13 +144,7 @@ class Filesystem { */ static public function getMountPoint($path) { \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); - if (!$path) { - $path = '/'; - } - if ($path[0] !== '/') { - $path = '/' . $path; - } - $path = str_replace('//', '/', $path); + $path = self::normalizePath($path) . '/'; $foundMountPoint = ''; $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { diff --git a/tests/lib/files/filesystem.php b/tests/lib/files/filesystem.php index 363426511b..5837093fdd 100644 --- a/tests/lib/files/filesystem.php +++ b/tests/lib/files/filesystem.php @@ -60,7 +60,7 @@ class Filesystem extends \PHPUnit_Framework_TestCase { $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/')); $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/folder')); $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some/')); - $this->assertEquals('/',\OC\Files\Filesystem::getMountPoint('/some')); + $this->assertEquals('/some/',\OC\Files\Filesystem::getMountPoint('/some')); list( , $internalPath)=\OC\Files\Filesystem::resolvePath('/some/folder'); $this->assertEquals('folder',$internalPath); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index ecfc803dc2..6f8d29c25b 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -71,6 +71,18 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); + $folderData = $rootView->getDirectoryContent('/substorage'); + /** + * expected entries: + * foo.png + * foo.txt + * folder + */ + $this->assertEquals(3, count($folderData)); + $this->assertEquals('foo.png', $folderData[0]['name']); + $this->assertEquals('foo.txt', $folderData[1]['name']); + $this->assertEquals('folder', $folderData[2]['name']); + $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); From cc5d8e56098189f49fbd68c598c11be2b8354846 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 24 Nov 2012 20:29:57 -0500 Subject: [PATCH 102/262] Check if data variable in scanner isn't null before using it --- lib/files/cache/scanner.php | 42 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 3c83b6528a..9ee509bb13 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -70,17 +70,19 @@ class Scanner { public function scanFile($file) { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); - if ($file !== '') { - $parent = dirname($file); - if ($parent === '.') { - $parent = ''; - } - if (!$this->cache->inCache($parent)) { - $this->scanFile($parent); + if ($data) { + if ($file !== '') { + $parent = dirname($file); + if ($parent === '.') { + $parent = ''; + } + if (!$this->cache->inCache($parent)) { + $this->scanFile($parent); + } } + $id = $this->cache->put($file, $data); + $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); } - $id = $this->cache->put($file, $data); - $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); return $data; } @@ -101,17 +103,19 @@ class Scanner { if ($file !== '.' and $file !== '..') { $child = ($path !== '') ? $path . '/' . $file : $file; $data = $this->scanFile($child); - if ($data['mimetype'] === 'httpd/unix-directory') { - if ($recursive === self::SCAN_RECURSIVE) { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); - } else { - $data['size'] = -1; + if ($data) { + if ($data['mimetype'] === 'httpd/unix-directory') { + if ($recursive === self::SCAN_RECURSIVE) { + $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + } else { + $data['size'] = -1; + } + } + if ($data['size'] === -1) { + $size = -1; + } elseif ($size !== -1) { + $size += $data['size']; } - } - if ($data['size'] === -1) { - $size = -1; - } elseif ($size !== -1) { - $size += $data['size']; } } } From 0cfef83ed98951f852b07ce61dc10ee2e8266445 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 25 Nov 2012 16:08:35 +0100 Subject: [PATCH 103/262] sort output of getFolderContent by name --- lib/files/cache/cache.php | 2 +- tests/lib/files/view.php | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 6b93673097..bc52f21d91 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -87,7 +87,7 @@ class Cache { if ($fileId > -1) { $query = \OC_DB::prepare( 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` - FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `fileid` ASC'); + FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); return $result->fetchAll(); } else { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 6f8d29c25b..ed08dcc114 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -55,33 +55,33 @@ class View extends \PHPUnit_Framework_TestCase { $folderData = $rootView->getDirectoryContent('/'); /** * expected entries: + * folder * foo.png * foo.txt - * folder * substorage */ $this->assertEquals(4, count($folderData)); - $this->assertEquals('foo.png', $folderData[0]['name']); - $this->assertEquals('foo.txt', $folderData[1]['name']); - $this->assertEquals('folder', $folderData[2]['name']); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); $this->assertEquals('substorage', $folderData[3]['name']); - $this->assertEquals($imageSize, $folderData[0]['size']); - $this->assertEquals($textSize, $folderData[1]['size']); - $this->assertEquals($storageSize + $textSize, $folderData[2]['size']); + $this->assertEquals($storageSize + $textSize, $folderData[0]['size']); + $this->assertEquals($imageSize, $folderData[1]['size']); + $this->assertEquals($textSize, $folderData[2]['size']); $this->assertEquals($storageSize, $folderData[3]['size']); $folderData = $rootView->getDirectoryContent('/substorage'); /** * expected entries: + * folder * foo.png * foo.txt - * folder */ $this->assertEquals(3, count($folderData)); - $this->assertEquals('foo.png', $folderData[0]['name']); - $this->assertEquals('foo.txt', $folderData[1]['name']); - $this->assertEquals('folder', $folderData[2]['name']); + $this->assertEquals('folder', $folderData[0]['name']); + $this->assertEquals('foo.png', $folderData[1]['name']); + $this->assertEquals('foo.txt', $folderData[2]['name']); $folderView = new \OC\Files\View('/folder'); $this->assertEquals($rootView->getFileInfo('/folder'), $folderView->getFileInfo('/')); From a609992a75d1dad15398f55e22ad2244c78650dc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 25 Nov 2012 16:30:57 +0100 Subject: [PATCH 104/262] better check if we are passing a fileid to Cache::get --- lib/files/cache/cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index bc52f21d91..5aeb6f25af 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -47,7 +47,7 @@ class Cache { * @return array */ public function get($file) { - if (is_string($file)) { + if (is_string($file) or $file == '') { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; $params = array($this->storageId, md5($file)); } else { //file id From dbbb357f62c1ba86bdff0fbe63e4cea9bc2977fc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 30 Nov 2012 01:41:30 +0100 Subject: [PATCH 105/262] add upgrade path from old cache to preserve file id's --- apps/files/appinfo/app.php | 14 +++++++++-- apps/files/appinfo/version | 2 +- lib/files/cache/upgrade.php | 50 +++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 lib/files/cache/upgrade.php diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index b431ddfec0..fb64a80ec0 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -1,8 +1,18 @@ "files_index", "order" => 0, "href" => OCP\Util::linkTo( "files", "index.php" ), "icon" => OCP\Util::imagePath( "core", "places/home.svg" ), "name" => $l->t("Files") )); +OCP\App::addNavigationEntry(array("id" => "files_index", "order" => 0, "href" => OCP\Util::linkTo("files", "index.php"), "icon" => OCP\Util::imagePath("core", "places/home.svg"), "name" => $l->t("Files"))); OC_Search::registerProvider('OC_Search_Provider_File'); + +if (OC_User::isLoggedIn()) { + // update OC4.5 filecache to OC5 filecache, can't do this in update.php since it needs to happen for each user individually + $cacheVersion = (int)OCP\Config::getUserValue(OC_User::getUser(), 'files', 'cache_version', 4); + if ($cacheVersion < 5) { + \OC_Log::write('files', 'updating filecache to 5.0 for user ' . OC_User::getUser(), \OC_Log::INFO); + \OC\Files\Cache\Upgrade::upgrade(); + OCP\Config::setUserValue(OC_User::getUser(), 'files', 'cache_version', 5); + } +} diff --git a/apps/files/appinfo/version b/apps/files/appinfo/version index 0664a8fd29..2bf1ca5f54 100644 --- a/apps/files/appinfo/version +++ b/apps/files/appinfo/version @@ -1 +1 @@ -1.1.6 +1.1.7 diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php new file mode 100644 index 0000000000..5be04b4207 --- /dev/null +++ b/lib/files/cache/upgrade.php @@ -0,0 +1,50 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +class Upgrade { + static $permissionsCaches = array(); + + static function upgrade() { + $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + + $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child + $oldEntriesResult = $oldEntriesQuery->execute(); + + while ($row = $oldEntriesResult->fetchRow()) { + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath; + */ + $pathHash = md5($internalPath); + $storageId = $storage->getId(); + $parentId = ($internalPath === '') ? -1 : $row['parent']; + + $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); + + $permissions = ($row['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ; + $permissionsCache = self::getPermissionsCache($storage); + $permissionsCache->set($row['id'], $row['user'], $permissions); + } + } + + /** + * @param \OC\Files\Storage\Storage $storage + * @return Permissions + */ + static function getPermissionsCache($storage) { + $storageId = $storage->getId(); + if (!isset(self::$permissionsCaches[$storageId])) { + self::$permissionsCaches[$storageId] = $storage->getPermissionsCache(); + } + return self::$permissionsCaches[$storageId]; + } +} From 702444b2422326388e494091e815fd3d9b03cc87 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 1 Dec 2012 00:59:49 +0100 Subject: [PATCH 106/262] fail gracefully when no old filecache is present during upgrade --- lib/files/cache/upgrade.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 5be04b4207..899f6f7ac8 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -16,7 +16,14 @@ class Upgrade { VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - $oldEntriesResult = $oldEntriesQuery->execute(); + try{ + $oldEntriesResult = $oldEntriesQuery->execute(); + }catch(\Exception $e){ + return; + } + if(!$oldEntriesResult){ + return; + } while ($row = $oldEntriesResult->fetchRow()) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); From 01eb5d2790638ab836adc95a9726b6a1003562b9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sun, 2 Dec 2012 03:43:51 +0100 Subject: [PATCH 107/262] fix some edge cases while scanning the root of a storage --- lib/files/cache/scanner.php | 4 ++-- lib/files/filesystem.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 9ee509bb13..4c0ec9617f 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -71,7 +71,7 @@ class Scanner { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId)); $data = $this->getData($file); if ($data) { - if ($file !== '') { + if ($file) { $parent = dirname($file); if ($parent === '.') { $parent = ''; @@ -101,7 +101,7 @@ class Scanner { if ($dh = $this->storage->opendir($path)) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { - $child = ($path !== '') ? $path . '/' . $file : $file; + $child = ($path) ? $path . '/' . $file : $file; $data = $this->scanFile($child); if ($data) { if ($data['mimetype'] === 'httpd/unix-directory') { diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 4e3eb1989b..724c83b361 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -143,8 +143,8 @@ class Filesystem { * @return string */ static public function getMountPoint($path) { - \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); $path = self::normalizePath($path) . '/'; + \OC_Hook::emit(self::CLASSNAME, 'get_mountpoint', array('path' => $path)); $foundMountPoint = ''; $mountPoints = array_keys(self::$mounts); foreach ($mountPoints as $mountpoint) { @@ -205,7 +205,7 @@ class Filesystem { $mountpoint = self::getMountPoint($path); if ($mountpoint) { $storage = self::getStorage($mountpoint); - if ($mountpoint === $path) { + if ($mountpoint === $path or $mountpoint . '/' === $path) { $internalPath = ''; } else { $internalPath = substr($path, strlen($mountpoint)); From 18663100d9f68400fba1fc344874aacb62bb4659 Mon Sep 17 00:00:00 2001 From: Thomas Mueller Date: Sun, 2 Dec 2012 12:12:20 +0100 Subject: [PATCH 108/262] fixing syntax error + reformat the code --- apps/files_sharing/public.php | 358 ++++++++++++++++++---------------- 1 file changed, 185 insertions(+), 173 deletions(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index fcf7063955..27d2b9dfa4 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -9,10 +9,10 @@ if (isset($_GET['token'])) { unset($_GET['file']); $qry = \OC_DB::prepare('SELECT `source` FROM `*PREFIX*sharing` WHERE `target` = ? LIMIT 1'); $filepath = $qry->execute(array($_GET['token']))->fetchOne(); - if(isset($filepath)) { + if (isset($filepath)) { $rootView = new \OC\Files\View(''); $info = $rootView->getFileInfo($filepath, ''); - if(strtolower($info['mimetype']) == 'httpd/unix-directory') { + if (strtolower($info['mimetype']) == 'httpd/unix-directory') { $_GET['dir'] = $filepath; } else { $_GET['file'] = $filepath; @@ -27,7 +27,7 @@ function getID($path) { if (substr(\OC\Files\Filesystem::getMountPoint($path), -7, 6) == "Shared") { $path_parts = explode('/', $path, 5); $user = $path_parts[1]; - $intPath = '/'.$path_parts[4]; + $intPath = '/' . $path_parts[4]; $query = \OC_DB::prepare('SELECT `item_source` FROM `*PREFIX*share` WHERE `uid_owner` = ? AND `file_target` = ? '); $result = $query->execute(array($user, $intPath)); $row = $result->fetchRow(); @@ -40,11 +40,12 @@ function getID($path) { return $fileSource; } + // Enf of backward compatibility /** * lookup file path and owner by fetching it from the fscache - * needed becaus OC_FileCache::getPath($id, $user) already requires the user + * needed because OC_FileCache::getPath($id, $user) already requires the user * @param int $id * @return array */ @@ -64,60 +65,62 @@ if (isset($_GET['t'])) { $type = $linkItem['item_type']; $fileSource = $linkItem['file_source']; $shareOwner = $linkItem['uid_owner']; - - if (OCP\User::userExists($shareOwner) && $fileSource != -1 ) { - + + if (OCP\User::userExists($shareOwner) && $fileSource != -1) { + $pathAndUser = getPathAndUser($linkItem['file_source']); $fileOwner = $pathAndUser['user']; - + //if this is a reshare check the file owner also exists - if ($shareOwner != $fileOwner && ! OCP\User::userExists($fileOwner)) { - OCP\Util::writeLog('share', 'original file owner '.$fileOwner.' does not exist for share '.$linkItem['id'], \OCP\Util::ERROR); - header('HTTP/1.0 404 Not Found'); - $tmpl = new OCP\Template('', '404', 'guest'); - $tmpl->printPage(); - exit(); + if ($shareOwner != $fileOwner && !OCP\User::userExists($fileOwner)) { + OCP\Util::writeLog('share', 'original file owner ' . $fileOwner . ' does not exist for share ' . $linkItem['id'], \OCP\Util::ERROR); + header('HTTP/1.0 404 Not Found'); + $tmpl = new OCP\Template('', '404', 'guest'); + $tmpl->printPage(); + exit(); } - + //mount filesystem of file owner OC_Util::setupFS($fileOwner); } } -} else if (isset($_GET['file']) || isset($_GET['dir'])) { - OCP\Util::writeLog('share', 'Missing token, trying fallback file/dir links', \OCP\Util::DEBUG); - if (isset($_GET['dir'])) { - $type = 'folder'; - $path = $_GET['dir']; - if(strlen($path)>1 and substr($path, -1, 1)==='/') { - $path=substr($path, 0, -1); +} else { + if (isset($_GET['file']) || isset($_GET['dir'])) { + OCP\Util::writeLog('share', 'Missing token, trying fallback file/dir links', \OCP\Util::DEBUG); + if (isset($_GET['dir'])) { + $type = 'folder'; + $path = $_GET['dir']; + if (strlen($path) > 1 and substr($path, -1, 1) === '/') { + $path = substr($path, 0, -1); + } + $baseDir = $path; + $dir = $baseDir; + } else { + $type = 'file'; + $path = $_GET['file']; + if (strlen($path) > 1 and substr($path, -1, 1) === '/') { + $path = substr($path, 0, -1); + } } - $baseDir = $path; - $dir = $baseDir; - } else { - $type = 'file'; - $path = $_GET['file']; - if(strlen($path)>1 and substr($path, -1, 1)==='/') { - $path=substr($path, 0, -1); - } - } - $shareOwner = substr($path, 1, strpos($path, '/', 1) - 1); - - if (OCP\User::userExists($shareOwner)) { - OC_Util::setupFS($shareOwner); - $fileSource = getId($path); - if ($fileSource != -1 ) { - $linkItem = OCP\Share::getItemSharedWithByLink($type, $fileSource, $shareOwner); - $pathAndUser['path'] = $path; - $path_parts = explode('/', $path, 5); - $pathAndUser['user'] = $path_parts[1]; - $fileOwner = $path_parts[1]; + $shareOwner = substr($path, 1, strpos($path, '/', 1) - 1); + + if (OCP\User::userExists($shareOwner)) { + OC_Util::setupFS($shareOwner); + $fileSource = getId($path); + if ($fileSource != -1) { + $linkItem = OCP\Share::getItemSharedWithByLink($type, $fileSource, $shareOwner); + $pathAndUser['path'] = $path; + $path_parts = explode('/', $path, 5); + $pathAndUser['user'] = $path_parts[1]; + $fileOwner = $path_parts[1]; + } } } } if ($linkItem) { if (!isset($linkItem['item_type'])) { - OCP\Util::writeLog('share', 'No item type set for share id: '.$linkItem['id'], \OCP\Util::ERROR); + OCP\Util::writeLog('share', 'No item type set for share id: ' . $linkItem['id'], \OCP\Util::ERROR); header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); @@ -125,11 +128,13 @@ if ($linkItem) { } if (isset($linkItem['share_with'])) { // Authenticate share_with - $url = OCP\Util::linkToPublic('files').'&t='.$token; + $url = OCP\Util::linkToPublic('files') . '&t=' . $token; if (isset($_GET['file'])) { - $url .= '&file='.urlencode($_GET['file']); - } else if (isset($_GET['dir'])) { - $url .= '&dir='.urlencode($_GET['dir']); + $url .= '&file=' . urlencode($_GET['file']); + } else { + if (isset($_GET['dir'])) { + $url .= '&dir=' . urlencode($_GET['dir']); + } } if (isset($_POST['password'])) { $password = $_POST['password']; @@ -137,7 +142,7 @@ if ($linkItem) { // Check Password $forcePortable = (CRYPT_BLOWFISH != 1); $hasher = new PasswordHash(8, $forcePortable); - if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), $linkItem['share_with']))) { + if (!($hasher->CheckPassword($password . OC_Config::getValue('passwordsalt', ''), $linkItem['share_with']))) { $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); $tmpl->assign('URL', $url); $tmpl->assign('error', true); @@ -148,28 +153,30 @@ if ($linkItem) { $_SESSION['public_link_authenticated'] = $linkItem['id']; } } else { - OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type'].' for share id '.$linkItem['id'], \OCP\Util::ERROR); + OCP\Util::writeLog('share', 'Unknown share type ' . $linkItem['share_type'] . ' for share id ' . $linkItem['id'], \OCP\Util::ERROR); header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); exit(); } - // Check if item id is set in session - } else if (!isset($_SESSION['public_link_authenticated']) || $_SESSION['public_link_authenticated'] !== $linkItem['id']) { - // Prompt for password - $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); - $tmpl->assign('URL', $url); - $tmpl->printPage(); - exit(); + // Check if item id is set in session + } else { + if (!isset($_SESSION['public_link_authenticated']) || $_SESSION['public_link_authenticated'] !== $linkItem['id']) { + // Prompt for password + $tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest'); + $tmpl->assign('URL', $url); + $tmpl->printPage(); + exit(); + } } } - $basePath = substr($pathAndUser['path'] , strlen('/'.$fileOwner.'/files')); + $basePath = substr($pathAndUser['path'], strlen('/' . $fileOwner . '/files')); $path = $basePath; if (isset($_GET['path'])) { $path .= $_GET['path']; } if (!$path || !OC_Filesystem::isValidPath($path) || !OC_Filesystem::file_exists($path)) { - OCP\Util::writeLog('share', 'Invalid path '.$path.' for share id '.$linkItem['id'], \OCP\Util::ERROR); + OCP\Util::writeLog('share', 'Invalid path ' . $path . ' for share id ' . $linkItem['id'], \OCP\Util::ERROR); header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); @@ -179,13 +186,15 @@ if ($linkItem) { $file = basename($path); // Download the file if (isset($_GET['download'])) { - if (isset($_GET['path']) && $_GET['path'] !== '' ) { - if ( isset($_GET['files']) ) { // download selected files + if (isset($_GET['path']) && $_GET['path'] !== '') { + if (isset($_GET['files'])) { // download selected files OC_Files::get($path, $_GET['files'], $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false); - } else if (isset($_GET['path']) && $_GET['path'] != '' ) { // download a file from a shared directory - OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false); - } else { // download the whole shared directory - OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false); + } else { + if (isset($_GET['path']) && $_GET['path'] != '') { // download a file from a shared directory + OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false); + } else { // download the whole shared directory + OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false); + } } } else { // download a single shared file OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false); @@ -206,7 +215,7 @@ if ($linkItem) { $getPath = ''; } // - $urlLinkIdentifiers= (isset($token)?'&t='.$token:'').(isset($_GET['dir'])?'&dir='.$_GET['dir']:'').(isset($_GET['file'])?'&file='.$_GET['file']:''); + $urlLinkIdentifiers = (isset($token) ? '&t=' . $token : '') . (isset($_GET['dir']) ? '&dir=' . $_GET['dir'] : '') . (isset($_GET['file']) ? '&file=' . $_GET['file'] : ''); // Show file list if (OC_Filesystem::is_dir($path)) { OCP\Util::addStyle('files', 'files'); @@ -219,9 +228,9 @@ if ($linkItem) { if ($i['type'] == 'file') { $fileinfo = pathinfo($i['name']); $i['basename'] = $fileinfo['filename']; - $i['extension'] = isset($fileinfo['extension']) ? ('.'.$fileinfo['extension']) : ''; + $i['extension'] = isset($fileinfo['extension']) ? ('.' . $fileinfo['extension']) : ''; } - $i['directory'] = '/'.substr($i['directory'], $rootLength); + $i['directory'] = '/' . substr($i['directory'], $rootLength); if ($i['directory'] == '/') { $i['directory'] = ''; } @@ -238,98 +247,31 @@ if ($linkItem) { //add subdir breadcrumbs foreach (explode('/', urldecode($_GET['path'])) as $i) { if ($i != '') { - $pathtohere .= '/'.$i; + $pathtohere .= '/' . $i; $breadcrumb[] = array('dir' => $pathtohere, 'name' => $i); - $path = $linkItem['path']; - if (isset($_GET['path'])) { - $path .= $_GET['path']; - $dir .= $_GET['path']; - if (!\OC\Files\Filesystem::file_exists($path)) { - header('HTTP/1.0 404 Not Found'); - $tmpl = new OCP\Template('', '404', 'guest'); - $tmpl->printPage(); - exit(); - } - } + $path = $linkItem['path']; + if (isset($_GET['path'])) { + $path .= $_GET['path']; + $dir .= $_GET['path']; + if (!\OC\Files\Filesystem::file_exists($path)) { + header('HTTP/1.0 404 Not Found'); + $tmpl = new OCP\Template('', '404', 'guest'); + $tmpl->printPage(); + exit(); + } + } - $list = new OCP\Template('files', 'part.list', ''); - $list->assign('files', $files, false); - $list->assign('publicListView', true); - $list->assign('baseURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&path=', false); - $list->assign('downloadURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&download&path=', false); - $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '' ); - $breadcrumbNav->assign('breadcrumb', $breadcrumb, false); - $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&path=', false); - $folder = new OCP\Template('files', 'index', ''); - $folder->assign('fileList', $list->fetchPage(), false); - $folder->assign('breadcrumb', $breadcrumbNav->fetchPage(), false); - $folder->assign('isCreatable', false); - $folder->assign('permissions', 0); - $folder->assign('files', $files); - $folder->assign('uploadMaxFilesize', 0); - $folder->assign('uploadMaxHumanFilesize', 0); - $folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); - $tmpl->assign('folder', $folder->fetchPage(), false); - $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); - $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&download&path='.urlencode($getPath)); - } else { - // Show file preview if viewer is available - if ($type == 'file') { - $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&download'); - } else { - OCP\Util::addStyle('files_sharing', 'public'); - OCP\Util::addScript('files_sharing', 'public'); - OCP\Util::addScript('files', 'fileactions'); - $tmpl = new OCP\Template('files_sharing', 'public', 'base'); - $tmpl->assign('owner', $uidOwner); - // Show file list - if (OC_Filesystem::is_dir($path)) { - OCP\Util::addStyle('files', 'files'); - OCP\Util::addScript('files', 'files'); - OCP\Util::addScript('files', 'filelist'); - $files = array(); - $rootLength = strlen($baseDir) + 1; - foreach (OC_Files::getDirectoryContent($path) as $i) { - $i['date'] = OCP\Util::formatDate($i['mtime']); - if ($i['type'] == 'file') { - $fileinfo = pathinfo($i['name']); - $i['basename'] = $fileinfo['filename']; - $i['extension'] = isset($fileinfo['extension']) ? ('.'.$fileinfo['extension']) : ''; - } - $i['directory'] = '/'.substr('/'.$uidOwner.'/files'.$i['directory'], $rootLength); - if ($i['directory'] == '/') { - $i['directory'] = ''; - } - $i['permissions'] = OCP\PERMISSION_READ; - $files[] = $i; - } - // Make breadcrumb - $breadcrumb = array(); - $pathtohere = ''; - $count = 1; - foreach (explode('/', $dir) as $i) { - if ($i != '') { - if ($i != $baseDir) { - $pathtohere .= '/'.$i; - } - if ( strlen($pathtohere) < strlen($_GET['dir'])) { - continue; - } - $breadcrumb[] = array('dir' => str_replace($_GET['dir'], "", $pathtohere, $count), 'name' => $i); - } - } $list = new OCP\Template('files', 'part.list', ''); $list->assign('files', $files, false); $list->assign('publicListView', true); - $list->assign('baseURL', OCP\Util::linkToPublic('files').'&dir='.urlencode($_GET['dir']).'&path=', false); - $list->assign('downloadURL', OCP\Util::linkToPublic('files').'&download&dir='.urlencode($_GET['dir']).'&path=', false); - $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '' ); + $list->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path=', false); + $list->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=', false); + $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', ''); $breadcrumbNav->assign('breadcrumb', $breadcrumb, false); - $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files').'&dir='.urlencode($_GET['dir']).'&path=', false); + $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&path=', false); $folder = new OCP\Template('files', 'index', ''); $folder->assign('fileList', $list->fetchPage(), false); $folder->assign('breadcrumb', $breadcrumbNav->fetchPage(), false); - $folder->assign('dir', basename($dir)); $folder->assign('isCreatable', false); $folder->assign('permissions', 0); $folder->assign('files', $files); @@ -337,43 +279,113 @@ if ($linkItem) { $folder->assign('uploadMaxHumanFilesize', 0); $folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $tmpl->assign('folder', $folder->fetchPage(), false); - $tmpl->assign('uidOwner', $uidOwner); - $tmpl->assign('dir', basename($dir)); - $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); - if (isset($_GET['path'])) { - $getPath = $_GET['path']; - } else { - $getPath = ''; - } - $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&download&dir='.urlencode($_GET['dir']).'&path='.urlencode($getPath), false); + $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download&path=' . urlencode($getPath)); } else { // Show file preview if viewer is available - $tmpl->assign('uidOwner', $uidOwner); - $tmpl->assign('dir', dirname($path)); - $tmpl->assign('filename', basename($path)); - $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); if ($type == 'file') { - $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&file='.urlencode($_GET['file']).'&download', false); + $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . $urlLinkIdentifiers . '&download'); } else { - if (isset($_GET['path'])) { - $getPath = $_GET['path']; + OCP\Util::addStyle('files_sharing', 'public'); + OCP\Util::addScript('files_sharing', 'public'); + OCP\Util::addScript('files', 'fileactions'); + $tmpl = new OCP\Template('files_sharing', 'public', 'base'); + $tmpl->assign('owner', $uidOwner); + // Show file list + if (OC_Filesystem::is_dir($path)) { + OCP\Util::addStyle('files', 'files'); + OCP\Util::addScript('files', 'files'); + OCP\Util::addScript('files', 'filelist'); + $files = array(); + $rootLength = strlen($baseDir) + 1; + foreach (OC_Files::getDirectoryContent($path) as $i) { + $i['date'] = OCP\Util::formatDate($i['mtime']); + if ($i['type'] == 'file') { + $fileinfo = pathinfo($i['name']); + $i['basename'] = $fileinfo['filename']; + $i['extension'] = isset($fileinfo['extension']) ? ('.' . $fileinfo['extension']) : ''; + } + $i['directory'] = '/' . substr('/' . $uidOwner . '/files' . $i['directory'], $rootLength); + if ($i['directory'] == '/') { + $i['directory'] = ''; + } + $i['permissions'] = OCP\PERMISSION_READ; + $files[] = $i; + } + // Make breadcrumb + $breadcrumb = array(); + $pathtohere = ''; + $count = 1; + foreach (explode('/', $dir) as $i) { + if ($i != '') { + if ($i != $baseDir) { + $pathtohere .= '/' . $i; + } + if (strlen($pathtohere) < strlen($_GET['dir'])) { + continue; + } + $breadcrumb[] = array('dir' => str_replace($_GET['dir'], "", $pathtohere, $count), 'name' => $i); + } + } + $list = new OCP\Template('files', 'part.list', ''); + $list->assign('files', $files, false); + $list->assign('publicListView', true); + $list->assign('baseURL', OCP\Util::linkToPublic('files') . '&dir=' . urlencode($_GET['dir']) . '&path=', false); + $list->assign('downloadURL', OCP\Util::linkToPublic('files') . '&download&dir=' . urlencode($_GET['dir']) . '&path=', false); + $breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', ''); + $breadcrumbNav->assign('breadcrumb', $breadcrumb, false); + $breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files') . '&dir=' . urlencode($_GET['dir']) . '&path=', false); + $folder = new OCP\Template('files', 'index', ''); + $folder->assign('fileList', $list->fetchPage(), false); + $folder->assign('breadcrumb', $breadcrumbNav->fetchPage(), false); + $folder->assign('dir', basename($dir)); + $folder->assign('isCreatable', false); + $folder->assign('permissions', 0); + $folder->assign('files', $files); + $folder->assign('uploadMaxFilesize', 0); + $folder->assign('uploadMaxHumanFilesize', 0); + $folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); + $tmpl->assign('folder', $folder->fetchPage(), false); + $tmpl->assign('uidOwner', $uidOwner); + $tmpl->assign('dir', basename($dir)); + $tmpl->assign('filename', basename($path)); + $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); + if (isset($_GET['path'])) { + $getPath = $_GET['path']; + } else { + $getPath = ''; + } + $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . '&download&dir=' . urlencode($_GET['dir']) . '&path=' . urlencode($getPath), false); } else { - $getPath = ''; + // Show file preview if viewer is available + $tmpl->assign('uidOwner', $uidOwner); + $tmpl->assign('dir', dirname($path)); + $tmpl->assign('filename', basename($path)); + $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); + if ($type == 'file') { + $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . '&file=' . urlencode($_GET['file']) . '&download', false); + } else { + if (isset($_GET['path'])) { + $getPath = $_GET['path']; + } else { + $getPath = ''; + } + $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files') . '&download&dir=' . urlencode($_GET['dir']) . '&path=' . urlencode($getPath), false); + } } - $tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&download&dir='.urlencode($_GET['dir']).'&path='.urlencode($getPath), false); + $tmpl->printPage(); } } $tmpl->printPage(); } + exit(); + } else { + OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); } - $tmpl->printPage(); } - exit(); -} else { - OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG); } header('HTTP/1.0 404 Not Found'); $tmpl = new OCP\Template('', '404', 'guest'); $tmpl->printPage(); + From 317cd4c70a3042c4e16424cafb4a8b34c8cd8c3c Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 6 Dec 2012 17:49:35 +0100 Subject: [PATCH 109/262] catch error if old filecache table is not present during upgrade --- lib/files/cache/upgrade.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 899f6f7ac8..ebac387de9 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -15,13 +15,17 @@ class Upgrade { $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); - $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - try{ - $oldEntriesResult = $oldEntriesQuery->execute(); - }catch(\Exception $e){ + try { + $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child + } catch (\Exception $e) { return; } - if(!$oldEntriesResult){ + try { + $oldEntriesResult = $oldEntriesQuery->execute(); + } catch (\Exception $e) { + return; + } + if (!$oldEntriesResult) { return; } From 8635699db932959ac147193473b014406b0e9e09 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Dec 2012 01:06:21 +0100 Subject: [PATCH 110/262] fix cache behaviour for non existing files --- lib/files/view.php | 26 ++++++++++++++------------ tests/lib/files/cache/cache.php | 5 +++++ tests/lib/files/view.php | 3 +++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 468808566a..994dbcc85c 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -691,20 +691,22 @@ class View { $data = $cache->get($internalPath); - if ($data['mimetype'] === 'httpd/unix-directory') { - //add the sizes of other mountpoints to the folder - $mountPoints = Filesystem::getMountPoints($path); - foreach ($mountPoints as $mountPoint) { - $subStorage = Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); + if ($data) { + if ($data['mimetype'] === 'httpd/unix-directory') { + //add the sizes of other mountpoints to the folder + $mountPoints = Filesystem::getMountPoints($path); + foreach ($mountPoints as $mountPoint) { + $subStorage = Filesystem::getStorage($mountPoint); + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); - $data['size'] += $rootEntry['size']; + $data['size'] += $rootEntry['size']; + } } - } - $permissionsCache = $storage->getPermissionsCache(); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + $permissionsCache = $storage->getPermissionsCache(); + $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + } } return $data; } @@ -888,7 +890,7 @@ class View { * @param string $path * @return string */ - public function getETag($path){ + public function getETag($path) { /** * @var Storage\Storage $storage * @var string $internalPath diff --git a/tests/lib/files/cache/cache.php b/tests/lib/files/cache/cache.php index e9105cd5ab..a2b131ac0a 100644 --- a/tests/lib/files/cache/cache.php +++ b/tests/lib/files/cache/cache.php @@ -192,6 +192,11 @@ class Cache extends \UnitTestCase { $this->assertEquals($file3, $this->cache->getIncomplete()); } + function testNonExisting() { + $this->assertFalse($this->cache->get('foo.txt')); + $this->assertEquals(array(), $this->cache->getFolderContents('foo')); + } + public function tearDown() { $this->cache->clear(); } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index ed08dcc114..1b8f6dc1e8 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -92,6 +92,9 @@ class View extends \PHPUnit_Framework_TestCase { $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertTrue($cachedData['encrypted']); $this->assertEquals($cachedData['fileid'], $id); + + $this->assertFalse($rootView->getFileInfo('/non/existing')); + $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } public function testAutoScan() { From 438d3c21f651240e416b6e50ad49f72dd079a9ae Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Dec 2012 01:24:53 +0100 Subject: [PATCH 111/262] actually connect the filesystem hooks to the cache updater --- lib/files/filesystem.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 724c83b361..c5b56ba9f0 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -685,4 +685,8 @@ class Filesystem { \OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); \OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); +\OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); +\OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); +\OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); + \OC_Util::setupFS(); From cc0a0df88b3b6fdd2b1f9c85349683eb640f9670 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Dec 2012 01:25:21 +0100 Subject: [PATCH 112/262] one additional test case for the cache updater --- tests/lib/files/cache/updater.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index b2eccf9130..d19966c191 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -99,6 +99,11 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->cache->inCache('foo.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); + + Filesystem::mkdir('bar_folder'); + $this->assertTrue($this->cache->inCache('bar_folder')); + Filesystem::rmdir('bar_folder'); + $this->assertFalse($this->cache->inCache('bar_folder')); } public function testRename() { From c6a5ce54a706efe6d157ec30a3960a3ebf8719a7 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 02:22:09 +0100 Subject: [PATCH 113/262] these functions should be static --- lib/files.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/files.php b/lib/files.php index 768a2ad219..2d7e335e96 100644 --- a/lib/files.php +++ b/lib/files.php @@ -28,11 +28,11 @@ class OC_Files { static $tmpFiles = array(); - public function getFileInfo($path){ + static public function getFileInfo($path){ return \OC\Files\Filesystem::getFileInfo($path); } - public function getDirectoryContent($path){ + static public function getDirectoryContent($path){ return \OC\Files\Filesystem::getDirectoryContent($path); } From bc52f121626bb1bb1f67bc1f876d0420d153b3d1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 02:29:34 +0100 Subject: [PATCH 114/262] dont insert and entry in the filecache during upgrade if the id already exists in the filecache most likely the result from an incompelte upgrade --- lib/files/cache/upgrade.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index ebac387de9..9219deebef 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -29,7 +29,13 @@ class Upgrade { return; } + $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + while ($row = $oldEntriesResult->fetchRow()) { + if($checkExistingQuery->execute(array($row['id']))->fetchRow()){ + continue; + } + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); /** * @var \OC\Files\Storage\Storage $storage From 4be039e6cbc0a826b07fc2af1a6c6d94888a9187 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 03:10:56 +0100 Subject: [PATCH 115/262] Filecache Watcher: use scan or scanFile based on the current item, not the cached item --- lib/files/cache/watcher.php | 6 ++++-- tests/lib/files/cache/watcher.php | 34 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php index d6039d9945..31059ec7f5 100644 --- a/lib/files/cache/watcher.php +++ b/lib/files/cache/watcher.php @@ -44,12 +44,14 @@ class Watcher { public function checkUpdate($path) { $cachedEntry = $this->cache->get($path); if ($this->storage->hasUpdated($path, $cachedEntry['mtime'])) { - if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + if ($this->storage->is_dir($path)) { $this->scanner->scan($path, Scanner::SCAN_SHALLOW); - $this->cleanFolder($path); } else { $this->scanner->scanFile($path); } + if ($cachedEntry['mimetype'] === 'httpd/unix-directory') { + $this->cleanFolder($path); + } $this->cache->correctFolderSize($path); } } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index 0125dd843b..07c8ac3640 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -63,6 +63,40 @@ class Watcher extends \PHPUnit_Framework_TestCase { $this->assertFalse($cache->inCache('folder/bar2.txt')); } + public function testFileToFolder() { + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('', array('mtime' => 10)); + + $storage->unlink('foo.txt'); + $storage->rename('folder','foo.txt'); + $updater->checkUpdate(''); + + $entry= $cache->get('foo.txt'); + $this->assertEquals(-1, $entry['size']); + $this->assertEquals('httpd/unix-directory', $entry['mimetype']); + $this->assertFalse($cache->inCache('folder')); + $this->assertFalse($cache->inCache('folder/bar.txt')); + + $storage = $this->getTestStorage(); + $cache = $storage->getCache(); + $updater = new \OC\Files\Cache\Watcher($storage); + + //set the mtime to the past so it can detect an mtime change + $cache->put('foo.txt', array('mtime' => 10)); + + $storage->unlink('foo.txt'); + $storage->rename('folder','foo.txt'); + $updater->checkUpdate('foo.txt'); + + $entry= $cache->get('foo.txt'); + $this->assertEquals('httpd/unix-directory', $entry['mimetype']); + $this->assertTrue($cache->inCache('foo.txt/bar.txt')); + } + /** * @param bool $scan * @return \OC\Files\Storage\Storage From cf3665057c0c195bb3a0e2d9f8f8746f5d2f5787 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 03:20:50 +0100 Subject: [PATCH 116/262] make sure folders that are not fully scanned are at least shallow scanned when we open them the fact that they are in the cache does not mean they are scanned --- lib/files/view.php | 2 +- tests/lib/files/view.php | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/files/view.php b/lib/files/view.php index 994dbcc85c..6d917bb585 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -728,7 +728,7 @@ class View { if ($storage) { $cache = $storage->getCache(); - if (!$cache->inCache($internalPath)) { + if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 1b8f6dc1e8..712166ab32 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -97,6 +97,19 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } + function testCacheIncompleteFolder() { + $storage1 = $this->getTestStorage(false); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + $rootView = new \OC\Files\View(''); + + $entries = $rootView->getDirectoryContent('/'); + $this->assertEquals(3, count($entries)); + + // /folder will already be in the cache but not scanned + $entries = $rootView->getDirectoryContent('/folder'); + $this->assertEquals(1, count($entries)); + } + public function testAutoScan() { $storage1 = $this->getTestStorage(false); $storage2 = $this->getTestStorage(false); From 8951769cae5f1acc9b709ac676fffe26513d14f6 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 15 Dec 2012 17:16:26 -0500 Subject: [PATCH 117/262] Check sub storage isn't null or false --- lib/files/view.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 6d917bb585..592c484a21 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -697,10 +697,11 @@ class View { $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); - $subCache = $subStorage->getCache(); - $rootEntry = $subCache->get(''); - - $data['size'] += $rootEntry['size']; + if ($subStorage) { + $subCache = $subStorage->getCache(); + $rootEntry = $subCache->get(''); + $data['size'] += $rootEntry['size']; + } } } From b12abb2c94072ab5b84d0477ecb7ce9789bdda0d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 15 Dec 2012 23:28:07 +0100 Subject: [PATCH 118/262] use numeric ids for storages in the filecache --- db_structure.xml | 40 +++++++++++++++++++++++++++++++-- lib/files/cache/cache.php | 44 ++++++++++++++++++++++++++++--------- lib/files/cache/upgrade.php | 21 ++++++++++++++++-- lib/util.php | 2 +- 4 files changed, 92 insertions(+), 15 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 2856ee4ff9..aa0916264c 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -58,6 +58,42 @@
+ + + *dbprefix*storages + + + + + id + text + + true + 64 + + + + numeric_id + integer + 0 + true + 1 + 4 + + + + storages_id_index + true + + id + ascending + + + + + +
+ *dbprefix*filecache @@ -75,10 +111,10 @@ storage - text + integer true - 64 + 4 diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5aeb6f25af..3ebae9baa5 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -29,6 +29,13 @@ class Cache { */ private $storageId; + /** + * numeric storage id + * + * @var int $numericId + */ + private $numericId; + /** * @param \OC\Files\Storage\Storage|string $storage */ @@ -38,6 +45,20 @@ class Cache { } else { $this->storageId = $storage; } + + $query = \OC_DB::prepare('SELECT `numeric_id` FROM `*PREFIX*storages` WHERE `id` = ?'); + $result = $query->execute(array($this->storageId)); + if ($row = $result->fetchRow()) { + $this->numericId = $row['numeric_id']; + } else { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*storages`(`id`) VALUES(?)'); + $query->execute(array($this->storageId)); + $this->numericId = \OC_DB::insertid('*PREFIX*filecache'); + } + } + + public function getNumericStorageId() { + return $this->numericId; } /** @@ -49,7 +70,7 @@ class Cache { public function get($file) { if (is_string($file) or $file == '') { $where = 'WHERE `storage` = ? AND `path_hash` = ?'; - $params = array($this->storageId, md5($file)); + $params = array($this->numericId, md5($file)); } else { //file id $where = 'WHERE `fileid` = ?'; $params = array($file); @@ -128,7 +149,7 @@ class Cache { list($queryParts, $params) = $this->buildParts($data); $queryParts[] = '`storage`'; - $params[] = $this->storageId; + $params[] = $this->numericId; $valuesPlaceholder = array_fill(0, count($queryParts), '?'); $query = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`(' . implode(', ', $queryParts) . ') VALUES(' . implode(', ', $valuesPlaceholder) . ')'); @@ -189,7 +210,7 @@ class Cache { $pathHash = md5($file); $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($this->storageId, $pathHash)); + $result = $query->execute(array($this->numericId, $pathHash)); if ($row = $result->fetchRow()) { return $row['fileid']; @@ -273,7 +294,10 @@ class Cache { * remove all entries for files that are stored on the storage from the cache */ public function clear() { - $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage=?'); + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*filecache` WHERE storage = ?'); + $query->execute(array($this->numericId)); + + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*storages` WHERE id = ?'); $query->execute(array($this->storageId)); } @@ -285,7 +309,7 @@ class Cache { public function getStatus($file) { $pathHash = md5($file); $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?'); - $result = $query->execute(array($this->storageId, $pathHash)); + $result = $query->execute(array($this->numericId, $pathHash)); if ($row = $result->fetchRow()) { if ((int)$row['size'] === -1) { return self::SHALLOW; @@ -312,7 +336,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' ); - $result = $query->execute(array($pattern, $this->storageId)); + $result = $query->execute(array($pattern, $this->numericId)); $files = array(); while ($row = $result->fetchRow()) { $files[] = $row; @@ -336,7 +360,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); - $result = $query->execute(array($mimetype, $this->storageId)); + $result = $query->execute(array($mimetype, $this->numericId)); return $result->fetchAll(); } @@ -368,7 +392,7 @@ class Cache { return 0; } $query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `parent` = ? AND `storage` = ?'); - $result = $query->execute(array($id, $this->storageId)); + $result = $query->execute(array($id, $this->numericId)); $totalSize = 0; $hasChilds = 0; while ($row = $result->fetchRow()) { @@ -395,7 +419,7 @@ class Cache { */ public function getAll() { $query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?'); - $result = $query->execute(array($this->storageId)); + $result = $query->execute(array($this->numericId)); $ids = array(); while ($row = $result->fetchRow()) { $ids[] = $row['fileid']; @@ -414,7 +438,7 @@ class Cache { */ public function getIncomplete() { $query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1'); - $query->execute(array($this->storageId)); + $query->execute(array($this->numericId)); if ($row = $query->fetchRow()) { return $row['path']; } else { diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 9219deebef..77db4c2339 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -11,6 +11,8 @@ namespace OC\Files\Cache; class Upgrade { static $permissionsCaches = array(); + static $numericIds = array(); + static function upgrade() { $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); @@ -32,7 +34,7 @@ class Upgrade { $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); while ($row = $oldEntriesResult->fetchRow()) { - if($checkExistingQuery->execute(array($row['id']))->fetchRow()){ + if ($checkExistingQuery->execute(array($row['id']))->fetchRow()) { continue; } @@ -42,7 +44,7 @@ class Upgrade { * @var string $internalPath; */ $pathHash = md5($internalPath); - $storageId = $storage->getId(); + $storageId = self::getNumericId($storage); $parentId = ($internalPath === '') ? -1 : $row['parent']; $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); @@ -64,4 +66,19 @@ class Upgrade { } return self::$permissionsCaches[$storageId]; } + + /** + * get the numeric storage id + * + * @param \OC\Files\Storage\Storage $storage + * @return int + */ + static function getNumericId($storage) { + $storageId = $storage->getId(); + if (!isset(self::$numericIds[$storageId])) { + $cache = new Cache($storage); + self::$numericIds[$storageId] = $cache->getNumericStorageId(); + } + return self::$numericIds[$storageId]; + } } diff --git a/lib/util.php b/lib/util.php index 0f6ead2419..4411b32731 100755 --- a/lib/util.php +++ b/lib/util.php @@ -75,7 +75,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,02); + return array(4,91,04); } /** From bf05ff351faa693337107ed4a316e36e9aacd296 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 15 Dec 2012 19:44:46 -0500 Subject: [PATCH 119/262] Initial support for file sharing with filesystem branch --- apps/files_sharing/appinfo/app.php | 3 + apps/files_sharing/lib/cache.php | 220 +++++++++++++++++++++++ apps/files_sharing/lib/permissions.php | 82 +++++++++ apps/files_sharing/lib/scanner.php | 69 +++++++ apps/files_sharing/lib/share/file.php | 74 ++++---- apps/files_sharing/lib/share/folder.php | 28 --- apps/files_sharing/lib/sharedstorage.php | 148 ++++++--------- lib/public/share.php | 8 +- 8 files changed, 475 insertions(+), 157 deletions(-) create mode 100644 apps/files_sharing/lib/cache.php create mode 100644 apps/files_sharing/lib/permissions.php create mode 100644 apps/files_sharing/lib/scanner.php diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 210c78ad17..189fd20cae 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -3,6 +3,9 @@ OC::$CLASSPATH['OC_Share_Backend_File'] = "apps/files_sharing/lib/share/file.php"; OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'apps/files_sharing/lib/share/folder.php'; OC::$CLASSPATH['OC\Files\Storage\Shared'] = "apps/files_sharing/lib/sharedstorage.php"; +OC::$CLASSPATH['OC\Files\Cache\Shared_Cache'] = 'apps/files_sharing/lib/cache.php'; +OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'apps/files_sharing/lib/permissions.php'; +OC::$CLASSPATH['OC\Files\Cache\Shared_Scanner'] = 'apps/files_sharing/lib/scanner.php'; OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php new file mode 100644 index 0000000000..196e767cf6 --- /dev/null +++ b/apps/files_sharing/lib/cache.php @@ -0,0 +1,220 @@ +. +*/ + +namespace OC\Files\Cache; + +/** + * Metadata cache for shared files + * + * don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead + */ +class Shared_Cache extends Cache { + + private $files = array(); + + /** + * @brief Get the source cache of a shared file or folder + * @param string Shared target file path + * @return \OC\Files\Storage\Cache + */ + private function getSourceCache($target) { + $source = \OC_Share_Backend_File::getSource($target); + if (isset($source['path'])) { + $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; + \OC\Files\Filesystem::initMountPoints($source['uid_owner']); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source['path']); + $this->files[$target] = $internalPath; + return $storage->getCache(); + } + return false; + } + + /** + * get the stored metadata of a file or folder + * + * @param string/int $file + * @return array + */ + public function get($file) { + if (is_string($file)) { + if ($cache = $this->getSourceCache($file)) { + return $cache->get($this->files[$file]); + } + } else { + $query = \OC_DB::prepare( + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + $result = $query->execute(array($file)); + $data = $result->fetchRow(); + $data['fileid'] = (int)$data['fileid']; + $data['size'] = (int)$data['size']; + $data['mtime'] = (int)$data['mtime']; + $data['encrypted'] = (bool)$data['encrypted']; + return $data; + } + return false; + } + + /** + * get the metadata of all files stored in $folder + * + * @param string $folder + * @return array + */ + public function getFolderContents($folder) { + if ($folder == '') { + return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS); + } else { + return $this->getSourceCache($folder)->getFolderContents('/'.$this->files[$folder]); + } + } + + /** + * store meta data for a file or folder + * + * @param string $file + * @param array $data + * + * @return int file id + */ + public function put($file, array $data) { + if ($cache = $this->getSourceCache($file)) { + return $cache->put($this->files[$file]); + } + return false; + } + + /** + * get the file id for a file + * + * @param string $file + * @return int + */ + public function getId($file) { + if ($cache = $this->getSourceCache($file)) { + return $cache->getId($this->files[$file]); + } + return -1; + } + + /** + * remove a file or folder from the cache + * + * @param string $file + */ + public function remove($file) { + if ($cache = $this->getSourceCache($file)) { + $cache->remove($this->files[$file]); + } + } + + /** + * Move a file or folder in the cache + * + * @param string $source + * @param string $target + */ + public function move($source, $target) { + if ($cache = $this->getSourceCache($source)) { + $targetPath = \OC_Share_Backend_File::getSourcePath(dirname($target)); + if ($targetPath) { + $targetPath .= '/'.basename($target); + $cache->move($this->files[$source], $targetPath); + } + + } + } + + /** + * remove all entries for files that are stored on the storage from the cache + */ + public function clear() { + // Not a valid action for Shared Cache + } + + /** + * @param string $file + * + * @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE + */ + public function getStatus($file) { + if ($cache = $this->getSourceCache($file)) { + return $cache->getStatus($this->files[$file]); + } + return false; + } + + /** + * search for files matching $pattern + * + * @param string $pattern + * @return array of file data + */ + public function search($pattern) { + // TODO + } + + /** + * search for files by mimetype + * + * @param string $part1 + * @param string $part2 + * @return array + */ + public function searchByMime($mimetype) { + if (strpos($mimetype, '/')) { + $where = '`mimetype` = ?'; + } else { + $where = '`mimepart` = ?'; + } + $ids = $this->getAll(); + $placeholders = join(',', array_fill(0, count($ids), '?')); + $query = \OC_DB::prepare(' + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `fileid` IN = ('.$placeholders.')' + ); + $result = $query->execute(array_merge(array($mimetype), $ids)); + return $result->fetchAll(); + } + + /** + * get the size of a folder and set it in the cache + * + * @param string $path + * @return int + */ + public function calculateFolderSize($path) { + if ($cache = $this->getSourceCache($path)) { + return $cache->calculateFolderSize($this->files[$path]); + } + return 0; + } + + /** + * get all file ids on the files on the storage + * + * @return int[] + */ + public function getAll() { + return OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL); + } + +} \ No newline at end of file diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php new file mode 100644 index 0000000000..51ae4cf102 --- /dev/null +++ b/apps/files_sharing/lib/permissions.php @@ -0,0 +1,82 @@ +. +*/ +namespace OC\Files\Cache; + +class Shared_Permissions { + + /** + * get the permissions for a single file + * + * @param int $fileId + * @param string $user + * @return int (-1 if file no permissions set) + */ + static public function get($fileId, $user) { + $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + if ($source) { + return $source['permissions']; + } else { + return -1; + } + } + + /** + * set the permissions of a file + * + * @param int $fileId + * @param string $user + * @param int $permissions + */ + static public function set($fileId, $user, $permissions) { + // Not a valid action for Shared Permissions + } + + /** + * get the permissions of multiply files + * + * @param int[] $fileIds + * @param string $user + * @return int[] + */ + static public function getMultiple($fileIds, $user) { + if (count($fileIds) === 0) { + return array(); + } + foreach ($fileIds as $fileId) { + $filePermissions[$fileId] = self::get($fileId, $user); + } + return $filePermissions; + } + + /** + * remove the permissions for a file + * + * @param int $fileId + * @param string $user + */ + static public function remove($fileId, $user) { + // Not a valid action for Shared Permissions + } + + static public function removeMultiple($fileIds, $user) { + // Not a valid action for Shared Permissions + } +} diff --git a/apps/files_sharing/lib/scanner.php b/apps/files_sharing/lib/scanner.php new file mode 100644 index 0000000000..d13d2f9cbc --- /dev/null +++ b/apps/files_sharing/lib/scanner.php @@ -0,0 +1,69 @@ +. +*/ + +namespace OC\Files\Cache; + +class Shared_Scanner extends Scanner { + + public function __construct(\OC\Files\Storage\Storage $storage) { + + } + + /** + * get all the metadata of a file or folder + * * + * + * @param string $path + * @return array with metadata of the file + */ + public function getData($path) { + // Not a valid action for Shared Scanner + } + + /** + * scan a single file and store it in the cache + * + * @param string $file + * @return array with metadata of the scanned file + */ + public function scanFile($file) { + // Not a valid action for Shared Scanner + } + + /** + * scan all the files in a folder and store them in the cache + * + * @param string $path + * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive + * @return int the size of the scanned folder or -1 if the size is unknown at this stage + */ + public function scan($path, $recursive = self::SCAN_RECURSIVE) { + // Not a valid action for Shared Scanner + } + + /** + * walk over any folders that are not fully scanned yet and scan them + */ + public function backgroundScan() { + // Not a valid action for Shared Scanner + } + +} \ No newline at end of file diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index ac58523683..52220dc5b2 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -22,16 +22,17 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { const FORMAT_SHARED_STORAGE = 0; - const FORMAT_FILE_APP = 1; - const FORMAT_FILE_APP_ROOT = 2; + const FORMAT_GET_FOLDER_CONTENTS = 1; + const FORMAT_GET_ALL = 2; const FORMAT_OPENDIR = 3; private $path; public function isValidSource($itemSource, $uidOwner) { - $path = OC_FileCache::getPath($itemSource, $uidOwner); - if ($path) { - $this->path = $path; + $query = \OC_DB::prepare('SELECT `name` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + $result = $query->execute(array($itemSource)); + if ($row = $result->fetchRow()) { + $this->path = $row['name']; return true; } return false; @@ -70,50 +71,29 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { public function formatItems($items, $format, $parameters = null) { if ($format == self::FORMAT_SHARED_STORAGE) { // Only 1 item should come through for this format call - return array('path' => $items[key($items)]['path'], 'permissions' => $items[key($items)]['permissions']); - } else if ($format == self::FORMAT_FILE_APP) { - if (isset($parameters['mimetype_filter']) && $parameters['mimetype_filter']) { - $mimetype_filter = $parameters['mimetype_filter']; - } + return array('path' => $items[key($items)]['path'], 'permissions' => $items[key($items)]['permissions'], 'uid_owner' => $items[key($items)]['uid_owner']); + } else if ($format == self::FORMAT_GET_FOLDER_CONTENTS) { $files = array(); foreach ($items as $item) { - if (isset($mimetype_filter) - && strpos($item['mimetype'], $mimetype_filter) !== 0 - && $item['mimetype'] != 'httpd/unix-directory') { - continue; - } $file = array(); - $file['id'] = $item['file_source']; + $file['fileid'] = $item['file_source']; + $file['storage'] = $item['storage']; $file['path'] = $item['file_target']; + $file['parent'] = $item['file_parent']; $file['name'] = basename($item['file_target']); - $file['ctime'] = $item['ctime']; - $file['mtime'] = $item['mtime']; $file['mimetype'] = $item['mimetype']; $file['size'] = $item['size']; + $file['mtime'] = $item['mtime']; $file['encrypted'] = $item['encrypted']; - $file['versioned'] = $item['versioned']; - $file['directory'] = $parameters['folder']; - $file['type'] = ($item['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file'; - $file['permissions'] = $item['permissions']; - if ($file['type'] == 'file') { - // Remove Create permission if type is file - $file['permissions'] &= ~OCP\PERMISSION_CREATE; - } - // NOTE: Temporary fix to allow unsharing of files in root of Shared directory - $file['permissions'] |= OCP\PERMISSION_DELETE; $files[] = $file; } return $files; - } else if ($format == self::FORMAT_FILE_APP_ROOT) { - $mtime = 0; - $size = 0; + } else if ($format == self::FORMAT_GET_ALL) { + $ids = array(); foreach ($items as $item) { - if ($item['mtime'] > $mtime) { - $mtime = $item['mtime']; - } - $size += $item['size']; + $ids[] = $item['file_source']; } - return array(0 => array('id' => -1, 'name' => 'Shared', 'mtime' => $mtime, 'mimetype' => 'httpd/unix-directory', 'size' => $size, 'writable' => false, 'type' => 'dir', 'directory' => '', 'permissions' => OCP\PERMISSION_READ)); + return $ids; } else if ($format == self::FORMAT_OPENDIR) { $files = array(); foreach ($items as $item) { @@ -124,4 +104,26 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { return array(); } + public static function getSource($target) { + $target = '/'.$target; + $target = rtrim($target, '/'); + $pos = strpos($target, '/', 1); + // Get shared folder name + if ($pos !== false) { + $folder = substr($target, 0, $pos); + $source = \OCP\Share::getItemSharedWith('folder', $folder, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + if ($source) { + $source['path'] = $source['path'].substr($target, strlen($folder)); + return $source; + } + } else { + $source = \OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + if ($source) { + return $source; + } + } + \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::ERROR); + return false; + } + } diff --git a/apps/files_sharing/lib/share/folder.php b/apps/files_sharing/lib/share/folder.php index d414fcf10f..a1bb843d72 100644 --- a/apps/files_sharing/lib/share/folder.php +++ b/apps/files_sharing/lib/share/folder.php @@ -21,34 +21,6 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File implements OCP\Share_Backend_Collection { - public function formatItems($items, $format, $parameters = null) { - if ($format == self::FORMAT_SHARED_STORAGE) { - // Only 1 item should come through for this format call - return array('path' => $items[key($items)]['path'], 'permissions' => $items[key($items)]['permissions']); - } else if ($format == self::FORMAT_FILE_APP && isset($parameters['folder'])) { - // Only 1 item should come through for this format call - $folder = $items[key($items)]; - if (isset($parameters['mimetype_filter'])) { - $mimetype_filter = $parameters['mimetype_filter']; - } else { - $mimetype_filter = ''; - } - $path = $folder['path'].substr($parameters['folder'], 7 + strlen($folder['file_target'])); - $files = OC_FileCache::getFolderContent($path, '', $mimetype_filter); - foreach ($files as &$file) { - $file['directory'] = $parameters['folder']; - $file['type'] = ($file['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file'; - $file['permissions'] = $folder['permissions']; - if ($file['type'] == 'file') { - // Remove Create permission if type is file - $file['permissions'] &= ~OCP\PERMISSION_CREATE; - } - } - return $files; - } - return array(); - } - public function getChildren($itemSource) { $children = array(); $parents = array($itemSource); diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 5abdbf29f0..960aa64099 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -34,41 +34,8 @@ class Shared extends \OC\Files\Storage\Common { $this->sharedFolder = $arguments['sharedFolder']; } - /** - * @brief Get the source file path and the permissions granted for a shared file - * @param string Shared target file path - * @return array with the keys path and permissions or false if not found - */ - private function getFile($target) { - $target = '/'.$target; - $target = rtrim($target, '/'); - if (isset($this->files[$target])) { - return $this->files[$target]; - } else { - $pos = strpos($target, '/', 1); - // Get shared folder name - if ($pos !== false) { - $folder = substr($target, 0, $pos); - if (isset($this->files[$folder])) { - $file = $this->files[$folder]; - } else { - $file = \OCP\Share::getItemSharedWith('folder', $folder, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); - } - if ($file) { - $this->files[$target]['path'] = $file['path'].substr($target, strlen($folder)); - $this->files[$target]['permissions'] = $file['permissions']; - return $this->files[$target]; - } - } else { - $file = \OCP\Share::getItemSharedWith('file', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); - if ($file) { - $this->files[$target] = $file; - return $this->files[$target]; - } - } - \OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, \OCP\Util::ERROR); - return false; - } + public function getId(){ + return 'shared::' . $this->sharedFolder; } /** @@ -77,13 +44,13 @@ class Shared extends \OC\Files\Storage\Common { * @return string source file path or false if not found */ private function getSourcePath($target) { - $file = $this->getFile($target); - if (isset($file['path'])) { - $uid = substr($file['path'], 1, strpos($file['path'], '/', 1) - 1); - \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => \OC_User::getHome($uid)), $uid); - return $file['path']; + if (!isset($this->files[$target])) { + $source = \OC_Share_Backend_File::getSource($target); + $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; + $this->files[$target] = $source; + \OC\Files\Filesystem::initMountPoints($source['uid_owner']); } - return false; + return $this->files[$target]['path']; } /** @@ -92,26 +59,18 @@ class Shared extends \OC\Files\Storage\Common { * @return int CRUDS permissions granted or false if not found */ public function getPermissions($target) { - $file = $this->getFile($target); - if (isset($file['permissions'])) { - return $file['permissions']; + if (!isset($this->files[$target])) { + $source = \OC_Share_Backend_File::getSource($target); + $this->files[$target] = $source; } - return false; - } - - public function getOwner($target) { - $shared_item = \OCP\Share::getItemSharedWith('folder', $target, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); - if ($shared_item) { - return $shared_item[0]["uid_owner"]; - } - return null; + return $this->files[$target]['permissions']; } public function mkdir($path) { if ($path == '' || $path == '/' || !$this->isCreatable(dirname($path))) { return false; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->mkdir($internalPath); } return false; @@ -119,7 +78,7 @@ class Shared extends \OC\Files\Storage\Common { public function rmdir($path) { if (($source = $this->getSourcePath($path)) && $this->isDeletable($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->rmdir($internalPath); } return false; @@ -131,7 +90,7 @@ class Shared extends \OC\Files\Storage\Common { \OC_FakeDirStream::$dirs['shared'] = $files; return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->opendir($internalPath); } return false; @@ -141,7 +100,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->is_dir($internalPath); } return false; @@ -149,7 +108,7 @@ class Shared extends \OC\Files\Storage\Common { public function is_file($path) { if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->is_file($internalPath); } return false; @@ -161,7 +120,7 @@ class Shared extends \OC\Files\Storage\Common { $stat['mtime'] = $this->filemtime($path); return $stat; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->stat($internalPath); } return false; @@ -171,7 +130,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/') { return 'dir'; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->filetype($internalPath); } return false; @@ -181,7 +140,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '' || $path == '/' || $this->is_dir($path)) { return 0; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->filesize($internalPath); } return false; @@ -191,7 +150,7 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\PERMISSION_CREATE); + return ($this->getPermissions($path) & \OCP\PERMISSION_CREATE); } public function isReadable($path) { @@ -202,28 +161,28 @@ class Shared extends \OC\Files\Storage\Common { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\PERMISSION_UPDATE); + return ($this->getPermissions($path) & \OCP\PERMISSION_UPDATE); } public function isDeletable($path) { if ($path == '') { return true; } - return ($this->getPermissions($path) & OCP\PERMISSION_DELETE); + return ($this->getPermissions($path) & \OCP\PERMISSION_DELETE); } public function isSharable($path) { if ($path == '') { return false; } - return ($this->getPermissions($path) & OCP\PERMISSION_SHARE); + return ($this->getPermissions($path) & \OCP\PERMISSION_SHARE); } public function file_exists($path) { if ($path == '' || $path == '/') { return true; } else if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->file_exists($internalPath); } return false; @@ -244,7 +203,7 @@ class Shared extends \OC\Files\Storage\Common { } else { $source = $this->getSourcePath($path); if ($source) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->filemtime($internalPath); } } @@ -258,7 +217,7 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_get_contents', $info); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->file_get_contents($internalPath); } } @@ -274,7 +233,7 @@ class Shared extends \OC\Files\Storage\Common { 'source' => $source, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'file_put_contents', $info); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); $result = $storage->file_put_contents($internalPath, $data); return $result; } @@ -285,7 +244,7 @@ class Shared extends \OC\Files\Storage\Common { // Delete the file if DELETE permission is granted if ($source = $this->getSourcePath($path)) { if ($this->isDeletable($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->unlink($internalPath); } else if (dirname($path) == '/' || dirname($path) == '.') { // Unshare the file from the user if in the root of the Shared folder @@ -309,8 +268,8 @@ class Shared extends \OC\Files\Storage\Common { if (dirname($path1) == dirname($path2)) { // Rename the file if UPDATE permission is granted if ($this->isUpdatable($path1)) { - list($storage, $oldInternalPath)=\OC\Files\Filesystem::resolvePath($oldSource); - list( , $newInternalPath)=\OC\Files\Filesystem::resolvePath($newSource); + list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); + list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); return $storage->rename($oldInternalPath, $newInternalPath); } } else { @@ -325,8 +284,8 @@ class Shared extends \OC\Files\Storage\Common { return $this->unlink($path1); } } else { - list($storage, $oldInternalPath)=\OC\Files\Filesystem::resolvePath($oldSource); - list( , $newInternalPath)=\OC\Files\Filesystem::resolvePath($newSource); + list($storage, $oldInternalPath) = \OC\Files\Filesystem::resolvePath($oldSource); + list( , $newInternalPath) = \OC\Files\Filesystem::resolvePath($newSource); return $storage->rename($oldInternalPath, $newInternalPath); } } @@ -372,7 +331,7 @@ class Shared extends \OC\Files\Storage\Common { 'mode' => $mode, ); \OCP\Util::emitHook('\OC\Files\Storage\Shared', 'fopen', $info); - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->fopen($internalPath, $mode); } return false; @@ -383,7 +342,7 @@ class Shared extends \OC\Files\Storage\Common { return 'httpd/unix-directory'; } if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->getMimeType($internalPath); } return false; @@ -392,21 +351,21 @@ class Shared extends \OC\Files\Storage\Common { public function free_space($path) { $source = $this->getSourcePath($path); if ($source) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->free_space($internalPath); } } public function getLocalFile($path) { if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->getLocalFile($internalPath); } return false; } public function touch($path, $mtime = null) { if ($source = $this->getSourcePath($path)) { - list($storage, $internalPath)=\OC\Files\Filesystem::resolvePath($source); + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); return $storage->touch($internalPath, $mtime); } return false; @@ -417,17 +376,28 @@ class Shared extends \OC\Files\Storage\Common { \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } - /** - * check if a file or folder has been updated since $time - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - //TODO - return false; + public function getCache() { + return new \OC\Files\Cache\Shared_Cache($this); } - public function getId(){ - return 'shared::' . $this->sharedFolder; + public function getScanner(){ + return new \OC\Files\Cache\Shared_Scanner($this); } + + public function getPermissionsCache() { + return new \OC\Files\Cache\Shared_Permissions($this); + } + + public function getOwner($path) { + if (!isset($this->files[$path])) { + $source = \OC_Share_Backend_File::getSource($path); + $this->files[$path] = $source; + } + return $this->files[$path]['uid_owner']; + } + + public function getETag($path) { + + } + } diff --git a/lib/public/share.php b/lib/public/share.php index 9bb64a38c8..8981de1b50 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -552,7 +552,7 @@ class Share { // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { $root = \OC\Files\Filesystem::getRoot(); - $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; + $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; } @@ -569,7 +569,7 @@ class Share { $itemTypes = $collectionTypes; } $placeholders = join(',', array_fill(0, count($itemTypes), '?')); - $where .= ' WHERE `item_type` IN ('.$placeholders.'))'; + $where = ' WHERE `item_type` IN ('.$placeholders.'))'; $queryArgs = $itemTypes; } else { $where = ' WHERE `item_type` = ?'; @@ -681,8 +681,8 @@ class Share { } } else { if ($fileDependent) { - if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_FILE_APP || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { - $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `name`, `ctime`, `mtime`, `mimetype`, `size`, `encrypted`, `versioned`, `writable`'; + if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS) { + $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `*PREFIX*filecache`.`parent` as `file_parent`, `name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; } From b4515d874e5259647886d148db902f9753bbeb81 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 26 Dec 2012 15:36:50 -0500 Subject: [PATCH 120/262] Only folders have Create permission --- lib/files/storage/common.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index c891d0c3ad..3cf960d05d 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -38,7 +38,10 @@ abstract class Common implements \OC\Files\Storage\Storage { } } public function isCreatable($path) { - return $this->isUpdatable($path); + if ($this->is_dir($path) && $this->isUpdatable($path)) { + return true; + } + return false; } public function isDeletable($path) { return $this->isUpdatable($path); From 1910057900476c5b7509a456a460d70664c01610 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 26 Dec 2012 16:20:10 -0500 Subject: [PATCH 121/262] Fix shared statuses inside folders --- apps/files_sharing/lib/share/folder.php | 4 ++-- lib/public/share.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/files_sharing/lib/share/folder.php b/apps/files_sharing/lib/share/folder.php index a1bb843d72..bbe4c130bd 100644 --- a/apps/files_sharing/lib/share/folder.php +++ b/apps/files_sharing/lib/share/folder.php @@ -26,11 +26,11 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File implements OCP\Share $parents = array($itemSource); while (!empty($parents)) { $parents = "'".implode("','", $parents)."'"; - $query = OC_DB::prepare('SELECT `id`, `name`, `mimetype` FROM `*PREFIX*fscache` WHERE `parent` IN ('.$parents.')'); + $query = OC_DB::prepare('SELECT `fileid`, `name`, `mimetype` FROM `*PREFIX*filecache` WHERE `parent` IN ('.$parents.')'); $result = $query->execute(); $parents = array(); while ($file = $result->fetchRow()) { - $children[] = array('source' => $file['id'], 'file_path' => $file['name']); + $children[] = array('source' => $file['fileid'], 'file_path' => $file['name']); // If a child folder is found look inside it if ($file['mimetype'] == 'httpd/unix-directory') { $parents[] = $file['id']; diff --git a/lib/public/share.php b/lib/public/share.php index 8981de1b50..2775a07f13 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -739,7 +739,8 @@ class Share { if (isset($row['parent'])) { $row['path'] = '/Shared/'.basename($row['path']); } else { - $row['path'] = substr($row['path'], $root); + // Strip 'files' from path + $row['path'] = substr($row['path'], 5); } } if (isset($row['expiration'])) { From 65f1e521079968a4450468917649b241b0fb6b24 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 27 Dec 2012 15:49:48 -0500 Subject: [PATCH 122/262] Change old is_readable to isReadable, fixes downloads --- lib/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files.php b/lib/files.php index e12797bd61..15bfbc3fc2 100644 --- a/lib/files.php +++ b/lib/files.php @@ -100,7 +100,7 @@ class OC_Files { $filename = $dir . '/' . $files; } OC_Util::obEnd(); - if($zip or \OC\Files\Filesystem::is_readable($filename)) { + if ($zip or \OC\Files\Filesystem::isReadable($filename)) { if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) { header( 'Content-Disposition: attachment; filename="' . rawurlencode( basename($filename) ) . '"' ); } else { From b03562670973fd924a042064644994639a59667d Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 27 Dec 2012 16:53:32 -0500 Subject: [PATCH 123/262] Retrieve storage correctly, filename is not the mountpoint --- lib/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files.php b/lib/files.php index 15bfbc3fc2..e1a31c6f03 100644 --- a/lib/files.php +++ b/lib/files.php @@ -117,7 +117,7 @@ class OC_Files { }else{ header('Content-Type: '.\OC\Files\Filesystem::getMimeType($filename)); header("Content-Length: ".\OC\Files\Filesystem::filesize($filename)); - $storage = \OC\Files\Filesystem::getStorage($filename); + list($storage) = \OC\Files\Filesystem::resolvePath($filename); if ($storage instanceof \OC\File\Storage\Local) { self::addSendfileHeader(\OC\Files\Filesystem::getLocalFile($filename)); } From 8bdfb040565eafb33bc27305463eb08374f14e32 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 28 Dec 2012 15:06:12 -0500 Subject: [PATCH 124/262] Fix shared folders --- apps/files_sharing/lib/cache.php | 17 ++++++++++++++--- lib/files/filesystem.php | 1 + lib/util.php | 1 - 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 196e767cf6..d2ac8ccaaa 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -30,6 +30,10 @@ class Shared_Cache extends Cache { private $files = array(); + public function __construct($storage) { + + } + /** * @brief Get the source cache of a shared file or folder * @param string Shared target file path @@ -41,8 +45,12 @@ class Shared_Cache extends Cache { $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; \OC\Files\Filesystem::initMountPoints($source['uid_owner']); list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source['path']); - $this->files[$target] = $internalPath; - return $storage->getCache(); + if ($storage) { + $this->files[$target] = $internalPath; + $cache = $storage->getCache(); + $this->numericId = $cache->getNumericStorageId(); + return $cache; + } } return false; } @@ -83,8 +91,11 @@ class Shared_Cache extends Cache { if ($folder == '') { return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS); } else { - return $this->getSourceCache($folder)->getFolderContents('/'.$this->files[$folder]); + if ($cache = $this->getSourceCache($folder)) { + return $cache->getFolderContents($this->files[$folder]); + } } + return false; } /** diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index c5b56ba9f0..8183b8ff99 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -276,6 +276,7 @@ class Filesystem { } // Load personal mount points $root = \OC_User::getHome($user); + self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); if (is_file($root.'/mount.php')) { $mountConfig = include $root.'/mount.php'; if (isset($mountConfig['user'][$user])) { diff --git a/lib/util.php b/lib/util.php index 4ebc2564d1..c5a495234d 100755 --- a/lib/util.php +++ b/lib/util.php @@ -51,7 +51,6 @@ class OC_Util { mkdir( $userdirectory, 0755, true ); } //jail the user into his "home" directory - \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir' => $user_root), $user); \OC\Files\Filesystem::init($user_dir); $quotaProxy=new OC_FileProxy_Quota(); From fb053f8e73056108acfd1574973d7b18581fc833 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 29 Dec 2012 11:09:57 -0500 Subject: [PATCH 125/262] Fix retrieving of shared source paths --- apps/files_sharing/lib/sharedstorage.php | 41 ++++++++++++++++-------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 960aa64099..cb9b36482f 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -38,19 +38,34 @@ class Shared extends \OC\Files\Storage\Common { return 'shared::' . $this->sharedFolder; } + /** + * @brief Get the source file path, permissions, and owner for a shared file + * @param string Shared target file path + * @return Returns array with the keys path, permissions, and owner or false if not found + */ + private function getFile($target) { + if (!isset($this->files[$target])) { + $source = \OC_Share_Backend_File::getSource($target); + if ($source) { + $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; + } + $this->files[$target] = $source; + } + return $this->files[$target]; + } + /** * @brief Get the source file path for a shared file * @param string Shared target file path * @return string source file path or false if not found */ private function getSourcePath($target) { - if (!isset($this->files[$target])) { - $source = \OC_Share_Backend_File::getSource($target); - $source['path'] = '/'.$source['uid_owner'].'/'.$source['path']; - $this->files[$target] = $source; + $source = $this->getFile($target); + if ($source) { \OC\Files\Filesystem::initMountPoints($source['uid_owner']); + return $source['path']; } - return $this->files[$target]['path']; + return false; } /** @@ -59,11 +74,11 @@ class Shared extends \OC\Files\Storage\Common { * @return int CRUDS permissions granted or false if not found */ public function getPermissions($target) { - if (!isset($this->files[$target])) { - $source = \OC_Share_Backend_File::getSource($target); - $this->files[$target] = $source; + $source = $this->getFile($target); + if ($source) { + return $source['permissions']; } - return $this->files[$target]['permissions']; + return false; } public function mkdir($path) { @@ -389,11 +404,11 @@ class Shared extends \OC\Files\Storage\Common { } public function getOwner($path) { - if (!isset($this->files[$path])) { - $source = \OC_Share_Backend_File::getSource($path); - $this->files[$path] = $source; + $source = $this->getFile($path); + if ($source) { + return $source['uid_owner']; } - return $this->files[$path]['uid_owner']; + return false; } public function getETag($path) { From cfc3526b25f1b96ab7a989f1c89f5b3911bc18fc Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 29 Dec 2012 11:45:13 -0500 Subject: [PATCH 126/262] Fix data for shared root folder --- apps/files_sharing/lib/cache.php | 4 +++- apps/files_sharing/lib/permissions.php | 3 +++ apps/files_sharing/lib/share/file.php | 26 +++++++++++++++++++------- lib/public/share.php | 2 +- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index d2ac8ccaaa..a22e7af7f5 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -62,7 +62,9 @@ class Shared_Cache extends Cache { * @return array */ public function get($file) { - if (is_string($file)) { + if ($file == '') { + return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT); + } else if (is_string($file)) { if ($cache = $this->getSourceCache($file)) { return $cache->get($this->files[$file]); } diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php index 51ae4cf102..6eaed34b33 100644 --- a/apps/files_sharing/lib/permissions.php +++ b/apps/files_sharing/lib/permissions.php @@ -30,6 +30,9 @@ class Shared_Permissions { * @return int (-1 if file no permissions set) */ static public function get($fileId, $user) { + if ($fileId == -1) { + return \OCP\PERMISSION_READ; + } $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); if ($source) { return $source['permissions']; diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index 52220dc5b2..5e98c455d3 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -23,8 +23,9 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { const FORMAT_SHARED_STORAGE = 0; const FORMAT_GET_FOLDER_CONTENTS = 1; - const FORMAT_GET_ALL = 2; + const FORMAT_FILE_APP_ROOT = 2; const FORMAT_OPENDIR = 3; + const FORMAT_GET_ALL = 4; private $path; @@ -82,24 +83,35 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { $file['parent'] = $item['file_parent']; $file['name'] = basename($item['file_target']); $file['mimetype'] = $item['mimetype']; + $file['mimepart'] = $item['mimepart']; $file['size'] = $item['size']; $file['mtime'] = $item['mtime']; $file['encrypted'] = $item['encrypted']; $files[] = $file; } return $files; + } else if ($format == self::FORMAT_FILE_APP_ROOT) { + $mtime = 0; + $size = 0; + foreach ($items as $item) { + if ($item['mtime'] > $mtime) { + $mtime = $item['mtime']; + } + $size += (int)$item['size']; + } + return array('fileid' => -1, 'name' => 'Shared', 'mtime' => $mtime, 'mimetype' => 'httpd/unix-directory', 'size' => $size); + } else if ($format == self::FORMAT_OPENDIR) { + $files = array(); + foreach ($items as $item) { + $files[] = basename($item['file_target']); + } + return $files; } else if ($format == self::FORMAT_GET_ALL) { $ids = array(); foreach ($items as $item) { $ids[] = $item['file_source']; } return $ids; - } else if ($format == self::FORMAT_OPENDIR) { - $files = array(); - foreach ($items as $item) { - $files[] = basename($item['file_target']); - } - return $files; } return array(); } diff --git a/lib/public/share.php b/lib/public/share.php index 2775a07f13..e438386ca3 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -681,7 +681,7 @@ class Share { } } else { if ($fileDependent) { - if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS) { + if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `*PREFIX*filecache`.`parent` as `file_parent`, `name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; From d275725e233092f21247a62bde3e46a352d5a1b5 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 29 Dec 2012 13:43:44 -0500 Subject: [PATCH 127/262] No longer need to create folders locally for external storage mount points --- apps/files_external/lib/config.php | 41 ------------------------------ 1 file changed, 41 deletions(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 0e0bc56ad0..323e4060a4 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -178,22 +178,6 @@ class OC_Mount_Config { return $personal; } - /** - * Add directory for mount point to the filesystem - * @param OC_Fileview instance $view - * @param string path to mount point - */ - private static function addMountPointDirectory($view, $path) { - $dir = ''; - foreach ( explode('/', $path) as $pathPart) { - $dir = $dir.'/'.$pathPart; - if ( !$view->file_exists($dir)) { - $view->mkdir($dir); - } - } - } - - /** * Add a mount point to the filesystem * @param string Mount point @@ -216,33 +200,8 @@ class OC_Mount_Config { if ($applicable != OCP\User::getUser() || $class == '\OC\Files\Storage\Local') { return false; } - $view = new \OC\Files\View('/'.OCP\User::getUser().'/files'); - self::addMountPointDirectory($view, ltrim($mountPoint, '/')); $mountPoint = '/'.$applicable.'/files/'.ltrim($mountPoint, '/'); } else { - $view = new \OC\Files\View('/'); - switch ($mountType) { - case 'user': - if ($applicable == "all") { - $users = OCP\User::getUsers(); - foreach ( $users as $user ) { - $path = $user.'/files/'.ltrim($mountPoint, '/'); - self::addMountPointDirectory($view, $path); - } - } else { - $path = $applicable.'/files/'.ltrim($mountPoint, '/'); - self::addMountPointDirectory($view, $path); - } - break; - case 'group' : - $groupMembers = OC_Group::usersInGroups(array($applicable)); - foreach ( $groupMembers as $user ) { - $path = $user.'/files/'.ltrim($mountPoint, '/'); - self::addMountPointDirectory($view, $path); - } - break; - } - $mountPoint = '/$user/files/'.ltrim($mountPoint, '/'); } $mount = array($applicable => array($mountPoint => array('class' => $class, 'options' => $classOptions))); From 2c23e143d33e231e62dccb450bf1f1b0f3938ccd Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 16:32:55 -0500 Subject: [PATCH 128/262] Store etags in the file cache --- db_structure.xml | 8 ++++++++ lib/files/cache/cache.php | 10 +++++----- lib/files/cache/scanner.php | 1 + lib/util.php | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index aa0916264c..7c67ca78f4 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -189,6 +189,14 @@ 4 + + etag + text + + true + 250 + + storage_path_hash true diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 3ebae9baa5..d105f865eb 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -76,7 +76,7 @@ class Cache { $params = array($file); } $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` ' . $where); $result = $query->execute($params); $data = $result->fetchRow(); @@ -107,7 +107,7 @@ class Cache { $fileId = $this->getId($folder); if ($fileId > -1) { $query = \OC_DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); return $result->fetchAll(); @@ -180,7 +180,7 @@ class Cache { * @return array */ static function buildParts(array $data) { - $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); + $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted', 'etag'); $params = array(); $queryParts = array(); @@ -333,7 +333,7 @@ class Cache { */ public function search($pattern) { $query = \OC_DB::prepare(' - SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?' ); $result = $query->execute(array($pattern, $this->numericId)); @@ -357,7 +357,7 @@ class Cache { $where = '`mimepart` = ?'; } $query = \OC_DB::prepare(' - SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` + SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); $result = $query->execute(array($mimetype, $this->numericId)); diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 4c0ec9617f..e7bfb1898e 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -58,6 +58,7 @@ class Scanner { $data['size'] = $this->storage->filesize($path); $data['permissions'] = $this->storage->getPermissions($path); } + $data['etag'] = $this->storage->getETag($path); return $data; } diff --git a/lib/util.php b/lib/util.php index c5a495234d..df26a825d1 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,04); + return array(4,91,05); } /** From a5cb7363a5031d25d3e4cbd46817930c19893143 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 19:18:05 -0500 Subject: [PATCH 129/262] Use etags from file cache in SabreDAV connector --- lib/connector/sabre/directory.php | 2 +- lib/connector/sabre/node.php | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 8d4dd92a3d..a720157936 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -121,8 +121,8 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa $paths = array(); foreach($folder_content as $info) { $paths[] = $this->path.'/'.$info['name']; + $properties[$this->path.'/'.$info['name']][self::GETETAG_PROPERTYNAME] = $info['etag']; } - $properties = array_fill_keys($paths, array()); if(count($paths)>0) { // // the number of arguments within IN conditions are limited in most databases diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index ad08bd434f..d4023dfad7 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -190,6 +190,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr while( $row = $result->fetchRow()) { $this->property_cache[$row['propertyname']] = $row['propertyvalue']; } + $this->property_cache[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path); } // if the array was empty, we need to return everything @@ -210,14 +211,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * @return string|null Returns null if the ETag can not effectively be determined */ static public function getETagPropertyForPath($path) { - $tag = \OC\Files\Filesystem::getETag($path); - if (empty($tag)) { - return null; + $data = \OC\Files\Filesystem::getFileInfo($path); + if (isset($data['etag'])) { + return $data['etag']; } - $etag = '"'.$tag.'"'; - $query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties` (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' ); - $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag )); - return $etag; + return null; } /** From 83064aca51db7d8382282743ade2ab9da2a6e1b0 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 19:23:31 -0500 Subject: [PATCH 130/262] Remove old etag code --- lib/connector/sabre/node.php | 24 ------------------------ lib/files/filesystem.php | 21 --------------------- lib/files/view.php | 2 -- lib/filesystem.php | 7 ------- 4 files changed, 54 deletions(-) diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index d4023dfad7..dd8ae152ff 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -218,28 +218,4 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr return null; } - /** - * @brief Remove the ETag from the cache. - * @param string $path Path of the file - */ - static public function removeETagPropertyForPath($path) { - // remove tags from this and parent paths - $paths = array(); - while ($path != '/' && $path != '.' && $path != '' && $path != '\\') { - $paths[] = $path; - $path = dirname($path); - } - if (empty($paths)) { - return; - } - $paths[] = $path; - $path_placeholders = join(',', array_fill(0, count($paths), '?')); - $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`' - .' WHERE `userid` = ?' - .' AND `propertyname` = ?' - .' AND `propertypath` IN ('.$path_placeholders.')' - ); - $vals = array( OC_User::getUser(), self::GETETAG_PROPERTYNAME ); - $query->execute(array_merge( $vals, $paths )); - } } diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 8183b8ff99..d62b5186cb 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -582,23 +582,6 @@ class Filesystem { return self::$defaultInstance->hasUpdated($path, $time); } - static public function removeETagHook($params, $root = false) { - if (isset($params['path'])) { - $path = $params['path']; - } else { - $path = $params['oldpath']; - } - - if ($root) { // reduce path to the required part of it (no 'username/files') - $fakeRootView = new View($root); - $count = 1; - $path = str_replace(\OC_App::getStorage("files")->getAbsolutePath(''), "", $fakeRootView->getAbsolutePath($path), $count); - } - - $path = self::normalizePath($path); - \OC_Connector_Sabre_Node::removeETagPropertyForPath($path); - } - /** * normalize a path * @@ -682,10 +665,6 @@ class Filesystem { } } -\OC_Hook::connect('OC_Filesystem', 'post_write', 'OC_Filesystem', 'removeETagHook'); -\OC_Hook::connect('OC_Filesystem', 'post_delete', 'OC_Filesystem', 'removeETagHook'); -\OC_Hook::connect('OC_Filesystem', 'post_rename', 'OC_Filesystem', 'removeETagHook'); - \OC_Hook::connect('OC_Filesystem', 'post_write', '\OC\Files\Cache\Updater', 'writeHook'); \OC_Hook::connect('OC_Filesystem', 'post_delete', '\OC\Files\Cache\Updater', 'deleteHook'); \OC_Hook::connect('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Updater', 'renameHook'); diff --git a/lib/files/view.php b/lib/files/view.php index 592c484a21..77146895e6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -462,8 +462,6 @@ class View { Filesystem::signal_post_write, array(Filesystem::signal_param_path => $path2) ); - } else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions - Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot); } return $result; } else { diff --git a/lib/filesystem.php b/lib/filesystem.php index 20b5ab2790..57cca90230 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -398,13 +398,6 @@ class OC_Filesystem { return \OC\Files\Filesystem::hasUpdated($path, $time); } - /** - * @deprecated OC_Filesystem is replaced by \OC\Files\Filesystem - */ - static public function removeETagHook($params, $root = false) { - \OC\Files\Filesystem::removeETagHook($params, $root); - } - /** * normalize a path * From 77f12c526bf0010219e363844b588ffae27f1251 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 19:54:51 -0500 Subject: [PATCH 131/262] Update etags in parent folders --- lib/files/cache/updater.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index fb9783023e..d57e4a1abe 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -34,6 +34,7 @@ class Updater { $scanner = new Scanner($storage); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); + self::eTagUpdate($path); } static public function deleteUpdate($path) { @@ -45,6 +46,29 @@ class Updater { $cache = new Cache($storage); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); + self::eTagUpdate($path); + } + + static public function eTagUpdate($path) { + if ($path !== '') { + $parent = dirname($path); + if ($parent === '.') { + $parent = ''; + } + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath + */ + list($storage, $internalPath) = self::resolvePath($parent); + if ($storage) { + $cache = $storage->getCache(); + $id = $cache->getId($internalPath); + if ($id !== -1) { + $cache->update($id, array('etag' => $storage->getETag($internalPath))); + self::updateFolderETags($parent); + } + } + } } /** From 3ee3323b8766992a0b60bb76b909e49fc1ea76d2 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 20:27:38 -0500 Subject: [PATCH 132/262] Fix retrieving of cache and scanner in Updater class --- lib/files/cache/updater.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index fb9783023e..c8c96a97ee 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -30,10 +30,12 @@ class Updater { * @var string $internalPath */ list($storage, $internalPath) = self::resolvePath($path); - $cache = new Cache($storage); - $scanner = new Scanner($storage); - $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); - $cache->correctFolderSize($internalPath); + if ($storage) { + $cache = $storage->getCache(); + $scanner = $storage->getScanner(); + $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); + $cache->correctFolderSize($internalPath); + } } static public function deleteUpdate($path) { @@ -42,9 +44,11 @@ class Updater { * @var string $internalPath */ list($storage, $internalPath) = self::resolvePath($path); - $cache = new Cache($storage); - $cache->remove($internalPath); - $cache->correctFolderSize($internalPath); + if ($storage) { + $cache = $storage->getCache(); + $cache->remove($internalPath); + $cache->correctFolderSize($internalPath); + } } /** From 96e08a1d962b42782d03721009970cbab352eec2 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 21:23:17 -0500 Subject: [PATCH 133/262] Fix function name --- lib/files/cache/updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index d57e4a1abe..7fc9bd382f 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -65,7 +65,7 @@ class Updater { $id = $cache->getId($internalPath); if ($id !== -1) { $cache->update($id, array('etag' => $storage->getETag($internalPath))); - self::updateFolderETags($parent); + self::eTagUpdate($parent); } } } From 29b82ccdf32f8a13723e7f49be0c3cbf7e64a404 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sun, 30 Dec 2012 21:23:54 -0500 Subject: [PATCH 134/262] Change length of etag field to 40 --- db_structure.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db_structure.xml b/db_structure.xml index 7c67ca78f4..527b53040d 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -194,7 +194,7 @@ text true - 250 + 40 From d0a50fae8317e4b4871027ee4b2940ab5443961f Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 31 Dec 2012 18:16:44 -0500 Subject: [PATCH 135/262] Fix eTagUpdate and add tests --- lib/files/cache/updater.php | 2 +- tests/lib/files/cache/updater.php | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 2604159009..cfc1ec731e 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -54,7 +54,7 @@ class Updater { } static public function eTagUpdate($path) { - if ($path !== '') { + if ($path !== '' && $path !== '/') { $parent = dirname($path); if ($parent === '.') { $parent = ''; diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index d19966c191..cad3d9d46f 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -70,14 +70,18 @@ class Updater extends \PHPUnit_Framework_TestCase { public function testWrite() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); + $fooCachedData = $this->cache->get('foo.txt'); Filesystem::file_put_contents('foo.txt', 'asd'); $cachedData = $this->cache->get('foo.txt'); $this->assertEquals(3, $cachedData['size']); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; $this->assertFalse($this->cache->inCache('bar.txt')); Filesystem::file_put_contents('bar.txt', 'asd'); @@ -86,38 +90,50 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertEquals(3, $cachedData['size']); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } public function testDelete() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $this->assertTrue($this->cache->inCache('foo.txt')); Filesystem::unlink('foo.txt', 'asd'); $this->assertFalse($this->cache->inCache('foo.txt')); $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; Filesystem::mkdir('bar_folder'); $this->assertTrue($this->cache->inCache('bar_folder')); + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $rootCachedData = $cachedData; Filesystem::rmdir('bar_folder'); $this->assertFalse($this->cache->inCache('bar_folder')); + $cachedData = $this->cache->get(''); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } public function testRename() { $textSize = strlen("dummy file data\n"); $imageSize = filesize(\OC::$SERVERROOT . '/core/img/logo.png'); - $cachedData = $this->cache->get(''); - $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $rootCachedData = $this->cache->get(''); + $this->assertEquals(3 * $textSize + $imageSize, $rootCachedData['size']); $this->assertTrue($this->cache->inCache('foo.txt')); + $fooCachedData = $this->cache->get('foo.txt'); $this->assertFalse($this->cache->inCache('bar.txt')); Filesystem::rename('foo.txt', 'bar.txt'); $this->assertFalse($this->cache->inCache('foo.txt')); $this->assertTrue($this->cache->inCache('bar.txt')); + $cachedData = $this->cache->get('foo.txt'); + $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); $cachedData = $this->cache->get(''); $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); + $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); } } From f2ca7023e1ece60dc3cebc5cd770c7373f53c93a Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 11:19:33 -0500 Subject: [PATCH 136/262] Fix Shared root problems with Watcher and Quota proxy --- apps/files_sharing/lib/cache.php | 3 +++ apps/files_sharing/lib/sharedstorage.php | 13 +++++++++++++ lib/fileproxy/quota.php | 4 +++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index a22e7af7f5..60f29ce5ee 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -169,6 +169,9 @@ class Shared_Cache extends Cache { * @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE */ public function getStatus($file) { + if ($file == '') { + return self::COMPLETE; + } if ($cache = $this->getSourceCache($file)) { return $cache->getStatus($this->files[$file]); } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index cb9b36482f..3a1d7ef101 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -364,6 +364,9 @@ class Shared extends \OC\Files\Storage\Common { } public function free_space($path) { + if ($path == '') { + return -1; + } $source = $this->getSourcePath($path); if ($source) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); @@ -391,6 +394,13 @@ class Shared extends \OC\Files\Storage\Common { \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); } + public function hasUpdated($path, $time) { + if ($path == '') { + return false; + } + return $this->filemtime($path) > $time; + } + public function getCache() { return new \OC\Files\Cache\Shared_Cache($this); } @@ -404,6 +414,9 @@ class Shared extends \OC\Files\Storage\Common { } public function getOwner($path) { + if ($path == '') { + return false; + } $source = $this->getFile($path); if ($source) { return $source['uid_owner']; diff --git a/lib/fileproxy/quota.php b/lib/fileproxy/quota.php index 80270728ab..c333efa6cd 100644 --- a/lib/fileproxy/quota.php +++ b/lib/fileproxy/quota.php @@ -63,6 +63,9 @@ class OC_FileProxy_Quota extends OC_FileProxy{ */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($path); $owner=$storage->getOwner($internalPath); + if (!$owner) { + return -1; + } $totalSpace=$this->getQuota($owner); if($totalSpace==-1) { @@ -73,7 +76,6 @@ class OC_FileProxy_Quota extends OC_FileProxy{ $rootInfo=$view->getFileInfo('/'); $usedSpace=isset($rootInfo['size'])?$rootInfo['size']:0; - $usedSpace=isset($sharedInfo['size'])?$usedSpace-$sharedInfo['size']:$usedSpace; return $totalSpace-$usedSpace; } From b41189de4420ea8a48adaaf7bb59f9227124b70a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 18:04:29 +0100 Subject: [PATCH 137/262] Cache: allow storage backends to overwrite Watcher --- lib/files/storage/common.php | 7 +++++++ lib/files/storage/storage.php | 5 +++++ lib/files/view.php | 4 ++-- tests/lib/files/cache/watcher.php | 14 +++++++------- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index 3cf960d05d..ab167f2864 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -249,6 +249,13 @@ abstract class Common implements \OC\Files\Storage\Storage { return new \OC\Files\Cache\Permissions($this); } + /** + * @return \OC\Files\Cache\Watcher + */ + public function getWatcher(){ + return new \OC\Files\Cache\Watcher($this); + } + /** * get the owner of a path * @param string $path The path to get the owner diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index 73dcb8fe36..b603381dc9 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -69,6 +69,11 @@ interface Storage{ */ public function getPermissionsCache(); + /** + * @return \OC\Files\Cache\Watcher + */ + public function getWatcher(); + /** * get the ETag for a file or folder * diff --git a/lib/files/view.php b/lib/files/view.php index 592c484a21..d3f93d39f5 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -685,7 +685,7 @@ class View { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher = $storage->getWatcher(); $watcher->checkUpdate($internalPath); } @@ -733,7 +733,7 @@ class View { $scanner = $storage->getScanner(); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = new \OC\Files\Cache\Watcher($storage); + $watcher = $storage->getWatcher(); $watcher->checkUpdate($internalPath); } diff --git a/tests/lib/files/cache/watcher.php b/tests/lib/files/cache/watcher.php index 07c8ac3640..e8a1689cab 100644 --- a/tests/lib/files/cache/watcher.php +++ b/tests/lib/files/cache/watcher.php @@ -32,7 +32,7 @@ class Watcher extends \PHPUnit_Framework_TestCase { function testWatcher() { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('', array('mtime' => 10)); @@ -66,16 +66,16 @@ class Watcher extends \PHPUnit_Framework_TestCase { public function testFileToFolder() { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('', array('mtime' => 10)); $storage->unlink('foo.txt'); - $storage->rename('folder','foo.txt'); + $storage->rename('folder', 'foo.txt'); $updater->checkUpdate(''); - $entry= $cache->get('foo.txt'); + $entry = $cache->get('foo.txt'); $this->assertEquals(-1, $entry['size']); $this->assertEquals('httpd/unix-directory', $entry['mimetype']); $this->assertFalse($cache->inCache('folder')); @@ -83,16 +83,16 @@ class Watcher extends \PHPUnit_Framework_TestCase { $storage = $this->getTestStorage(); $cache = $storage->getCache(); - $updater = new \OC\Files\Cache\Watcher($storage); + $updater = $storage->getWatcher(); //set the mtime to the past so it can detect an mtime change $cache->put('foo.txt', array('mtime' => 10)); $storage->unlink('foo.txt'); - $storage->rename('folder','foo.txt'); + $storage->rename('folder', 'foo.txt'); $updater->checkUpdate('foo.txt'); - $entry= $cache->get('foo.txt'); + $entry = $cache->get('foo.txt'); $this->assertEquals('httpd/unix-directory', $entry['mimetype']); $this->assertTrue($cache->inCache('foo.txt/bar.txt')); } From 4b65dd608a70117141c52749f4a06e6c5466ff7b Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 18:07:10 +0100 Subject: [PATCH 138/262] Share: small phpdoc fixes --- apps/files_sharing/lib/cache.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 60f29ce5ee..679e42d94d 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -36,8 +36,8 @@ class Shared_Cache extends Cache { /** * @brief Get the source cache of a shared file or folder - * @param string Shared target file path - * @return \OC\Files\Storage\Cache + * @param string $target Shared target file path + * @return \OC\Files\Cache\Cache */ private function getSourceCache($target) { $source = \OC_Share_Backend_File::getSource($target); @@ -230,7 +230,7 @@ class Shared_Cache extends Cache { * @return int[] */ public function getAll() { - return OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL); + return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL); } -} \ No newline at end of file +} From 0ac78a64110b628832d94061c78fb8f1b89405cb Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 18:10:38 +0100 Subject: [PATCH 139/262] Share: fix cache put function --- apps/files_sharing/lib/cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 679e42d94d..07c305bb95 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -110,7 +110,7 @@ class Shared_Cache extends Cache { */ public function put($file, array $data) { if ($cache = $this->getSourceCache($file)) { - return $cache->put($this->files[$file]); + return $cache->put($this->files[$file], $data); } return false; } From f4e4a06826459befc4a7df429fe02081a14348f3 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 11:26:04 -0500 Subject: [PATCH 140/262] Forgot to select storage from filecache --- lib/public/share.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/public/share.php b/lib/public/share.php index e438386ca3..c74960b94c 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -682,7 +682,7 @@ class Share { } else { if ($fileDependent) { if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { - $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `*PREFIX*filecache`.`parent` as `file_parent`, `name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`'; + $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, `name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; } From 3b67613afc6d0b74c0e49e567f5e22ec020172d3 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 12:43:38 -0500 Subject: [PATCH 141/262] Remove Shared_Scanner and add Shared_Watcher instead --- apps/files_sharing/appinfo/app.php | 2 +- apps/files_sharing/lib/scanner.php | 69 ------------------------ apps/files_sharing/lib/sharedstorage.php | 8 +-- 3 files changed, 5 insertions(+), 74 deletions(-) delete mode 100644 apps/files_sharing/lib/scanner.php diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php index 189fd20cae..d3e05cc62d 100644 --- a/apps/files_sharing/appinfo/app.php +++ b/apps/files_sharing/appinfo/app.php @@ -5,7 +5,7 @@ OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'apps/files_sharing/lib/share/folder OC::$CLASSPATH['OC\Files\Storage\Shared'] = "apps/files_sharing/lib/sharedstorage.php"; OC::$CLASSPATH['OC\Files\Cache\Shared_Cache'] = 'apps/files_sharing/lib/cache.php'; OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'apps/files_sharing/lib/permissions.php'; -OC::$CLASSPATH['OC\Files\Cache\Shared_Scanner'] = 'apps/files_sharing/lib/scanner.php'; +OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'apps/files_sharing/lib/watcher.php'; OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup'); OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); diff --git a/apps/files_sharing/lib/scanner.php b/apps/files_sharing/lib/scanner.php deleted file mode 100644 index d13d2f9cbc..0000000000 --- a/apps/files_sharing/lib/scanner.php +++ /dev/null @@ -1,69 +0,0 @@ -. -*/ - -namespace OC\Files\Cache; - -class Shared_Scanner extends Scanner { - - public function __construct(\OC\Files\Storage\Storage $storage) { - - } - - /** - * get all the metadata of a file or folder - * * - * - * @param string $path - * @return array with metadata of the file - */ - public function getData($path) { - // Not a valid action for Shared Scanner - } - - /** - * scan a single file and store it in the cache - * - * @param string $file - * @return array with metadata of the scanned file - */ - public function scanFile($file) { - // Not a valid action for Shared Scanner - } - - /** - * scan all the files in a folder and store them in the cache - * - * @param string $path - * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive - * @return int the size of the scanned folder or -1 if the size is unknown at this stage - */ - public function scan($path, $recursive = self::SCAN_RECURSIVE) { - // Not a valid action for Shared Scanner - } - - /** - * walk over any folders that are not fully scanned yet and scan them - */ - public function backgroundScan() { - // Not a valid action for Shared Scanner - } - -} \ No newline at end of file diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 3a1d7ef101..8504a2d894 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -405,14 +405,14 @@ class Shared extends \OC\Files\Storage\Common { return new \OC\Files\Cache\Shared_Cache($this); } - public function getScanner(){ - return new \OC\Files\Cache\Shared_Scanner($this); - } - public function getPermissionsCache() { return new \OC\Files\Cache\Shared_Permissions($this); } + public function getWatcher() { + return new \OC\Files\Cache\Shared_Watcher($this); + } + public function getOwner($path) { if ($path == '') { return false; From 268c7acfc47eb44ab154eb90cfbb4484bd64b296 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 13:16:42 -0500 Subject: [PATCH 142/262] Actually add Shared_Watcher --- apps/files_sharing/lib/watcher.php | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 apps/files_sharing/lib/watcher.php diff --git a/apps/files_sharing/lib/watcher.php b/apps/files_sharing/lib/watcher.php new file mode 100644 index 0000000000..e67d1ee908 --- /dev/null +++ b/apps/files_sharing/lib/watcher.php @@ -0,0 +1,51 @@ +. +*/ + +namespace OC\Files\Cache; + +/** + * check the storage backends for updates and change the cache accordingly + */ +class Shared_Watcher extends Watcher { + + /** + * check $path for updates + * + * @param string $path + */ + public function checkUpdate($path) { + if ($path != '') { + parent::checkUpdate($path); + } + } + + /** + * remove deleted files in $path from the cache + * + * @param string $path + */ + public function cleanFolder($path) { + if ($path != '') { + parent::cleanFolder($path); + } + } + +} \ No newline at end of file From 04f83e3b539c6a20ce819bbe4f66c1996e7169f7 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 20:11:39 +0100 Subject: [PATCH 143/262] Cache: optional path argument for getCache/Scanner/etc --- lib/files/storage/common.php | 11 ++++------- lib/files/storage/storage.php | 12 ++++++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index ab167f2864..e859d447f3 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -237,22 +237,19 @@ abstract class Common implements \OC\Files\Storage\Storage { return $this->filemtime($path)>$time; } - public function getCache(){ + public function getCache($path=''){ return new \OC\Files\Cache\Cache($this); } - public function getScanner(){ + public function getScanner($path=''){ return new \OC\Files\Cache\Scanner($this); } - public function getPermissionsCache(){ + public function getPermissionsCache($path=''){ return new \OC\Files\Cache\Permissions($this); } - /** - * @return \OC\Files\Cache\Watcher - */ - public function getWatcher(){ + public function getWatcher($path=''){ return new \OC\Files\Cache\Watcher($this); } diff --git a/lib/files/storage/storage.php b/lib/files/storage/storage.php index b603381dc9..2cc835236b 100644 --- a/lib/files/storage/storage.php +++ b/lib/files/storage/storage.php @@ -54,25 +54,29 @@ interface Storage{ public function hasUpdated($path,$time); /** + * @param string $path * @return \OC\Files\Cache\Cache */ - public function getCache(); + public function getCache($path=''); /** + * @param string $path * @return \OC\Files\Cache\Scanner */ - public function getScanner(); + public function getScanner($path=''); public function getOwner($path); /** + * @param string $path * @return \OC\Files\Cache\Permissions */ - public function getPermissionsCache(); + public function getPermissionsCache($path=''); /** + * @param string $path * @return \OC\Files\Cache\Watcher */ - public function getWatcher(); + public function getWatcher($path=''); /** * get the ETag for a file or folder From a164fd160fb0d3da548dfe01ec27df67d76b0b59 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 1 Jan 2013 20:19:53 +0100 Subject: [PATCH 144/262] Cache: provide path hints to getCache/etc where available --- lib/files/cache/updater.php | 6 +++--- lib/files/view.php | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index c8c96a97ee..c14adba3e5 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -31,8 +31,8 @@ class Updater { */ list($storage, $internalPath) = self::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); - $scanner = $storage->getScanner(); + $cache = $storage->getCache($internalPath); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); } @@ -45,7 +45,7 @@ class Updater { */ list($storage, $internalPath) = self::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); } diff --git a/lib/files/view.php b/lib/files/view.php index d3f93d39f5..8558b03fe1 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -679,13 +679,13 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = $storage->getWatcher(); + $watcher = $storage->getWatcher($internalPath); $watcher->checkUpdate($internalPath); } @@ -698,14 +698,14 @@ class View { foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { - $subCache = $subStorage->getCache(); + $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $data['size'] += $rootEntry['size']; } } } - $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache = $storage->getPermissionsCache($internalPath); $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); } } @@ -727,13 +727,13 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($internalPath); if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { - $watcher = $storage->getWatcher(); + $watcher = $storage->getWatcher($internalPath); $watcher->checkUpdate($internalPath); } @@ -745,7 +745,7 @@ class View { foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { - $subCache = $subStorage->getCache(); + $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $relativePath = trim(substr($mountPoint, $dirLength), '/'); @@ -769,7 +769,7 @@ class View { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; } - $permissionsCache = $storage->getPermissionsCache(); + $permissionsCache = $storage->getPermissionsCache($internalPath); $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); foreach ($files as $i => $file) { @@ -812,10 +812,10 @@ class View { */ list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache($path); if (!$cache->inCache($internalPath)) { - $scanner = $storage->getScanner(); + $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } @@ -857,7 +857,7 @@ class View { $mountPoint = Filesystem::getMountPoint($this->fakeRoot); $storage = Filesystem::getStorage($mountPoint); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache(''); $results = $cache->$method($query); foreach ($results as $result) { @@ -871,7 +871,7 @@ class View { foreach ($mountPoints as $mountPoint) { $storage = Filesystem::getStorage($mountPoint); if ($storage) { - $cache = $storage->getCache(); + $cache = $storage->getCache(''); $relativeMountPoint = substr($mountPoint, $rootLength); $results = $cache->$method($query); From fe90130618e4ce9b1829b4ce8e87311a15f53b83 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 14:13:05 -0500 Subject: [PATCH 145/262] Initialize storageId variable in shared cache --- apps/files_sharing/lib/cache.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 07c305bb95..0534d6dd89 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -48,6 +48,7 @@ class Shared_Cache extends Cache { if ($storage) { $this->files[$target] = $internalPath; $cache = $storage->getCache(); + $this->storageId = $storage->getId(); $this->numericId = $cache->getNumericStorageId(); return $cache; } From a1f7c28e28e221a6939a74eb5ae7b43c02a1d8e6 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 1 Jan 2013 14:47:25 -0500 Subject: [PATCH 146/262] Use the source Scanner for shared storage when the path is specified --- apps/files_sharing/lib/sharedstorage.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 8504a2d894..3a5755c01f 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -401,15 +401,25 @@ class Shared extends \OC\Files\Storage\Common { return $this->filemtime($path) > $time; } - public function getCache() { + public function getCache($path = '') { return new \OC\Files\Cache\Shared_Cache($this); } - public function getPermissionsCache() { + public function getScanner($path = '') { + if ($path != '' && ($source = $this->getSourcePath($path))) { + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); + if ($storage) { + return $storage->getScanner($internalPath); + } + } + return new \OC\Files\Cache\Scanner($this); + } + + public function getPermissionsCache($path = '') { return new \OC\Files\Cache\Shared_Permissions($this); } - public function getWatcher() { + public function getWatcher($path = '') { return new \OC\Files\Cache\Shared_Watcher($this); } From a068ddff64bb6071de204b948129c4ca23c16d26 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 2 Jan 2013 14:40:06 -0500 Subject: [PATCH 147/262] Use the sub storage's permission cache for retrieving the correct permission --- lib/files/view.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 8558b03fe1..9ba3eea3cf 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -739,6 +739,18 @@ class View { $files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter + $ids = array(); + foreach ($files as $i => $file) { + $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $ids[] = $file['fileid']; + } + + $permissionsCache = $storage->getPermissionsCache($internalPath); + $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); + foreach ($files as $i => $file) { + $files[$i]['permissions'] = $permissions[$file['fileid']]; + } + //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders $mountPoints = Filesystem::getMountPoints($path); $dirLength = strlen($path); @@ -758,24 +770,14 @@ class View { } } else { //mountpoint in this folder, add an entry for it $rootEntry['name'] = $relativePath; + $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $subPermissionsCache = $subStorage->getPermissionsCache(''); + $rootEntry['permissions'] = $subPermissionsCache->get($rootEntry['fileid'], \OC_User::getUser()); $files[] = $rootEntry; } } } - $ids = array(); - - foreach ($files as $i => $file) { - $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache($internalPath); - - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$file['fileid']]; - } - if ($mimetype_filter) { foreach ($files as $file) { if (strpos($mimetype_filter, '/')) { From 6a6d6756b7a6495d044d44c8d6081505880d96b9 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 3 Jan 2013 00:29:10 +0100 Subject: [PATCH 148/262] Cache: rename index to prevent colissions with old fscache indexes --- db_structure.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index aa0916264c..e47cf3c629 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -190,7 +190,7 @@ - storage_path_hash + fs_storage_path_hash true storage @@ -203,7 +203,7 @@ - parent_name_hash + fs_parent_name_hash parent ascending From f144be8857e3356495acefca787637b5672f73ef Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 2 Jan 2013 19:20:34 -0500 Subject: [PATCH 149/262] Don't mount shared storage unless there are shared files --- apps/files_sharing/lib/sharedstorage.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 3a5755c01f..24096e0c10 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -390,8 +390,10 @@ class Shared extends \OC\Files\Storage\Common { } public static function setup($options) { - $user_dir = $options['user_dir']; - \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); + if (\OCP\Share::getItemsSharedWith('file')) { + $user_dir = $options['user_dir']; + \OC\Files\Filesystem::mount('\OC\Files\Storage\Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/'); + } } public function hasUpdated($path, $time) { From 38876fc98a11a917e68780357d7f4b5a146ba89a Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 3 Jan 2013 12:07:04 -0500 Subject: [PATCH 150/262] Update old storage classes names to the new namespace during mounting --- apps/files_external/lib/config.php | 12 ++++++++++++ lib/files/filesystem.php | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 323e4060a4..d7286c52c0 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -120,6 +120,10 @@ class OC_Mount_Config { if (isset($mountPoints[self::MOUNT_TYPE_GROUP])) { foreach ($mountPoints[self::MOUNT_TYPE_GROUP] as $group => $mounts) { foreach ($mounts as $mountPoint => $mount) { + // Update old classes to new namespace + if (strpos($mount['class'], 'OC_Filestorage_') !== false) { + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); // Merge the mount point into the current mount points @@ -139,6 +143,10 @@ class OC_Mount_Config { if (isset($mountPoints[self::MOUNT_TYPE_USER])) { foreach ($mountPoints[self::MOUNT_TYPE_USER] as $user => $mounts) { foreach ($mounts as $mountPoint => $mount) { + // Update old classes to new namespace + if (strpos($mount['class'], 'OC_Filestorage_') !== false) { + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); // Merge the mount point into the current mount points @@ -169,6 +177,10 @@ class OC_Mount_Config { $personal = array(); if (isset($mountPoints[self::MOUNT_TYPE_USER][$uid])) { foreach ($mountPoints[self::MOUNT_TYPE_USER][$uid] as $mountPoint => $mount) { + // Update old classes to new namespace + if (strpos($mount['class'], 'OC_Filestorage_') !== false) { + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + } // Remove '/uid/files/' from mount point $personal[substr($mountPoint, strlen($uid) + 8)] = array('class' => $mount['class'], 'backend' => $backends[$mount['class']]['backend'], diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 8183b8ff99..b9fd6a0376 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -364,7 +364,10 @@ class Filesystem { if (strlen($mountpoint) > 1) { $mountpoint .= '/'; } - + // Update old classes to new namespace + if (strpos($class, 'OC_Filestorage_') !== false) { + $class = '\OC\Files\Storage\\'.substr($class, 15, strlen($class) - 15); + } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); self::$storages[$mountpoint] = $class; From 1137723b2a46c37d61e7f501694c73562b21ef74 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 3 Jan 2013 12:13:45 -0500 Subject: [PATCH 151/262] Remove unnecessary length parameter from last commit --- apps/files_external/lib/config.php | 6 +++--- lib/files/filesystem.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index d7286c52c0..3bb512493d 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -122,7 +122,7 @@ class OC_Mount_Config { foreach ($mounts as $mountPoint => $mount) { // Update old classes to new namespace if (strpos($mount['class'], 'OC_Filestorage_') !== false) { - $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15); } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); @@ -145,7 +145,7 @@ class OC_Mount_Config { foreach ($mounts as $mountPoint => $mount) { // Update old classes to new namespace if (strpos($mount['class'], 'OC_Filestorage_') !== false) { - $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15); } // Remove '/$user/files/' from mount point $mountPoint = substr($mountPoint, 13); @@ -179,7 +179,7 @@ class OC_Mount_Config { foreach ($mountPoints[self::MOUNT_TYPE_USER][$uid] as $mountPoint => $mount) { // Update old classes to new namespace if (strpos($mount['class'], 'OC_Filestorage_') !== false) { - $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15, strlen($mount['class']) - 15); + $mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15); } // Remove '/uid/files/' from mount point $personal[substr($mountPoint, strlen($uid) + 8)] = array('class' => $mount['class'], diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index b9fd6a0376..d9487bde80 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -366,7 +366,7 @@ class Filesystem { } // Update old classes to new namespace if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15, strlen($class) - 15); + $class = '\OC\Files\Storage\\'.substr($class, 15); } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); From 0ca5047da56c1b6d0614174b01d42bace85d53ee Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 00:36:01 +0100 Subject: [PATCH 152/262] Autoload namespaced test classes --- lib/base.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/base.php b/lib/base.php index 3d3e7d59f9..80e5c5ed77 100644 --- a/lib/base.php +++ b/lib/base.php @@ -105,6 +105,8 @@ class OC $path = str_replace('\\', '/', $className) . '.php'; } elseif (strpos($className, 'Test_') === 0) { $path = 'tests/lib/' . strtolower(str_replace('_', '/', substr($className, 5)) . '.php'); + } elseif (strpos($className, 'Test\\') === 0) { + $path = 'tests/lib/' . strtolower(str_replace('\\', '/', substr($className, 5)) . '.php'); } else { return false; } From 457dc270f5147863c00b55355542298ba4d41762 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 00:36:39 +0100 Subject: [PATCH 153/262] Fix messed up mounts --- lib/files/filesystem.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index d9487bde80..b3ba62c3a4 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -364,14 +364,14 @@ class Filesystem { if (strlen($mountpoint) > 1) { $mountpoint .= '/'; } - // Update old classes to new namespace - if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15); - } if ($class instanceof \OC\Files\Storage\Storage) { self::$mounts[$mountpoint] = array('class' => get_class($class), 'arguments' => $arguments); self::$storages[$mountpoint] = $class; } else { + // Update old classes to new namespace + if (strpos($class, 'OC_Filestorage_') !== false) { + $class = '\OC\Files\Storage\\'.substr($class, 15); + } self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } } From 439578288facbae3144f131aca85a7235f622053 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 01:03:11 +0100 Subject: [PATCH 154/262] Cache: split permission cache scanning and cache scanning --- lib/files/cache/scanner.php | 9 --------- lib/files/view.php | 30 ++++++++++++++++++++++-------- tests/lib/files/view.php | 1 + 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 4c0ec9617f..526d4a2aab 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -24,11 +24,6 @@ class Scanner { */ private $cache; - /** - * @var \OC\Files\Cache\Permissions $permissionsCache - */ - private $permissionsCache; - const SCAN_RECURSIVE = true; const SCAN_SHALLOW = false; @@ -36,7 +31,6 @@ class Scanner { $this->storage = $storage; $this->storageId = $this->storage->getId(); $this->cache = $storage->getCache(); - $this->permissionsCache = $storage->getPermissionsCache(); } /** @@ -53,10 +47,8 @@ class Scanner { $data['mtime'] = $this->storage->filemtime($path); if ($data['mimetype'] == 'httpd/unix-directory') { $data['size'] = -1; //unknown - $data['permissions'] = $this->storage->getPermissions($path . '/'); } else { $data['size'] = $this->storage->filesize($path); - $data['permissions'] = $this->storage->getPermissions($path); } return $data; } @@ -81,7 +73,6 @@ class Scanner { } } $id = $this->cache->put($file, $data); - $this->permissionsCache->set($id, \OC_User::getUser(), $data['permissions']); } return $data; } diff --git a/lib/files/view.php b/lib/files/view.php index 9ba3eea3cf..124345f3c6 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -680,6 +680,8 @@ class View { list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { $cache = $storage->getCache($internalPath); + $permissionsCache = $storage->getPermissionsCache($internalPath); + $user = \OC_User::getUser(); if (!$cache->inCache($internalPath)) { $scanner = $storage->getScanner($internalPath); @@ -705,8 +707,12 @@ class View { } } - $permissionsCache = $storage->getPermissionsCache($internalPath); - $data['permissions'] = $permissionsCache->get($data['fileid'], \OC_User::getUser()); + $permissions = $permissionsCache->get($data['fileid'], $user); + if ($permissions === -1) { + $permissions = $storage->getPermissions($internalPath); + $permissionsCache->set($data['fileid'], $user, $permissions); + } + $data['permissions'] = $permissions; } } return $data; @@ -728,6 +734,8 @@ class View { list($storage, $internalPath) = Filesystem::resolvePath($path); if ($storage) { $cache = $storage->getCache($internalPath); + $permissionsCache = $storage->getPermissionsCache($internalPath); + $user = \OC_User::getUser(); if ($cache->getStatus($internalPath) < Cache\Cache::COMPLETE) { $scanner = $storage->getScanner($internalPath); @@ -743,12 +751,13 @@ class View { foreach ($files as $i => $file) { $files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $ids[] = $file['fileid']; - } - $permissionsCache = $storage->getPermissionsCache($internalPath); - $permissions = $permissionsCache->getMultiple($ids, \OC_User::getUser()); - foreach ($files as $i => $file) { - $files[$i]['permissions'] = $permissions[$file['fileid']]; + $permissions = $permissionsCache->get($file['fileid'], $user); + if ($permissions === -1) { + $permissions = $storage->getPermissions($file['path']); + $permissionsCache->set($file['fileid'], $user, $permissions); + } + $files[$i]['permissions'] = $permissions; } //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders @@ -772,7 +781,12 @@ class View { $rootEntry['name'] = $relativePath; $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $subPermissionsCache = $subStorage->getPermissionsCache(''); - $rootEntry['permissions'] = $subPermissionsCache->get($rootEntry['fileid'], \OC_User::getUser()); + $permissions = $subPermissionsCache->get($rootEntry['fileid'], $user); + if ($permissions === -1) { + $permissions = $subStorage->getPermissions($rootEntry['path']); + $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); + } + $rootEntry['permissions'] = $subPermissionsCache; $files[] = $rootEntry; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 712166ab32..4b0abc2201 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -43,6 +43,7 @@ class View extends \PHPUnit_Framework_TestCase { $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertEquals($textSize, $cachedData['size']); $this->assertEquals('text/plain', $cachedData['mimetype']); + $this->assertEquals(\OCP\PERMISSION_ALL ^ \OCP\PERMISSION_CREATE, $cachedData['permissions']); $cachedData = $rootView->getFileInfo('/'); $this->assertEquals($storageSize * 3, $cachedData['size']); From ad3badeabff9dde839827558c281a691c611cf87 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 01:03:11 +0100 Subject: [PATCH 155/262] Cache: split permission cache scanning and cache scanning --- tests/lib/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 4b0abc2201..5327114267 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -43,7 +43,7 @@ class View extends \PHPUnit_Framework_TestCase { $cachedData = $rootView->getFileInfo('/foo.txt'); $this->assertEquals($textSize, $cachedData['size']); $this->assertEquals('text/plain', $cachedData['mimetype']); - $this->assertEquals(\OCP\PERMISSION_ALL ^ \OCP\PERMISSION_CREATE, $cachedData['permissions']); + $this->assertNotEquals(-1, $cachedData['permissions']); $cachedData = $rootView->getFileInfo('/'); $this->assertEquals($storageSize * 3, $cachedData['size']); From d0377b1951a156e218ca0200340e2bcfb51ac0c8 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 7 Jan 2013 01:40:09 +0100 Subject: [PATCH 156/262] Cache: normalize mimetypes --- db_structure.xml | 44 ++++++++++++++++++++++++++--- lib/files/cache/cache.php | 59 +++++++++++++++++++++++++++++++++++---- lib/files/view.php | 2 +- lib/util.php | 2 +- 4 files changed, 96 insertions(+), 11 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index e47cf3c629..3022983473 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -94,6 +94,42 @@
+ + + *dbprefix*mimetypes + + + + + id + integer + 0 + true + 1 + 4 + + + + mimetype + text + + true + 64 + + + + mimetype_id_index + true + + mimetype + ascending + + + + + +
+ *dbprefix*filecache @@ -151,18 +187,18 @@ mimetype - text + integer true - 64 + 4 mimepart - text + integer true - 32 + 4 diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 3ebae9baa5..0001c2752d 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -36,6 +36,9 @@ class Cache { */ private $numericId; + private $mimetypeIds = array(); + private $mimetypes = array(); + /** * @param \OC\Files\Storage\Storage|string $storage */ @@ -61,6 +64,41 @@ class Cache { return $this->numericId; } + /** + * normalize mimetypes + * + * @param string $mime + * @return int + */ + public function getMimetypeId($mime) { + if (!isset($this->mimetypeIds[$mime])) { + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'); + $result = $query->execute(array($mime)); + if ($row = $result->fetchRow()) { + $this->mimetypeIds[$mime] = $row['id']; + } else { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*mimetypes`(`mimetype`) VALUES(?)'); + $query->execute(array($mime)); + $this->mimetypeIds[$mime] = \OC_DB::insertid('*PREFIX*mimetypes'); + } + $this->mimetypes[$this->mimetypeIds[$mime]] = $mime; + } + return $this->mimetypeIds[$mime]; + } + + public function getMimetype($id) { + if (!isset($this->mimetypes[$id])) { + $query = \OC_DB::prepare('SELECT `mimetype` FROM `*PREFIX*mimetypes` WHERE `id` = ?'); + $result = $query->execute(array($id)); + if ($row = $result->fetchRow()) { + $this->mimetypes[$id] = $row['mimetype']; + } else { + return null; + } + } + return $this->mimetypes[$id]; + } + /** * get the stored metadata of a file or folder * @@ -92,6 +130,8 @@ class Cache { $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; $data['encrypted'] = (bool)$data['encrypted']; + $data['mimetype'] = $this->getMimetype($data['mimetype']); + $data['mimepart'] = $this->getMimetype($data['mimepart']); } return $data; @@ -110,7 +150,12 @@ class Cache { 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC'); $result = $query->execute(array($fileId)); - return $result->fetchAll(); + $files = $result->fetchAll(); + foreach ($files as &$file) { + $file['mimetype'] = $this->getMimetype($file['mimetype']); + $file['mimepart'] = $this->getMimetype($file['mimepart']); + } + return $files; } else { return array(); } @@ -179,22 +224,23 @@ class Cache { * @param array $data * @return array */ - static function buildParts(array $data) { + function buildParts(array $data) { $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted'); $params = array(); $queryParts = array(); foreach ($data as $name => $value) { if (array_search($name, $fields) !== false) { - $params[] = $value; - $queryParts[] = '`' . $name . '`'; if ($name === 'path') { $params[] = md5($value); $queryParts[] = '`path_hash`'; } elseif ($name === 'mimetype') { - $params[] = substr($value, 0, strpos($value, '/')); + $params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/'))); $queryParts[] = '`mimepart`'; + $value = $this->getMimetypeId($value); } + $params[] = $value; + $queryParts[] = '`' . $name . '`'; } } return array($queryParts, $params); @@ -339,6 +385,8 @@ class Cache { $result = $query->execute(array($pattern, $this->numericId)); $files = array(); while ($row = $result->fetchRow()) { + $row['mimetype'] = $this->getMimetype($row['mimetype']); + $row['mimepart'] = $this->getMimetype($row['mimepart']); $files[] = $row; } return $files; @@ -360,6 +408,7 @@ class Cache { SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?' ); + $mimetype = $this->getMimetypeId($mimetype); $result = $query->execute(array($mimetype, $this->numericId)); return $result->fetchAll(); } diff --git a/lib/files/view.php b/lib/files/view.php index 124345f3c6..8303a080bd 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -693,7 +693,7 @@ class View { $data = $cache->get($internalPath); - if ($data) { + if ($data and $data['fileid']) { if ($data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mountpoints to the folder $mountPoints = Filesystem::getMountPoints($path); diff --git a/lib/util.php b/lib/util.php index 805ef6f18b..93c0d0f26d 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,04); + return array(4,91,05); } /** From 5174eda23270463f09c82db77f2f61d3496f752f Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 15:21:38 -0500 Subject: [PATCH 157/262] Fix permissions for mount point --- lib/files/view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/view.php b/lib/files/view.php index 8303a080bd..94c89603ae 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -786,7 +786,7 @@ class View { $permissions = $subStorage->getPermissions($rootEntry['path']); $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); } - $rootEntry['permissions'] = $subPermissionsCache; + $rootEntry['permissions'] = $permissions; $files[] = $rootEntry; } } From a7d4d042239236082d7f2c2679249ea7d48e596c Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 15:27:22 -0500 Subject: [PATCH 158/262] Fix mimetypes in shared cache --- apps/files_sharing/lib/cache.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 0534d6dd89..8b989db3b0 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -79,6 +79,8 @@ class Shared_Cache extends Cache { $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; $data['encrypted'] = (bool)$data['encrypted']; + $data['mimetype'] = $this->getMimetype($data['mimetype']); + $data['mimepart'] = $this->getMimetype($data['mimepart']); return $data; } return false; @@ -92,7 +94,12 @@ class Shared_Cache extends Cache { */ public function getFolderContents($folder) { if ($folder == '') { - return \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS); + $files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS); + foreach ($files as &$file) { + $file['mimetype'] = $this->getMimetype($file['mimetype']); + $file['mimepart'] = $this->getMimetype($file['mimepart']); + } + return $files; } else { if ($cache = $this->getSourceCache($folder)) { return $cache->getFolderContents($this->files[$folder]); From 8f8a5bbfb750b3c9091da810749a43cada2740b2 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 18:17:14 -0500 Subject: [PATCH 159/262] Maked Shared_Permissions extend Permissions class --- apps/files_sharing/lib/permissions.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php index 6eaed34b33..508c3a384f 100644 --- a/apps/files_sharing/lib/permissions.php +++ b/apps/files_sharing/lib/permissions.php @@ -20,7 +20,7 @@ */ namespace OC\Files\Cache; -class Shared_Permissions { +class Shared_Permissions extends Permissions { /** * get the permissions for a single file @@ -29,7 +29,7 @@ class Shared_Permissions { * @param string $user * @return int (-1 if file no permissions set) */ - static public function get($fileId, $user) { + public function get($fileId, $user) { if ($fileId == -1) { return \OCP\PERMISSION_READ; } @@ -48,7 +48,7 @@ class Shared_Permissions { * @param string $user * @param int $permissions */ - static public function set($fileId, $user, $permissions) { + public function set($fileId, $user, $permissions) { // Not a valid action for Shared Permissions } @@ -59,7 +59,7 @@ class Shared_Permissions { * @param string $user * @return int[] */ - static public function getMultiple($fileIds, $user) { + public function getMultiple($fileIds, $user) { if (count($fileIds) === 0) { return array(); } @@ -75,11 +75,11 @@ class Shared_Permissions { * @param int $fileId * @param string $user */ - static public function remove($fileId, $user) { + public function remove($fileId, $user) { // Not a valid action for Shared Permissions } - static public function removeMultiple($fileIds, $user) { + public function removeMultiple($fileIds, $user) { // Not a valid action for Shared Permissions } } From e8b195bf109d702402735e628b2d239b199088e5 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 7 Jan 2013 20:52:51 -0500 Subject: [PATCH 160/262] Almost fix Shared scanner... --- apps/files_sharing/lib/cache.php | 13 +++++++++++++ apps/files_sharing/lib/permissions.php | 2 +- apps/files_sharing/lib/share/file.php | 3 +++ apps/files_sharing/lib/share/folder.php | 11 +++++++++-- apps/files_sharing/lib/sharedstorage.php | 6 ------ lib/public/share.php | 5 ++++- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 8b989db3b0..d35a5148de 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -136,6 +136,19 @@ class Shared_Cache extends Cache { return -1; } + /** + * check if a file is available in the cache + * + * @param string $file + * @return bool + */ + public function inCache($file) { + if ($file == '') { + return true; + } + return parent::inCache($file); + } + /** * remove a file or folder from the cache * diff --git a/apps/files_sharing/lib/permissions.php b/apps/files_sharing/lib/permissions.php index 508c3a384f..2b068ff935 100644 --- a/apps/files_sharing/lib/permissions.php +++ b/apps/files_sharing/lib/permissions.php @@ -33,7 +33,7 @@ class Shared_Permissions extends Permissions { if ($fileId == -1) { return \OCP\PERMISSION_READ; } - $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE); + $source = \OCP\Share::getItemSharedWithBySource('file', $fileId, \OC_Share_Backend_File::FORMAT_SHARED_STORAGE, null, true); if ($source) { return $source['permissions']; } else { diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php index 5e98c455d3..6d3c55a008 100644 --- a/apps/files_sharing/lib/share/file.php +++ b/apps/files_sharing/lib/share/file.php @@ -117,6 +117,9 @@ class OC_Share_Backend_File implements OCP\Share_Backend_File_Dependent { } public static function getSource($target) { + if ($target == '') { + return false; + } $target = '/'.$target; $target = rtrim($target, '/'); $pos = strpos($target, '/', 1); diff --git a/apps/files_sharing/lib/share/folder.php b/apps/files_sharing/lib/share/folder.php index bbe4c130bd..11c8c6b1e8 100644 --- a/apps/files_sharing/lib/share/folder.php +++ b/apps/files_sharing/lib/share/folder.php @@ -24,6 +24,13 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File implements OCP\Share public function getChildren($itemSource) { $children = array(); $parents = array($itemSource); + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'); + $result = $query->execute(array('httpd/unix-directory')); + if ($row = $result->fetchRow()) { + $mimetype = $row['id']; + } else { + $mimetype = -1; + } while (!empty($parents)) { $parents = "'".implode("','", $parents)."'"; $query = OC_DB::prepare('SELECT `fileid`, `name`, `mimetype` FROM `*PREFIX*filecache` WHERE `parent` IN ('.$parents.')'); @@ -32,8 +39,8 @@ class OC_Share_Backend_Folder extends OC_Share_Backend_File implements OCP\Share while ($file = $result->fetchRow()) { $children[] = array('source' => $file['fileid'], 'file_path' => $file['name']); // If a child folder is found look inside it - if ($file['mimetype'] == 'httpd/unix-directory') { - $parents[] = $file['id']; + if ($file['mimetype'] == $mimetype) { + $parents[] = $file['fileid']; } } } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 24096e0c10..c8756af8ed 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -408,12 +408,6 @@ class Shared extends \OC\Files\Storage\Common { } public function getScanner($path = '') { - if ($path != '' && ($source = $this->getSourcePath($path))) { - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); - if ($storage) { - return $storage->getScanner($internalPath); - } - } return new \OC\Files\Cache\Scanner($this); } diff --git a/lib/public/share.php b/lib/public/share.php index c74960b94c..7722e0b86c 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -756,7 +756,7 @@ class Share { $collectionItems = array(); foreach ($items as &$row) { // Return only the item instead of a 2-dimensional array - if ($limit == 1 && $row['item_type'] == $itemType && $row[$column] == $item) { + if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) { if ($format == self::FORMAT_NONE) { return $row; } else { @@ -823,6 +823,9 @@ class Share { if (!empty($collectionItems)) { $items = array_merge($items, $collectionItems); } + if (empty($items) && $limit == 1) { + return false; + } if ($format == self::FORMAT_NONE) { return $items; } else if ($format == self::FORMAT_STATUSES) { From 464dafd7d2627d59732c09e01986d705d604ee56 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 9 Jan 2013 22:17:39 -0500 Subject: [PATCH 161/262] Make Google Drive storage id unique, before it was anonymousanonymous --- apps/files_external/lib/google.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index bbb315c491..4c485773e7 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -41,7 +41,7 @@ class Google extends \OC\Files\Storage\Common { ) { $consumer_key = isset($params['consumer_key']) ? $params['consumer_key'] : 'anonymous'; $consumer_secret = isset($params['consumer_secret']) ? $params['consumer_secret'] : 'anonymous'; - $this->id = 'google::' . $consumer_key . $consumer_secret; + $this->id = 'google::' . $params['token']; $this->consumer = new \OAuthConsumer($consumer_key, $consumer_secret); $this->oauth_token = new \OAuthToken($params['token'], $params['token_secret']); $this->sig_method = new \OAuthSignatureMethod_HMAC_SHA1(); From 106541361c3857ed8e35c6869c91faffb8ae984d Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Wed, 9 Jan 2013 22:57:42 -0500 Subject: [PATCH 162/262] Change length of mimetypes to 255, the maximum length according to RFC 4288 --- db_structure.xml | 2 +- lib/util.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/db_structure.xml b/db_structure.xml index 3022983473..7b6829aa30 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -114,7 +114,7 @@ text true - 64 + 255 diff --git a/lib/util.php b/lib/util.php index 93c0d0f26d..e814a3a32d 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,05); + return array(4,91,06); } /** From aa15fcf22f4c32026eca5ff8ae5e5df244f2c53e Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 10 Jan 2013 12:09:55 -0500 Subject: [PATCH 163/262] Scan mount points in root before adding a entry --- lib/files/view.php | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 94c89603ae..703cda5123 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -767,27 +767,37 @@ class View { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { $subCache = $subStorage->getCache(''); - $rootEntry = $subCache->get(''); - $relativePath = trim(substr($mountPoint, $dirLength), '/'); - if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder - $entryName = substr($relativePath, 0, $pos); - foreach ($files as &$entry) { - if ($entry['name'] === $entryName) { - $entry['size'] += $rootEntry['size']; + if ($subCache->getStatus('') < Cache\Cache::COMPLETE) { + $subScanner = $subStorage->getScanner(''); + $subScanner->scan('', Cache\Scanner::SCAN_SHALLOW); + } else { + $subWatcher = $subStorage->getWatcher(''); + $subWatcher->checkUpdate(''); + } + + $rootEntry = $subCache->get(''); + if ($rootEntry) { + $relativePath = trim(substr($mountPoint, $dirLength), '/'); + if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder + $entryName = substr($relativePath, 0, $pos); + foreach ($files as &$entry) { + if ($entry['name'] === $entryName) { + $entry['size'] += $rootEntry['size']; + } } + } else { //mountpoint in this folder, add an entry for it + $rootEntry['name'] = $relativePath; + $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; + $subPermissionsCache = $subStorage->getPermissionsCache(''); + $permissions = $subPermissionsCache->get($rootEntry['fileid'], $user); + if ($permissions === -1) { + $permissions = $subStorage->getPermissions($rootEntry['path']); + $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); + } + $rootEntry['permissions'] = $permissions; + $files[] = $rootEntry; } - } else { //mountpoint in this folder, add an entry for it - $rootEntry['name'] = $relativePath; - $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; - $subPermissionsCache = $subStorage->getPermissionsCache(''); - $permissions = $subPermissionsCache->get($rootEntry['fileid'], $user); - if ($permissions === -1) { - $permissions = $subStorage->getPermissions($rootEntry['path']); - $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); - } - $rootEntry['permissions'] = $permissions; - $files[] = $rootEntry; } } } From 4835525c469d5ac75104e92c2dfbbb049d62890c Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 10 Jan 2013 22:28:50 -0500 Subject: [PATCH 164/262] Switch scan to scanFile for root of mount points --- lib/files/view.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index 703cda5123..fa031b7478 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -768,9 +768,9 @@ class View { if ($subStorage) { $subCache = $subStorage->getCache(''); - if ($subCache->getStatus('') < Cache\Cache::COMPLETE) { + if ($subCache->getStatus('') === Cache\Cache::NOT_FOUND) { $subScanner = $subStorage->getScanner(''); - $subScanner->scan('', Cache\Scanner::SCAN_SHALLOW); + $subScanner->scanFile(''); } else { $subWatcher = $subStorage->getWatcher(''); $subWatcher->checkUpdate(''); From 36cac7f924ad07738a3cb72fee06f21d07baad42 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Thu, 10 Jan 2013 22:29:47 -0500 Subject: [PATCH 165/262] Return NOT_FOUND in shared cache --- apps/files_sharing/lib/cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index d35a5148de..0b187a3c3f 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -196,7 +196,7 @@ class Shared_Cache extends Cache { if ($cache = $this->getSourceCache($file)) { return $cache->getStatus($this->files[$file]); } - return false; + return self::NOT_FOUND; } /** From 8a63bcc1e85499335ade1df459f0c9f467161404 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 20:56:36 -0500 Subject: [PATCH 166/262] Don't use more entropy for etags --- lib/files/storage/common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php index e859d447f3..591803f044 100644 --- a/lib/files/storage/common.php +++ b/lib/files/storage/common.php @@ -274,7 +274,7 @@ abstract class Common implements \OC\Files\Storage\Storage { $hash = call_user_func($ETagFunction, $path); return $hash; }else{ - return uniqid('', true); + return uniqid(); } } } From 9e2f3a53244e353cb75f9927e1c69ef40f589db7 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 20:59:53 -0500 Subject: [PATCH 167/262] Remove old create etag function --- lib/connector/sabre/file.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index 1770b49128..e0723e1230 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -101,15 +101,6 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D return $this->getETagPropertyForPath($this->path); } - /** - * Creates a ETag for this path. - * @param string $path Path of the file - * @return string|null Returns null if the ETag can not effectively be determined - */ - static protected function createETag($path) { - return \OC\Files\Filesystem::hash('md5', $path); - } - /** * Returns the mime-type for a file * From a00b9e0a03a7cdb1103415d33d2c3f22e86edffb Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 21:01:28 -0500 Subject: [PATCH 168/262] Bump version --- lib/util.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util.php b/lib/util.php index e814a3a32d..faae962859 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,06); + return array(4,91,07); } /** From b30648cb7dc258208fad4dadb297aa1d792fa7ef Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 21:09:01 -0500 Subject: [PATCH 169/262] Don't waste time making another call since we know it doesn't exist --- lib/connector/sabre/file.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index e0723e1230..1c18a39174 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -98,7 +98,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D if (isset($properties[self::GETETAG_PROPERTYNAME])) { return $properties[self::GETETAG_PROPERTYNAME]; } - return $this->getETagPropertyForPath($this->path); + return null; } /** From 094a852bff378c03c873b6e8fd94587d2a2c784e Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 11 Jan 2013 21:09:58 -0500 Subject: [PATCH 170/262] Wrap the etag in double quotes --- lib/connector/sabre/node.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index dd8ae152ff..93d8fc477d 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -213,7 +213,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr static public function getETagPropertyForPath($path) { $data = \OC\Files\Filesystem::getFileInfo($path); if (isset($data['etag'])) { - return $data['etag']; + return '"'.$data['etag'].'"'; } return null; } From 94068e5d08cba776e410d925e26037d442b5bc62 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 3 Jan 2013 00:26:13 +0100 Subject: [PATCH 171/262] Cache: show upgrade progress --- apps/files/ajax/upgrade.php | 42 ++++++++ apps/files/appinfo/app.php | 10 -- apps/files/css/files.css | 9 ++ apps/files/index.php | 72 ++++++++------ apps/files/js/upgrade.js | 17 ++++ apps/files/templates/upgrade.php | 4 + lib/files/cache/legacy.php | 73 ++++++++++++++ lib/files/cache/upgrade.php | 161 ++++++++++++++++++++++--------- 8 files changed, 305 insertions(+), 83 deletions(-) create mode 100644 apps/files/ajax/upgrade.php create mode 100644 apps/files/js/upgrade.js create mode 100644 apps/files/templates/upgrade.php create mode 100644 lib/files/cache/legacy.php diff --git a/apps/files/ajax/upgrade.php b/apps/files/ajax/upgrade.php new file mode 100644 index 0000000000..965c0073b8 --- /dev/null +++ b/apps/files/ajax/upgrade.php @@ -0,0 +1,42 @@ +hasItems()) { + OC_Hook::connect('\OC\Files\Cache\Upgrade', 'migrate_path', $listener, 'upgradePath'); + + $upgrade = new \OC\Files\Cache\Upgrade($legacy); + $count = $legacy->getCount(); + $eventSource->send('total', $count); + $upgrade->upgradePath('/' . $user . '/files'); +} +\OC\Files\Cache\Upgrade::upgradeDone($user); +$eventSource->send('done', true); +$eventSource->close(); + +class UpgradeListener { + /** + * @var OC_EventSource $eventSource + */ + private $eventSource; + + private $count = 0; + private $lastSend = 0; + + public function __construct($eventSource) { + $this->eventSource = $eventSource; + } + + public function upgradePath($path) { + $this->count++; + if ($this->count > ($this->lastSend + 5)) { + $this->lastSend = $this->count; + $this->eventSource->send('count', $this->count); + } + } +} diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php index 643d8ed18a..ab2f3b01a2 100644 --- a/apps/files/appinfo/app.php +++ b/apps/files/appinfo/app.php @@ -10,13 +10,3 @@ OCP\App::addNavigationEntry( array( "id" => "files_index", "name" => $l->t("Files") )); OC_Search::registerProvider('OC_Search_Provider_File'); - -if (OC_User::isLoggedIn()) { - // update OC4.5 filecache to OC5 filecache, can't do this in update.php since it needs to happen for each user individually - $cacheVersion = (int)OCP\Config::getUserValue(OC_User::getUser(), 'files', 'cache_version', 4); - if ($cacheVersion < 5) { - \OC_Log::write('files', 'updating filecache to 5.0 for user ' . OC_User::getUser(), \OC_Log::INFO); - \OC\Files\Cache\Upgrade::upgrade(); - OCP\Config::setUserValue(OC_User::getUser(), 'files', 'cache_version', 5); - } -} diff --git a/apps/files/css/files.css b/apps/files/css/files.css index 36a1e5c954..0c130efe47 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -122,3 +122,12 @@ a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; } #scanning-message{ top:40%; left:40%; position:absolute; display:none; } div.crumb a{ padding:0.9em 0 0.7em 0; } + +#upgrade { + width: 400px; + position: absolute; + top: 200px; + left: 50%; + text-align: center; + margin-left: -200px; +} diff --git a/apps/files/index.php b/apps/files/index.php index 993d8b4dcf..0dce768696 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -28,7 +28,6 @@ OCP\User::checkLoggedIn(); OCP\Util::addStyle('files', 'files'); OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); -OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'filelist'); OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'keyboardshortcuts'); @@ -37,8 +36,8 @@ OCP\App::setActiveNavigationEntry('files_index'); // Load the files $dir = isset($_GET['dir']) ? stripslashes($_GET['dir']) : ''; // Redirect if directory does not exist -if(!\OC\Files\Filesystem::is_dir($dir . '/')) { - header('Location: '.$_SERVER['SCRIPT_NAME'].''); +if (!\OC\Files\Filesystem::is_dir($dir . '/')) { + header('Location: ' . $_SERVER['SCRIPT_NAME'] . ''); exit(); } @@ -53,16 +52,25 @@ function fileCmp($a, $b) { } $files = array(); -foreach( \OC\Files\Filesystem::getDirectoryContent( $dir ) as $i ) { - $i['date'] = OCP\Util::formatDate($i['mtime'] ); - if($i['type'] == 'file') { +$user = OC_User::getUser(); +if (\OC\Files\Cache\Upgrade::needUpgrade($user)) { //dont load anything if we need to upgrade the cache + $content = array(); + $needUpgrade = true; + $freeSpace = 0; +} else { + $content = \OC\Files\Filesystem::getDirectoryContent($dir); + $freeSpace = \OC\Files\Filesystem::free_space($dir); + $needUpgrade = false; +} +foreach ($content as $i) { + $i['date'] = OCP\Util::formatDate($i['mtime']); + if ($i['type'] == 'file') { $fileinfo = pathinfo($i['name']); $i['basename'] = $fileinfo['filename']; if (!empty($fileinfo['extension'])) { - $i['extension']='.' . $fileinfo['extension']; - } - else { - $i['extension']=''; + $i['extension'] = '.' . $fileinfo['extension']; + } else { + $i['extension'] = ''; } } $i['directory'] = $dir; @@ -74,10 +82,10 @@ usort($files, "fileCmp"); // Make breadcrumb $breadcrumb = array(); $pathtohere = ''; -foreach( explode( '/', $dir ) as $i ) { - if( $i != '' ) { +foreach (explode('/', $dir) as $i) { + if ($i != '') { $pathtohere .= '/' . $i; - $breadcrumb[] = array( 'dir' => $pathtohere, 'name' => $i ); + $breadcrumb[] = array('dir' => $pathtohere, 'name' => $i); } } @@ -94,29 +102,35 @@ $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize') $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size')); $maxUploadFilesize = min($upload_max_filesize, $post_max_size); -$freeSpace = \OC\Files\Filesystem::free_space($dir); -$freeSpace = max($freeSpace,0); +$freeSpace = max($freeSpace, 0); $maxUploadFilesize = min($maxUploadFilesize, $freeSpace); $permissions = OCP\PERMISSION_READ; if (\OC\Files\Filesystem::isUpdatable($dir . '/')) { - $permissions |= OCP\PERMISSION_UPDATE; + $permissions |= OCP\PERMISSION_UPDATE; } if (\OC\Files\Filesystem::isDeletable($dir . '/')) { - $permissions |= OCP\PERMISSION_DELETE; + $permissions |= OCP\PERMISSION_DELETE; } if (\OC\Files\Filesystem::isSharable($dir . '/')) { - $permissions |= OCP\PERMISSION_SHARE; + $permissions |= OCP\PERMISSION_SHARE; } -$tmpl = new OCP\Template( 'files', 'index', 'user' ); -$tmpl->assign( 'fileList', $list->fetchPage(), false ); -$tmpl->assign( 'breadcrumb', $breadcrumbNav->fetchPage(), false ); -$tmpl->assign( 'dir', \OC\Files\Filesystem::normalizePath($dir)); -$tmpl->assign( 'isCreatable', \OC\Files\Filesystem::isCreatable($dir . '/')); -$tmpl->assign('permissions', $permissions); -$tmpl->assign('files', $files); -$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); -$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); -$tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); -$tmpl->printPage(); +if ($needUpgrade) { + OCP\Util::addscript('files', 'upgrade'); + $tmpl = new OCP\Template('files', 'upgrade', 'user'); + $tmpl->printPage(); +} else { + OCP\Util::addscript('files', 'files'); + $tmpl = new OCP\Template('files', 'index', 'user'); + $tmpl->assign('fileList', $list->fetchPage(), false); + $tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage(), false); + $tmpl->assign('dir', \OC\Files\Filesystem::normalizePath($dir)); + $tmpl->assign('isCreatable', \OC\Files\Filesystem::isCreatable($dir . '/')); + $tmpl->assign('permissions', $permissions); + $tmpl->assign('files', $files); + $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); + $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); + $tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); + $tmpl->printPage(); +} diff --git a/apps/files/js/upgrade.js b/apps/files/js/upgrade.js new file mode 100644 index 0000000000..02d57fc9e6 --- /dev/null +++ b/apps/files/js/upgrade.js @@ -0,0 +1,17 @@ +$(document).ready(function () { + var eventSource, total, bar = $('#progressbar'); + console.log('start'); + bar.progressbar({value: 0}); + eventSource = new OC.EventSource(OC.filePath('files', 'ajax', 'upgrade.php')); + eventSource.listen('total', function (count) { + total = count; + console.log(count + ' files needed to be migrated'); + }); + eventSource.listen('count', function (count) { + bar.progressbar({value: (count / total) * 100}); + console.log(count); + }); + eventSource.listen('done', function () { + document.location.reload(); + }); +}); diff --git a/apps/files/templates/upgrade.php b/apps/files/templates/upgrade.php new file mode 100644 index 0000000000..de6cc71302 --- /dev/null +++ b/apps/files/templates/upgrade.php @@ -0,0 +1,4 @@ +
+ t('Upgrading filesystem cache...');?> +
+
diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php new file mode 100644 index 0000000000..ee10a1c135 --- /dev/null +++ b/lib/files/cache/legacy.php @@ -0,0 +1,73 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Cache; + +/** + * Provide read only support for the old filecache + */ +class Legacy { + private $user; + + public function __construct($user) { + $this->user = $user; + } + + function getCount() { + $query = \OC_DB::prepare('SELECT COUNT(`id`) AS `count` FROM `*PREFIX*fscache` WHERE `user` = ?'); + $result = $query->execute(array($this->user)); + if ($row = $result->fetchRow()) { + return $row['count']; + } else { + return 0; + } + } + + /** + * check if a legacy cache is present and holds items + * + * @return bool + */ + function hasItems() { + try { + $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `user` = ? LIMIT 1'); + } catch (\Exception $e) { + return false; + } + try { + $result = $query->execute(array($this->user)); + } catch (\Exception $e) { + return false; + } + return (bool)$result->fetchRow(); + } + + /** + * @param string|int $path + * @return array + */ + function get($path) { + if (is_numeric($path)) { + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `id` = ?'); + } else { + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `path` = ?'); + } + $result = $query->execute(array($path)); + return $result->fetchRow(); + } + + /** + * @param int $id + * @return array + */ + function getChildren($id) { + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` WHERE `parent` = ?'); + $result = $query->execute(array($id)); + return $result->fetchAll(); + } +} diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 77db4c2339..1032e0a844 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -9,62 +9,102 @@ namespace OC\Files\Cache; class Upgrade { - static $permissionsCaches = array(); + /** + * @var Legacy $legacy + */ + private $legacy; - static $numericIds = array(); + private $permissionsCaches = array(); - static function upgrade() { - $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache`( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + private $numericIds = array(); - try { - $oldEntriesQuery = \OC_DB::prepare('SELECT * FROM `*PREFIX*fscache` ORDER BY `id` ASC'); //sort ascending to ensure the parent gets inserted before a child - } catch (\Exception $e) { - return; - } - try { - $oldEntriesResult = $oldEntriesQuery->execute(); - } catch (\Exception $e) { - return; - } - if (!$oldEntriesResult) { + private $mimeTypeIds = array(); + + /** + * @param Legacy $legacy + */ + public function __construct($legacy) { + $this->legacy = $legacy; + } + + /** + * Preform a shallow upgrade + * + * @param string $path + * @param int $mode + */ + function upgradePath($path, $mode = Scanner::SCAN_RECURSIVE) { + if (!$this->legacy->hasItems()) { return; } + \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $path); - $checkExistingQuery = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `fileid` = ?'); + if ($row = $this->legacy->get($path)) { + $data = $this->getNewData($row); + $this->insert($data); - while ($row = $oldEntriesResult->fetchRow()) { - if ($checkExistingQuery->execute(array($row['id']))->fetchRow()) { - continue; + $children = $this->legacy->getChildren($data['id']); + foreach ($children as $child) { + if ($mode == Scanner::SCAN_SHALLOW) { + $childData = $this->getNewData($child); + \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']); + $this->insert($childData); + } else { + $this->upgradePath($child['path']); + } } - - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($row['path']); - /** - * @var \OC\Files\Storage\Storage $storage - * @var string $internalPath; - */ - $pathHash = md5($internalPath); - $storageId = self::getNumericId($storage); - $parentId = ($internalPath === '') ? -1 : $row['parent']; - - $insertQuery->execute(array($row['id'], $storageId, $internalPath, $pathHash, $parentId, $row['name'], $row['mimetype'], $row['mimepart'], $row['size'], $row['mtime'], $row['encrypted'])); - - $permissions = ($row['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ; - $permissionsCache = self::getPermissionsCache($storage); - $permissionsCache->set($row['id'], $row['user'], $permissions); } } + /** + * @param array $data the data for the new cache + */ + function insert($data) { + $insertQuery = \OC_DB::prepare('INSERT INTO `*PREFIX*filecache` + ( `fileid`, `storage`, `path`, `path_hash`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted` ) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); + + $insertQuery->execute(array($data['id'], $data['storage'], $data['path'], $data['path_hash'], $data['parent'], $data['name'], + $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'])); + + $permissionsCache = $this->getPermissionsCache($data['storage_object']); + $permissionsCache->set($data['id'], $data['user'], $data['permissions']); + } + + /** + * get the new data array from the old one + * + * @param array $data the data from the old cache + * @return array + */ + function getNewData($data) { + $newData = $data; + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($data['path']); + /** + * @var \OC\Files\Storage\Storage $storage + * @var string $internalPath; + */ + $newData['path_hash'] = md5($internalPath); + $newData['path'] = $internalPath; + $newData['storage'] = $this->getNumericId($storage); + $newData['parent'] = ($internalPath === '') ? -1 : $data['parent']; + $newData['permissions'] = ($data['writable']) ? \OCP\PERMISSION_ALL : \OCP\PERMISSION_READ; + $newData['storage_object'] = $storage; + $newData['mimetype'] = $this->getMimetypeId($newData['mimetype'], $storage); + $newData['mimepart'] = $this->getMimetypeId($newData['mimepart'], $storage); + return $newData; + } + /** * @param \OC\Files\Storage\Storage $storage * @return Permissions */ - static function getPermissionsCache($storage) { + function getPermissionsCache($storage) { $storageId = $storage->getId(); - if (!isset(self::$permissionsCaches[$storageId])) { - self::$permissionsCaches[$storageId] = $storage->getPermissionsCache(); + if (!isset($this->permissionsCaches[$storageId])) { + $this->permissionsCaches[$storageId] = $storage->getPermissionsCache(); } - return self::$permissionsCaches[$storageId]; + return $this->permissionsCaches[$storageId]; } /** @@ -73,12 +113,45 @@ class Upgrade { * @param \OC\Files\Storage\Storage $storage * @return int */ - static function getNumericId($storage) { + function getNumericId($storage) { $storageId = $storage->getId(); - if (!isset(self::$numericIds[$storageId])) { - $cache = new Cache($storage); - self::$numericIds[$storageId] = $cache->getNumericStorageId(); + if (!isset($this->numericIds[$storageId])) { + $cache = $storage->getCache(); + $this->numericIds[$storageId] = $cache->getNumericStorageId(); } - return self::$numericIds[$storageId]; + return $this->numericIds[$storageId]; + } + + /** + * @param string $mimetype + * @param \OC\Files\Storage\Storage $storage + * @return int + */ + function getMimetypeId($mimetype, $storage) { + if (!isset($this->mimeTypeIds[$mimetype])) { + $cache = new Cache($storage); + $this->mimeTypeIds[$mimetype] = $cache->getMimetypeId($mimetype); + } + return $this->mimeTypeIds[$mimetype]; + } + + /** + * check if a cache upgrade is required for $user + * + * @param string $user + * @return bool + */ + static function needUpgrade($user) { + $cacheVersion = (int)\OCP\Config::getUserValue($user, 'files', 'cache_version', 4); + return $cacheVersion < 5; + } + + /** + * mark the filecache as upgrade + * + * @param string $user + */ + static function upgradeDone($user) { + \OCP\Config::setUserValue($user, 'files', 'cache_version', 5); } } From 7debfac0dc8f602168d8db480cfd4757b4d612b0 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 15 Jan 2013 19:11:12 +0100 Subject: [PATCH 172/262] Cache: more efficient upgrading --- apps/files/ajax/upgrade.php | 2 ++ lib/files/cache/legacy.php | 10 +++++++++- lib/files/cache/upgrade.php | 24 +++++++++++++++--------- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/apps/files/ajax/upgrade.php b/apps/files/ajax/upgrade.php index 965c0073b8..7237b02c0b 100644 --- a/apps/files/ajax/upgrade.php +++ b/apps/files/ajax/upgrade.php @@ -10,10 +10,12 @@ $legacy = new \OC\Files\Cache\Legacy($user); if ($legacy->hasItems()) { OC_Hook::connect('\OC\Files\Cache\Upgrade', 'migrate_path', $listener, 'upgradePath'); + OC_DB::beginTransaction(); $upgrade = new \OC\Files\Cache\Upgrade($legacy); $count = $legacy->getCount(); $eventSource->send('total', $count); $upgrade->upgradePath('/' . $user . '/files'); + OC_DB::commit(); } \OC\Files\Cache\Upgrade::upgradeDone($user); $eventSource->send('done', true); diff --git a/lib/files/cache/legacy.php b/lib/files/cache/legacy.php index ee10a1c135..33d4b8e7c9 100644 --- a/lib/files/cache/legacy.php +++ b/lib/files/cache/legacy.php @@ -14,6 +14,8 @@ namespace OC\Files\Cache; class Legacy { private $user; + private $cacheHasItems = null; + public function __construct($user) { $this->user = $user; } @@ -34,17 +36,23 @@ class Legacy { * @return bool */ function hasItems() { + if (!is_null($this->cacheHasItems)) { + return $this->cacheHasItems; + } try { $query = \OC_DB::prepare('SELECT `id` FROM `*PREFIX*fscache` WHERE `user` = ? LIMIT 1'); } catch (\Exception $e) { + $this->cacheHasItems = false; return false; } try { $result = $query->execute(array($this->user)); } catch (\Exception $e) { + $this->cacheHasItems = false; return false; } - return (bool)$result->fetchRow(); + $this->cacheHasItems = (bool)$result->fetchRow(); + return $this->cacheHasItems; } /** diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index 1032e0a844..cd9a9e91a8 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -43,15 +43,21 @@ class Upgrade { $data = $this->getNewData($row); $this->insert($data); - $children = $this->legacy->getChildren($data['id']); - foreach ($children as $child) { - if ($mode == Scanner::SCAN_SHALLOW) { - $childData = $this->getNewData($child); - \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']); - $this->insert($childData); - } else { - $this->upgradePath($child['path']); - } + $this->upgradeChilds($data['id'], $mode); + } + } + + /** + * @param int $id + */ + function upgradeChilds($id, $mode = Scanner::SCAN_RECURSIVE) { + $children = $this->legacy->getChildren($id); + foreach ($children as $child) { + $childData = $this->getNewData($child); + \OC_Hook::emit('\OC\Files\Cache\Upgrade', 'migrate_path', $child['path']); + $this->insert($childData); + if ($mode == Scanner::SCAN_RECURSIVE) { + $this->upgradeChilds($child['id']); } } } From 29ec00797948d98ffa5dcb0baa1518630ab3ef56 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 19:11:33 +0100 Subject: [PATCH 173/262] Cache: dont migrate permissions, cache them on demain instead --- lib/files/cache/upgrade.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/files/cache/upgrade.php b/lib/files/cache/upgrade.php index cd9a9e91a8..19e3d9ad57 100644 --- a/lib/files/cache/upgrade.php +++ b/lib/files/cache/upgrade.php @@ -14,8 +14,6 @@ class Upgrade { */ private $legacy; - private $permissionsCaches = array(); - private $numericIds = array(); private $mimeTypeIds = array(); @@ -72,9 +70,6 @@ class Upgrade { $insertQuery->execute(array($data['id'], $data['storage'], $data['path'], $data['path_hash'], $data['parent'], $data['name'], $data['mimetype'], $data['mimepart'], $data['size'], $data['mtime'], $data['encrypted'])); - - $permissionsCache = $this->getPermissionsCache($data['storage_object']); - $permissionsCache->set($data['id'], $data['user'], $data['permissions']); } /** @@ -101,18 +96,6 @@ class Upgrade { return $newData; } - /** - * @param \OC\Files\Storage\Storage $storage - * @return Permissions - */ - function getPermissionsCache($storage) { - $storageId = $storage->getId(); - if (!isset($this->permissionsCaches[$storageId])) { - $this->permissionsCaches[$storageId] = $storage->getPermissionsCache(); - } - return $this->permissionsCaches[$storageId]; - } - /** * get the numeric storage id * From f9c42a196f03bb193b07a8f5f8ecf42b911ef4b5 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 21:36:04 +0100 Subject: [PATCH 174/262] Cache: no longer using this file --- lib/files/file.php | 61 ---------------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 lib/files/file.php diff --git a/lib/files/file.php b/lib/files/file.php deleted file mode 100644 index 0d33cea7ee..0000000000 --- a/lib/files/file.php +++ /dev/null @@ -1,61 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Files; - -/** - * representation of the location a file or folder is stored - */ - -class File{ - /** - * @var Storage\Storage $storage - */ - private $storage; - /** - * @var string internalPath - */ - private $internalPath; - - public function __construct(Storage\Storage $storage, $internalPath){ - $this->storage = $storage; - $this->internalPath = $internalPath; - } - - public static function resolve($fullPath){ - $storage = null; - $internalPath = ''; - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); - return new File($storage, $internalPath); - } - - /** - * get the internal path of the file inside the filestorage - * @return string - */ - public function getInternalPath(){ - return $this->internalPath; - } - - /** - * get the storage the file is stored in - * @return \OC\Files\Storage\Storage - */ - public function getStorage(){ - return $this->storage; - } - - /** - * get the id of the storage the file is stored in - * @return string - */ - public function getStorageId(){ - return $this->storage->getId(); - } - -} From bb43cf378b5e7c6a18a30d8fbb226b72f1e4eb88 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 21:36:25 +0100 Subject: [PATCH 175/262] Files: make sure keybinds js is loaded after files js --- apps/files/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/index.php b/apps/files/index.php index 0dce768696..854218eee5 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -30,7 +30,6 @@ OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); OCP\Util::addscript('files', 'filelist'); OCP\Util::addscript('files', 'fileactions'); -OCP\Util::addscript('files', 'keyboardshortcuts'); OCP\App::setActiveNavigationEntry('files_index'); // Load the files @@ -122,6 +121,7 @@ if ($needUpgrade) { $tmpl->printPage(); } else { OCP\Util::addscript('files', 'files'); + OCP\Util::addscript('files', 'keyboardshortcuts'); $tmpl = new OCP\Template('files', 'index', 'user'); $tmpl->assign('fileList', $list->fetchPage(), false); $tmpl->assign('breadcrumb', $breadcrumbNav->fetchPage(), false); From 6871a150bd1309af0ca22e45487043d9640bb356 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 16 Jan 2013 21:58:17 +0100 Subject: [PATCH 176/262] Cache: use a database transition for scanning each folder gives a massive speed improvement while scanning files --- lib/files/cache/scanner.php | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index b62a093cec..bf0ef01d6b 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -83,14 +83,19 @@ class Scanner { * * @param string $path * @param SCAN_RECURSIVE/SCAN_SHALLOW $recursive + * @param bool $onlyChilds * @return int the size of the scanned folder or -1 if the size is unknown at this stage */ - public function scan($path, $recursive = self::SCAN_RECURSIVE) { + public function scan($path, $recursive = self::SCAN_RECURSIVE, $onlyChilds = false) { \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_folder', array('path' => $path, 'storage' => $this->storageId)); - $this->scanFile($path); + $childQueue = array(); + if (!$onlyChilds) { + $this->scanFile($path); + } $size = 0; if ($dh = $this->storage->opendir($path)) { + \OC_DB::beginTransaction(); while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { $child = ($path) ? $path . '/' . $file : $file; @@ -98,10 +103,12 @@ class Scanner { if ($data) { if ($data['mimetype'] === 'httpd/unix-directory') { if ($recursive === self::SCAN_RECURSIVE) { - $data['size'] = $this->scan($child, self::SCAN_RECURSIVE); + $childQueue[] = $child; + $data['size'] = 0; } else { $data['size'] = -1; } + } else { } if ($data['size'] === -1) { $size = -1; @@ -111,6 +118,15 @@ class Scanner { } } } + \OC_DB::commit(); + foreach ($childQueue as $child) { + $childSize = $this->scan($child, self::SCAN_RECURSIVE, true); + if ($childSize === -1) { + $size = -1; + } else { + $size += $childSize; + } + } if ($size !== -1) { $this->cache->put($path, array('size' => $size)); } From 5e16510a5360e256a6dea7389a48d06ec85b5f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 18 Jan 2013 22:06:42 +0100 Subject: [PATCH 177/262] hide upload progress bar and cancel action in IE < 10 --- apps/files/js/files.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 3a4af6416e..5d050cb7e6 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -434,6 +434,10 @@ $(document).ready(function() { $('#uploadprogressbar').progressbar('value',progress); }, start: function(e, data) { + //IE < 10 does not fire the necessary events for the progress bar. + if($.browser.msie && parseInt($.browser.version) < 10) { + return; + } $('#uploadprogressbar').progressbar({value:0}); $('#uploadprogressbar').fadeIn(); if(data.dataType != 'iframe ') { From 5df6f9d14d5a05d91d6706b420c8ad9a387a9f6d Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 18 Jan 2013 23:56:47 -0500 Subject: [PATCH 178/262] Fix merge --- lib/public/share.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/public/share.php b/lib/public/share.php index 9d2a64b459..5f9ad7fc09 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -684,13 +684,13 @@ class Share { } else { if ($fileDependent) { if (($itemType == 'file' || $itemType == 'folder') - && $format == \OC_Share_Backend_File::FORMAT_FILE_APP + && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT ) { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, ' - .'`share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, ' - .'`expiration`, `name`, `ctime`, `mtime`, `mimetype`, `size`, `encrypted`, ' - .'`versioned`, `writable`'; + .'`share_type`, `share_with`, `file_source`, `path`, `file_target`, ' + .'`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' + .'`name` `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`'; } From cd8d8360b0bcc07e22c4c9b86252ef1676b123dc Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Fri, 18 Jan 2013 23:57:13 -0500 Subject: [PATCH 179/262] Disable fancy folder sharing for now --- lib/public/share.php | 56 ++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/public/share.php b/lib/public/share.php index 5f9ad7fc09..f65d272ff1 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -300,36 +300,36 @@ class Share { throw new \Exception($message); } // If the item is a folder, scan through the folder looking for equivalent item types - if ($itemType == 'folder') { - $parentFolder = self::put('folder', $itemSource, $shareType, $shareWith, $uidOwner, $permissions, true); - if ($parentFolder && $files = \OC\Files\Filesystem::getDirectoryContent($itemSource)) { - for ($i = 0; $i < count($files); $i++) { - $name = substr($files[$i]['name'], strpos($files[$i]['name'], $itemSource) - strlen($itemSource)); - if ($files[$i]['mimetype'] == 'httpd/unix-directory' - && $children = \OC\Files\Filesystem::getDirectoryContent($name, '/') - ) { - // Continue scanning into child folders - array_push($files, $children); - } else { - // Check file extension for an equivalent item type to convert to - $extension = strtolower(substr($itemSource, strrpos($itemSource, '.') + 1)); - foreach (self::$backends as $type => $backend) { - if (isset($backend->dependsOn) && $backend->dependsOn == 'file' && isset($backend->supportedFileExtensions) && in_array($extension, $backend->supportedFileExtensions)) { - $itemType = $type; - break; - } - } - // Pass on to put() to check if this item should be converted, the item won't be inserted into the database unless it can be converted - self::put($itemType, $name, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder); - } - } - return true; - } - return false; - } else { +// if ($itemType == 'folder') { +// $parentFolder = self::put('folder', $itemSource, $shareType, $shareWith, $uidOwner, $permissions, true); +// if ($parentFolder && $files = \OC\Files\Filesystem::getDirectoryContent($itemSource)) { +// for ($i = 0; $i < count($files); $i++) { +// $name = substr($files[$i]['name'], strpos($files[$i]['name'], $itemSource) - strlen($itemSource)); +// if ($files[$i]['mimetype'] == 'httpd/unix-directory' +// && $children = \OC\Files\Filesystem::getDirectoryContent($name, '/') +// ) { +// // Continue scanning into child folders +// array_push($files, $children); +// } else { +// // Check file extension for an equivalent item type to convert to +// $extension = strtolower(substr($itemSource, strrpos($itemSource, '.') + 1)); +// foreach (self::$backends as $type => $backend) { +// if (isset($backend->dependsOn) && $backend->dependsOn == 'file' && isset($backend->supportedFileExtensions) && in_array($extension, $backend->supportedFileExtensions)) { +// $itemType = $type; +// break; +// } +// } +// // Pass on to put() to check if this item should be converted, the item won't be inserted into the database unless it can be converted +// self::put($itemType, $name, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder); +// } +// } +// return true; +// } +// return false; +// } else { // Put the item into the database return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions); - } +// } } /** From 8ca30d244c19b33e7e3b0da247b70160a3acc44f Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 19 Jan 2013 00:02:40 -0500 Subject: [PATCH 180/262] Implement getETag() in shared storage --- apps/files_sharing/lib/sharedstorage.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index c8756af8ed..b0be6843c5 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -431,7 +431,14 @@ class Shared extends \OC\Files\Storage\Common { } public function getETag($path) { - + if ($path == '') { + return parent::getETag($path); + } + if ($source = $this->getSourcePath($path)) { + list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); + return $storage->getETag($internalPath); + } + return null; } } From 664f33a29c81701fbf6a7fb18eda81e1c4665ecc Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Sat, 19 Jan 2013 21:04:25 -0500 Subject: [PATCH 181/262] Update mtimes of all parent folders after change inside --- lib/files/cache/updater.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php index 8b0d383503..d04541c219 100644 --- a/lib/files/cache/updater.php +++ b/lib/files/cache/updater.php @@ -35,7 +35,7 @@ class Updater { $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Scanner::SCAN_SHALLOW); $cache->correctFolderSize($internalPath); - self::eTagUpdate($path); + self::correctFolder($path, $storage->filemtime($internalPath)); } } @@ -49,11 +49,17 @@ class Updater { $cache = $storage->getCache($internalPath); $cache->remove($internalPath); $cache->correctFolderSize($internalPath); - self::eTagUpdate($path); + self::correctFolder($path, time()); } } - static public function eTagUpdate($path) { + /** + * Update the mtime and ETag of all parent folders + * + * @param string $path + * @param string $time + */ + static public function correctFolder($path, $time) { if ($path !== '' && $path !== '/') { $parent = dirname($path); if ($parent === '.') { @@ -68,8 +74,8 @@ class Updater { $cache = $storage->getCache(); $id = $cache->getId($internalPath); if ($id !== -1) { - $cache->update($id, array('etag' => $storage->getETag($internalPath))); - self::eTagUpdate($parent); + $cache->update($id, array('mtime' => $time, 'etag' => $storage->getETag($internalPath))); + self::correctFolder($parent, $time); } } } From 42a1a17a30b8299a7dc4ea71aed57e607bdc2838 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Jan 2013 22:01:22 +0100 Subject: [PATCH 182/262] Cache: return non numberic storage id --- lib/files/cache/cache.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php index 5c306c2ed1..7f6d191fee 100644 --- a/lib/files/cache/cache.php +++ b/lib/files/cache/cache.php @@ -130,6 +130,7 @@ class Cache { $data['size'] = (int)$data['size']; $data['mtime'] = (int)$data['mtime']; $data['encrypted'] = (bool)$data['encrypted']; + $data['storage'] = $this->storageId; $data['mimetype'] = $this->getMimetype($data['mimetype']); $data['mimepart'] = $this->getMimetype($data['mimepart']); } From 1762378f67085cc9e8fecb287d73f1f1570cb3cc Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Jan 2013 22:07:55 +0100 Subject: [PATCH 183/262] Files: don't load fileactions.js when upgrading filecache --- apps/files/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/index.php b/apps/files/index.php index c10ae76e9e..b1cd40f254 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -30,7 +30,6 @@ OCP\Util::addscript('files', 'jquery.iframe-transport'); OCP\Util::addscript('files', 'jquery.fileupload'); OCP\Util::addscript('files', 'jquery-visibility'); OCP\Util::addscript('files', 'filelist'); -OCP\Util::addscript('files', 'fileactions'); OCP\App::setActiveNavigationEntry('files_index'); // Load the files @@ -116,6 +115,7 @@ if ($needUpgrade) { $tmpl = new OCP\Template('files', 'upgrade', 'user'); $tmpl->printPage(); } else { + OCP\Util::addscript('files', 'fileactions'); OCP\Util::addscript('files', 'files'); OCP\Util::addscript('files', 'keyboardshortcuts'); $tmpl = new OCP\Template('files', 'index', 'user'); From 8ede3290ae2da4b04f451ff3d502f0ac60ac6585 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 21 Jan 2013 22:31:44 +0100 Subject: [PATCH 184/262] Cache: add database indexes for mimetype and mimepart --- db_structure.xml | 24 ++++++++++++++++++++++++ lib/util.php | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/db_structure.xml b/db_structure.xml index f1f0257281..479ee3259f 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -258,6 +258,30 @@ + + fs_storage_mimetype + + storage + ascending + + + mimetype + ascending + + + + + fs_storage_mimepart + + storage + ascending + + + mimepart + ascending + + +
diff --git a/lib/util.php b/lib/util.php index 59566c9f4f..f947ed9c17 100755 --- a/lib/util.php +++ b/lib/util.php @@ -74,7 +74,7 @@ class OC_Util { */ public static function getVersion() { // hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user - return array(4,91,07); + return array(4,91,8); } /** From e666ce3622bed37ba6d9327aeecdf4a96dc7f5f4 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 21 Jan 2013 23:57:26 -0500 Subject: [PATCH 185/262] Fix external storage UI for new storage namespaces --- apps/files_external/js/dropbox.js | 4 ++-- apps/files_external/js/google.js | 7 ++++--- apps/files_external/js/settings.js | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/files_external/js/dropbox.js b/apps/files_external/js/dropbox.js index c1e3864070..a9a3155e67 100644 --- a/apps/files_external/js/dropbox.js +++ b/apps/files_external/js/dropbox.js @@ -1,6 +1,6 @@ $(document).ready(function() { - $('#externalStorage tbody tr.OC_Filestorage_Dropbox').each(function() { + $('#externalStorage tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Dropbox').each(function() { var configured = $(this).find('[data-parameter="configured"]'); if ($(configured).val() == 'true') { $(this).find('.configuration input').attr('disabled', 'disabled'); @@ -38,7 +38,7 @@ $(document).ready(function() { $('#externalStorage tbody tr input').live('keyup', function() { var tr = $(this).parent().parent(); - if ($(tr).hasClass('OC_Filestorage_Dropbox') && $(tr).find('[data-parameter="configured"]').val() != 'true') { + if ($(tr).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Dropbox') && $(tr).find('[data-parameter="configured"]').val() != 'true') { var config = $(tr).find('.configuration'); if ($(tr).find('.mountPoint input').val() != '' && $(config).find('[data-parameter="app_key"]').val() != '' && $(config).find('[data-parameter="app_secret"]').val() != '') { if ($(tr).find('.dropbox').length == 0) { diff --git a/apps/files_external/js/google.js b/apps/files_external/js/google.js index 0b3c314eb5..7d759d13da 100644 --- a/apps/files_external/js/google.js +++ b/apps/files_external/js/google.js @@ -1,6 +1,6 @@ $(document).ready(function() { - $('#externalStorage tbody tr.OC_Filestorage_Google').each(function() { + $('#externalStorage tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google').each(function() { var configured = $(this).find('[data-parameter="configured"]'); if ($(configured).val() == 'true') { $(this).find('.configuration') @@ -34,7 +34,8 @@ $(document).ready(function() { }); $('#externalStorage tbody tr').live('change', function() { - if ($(this).hasClass('OC_Filestorage_Google') && $(this).find('[data-parameter="configured"]').val() != 'true') { + console.log('hello'); + if ($(this).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Google') && $(this).find('[data-parameter="configured"]').val() != 'true') { if ($(this).find('.mountPoint input').val() != '') { if ($(this).find('.google').length == 0) { $(this).find('.configuration').append('
'+t('files_external', 'Grant access')+''); @@ -45,7 +46,7 @@ $(document).ready(function() { $('#externalStorage tbody tr .mountPoint input').live('keyup', function() { var tr = $(this).parent().parent(); - if ($(tr).hasClass('OC_Filestorage_Google') && $(tr).find('[data-parameter="configured"]').val() != 'true' && $(tr).find('.google').length > 0) { + if ($(tr).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Google') && $(tr).find('[data-parameter="configured"]').val() != 'true' && $(tr).find('.google').length > 0) { if ($(this).val() != '') { $(tr).find('.google').show(); } else { diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 0dc983ca8a..6cbc218008 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -100,7 +100,7 @@ $(document).ready(function() { td.append(''); } }); - if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass).length == 1) { + if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length == 1) { OC.addScript('files_external', parameters['custom']); } return false; From 465c100d8f5932340ea80f8a426ca7f404fc97c6 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Tue, 22 Jan 2013 00:43:43 -0500 Subject: [PATCH 186/262] Add tests for mtime changes in folders - testRename is failing right now --- tests/lib/files/cache/updater.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index cad3d9d46f..8bf395698a 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -78,9 +78,11 @@ class Updater extends \PHPUnit_Framework_TestCase { $cachedData = $this->cache->get('foo.txt'); $this->assertEquals(3, $cachedData['size']); $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 3, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $rootCachedData['mtime']); $rootCachedData = $cachedData; $this->assertFalse($this->cache->inCache('bar.txt')); @@ -88,9 +90,11 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->cache->inCache('bar.txt')); $cachedData = $this->cache->get('bar.txt'); $this->assertEquals(3, $cachedData['size']); + $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize + 2 * 3, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $rootCachedData['mtime']); } public function testDelete() { @@ -105,6 +109,7 @@ class Updater extends \PHPUnit_Framework_TestCase { $cachedData = $this->cache->get(''); $this->assertEquals(2 * $textSize + $imageSize, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); $rootCachedData = $cachedData; Filesystem::mkdir('bar_folder'); @@ -116,6 +121,7 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertFalse($this->cache->inCache('bar_folder')); $cachedData = $this->cache->get(''); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertGreaterThanOrEqual($rootCachedData['mtime'], $cachedData['mtime']); } public function testRename() { @@ -132,8 +138,10 @@ class Updater extends \PHPUnit_Framework_TestCase { $this->assertTrue($this->cache->inCache('bar.txt')); $cachedData = $this->cache->get('foo.txt'); $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); + $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); $this->assertEquals(3 * $textSize + $imageSize, $cachedData['size']); $this->assertNotEquals($rootCachedData['etag'], $cachedData['etag']); + $this->assertEquals($mtime, $cachedData['mtime']); } } From db2b485b9681b93200bcca6b5780b78008f9c1de Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 22 Jan 2013 16:36:03 +0100 Subject: [PATCH 187/262] Cache: fix test case Updater::testRename --- tests/lib/files/cache/updater.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/files/cache/updater.php b/tests/lib/files/cache/updater.php index 8bf395698a..b4f373cdc2 100644 --- a/tests/lib/files/cache/updater.php +++ b/tests/lib/files/cache/updater.php @@ -136,7 +136,7 @@ class Updater extends \PHPUnit_Framework_TestCase { Filesystem::rename('foo.txt', 'bar.txt'); $this->assertFalse($this->cache->inCache('foo.txt')); $this->assertTrue($this->cache->inCache('bar.txt')); - $cachedData = $this->cache->get('foo.txt'); + $cachedData = $this->cache->get('bar.txt'); $this->assertNotEquals($fooCachedData['etag'], $cachedData['etag']); $mtime = $cachedData['mtime']; $cachedData = $this->cache->get(''); From 7330fcf5e81e7d91ed37f01da7cc45833e10f1c4 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 22 Jan 2013 20:57:15 +0100 Subject: [PATCH 188/262] Cache: make mounts overwrite existing folders, prevents duplicate entries --- lib/files/view.php | 8 ++++++++ tests/lib/files/view.php | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/files/view.php b/lib/files/view.php index 0602791012..c50897603e 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -794,6 +794,14 @@ class View { $subPermissionsCache->set($rootEntry['fileid'], $user, $permissions); } $rootEntry['permissions'] = $permissions; + + //remove any existing entry with the same name + foreach ($files as $i => $file) { + if ($file['name'] === $rootEntry['name']) { + unset($files[$i]); + break; + } + } $files[] = $rootEntry; } } diff --git a/tests/lib/files/view.php b/tests/lib/files/view.php index 5327114267..586ad17842 100644 --- a/tests/lib/files/view.php +++ b/tests/lib/files/view.php @@ -98,6 +98,18 @@ class View extends \PHPUnit_Framework_TestCase { $this->assertEquals(array(), $rootView->getDirectoryContent('/non/existing')); } + function testMountPointOverwrite() { + $storage1 = $this->getTestStorage(false); + $storage2 = $this->getTestStorage(); + $storage1->mkdir('substorage'); + \OC\Files\Filesystem::mount($storage1, array(), '/'); + \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); + + $rootView = new \OC\Files\View(''); + $folderContent = $rootView->getDirectoryContent('/'); + $this->assertEquals(4, count($folderContent)); + } + function testCacheIncompleteFolder() { $storage1 = $this->getTestStorage(false); \OC\Files\Filesystem::mount($storage1, array(), '/'); From 9a1f65aab176604c90114891b4bc0346fbb7d561 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 22 Jan 2013 20:58:09 +0100 Subject: [PATCH 189/262] Some style fixes --- lib/files/filesystem.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php index 28e8b04689..9a3d13e343 100644 --- a/lib/files/filesystem.php +++ b/lib/files/filesystem.php @@ -231,16 +231,16 @@ class Filesystem { } /** - * Initialize system and personal mount points for a user - * - * @param string $user - */ + * Initialize system and personal mount points for a user + * + * @param string $user + */ public static function initMountPoints($user = '') { if ($user == '') { $user = \OC_User::getUser(); } // Load system mount points - if (is_file(\OC::$SERVERROOT.'/config/mount.php')) { + if (is_file(\OC::$SERVERROOT . '/config/mount.php')) { $mountConfig = include 'config/mount.php'; if (isset($mountConfig['global'])) { foreach ($mountConfig['global'] as $mountPoint => $options) { @@ -277,8 +277,8 @@ class Filesystem { // Load personal mount points $root = \OC_User::getHome($user); self::mount('\OC\Files\Storage\Local', array('datadir' => $root), $user); - if (is_file($root.'/mount.php')) { - $mountConfig = include $root.'/mount.php'; + if (is_file($root . '/mount.php')) { + $mountConfig = include $root . '/mount.php'; if (isset($mountConfig['user'][$user])) { foreach ($mountConfig['user'][$user] as $mountPoint => $options) { self::mount($options['class'], $options['options'], $mountPoint); @@ -370,7 +370,7 @@ class Filesystem { } else { // Update old classes to new namespace if (strpos($class, 'OC_Filestorage_') !== false) { - $class = '\OC\Files\Storage\\'.substr($class, 15); + $class = '\OC\Files\Storage\\' . substr($class, 15); } self::$mounts[$mountpoint] = array('class' => $class, 'arguments' => $arguments); } @@ -663,7 +663,7 @@ class Filesystem { * @param string $path * @return string */ - static public function getETag($path){ + static public function getETag($path) { return self::$defaultInstance->getETag($path); } } From d16574f0702d7bafa35b27ed8961580ad0a671ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Thu, 24 Jan 2013 13:07:59 +0100 Subject: [PATCH 190/262] new branch which introduces display names first commit with some infrastructure code --- lib/public/user.php | 10 +++++++++- lib/user.php | 41 ++++++++++++++++++++++++++++++++++++++++- lib/user/backend.php | 11 +++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/public/user.php b/lib/public/user.php index 204d8e4c0f..2d22bdd96c 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -51,7 +51,15 @@ class User { public static function getUsers($search = '', $limit = null, $offset = null) { return \OC_USER::getUsers(); } - + + /** + * @brief get the user display name of the user currently logged in. + * @return string display name + */ + public static function getDisplayName() { + return \OC_USER::getDisplayName(); + } + /** * @brief Check if the user is logged in * @returns true/false diff --git a/lib/user.php b/lib/user.php index fd0ed6ecd3..d6d47293cb 100644 --- a/lib/user.php +++ b/lib/user.php @@ -251,6 +251,7 @@ class OC_User { if($uid && $enabled) { session_regenerate_id(true); self::setUserId($uid); + self::setDisplayName($uid); OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>$password )); return true; } @@ -264,6 +265,31 @@ class OC_User { public static function setUserId($uid) { $_SESSION['user_id'] = $uid; } + + /** + * @brief Sets user display name for session + */ + private static function setDisplayName($uid) { + $_SESSION['display_name'] = self::determineDisplayName($uid); + } + + /** + * @brief get display name + * @param $uid The username + * @returns string display name or uid if no display name is defined + * + */ + private static function determineDisplayName( $uid ) { + foreach(self::$_usedBackends as $backend) { + if($backend->implementsActions(OC_USER_BACKEND_GET_DISPLAYNAME)) { + $result=$backend->getDisplayName( $uid ); + if($result) { + return $result; + } + } + } + return $uid; + } /** * @brief Logs the current user out and kills all the session data @@ -319,7 +345,20 @@ class OC_User { return false; } } - + + /** + * @brief get the display name of the user currently logged in. + * @return string uid or false + */ + public static function getDisplayName() { + if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ) { + return $_SESSION['display_name']; + } + else{ + return false; + } + } + /** * @brief Autogenerate a password * @returns string diff --git a/lib/user/backend.php b/lib/user/backend.php index 2a95db9369..47c92f5fe7 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -35,6 +35,7 @@ define('OC_USER_BACKEND_CREATE_USER', 0x000001); define('OC_USER_BACKEND_SET_PASSWORD', 0x000010); define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100); define('OC_USER_BACKEND_GET_HOME', 0x001000); +define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x010000); /** @@ -50,6 +51,7 @@ abstract class OC_User_Backend implements OC_User_Interface { OC_USER_BACKEND_SET_PASSWORD => 'setPassword', OC_USER_BACKEND_CHECK_PASSWORD => 'checkPassword', OC_USER_BACKEND_GET_HOME => 'getHome', + OC_USER_BACKEND_GET_DISPLAYNAME => 'getDisplayName', ); /** @@ -120,4 +122,13 @@ abstract class OC_User_Backend implements OC_User_Interface { public function getHome($uid) { return false; } + + /** + * @brief get display name of the user + * @param $uid user ID of the user + * @return display name + */ + public function getDisplayName($uid) { + return $uid; + } } From 2fee1208eff1911ffcdbba24ea1e8543ed6ec26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Thu, 24 Jan 2013 15:49:23 +0100 Subject: [PATCH 191/262] add display name to title instead if login-ID --- core/templates/layout.user.php | 2 +- lib/user.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php index a16d2c9e55..fb63200123 100644 --- a/core/templates/layout.user.php +++ b/core/templates/layout.user.php @@ -1,7 +1,7 @@ - <?php echo isset($_['application']) && !empty($_['application'])?$_['application'].' | ':'' ?>ownCloud <?php echo OC_User::getUser()?' ('.OC_User::getUser().') ':'' ?> + <?php echo isset($_['application']) && !empty($_['application'])?$_['application'].' | ':'' ?>ownCloud <?php echo OC_User::getDisplayName()?' ('.OC_User::getDisplayName().') ':'' ?> diff --git a/lib/user.php b/lib/user.php index d6d47293cb..f9c8f48568 100644 --- a/lib/user.php +++ b/lib/user.php @@ -351,7 +351,7 @@ class OC_User { * @return string uid or false */ public static function getDisplayName() { - if( isset($_SESSION['user_id']) AND $_SESSION['user_id'] ) { + if( isset($_SESSION['display_name']) AND $_SESSION['display_name'] ) { return $_SESSION['display_name']; } else{ From 9bb8e0583995fff244432bc34820127ef8ff6ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 11:05:00 +0100 Subject: [PATCH 192/262] get all display names --- lib/public/user.php | 10 ++++++++++ lib/user.php | 18 ++++++++++++++++++ lib/user/backend.php | 15 +++++++++++++++ settings/users.php | 15 ++++++++++----- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/lib/public/user.php b/lib/public/user.php index 2d22bdd96c..3a2f4d02f5 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -60,6 +60,16 @@ class User { return \OC_USER::getDisplayName(); } + /** + * @brief Get a list of all display names + * @returns array with all display names and the correspondig uids + * + * Get a list of all display names. + */ + public static function getDisplayNames($search = '', $limit = null, $offset = null) { + return \OC_USER::getDisplayNames($search, $limit, $offset); + } + /** * @brief Check if the user is logged in * @returns true/false diff --git a/lib/user.php b/lib/user.php index f9c8f48568..f84b4c01df 100644 --- a/lib/user.php +++ b/lib/user.php @@ -457,6 +457,24 @@ class OC_User { asort($users); return $users; } + + /** + * @brief Get a list of all users display name + * @returns associative array with all display names and corresponding uids + * + * Get a list of all users. + */ + public static function getDisplayNames($search = '', $limit = null, $offset = null) { + $displayNames = array(); + foreach (self::$_usedBackends as $backend) { + $backendDisplayNames = $backend->getDisplayNames($search, $limit, $offset); + if (is_array($backendDisplayNames)) { + $displayNames = array_merge($displayNames, $backendDisplayNames); + } + } + ksort($displayNames); + return $displayNames; + } /** * @brief check if a user exists diff --git a/lib/user/backend.php b/lib/user/backend.php index 47c92f5fe7..5823e39040 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -131,4 +131,19 @@ abstract class OC_User_Backend implements OC_User_Interface { public function getDisplayName($uid) { return $uid; } + + /** + * @brief Get a list of all display names + * @returns array with all displayNames and the correspondig uids + * + * Get a list of all display names. + */ + public function getDisplayNames($search = '', $limit = null, $offset = null) { + $displayNames = array(); + $users = $this->getUsers($search, $limit, $offset); + foreach ( $users as $user) { + $displayNames[$user] = $user; + } + return $displayNames; + } } diff --git a/settings/users.php b/settings/users.php index 668d974693..3706dc918c 100644 --- a/settings/users.php +++ b/settings/users.php @@ -22,7 +22,7 @@ $isadmin = OC_User::isAdminUser(OC_User::getUser()); if($isadmin) { $accessiblegroups = OC_Group::getGroups(); - $accessibleusers = OC_User::getUsers('', 30); + $accessibleusers = OC_User::getDisplayNames('', 30); $subadmins = OC_SubAdmin::getAllSubAdmins(); }else{ $accessiblegroups = OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()); @@ -42,16 +42,21 @@ $defaultQuota=OC_Appconfig::getValue('files', 'default_quota', 'none'); $defaultQuotaIsUserDefined=array_search($defaultQuota, $quotaPreset)===false && array_search($defaultQuota, array('none', 'default'))===false; // load users and quota -foreach($accessibleusers as $i) { +foreach($accessibleusers as $displayName => $uid) { $quota=OC_Preferences::getValue($i, 'files', 'quota', 'default'); $isQuotaUserDefined=array_search($quota, $quotaPreset)===false && array_search($quota, array('none', 'default'))===false; + $name = $displayName; + if ( $displayName != $uid ) { + $name = $name . ' ('.$uid.')'; + } + $users[] = array( - "name" => $i, - "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($i)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/), + "name" => $name, + "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($uid)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/), 'quota'=>$quota, 'isQuotaUserDefined'=>$isQuotaUserDefined, - 'subadmin'=>implode(', ', OC_SubAdmin::getSubAdminsGroups($i))); + 'subadmin'=>implode(', ', OC_SubAdmin::getSubAdminsGroups($iuid))); } foreach( $accessiblegroups as $i ) { From 4271430e609be252d9b4a69fd7b3590571c14f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 11:48:03 +0100 Subject: [PATCH 193/262] get all display names from users in a given group --- lib/group.php | 29 +++++++++++++++++++++++++++++ lib/group/backend.php | 18 ++++++++++++++++++ lib/public/user.php | 4 ++-- lib/user.php | 4 ++-- lib/user/backend.php | 4 ++-- settings/users.php | 2 +- 6 files changed, 54 insertions(+), 7 deletions(-) diff --git a/lib/group.php b/lib/group.php index ed9482418b..8ebb698692 100644 --- a/lib/group.php +++ b/lib/group.php @@ -286,4 +286,33 @@ class OC_Group { } return $users; } + + /** + * @brief get a list of all display names in a group + * @returns array with display names (key) and user ids(value) + */ + public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + $displayNames=array(); + foreach(self::$_usedBackends as $backend) { + $displayNames = array_merge($backend->displayNamesInGroup($gid, $search, $limit, $offset), $displayNames); + } + return $displayNames; + } + + /** + * @brief get a list of all display names in several groups + * @param array $gids + * @param string $search + * @param int $limit + * @param int $offset + * @return array with display names (Key) user ids (value) + */ + public static function displayNamesInGroups($gids, $search = '', $limit = -1, $offset = 0) { + $displayNames = array(); + foreach ($gids as $gid) { + // TODO Need to apply limits to groups as total + $displayNames = array_merge(array_diff(self::displayNamesInGroup($gid, $search, $limit, $offset), $displayNames), $displayNames); + } + return $displayNames; + } } diff --git a/lib/group/backend.php b/lib/group/backend.php index 9ff432d066..ceb2d9242d 100644 --- a/lib/group/backend.php +++ b/lib/group/backend.php @@ -133,5 +133,23 @@ abstract class OC_Group_Backend implements OC_Group_Interface { public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) { return array(); } + + /** + * @brief get a list of all display names in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return array with display names (key) and user ids (value) + */ + public function DisplayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + $displayNames = ''; + $users = $this->usersInGroup($gid, $search, $limit, $offset); + foreach ( $users as $user ) { + $DisplayNames[$user] = $user; + } + + return $DisplayNames; + } } diff --git a/lib/public/user.php b/lib/public/user.php index 3a2f4d02f5..a93e3a674a 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -62,9 +62,9 @@ class User { /** * @brief Get a list of all display names - * @returns array with all display names and the correspondig uids + * @returns array with all display names (key) and the correspondig uids (value) * - * Get a list of all display names. + * Get a list of all display names and user ids. */ public static function getDisplayNames($search = '', $limit = null, $offset = null) { return \OC_USER::getDisplayNames($search, $limit, $offset); diff --git a/lib/user.php b/lib/user.php index f84b4c01df..4cdf07dc3f 100644 --- a/lib/user.php +++ b/lib/user.php @@ -460,9 +460,9 @@ class OC_User { /** * @brief Get a list of all users display name - * @returns associative array with all display names and corresponding uids + * @returns associative array with all display names (key) and corresponding uids (value) * - * Get a list of all users. + * Get a list of all display names and user ids. */ public static function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = array(); diff --git a/lib/user/backend.php b/lib/user/backend.php index 5823e39040..ec43d7f187 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -134,9 +134,9 @@ abstract class OC_User_Backend implements OC_User_Interface { /** * @brief Get a list of all display names - * @returns array with all displayNames and the correspondig uids + * @returns array with all displayNames (key) and the correspondig uids (value) * - * Get a list of all display names. + * Get a list of all display names and user ids. */ public function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = array(); diff --git a/settings/users.php b/settings/users.php index 3706dc918c..bf27e80441 100644 --- a/settings/users.php +++ b/settings/users.php @@ -26,7 +26,7 @@ if($isadmin) { $subadmins = OC_SubAdmin::getAllSubAdmins(); }else{ $accessiblegroups = OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()); - $accessibleusers = OC_Group::usersInGroups($accessiblegroups, '', 30); + $accessibleusers = OC_Group::displayNamesInGroups($accessiblegroups, '', 30); $subadmins = false; } From 64e853394c120888a7555901a52c5868f33aef3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 12:46:32 +0100 Subject: [PATCH 194/262] compare the correct uids --- settings/templates/users.php | 2 +- settings/users.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/settings/templates/users.php b/settings/templates/users.php index 6cbbca2404..44e9b5bafe 100644 --- a/settings/templates/users.php +++ b/settings/templates/users.php @@ -157,7 +157,7 @@ var isadmin = ; - + diff --git a/settings/users.php b/settings/users.php index bf27e80441..c8f5ef5ff3 100644 --- a/settings/users.php +++ b/settings/users.php @@ -53,6 +53,7 @@ foreach($accessibleusers as $displayName => $uid) { $users[] = array( "name" => $name, + "uid" => $uid, "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($uid)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/), 'quota'=>$quota, 'isQuotaUserDefined'=>$isQuotaUserDefined, From b4291f1e8e2326f5f1cbd97fa130d547f949b62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 13:00:17 +0100 Subject: [PATCH 195/262] allow to get the display name from an abitrary user --- lib/public/user.php | 4 ++-- lib/user.php | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/public/user.php b/lib/public/user.php index a93e3a674a..411098ed5a 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -56,8 +56,8 @@ class User { * @brief get the user display name of the user currently logged in. * @return string display name */ - public static function getDisplayName() { - return \OC_USER::getDisplayName(); + public static function getDisplayName($user=null) { + return \OC_USER::getDisplayName($user); } /** diff --git a/lib/user.php b/lib/user.php index 4cdf07dc3f..65f899aa27 100644 --- a/lib/user.php +++ b/lib/user.php @@ -350,8 +350,10 @@ class OC_User { * @brief get the display name of the user currently logged in. * @return string uid or false */ - public static function getDisplayName() { - if( isset($_SESSION['display_name']) AND $_SESSION['display_name'] ) { + public static function getDisplayName($user=null) { + if ( $user ) { + return self::determineDisplayName($user); + } else if( isset($_SESSION['display_name']) AND $_SESSION['display_name'] ) { return $_SESSION['display_name']; } else{ From 839f4bd94916d0673341528ffa8a2a7b3242bf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 13:01:53 +0100 Subject: [PATCH 196/262] show display name instead of uid in the public shared files view --- apps/files_sharing/public.php | 1 + apps/files_sharing/templates/public.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php index efd977a1b6..93f3b4da2b 100644 --- a/apps/files_sharing/public.php +++ b/apps/files_sharing/public.php @@ -207,6 +207,7 @@ if ($linkItem) { OCP\Util::addScript('files', 'fileactions'); $tmpl = new OCP\Template('files_sharing', 'public', 'base'); $tmpl->assign('uidOwner', $shareOwner); + $tmpl->assign('displayName', \OCP\User::getDisplayName($shareOwner)); $tmpl->assign('dir', $dir); $tmpl->assign('filename', $file); $tmpl->assign('mimetype', OC_Filesystem::getMimeType($path)); diff --git a/apps/files_sharing/templates/public.php b/apps/files_sharing/templates/public.php index 647e1e08a3..13af528ce8 100644 --- a/apps/files_sharing/templates/public.php +++ b/apps/files_sharing/templates/public.php @@ -14,9 +14,9 @@ ownCloud
- t('%s shared the folder %s with you', array($_['uidOwner'], $_['filename'])) ?> + t('%s shared the folder %s with you', array($_['displayName'], $_['filename'])) ?> - t('%s shared the file %s with you', array($_['uidOwner'], $_['filename'])) ?> + t('%s shared the file %s with you', array($_['displayName'], $_['filename'])) ?> Download" />t('Download')?> From e9a57e28fc9b87c0fd84de39a0e4cb305165a9d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 13:57:08 +0100 Subject: [PATCH 197/262] show display name instead of uid --- core/ajax/share.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/core/ajax/share.php b/core/ajax/share.php index 077baa8ba5..231cdc5e24 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -72,6 +72,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo case 'email': // read post variables $user = OCP\USER::getUser(); + $displayName = OCP\User::getDisplayName(); $type = $_POST['itemType']; $link = $_POST['link']; $file = $_POST['file']; @@ -81,13 +82,13 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo $l = OC_L10N::get('core'); // setup the email - $subject = (string)$l->t('User %s shared a file with you', $user); + $subject = (string)$l->t('User %s shared a file with you', $displayName); if ($type === 'dir') - $subject = (string)$l->t('User %s shared a folder with you', $user); + $subject = (string)$l->t('User %s shared a folder with you', $displayName); - $text = (string)$l->t('User %s shared the file "%s" with you. It is available for download here: %s', array($user, $file, $link)); + $text = (string)$l->t('User %s shared the file "%s" with you. It is available for download here: %s', array($displayName, $file, $link)); if ($type === 'dir') - $text = (string)$l->t('User %s shared the folder "%s" with you. It is available for download here: %s', array($user, $file, $link)); + $text = (string)$l->t('User %s shared the folder "%s" with you. It is available for download here: %s', array($displayName, $file, $link)); $default_from = OCP\Util::getDefaultEmailAddress('sharing-noreply'); @@ -158,14 +159,14 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo while ($count < 4 && count($users) == $limit) { $limit = 4 - $count; if ($sharePolicy == 'groups_only') { - $users = OC_Group::usersInGroups($groups, $_GET['search'], $limit, $offset); + $users = OC_Group::DisplayNamesInGroups($groups, $_GET['search'], $limit, $offset); } else { - $users = OC_User::getUsers($_GET['search'], $limit, $offset); + $users = OC_User::getDisplayNames($_GET['search'], $limit, $offset); } $offset += $limit; - foreach ($users as $user) { - if ((!isset($_GET['itemShares']) || !is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]) || !in_array($user, $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])) && $user != OC_User::getUser()) { - $shareWith[] = array('label' => $user, 'value' => array('shareType' => OCP\Share::SHARE_TYPE_USER, 'shareWith' => $user)); + foreach ($users as $displayName => $uid) { + if ((!isset($_GET['itemShares']) || !is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]) || !in_array($uid, $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])) && $uid != OC_User::getUser()) { + $shareWith[] = array('label' => $displayName, 'value' => array('shareType' => OCP\Share::SHARE_TYPE_USER, 'shareWith' => $uid)); $count++; } } From 9f5847b739c20a0b2de3672459445f08300ef790 Mon Sep 17 00:00:00 2001 From: TheSFReader Date: Fri, 25 Jan 2013 17:02:44 +0100 Subject: [PATCH 198/262] Simplify the code and remove a first unnecessary (and non conform) '&' character when there are pending arguments --- lib/helper.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/helper.php b/lib/helper.php index 5d7e3fa489..540a7dceb3 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -78,11 +78,8 @@ class OC_Helper { } } - if (!empty($args)) { - $urlLinkTo .= '?'; - foreach($args as $k => $v) { - $urlLinkTo .= '&'.$k.'='.urlencode($v); - } + if ($args && $query = http_build_query($args, '', '&')) { + $urlLinkTo .= '?'.$query; } return $urlLinkTo; From a606e8d944f7c2754f00e9c50804b8c2beedc986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Fri, 25 Jan 2013 17:40:23 +0100 Subject: [PATCH 199/262] use display name to show share_width and owner information --- core/js/share.js | 18 +++++++++--------- lib/public/share.php | 9 +++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/core/js/share.js b/core/js/share.js index bb3ec010ff..1486d7f177 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -148,9 +148,9 @@ OC.Share={ var html = ' - + diff --git a/settings/users.php b/settings/users.php index d779cc782c..df7cf8ac1d 100644 --- a/settings/users.php +++ b/settings/users.php @@ -42,7 +42,7 @@ $defaultQuota=OC_Appconfig::getValue('files', 'default_quota', 'none'); $defaultQuotaIsUserDefined=array_search($defaultQuota, $quotaPreset)===false && array_search($defaultQuota, array('none', 'default'))===false; // load users and quota -foreach($accessibleusers as $displayName => $uid) { +foreach($accessibleusers as $uid => $displayName) { $quota=OC_Preferences::getValue($i, 'files', 'quota', 'default'); $isQuotaUserDefined=array_search($quota, $quotaPreset)===false && array_search($quota, array('none', 'default'))===false; @@ -52,8 +52,8 @@ foreach($accessibleusers as $displayName => $uid) { } $users[] = array( - "name" => $name, - "uid" => $uid, + "name" => $uid, + "displayName" => $displayName, "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($uid)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/), 'quota'=>$quota, 'isQuotaUserDefined'=>$isQuotaUserDefined, From e0f2ed2757b698448d49fa3e73340ce9ced25e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 28 Jan 2013 14:09:11 +0100 Subject: [PATCH 217/262] interface and API to change display names --- lib/user.php | 19 ++++++++++++++++-- lib/user/backend.php | 2 ++ settings/js/users.js | 37 ++++++++++++++++++++++++++++++++++++ settings/routes.php | 2 ++ settings/templates/users.php | 2 +- 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/lib/user.php b/lib/user.php index 65f899aa27..b91abd71fe 100644 --- a/lib/user.php +++ b/lib/user.php @@ -269,10 +269,25 @@ class OC_User { /** * @brief Sets user display name for session */ - private static function setDisplayName($uid) { - $_SESSION['display_name'] = self::determineDisplayName($uid); + public static function setDisplayName($uid, $displayName = null) { + $result = false; + if ($displayName ) { + foreach(self::$_usedBackends as $backend) { + if($backend->implementsActions(OC_USER_BACKEND_SET_DISPLAYNAME)) { + if($backend->userExists($uid)) { + $success |= $backend->setDisplayName($uid, $displayName); + } + } + } + } else { + $displayName = self::determineDisplayName($uid); + $result = true; + } + $_SESSION['display_name'] = $displayName; + return result; } + /** * @brief get display name * @param $uid The username diff --git a/lib/user/backend.php b/lib/user/backend.php index fe37a64cc0..efea622e31 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -36,6 +36,7 @@ define('OC_USER_BACKEND_SET_PASSWORD', 0x000010); define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100); define('OC_USER_BACKEND_GET_HOME', 0x001000); define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x010000); +define('OC_USER_BACKEND_SET_DISPLAYNAME', 0x010000); /** @@ -52,6 +53,7 @@ abstract class OC_User_Backend implements OC_User_Interface { OC_USER_BACKEND_CHECK_PASSWORD => 'checkPassword', OC_USER_BACKEND_GET_HOME => 'getHome', OC_USER_BACKEND_GET_DISPLAYNAME => 'getDisplayName', + OC_USER_BACKEND_SET_DISPLAYNAME => 'setDisplayName', ); /** diff --git a/settings/js/users.js b/settings/js/users.js index fa6f058d92..835f46f6ed 100644 --- a/settings/js/users.js +++ b/settings/js/users.js @@ -300,6 +300,43 @@ $(document).ready(function () { $('td.password').live('click', function (event) { $(this).children('img').click(); }); + + $('td.displayName>img').live('click', function (event) { + event.stopPropagation(); + var img = $(this); + var uid = img.parent().parent().attr('data-uid'); + var input = $(''); + img.css('display', 'none'); + img.parent().children('span').replaceWith(input); + input.focus(); + input.keypress(function (event) { + console.log("event!"); + if (event.keyCode == 13) { + console.log("13"); + if ($(this).val().length > 0) { + console.log("post"); + $.post( + OC.filePath('settings', 'ajax', 'changedisplayname.php'), + {username:uid, displayName:$(this).val()}, + function (result) { + console.log("come back!"); + } + ); + input.blur(); + } else { + input.blur(); + } + } + }); + input.blur(function () { + $(this).replaceWith($(this).val()); + img.css('display', ''); + }); + }); + $('td.displayName').live('click', function (event) { + $(this).children('img').click(); + }); + $('select.quota, select.quota-user').live('change', function () { var select = $(this); diff --git a/settings/routes.php b/settings/routes.php index 9b5bf80923..c9156f9a11 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -39,6 +39,8 @@ $this->create('settings_ajax_removegroup', '/settings/ajax/removegroup.php') ->actionInclude('settings/ajax/removegroup.php'); $this->create('settings_ajax_changepassword', '/settings/ajax/changepassword.php') ->actionInclude('settings/ajax/changepassword.php'); +$this->create('settings_ajax_changedisplayname', '/settings/ajax/changedisplayname.php') +->actionInclude('settings/ajax/changedisplayname.php'); // personel $this->create('settings_ajax_lostpassword', '/settings/ajax/lostpassword.php') ->actionInclude('settings/ajax/lostpassword.php'); diff --git a/settings/templates/users.php b/settings/templates/users.php index 64dce38ba3..2ba57fb4a7 100644 --- a/settings/templates/users.php +++ b/settings/templates/users.php @@ -93,7 +93,7 @@ var isadmin = ; "> - change display name From 70c3ab3c53fa31331c19d3f1d74fce29efc047d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 28 Jan 2013 14:23:15 +0100 Subject: [PATCH 218/262] update the display name for the database back-end --- lib/user/database.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/user/database.php b/lib/user/database.php index f33e338e2e..49c7654532 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -110,6 +110,24 @@ class OC_User_Database extends OC_User_Backend { return false; } } + + /** + * @brief Set display name + * @param $uid The username + * @param $displayName The new display name + * @returns true/false + * + * Change the display name of a user + */ + public function setDisplayName( $uid, $displayName ) { + if( $this->userExists($uid) ) { + $query = OC_DB::prepare( 'UPDATE `*PREFIX*users` SET `displayname` = ? WHERE `uid` = ?' ); + $query->execute( array( $displayName, $uid )); + return true; + }else{ + return false; + } + } /** * @brief Check if the password is correct From 3e0d117d6078703b46e73c6f5642f1945857da17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 28 Jan 2013 14:38:38 +0100 Subject: [PATCH 219/262] add display name to the database table oc_users --- db_structure.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/db_structure.xml b/db_structure.xml index db43ef2114..e878eac769 100644 --- a/db_structure.xml +++ b/db_structure.xml @@ -679,6 +679,14 @@ 64 + + displayname + text + + true + 64 + + password text From e6cc0cd08a502fc426c868bd1981c80eb39a9062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 28 Jan 2013 15:07:31 +0100 Subject: [PATCH 220/262] implement display names for the database back-end --- lib/user/database.php | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/lib/user/database.php b/lib/user/database.php index 49c7654532..52f11a5e29 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -129,6 +129,40 @@ class OC_User_Database extends OC_User_Backend { } } + /** + * @brief get display name of the user + * @param $uid user ID of the user + * @return display name + */ + public function getDisplayName($uid) { + if( $this->userExists($uid) ) { + $query = OC_DB::prepare( 'SELECT displayname FROM `*PREFIX*users` WHERE `uid` = ?' ); + $result = $query->execute( array( $uid ))->fetchAll(); + if (!empty($result[0]['displayname'])) { + return $result[0]['displayname']; + } else { + return $uid; + } + } + } + + /** + * @brief Get a list of all display names + * @returns array with all displayNames (value) and the correspondig uids (key) + * + * Get a list of all display names and user ids. + */ + public function getDisplayNames($search = '', $limit = null, $offset = null) { + $displayNames = array(); + $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); + $result = $query->execute(array($search.'%')); + $users = array(); + while ($row = $result->fetchRow()) { + $displayNames[$row['uid']] = $row['displayname']; + } + return $displayNames; + } + /** * @brief Check if the password is correct * @param $uid The username From c9c919da5738f963247307ca3878e06beff87ade Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 15:34:15 +0100 Subject: [PATCH 221/262] Move streamwrappers to seperate files and put them in a namespace --- apps/files_external/lib/amazons3.php | 54 +++---- apps/files_external/lib/dropbox.php | 4 +- apps/files_external/lib/ftp.php | 2 +- apps/files_external/lib/google.php | 4 +- apps/files_external/lib/swift.php | 4 +- apps/files_external/lib/webdav.php | 6 +- apps/files_sharing/lib/sharedstorage.php | 2 +- lib/archive/tar.php | 2 +- lib/archive/zip.php | 2 +- lib/base.php | 7 +- lib/files/stream/close.php | 100 +++++++++++++ lib/files/stream/dir.php | 47 ++++++ .../stream/staticstream.php} | 136 ++---------------- tests/lib/streamwrappers.php | 76 +++++----- 14 files changed, 242 insertions(+), 204 deletions(-) create mode 100644 lib/files/stream/close.php create mode 100644 lib/files/stream/dir.php rename lib/{streamwrappers.php => files/stream/staticstream.php} (57%) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index a209f0d050..494885a1dd 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -1,24 +1,24 @@ . -*/ + * 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 . + */ namespace OC\Files\Storage; @@ -36,7 +36,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { // TODO options: storage class, encryption server side, encrypt before upload? public function __construct($params) { - $this->id = 'amazon::'.$params['key'] . md5($params['secret']); + $this->id = 'amazon::' . $params['key'] . md5($params['secret']); $this->s3 = new \AmazonS3(array('key' => $params['key'], 'secret' => $params['secret'])); $this->bucket = $params['bucket']; } @@ -51,7 +51,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return $response; // This object could be a folder, a '/' must be at the end of the path } else if (substr($path, -1) != '/') { - $response = $this->s3->get_object_metadata($this->bucket, $path.'/'); + $response = $this->s3->get_object_metadata($this->bucket, $path . '/'); if ($response) { $this->objects[$path] = $response; return $response; @@ -61,7 +61,7 @@ class AmazonS3 extends \OC\Files\Storage\Common { return false; } - public function getId(){ + public function getId() { return $this->id; } @@ -104,8 +104,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { foreach ($response->body->CommonPrefixes as $object) { $files[] = basename($object->Prefix); } - \OC_FakeDirStream::$dirs['amazons3'.$path] = $files; - return opendir('fakedir://amazons3'.$path); + \OC\Files\Stream\Dir::register('amazons3' . $path, $files); + return opendir('fakedir://amazons3' . $path); } return false; } @@ -194,13 +194,13 @@ class AmazonS3 extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); } self::$tempFiles[$tmpFile] = $path; - return fopen('close://'.$tmpFile, $mode); + return fopen('close://' . $tmpFile, $mode); } return false; } @@ -209,8 +209,8 @@ class AmazonS3 extends \OC\Files\Storage\Common { if (isset(self::$tempFiles[$tmpFile])) { $handle = fopen($tmpFile, 'r'); $response = $this->s3->create_object($this->bucket, - self::$tempFiles[$tmpFile], - array('fileUpload' => $handle)); + self::$tempFiles[$tmpFile], + array('fileUpload' => $handle)); if ($response->isOK()) { unlink($tmpFile); } diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 9223b4ca87..11644e4a2c 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -114,7 +114,7 @@ class Dropbox extends \OC\Files\Storage\Common { foreach ($contents as $file) { $files[] = basename($file['path']); } - \OC_FakeDirStream::$dirs['dropbox'.$path] = $files; + \OC\Files\Stream\Dir::register('dropbox'.$path, $files); return opendir('fakedir://dropbox'.$path); } return false; @@ -232,7 +232,7 @@ class Dropbox extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php index 973b33fbfd..9a27b63323 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/ftp.php @@ -84,7 +84,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $this->getFile($path, $tmpFile); } diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index 4c485773e7..7396c7e3f2 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -273,7 +273,7 @@ class Google extends \OC\Files\Storage\Common { $this->entries[$name] = $entry; } } - \OC_FakeDirStream::$dirs['google'.$path] = $files; + \OC\Files\Stream\Dir::register('google'.$path, $files); return opendir('fakedir://google'.$path); } @@ -450,7 +450,7 @@ class Google extends \OC\Files\Storage\Common { $ext = ''; } $tmpFile = \OC_Helper::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile] = array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if ($this->file_exists($path)) { $source = $this->fopen($path, 'r'); file_put_contents($tmpFile, $source); diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php index bd1f4c572a..cbf2007052 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/swift.php @@ -371,7 +371,7 @@ class SWIFT extends \OC\Files\Storage\Common{ $subContainers=$this->getSubContainers($container); $files=array_merge($files, $subContainers); $id=$this->getContainerName($path); - \OC_FakeDirStream::$dirs[$id]=$files; + \OC\Files\Stream\Dir::register($id, $files); return opendir('fakedir://'.$id); } @@ -465,7 +465,7 @@ class SWIFT extends \OC\Files\Storage\Common{ case 'c': case 'c+': $tmpFile=$this->getTmpFile($path); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); self::$tempFiles[$tmpFile]=$path; return fopen('close://'.$tmpFile, $mode); } diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index 6d43a03058..571b4d79ae 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -104,13 +104,15 @@ class DAV extends \OC\Files\Storage\Common{ try { $response=$this->client->propfind($path, array(), 1); $id=md5('webdav'.$this->root.$path); + $content = array(); \OC_FakeDirStream::$dirs[$id]=array(); $files=array_keys($response); array_shift($files);//the first entry is the current directory foreach ($files as $file) { $file = urldecode(basename($file)); - \OC_FakeDirStream::$dirs[$id][]=$file; + $content[]=$file; } + \OC\Files\Stream\Dir::register($id, $content); return opendir('fakedir://'.$id); } catch(\Exception $e) { return false; @@ -194,7 +196,7 @@ class DAV extends \OC\Files\Storage\Common{ $ext=''; } $tmpFile = \OCP\Files::tmpFile($ext); - \OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if($this->file_exists($path)) { $this->getFile($path, $tmpFile); } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index b0be6843c5..ea28ca69b9 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -102,7 +102,7 @@ class Shared extends \OC\Files\Storage\Common { public function opendir($path) { if ($path == '' || $path == '/') { $files = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_Folder::FORMAT_OPENDIR); - \OC_FakeDirStream::$dirs['shared'] = $files; + \OC\Files\Stream\Dir::register('shared', $files); return opendir('fakedir://shared'); } else if ($source = $this->getSourcePath($path)) { list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($source); diff --git a/lib/archive/tar.php b/lib/archive/tar.php index 0fa633c603..117d88e5f4 100644 --- a/lib/archive/tar.php +++ b/lib/archive/tar.php @@ -308,7 +308,7 @@ class OC_Archive_TAR extends OC_Archive{ if($mode=='r' or $mode=='rb') { return fopen($tmpFile, $mode); }else{ - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); self::$tempFiles[$tmpFile]=$path; return fopen('close://'.$tmpFile, $mode); } diff --git a/lib/archive/zip.php b/lib/archive/zip.php index 1c967baa08..8e31795ded 100644 --- a/lib/archive/zip.php +++ b/lib/archive/zip.php @@ -171,7 +171,7 @@ class OC_Archive_ZIP extends OC_Archive{ $ext=''; } $tmpFile=OCP\Files::tmpFile($ext); - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this, 'writeBack'); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); if($this->fileExists($path)) { $this->extractFile($path, $tmpFile); } diff --git a/lib/base.php b/lib/base.php index e3baa617c3..45e2f633cb 100644 --- a/lib/base.php +++ b/lib/base.php @@ -421,10 +421,9 @@ class OC } // register the stream wrappers - require_once 'streamwrappers.php'; - stream_wrapper_register("fakedir", "OC_FakeDirStream"); - stream_wrapper_register('static', 'OC_StaticStreamWrapper'); - stream_wrapper_register('close', 'OC_CloseStreamWrapper'); + stream_wrapper_register('fakedir', 'OC\Files\Stream\Dir'); + stream_wrapper_register('static', 'OC\Files\Stream\StaticStream'); + stream_wrapper_register('close', 'OC\Files\Stream\Close'); self::checkConfig(); self::checkInstalled(); diff --git a/lib/files/stream/close.php b/lib/files/stream/close.php new file mode 100644 index 0000000000..80de3497c3 --- /dev/null +++ b/lib/files/stream/close.php @@ -0,0 +1,100 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Stream; + +/** + * stream wrapper that provides a callback on stream close + */ +class Close { + private static $callBacks = array(); + private $path = ''; + private $source; + private static $open = array(); + + public function stream_open($path, $mode, $options, &$opened_path) { + $path = substr($path, strlen('close://')); + $this->path = $path; + $this->source = fopen($path, $mode); + if (is_resource($this->source)) { + $this->meta = stream_get_meta_data($this->source); + } + self::$open[] = $path; + return is_resource($this->source); + } + + public function stream_seek($offset, $whence = SEEK_SET) { + fseek($this->source, $offset, $whence); + } + + public function stream_tell() { + return ftell($this->source); + } + + public function stream_read($count) { + return fread($this->source, $count); + } + + public function stream_write($data) { + return fwrite($this->source, $data); + } + + public function stream_set_option($option, $arg1, $arg2) { + switch ($option) { + case STREAM_OPTION_BLOCKING: + stream_set_blocking($this->source, $arg1); + break; + case STREAM_OPTION_READ_TIMEOUT: + stream_set_timeout($this->source, $arg1, $arg2); + break; + case STREAM_OPTION_WRITE_BUFFER: + stream_set_write_buffer($this->source, $arg1, $arg2); + } + } + + public function stream_stat() { + return fstat($this->source); + } + + public function stream_lock($mode) { + flock($this->source, $mode); + } + + public function stream_flush() { + return fflush($this->source); + } + + public function stream_eof() { + return feof($this->source); + } + + public function url_stat($path) { + $path = substr($path, strlen('close://')); + if (file_exists($path)) { + return stat($path); + } else { + return false; + } + } + + public function stream_close() { + fclose($this->source); + if (isset(self::$callBacks[$this->path])) { + call_user_func(self::$callBacks[$this->path], $this->path); + } + } + + public function unlink($path) { + $path = substr($path, strlen('close://')); + return unlink($path); + } + + public static function registerCallback($path, $callback) { + self::$callBacks[$path] = $callback; + } +} diff --git a/lib/files/stream/dir.php b/lib/files/stream/dir.php new file mode 100644 index 0000000000..6ca884fc99 --- /dev/null +++ b/lib/files/stream/dir.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Stream; + +class Dir { + private static $dirs = array(); + private $name; + private $index; + + public function dir_opendir($path, $options) { + $this->name = substr($path, strlen('fakedir://')); + $this->index = 0; + if (!isset(self::$dirs[$this->name])) { + self::$dirs[$this->name] = array(); + } + return true; + } + + public function dir_readdir() { + if ($this->index >= count(self::$dirs[$this->name])) { + return false; + } + $filename = self::$dirs[$this->name][$this->index]; + $this->index++; + return $filename; + } + + public function dir_closedir() { + $this->name = ''; + return true; + } + + public function dir_rewinddir() { + $this->index = 0; + return true; + } + + public static function register($path, $content) { + self::$dirs[$path] = $content; + } +} diff --git a/lib/streamwrappers.php b/lib/files/stream/staticstream.php similarity index 57% rename from lib/streamwrappers.php rename to lib/files/stream/staticstream.php index 981c280f0d..7725a6a5a0 100644 --- a/lib/streamwrappers.php +++ b/lib/files/stream/staticstream.php @@ -1,54 +1,30 @@ + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ -class OC_FakeDirStream{ - public static $dirs=array(); - private $name; - private $index; +namespace OC\Files\Stream; - public function dir_opendir($path, $options) { - $this->name=substr($path, strlen('fakedir://')); - $this->index=0; - if(!isset(self::$dirs[$this->name])) { - self::$dirs[$this->name]=array(); - } - return true; - } - - public function dir_readdir() { - if($this->index>=count(self::$dirs[$this->name])) { - return false; - } - $filename=self::$dirs[$this->name][$this->index]; - $this->index++; - return $filename; - } - - public function dir_closedir() { - $this->name=''; - return true; - } - - public function dir_rewinddir() { - $this->index=0; - return true; - } -} - -class OC_StaticStreamWrapper { +class StaticStream { public $context; protected static $data = array(); - protected $path = ''; + protected $path = ''; protected $pointer = 0; protected $writable = false; - public function stream_close() {} + public function stream_close() { + } public function stream_eof() { return $this->pointer >= strlen(self::$data[$this->path]); } - public function stream_flush() {} + public function stream_flush() { + } public function stream_open($path, $mode, $options, &$opened_path) { switch ($mode[0]) { @@ -213,89 +189,3 @@ class OC_StaticStreamWrapper { return false; } } - -/** - * stream wrapper that provides a callback on stream close - */ -class OC_CloseStreamWrapper{ - public static $callBacks=array(); - private $path=''; - private $source; - private static $open=array(); - public function stream_open($path, $mode, $options, &$opened_path) { - $path=substr($path, strlen('close://')); - $this->path=$path; - $this->source=fopen($path, $mode); - if(is_resource($this->source)) { - $this->meta=stream_get_meta_data($this->source); - } - self::$open[]=$path; - return is_resource($this->source); - } - - public function stream_seek($offset, $whence=SEEK_SET) { - fseek($this->source, $offset, $whence); - } - - public function stream_tell() { - return ftell($this->source); - } - - public function stream_read($count) { - return fread($this->source, $count); - } - - public function stream_write($data) { - return fwrite($this->source, $data); - } - - public function stream_set_option($option, $arg1, $arg2) { - switch($option) { - case STREAM_OPTION_BLOCKING: - stream_set_blocking($this->source, $arg1); - break; - case STREAM_OPTION_READ_TIMEOUT: - stream_set_timeout($this->source, $arg1, $arg2); - break; - case STREAM_OPTION_WRITE_BUFFER: - stream_set_write_buffer($this->source, $arg1, $arg2); - } - } - - public function stream_stat() { - return fstat($this->source); - } - - public function stream_lock($mode) { - flock($this->source, $mode); - } - - public function stream_flush() { - return fflush($this->source); - } - - public function stream_eof() { - return feof($this->source); - } - - public function url_stat($path) { - $path=substr($path, strlen('close://')); - if(file_exists($path)) { - return stat($path); - }else{ - return false; - } - } - - public function stream_close() { - fclose($this->source); - if(isset(self::$callBacks[$this->path])) { - call_user_func(self::$callBacks[$this->path], $this->path); - } - } - - public function unlink($path) { - $path=substr($path, strlen('close://')); - return unlink($path); - } -} diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index aebbc93b90..e40f2e7612 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -1,41 +1,41 @@ . -* -*/ + * ownCloud + * + * @author Robin Appelman + * @copyright 2012 Robin Appelman icewind@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 . + * + */ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public function testFakeDir() { - $items=array('foo', 'bar'); - OC_FakeDirStream::$dirs['test']=$items; - $dh=opendir('fakedir://test'); - $result=array(); - while($file=readdir($dh)) { - $result[]=$file; + $items = array('foo', 'bar'); + \OC\Files\Stream\Dir::register('test', $items); + $dh = opendir('fakedir://test'); + $result = array(); + while ($file = readdir($dh)) { + $result[] = $file; $this->assertContains($file, $items); } $this->assertEquals(count($items), count($result)); } public function testStaticStream() { - $sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $staticFile='static://test'; + $sourceFile = OC::$SERVERROOT . '/tests/data/lorem.txt'; + $staticFile = 'static://test'; $this->assertFalse(file_exists($staticFile)); file_put_contents($staticFile, file_get_contents($sourceFile)); $this->assertTrue(file_exists($staticFile)); @@ -47,27 +47,27 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public function testCloseStream() { //ensure all basic stream stuff works - $sourceFile=OC::$SERVERROOT.'/tests/data/lorem.txt'; - $tmpFile=OC_Helper::TmpFile('.txt'); - $file='close://'.$tmpFile; + $sourceFile = OC::$SERVERROOT . '/tests/data/lorem.txt'; + $tmpFile = OC_Helper::TmpFile('.txt'); + $file = 'close://' . $tmpFile; $this->assertTrue(file_exists($file)); file_put_contents($file, file_get_contents($sourceFile)); $this->assertEquals(file_get_contents($sourceFile), file_get_contents($file)); unlink($file); clearstatcache(); $this->assertFalse(file_exists($file)); - + //test callback - $tmpFile=OC_Helper::TmpFile('.txt'); - $file='close://'.$tmpFile; - OC_CloseStreamWrapper::$callBacks[$tmpFile]=array('Test_StreamWrappers', 'closeCallBack'); - $fh=fopen($file, 'w'); + $tmpFile = OC_Helper::TmpFile('.txt'); + $file = 'close://' . $tmpFile; + \OC\Files\Stream\Close::registerCallback($tmpFile, array('Test_StreamWrappers', 'closeCallBack')); + $fh = fopen($file, 'w'); fwrite($fh, 'asd'); - try{ + try { fclose($fh); $this->fail('Expected exception'); - }catch(Exception $e) { - $path=$e->getMessage(); + } catch (Exception $e) { + $path = $e->getMessage(); $this->assertEquals($path, $tmpFile); } } From 232cc3211b2b312d4e32e7d0fb482a2b7affe89a Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 28 Jan 2013 15:35:30 +0100 Subject: [PATCH 222/262] add oc:// streamwrapper to provide access to ownCloud's virtual filesystem --- lib/base.php | 1 + lib/files/stream/oc.php | 129 +++++++++++++++++++++++++++++++++++ tests/lib/streamwrappers.php | 19 ++++++ 3 files changed, 149 insertions(+) create mode 100644 lib/files/stream/oc.php diff --git a/lib/base.php b/lib/base.php index 45e2f633cb..e6f00839aa 100644 --- a/lib/base.php +++ b/lib/base.php @@ -424,6 +424,7 @@ class OC stream_wrapper_register('fakedir', 'OC\Files\Stream\Dir'); stream_wrapper_register('static', 'OC\Files\Stream\StaticStream'); stream_wrapper_register('close', 'OC\Files\Stream\Close'); + stream_wrapper_register('oc', 'OC\Files\Stream\OC'); self::checkConfig(); self::checkInstalled(); diff --git a/lib/files/stream/oc.php b/lib/files/stream/oc.php new file mode 100644 index 0000000000..88e7e062df --- /dev/null +++ b/lib/files/stream/oc.php @@ -0,0 +1,129 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Files\Stream; + +/** + * a stream wrappers for ownCloud's virtual filesystem + */ +class OC { + /** + * @var \OC\Files\View + */ + static private $rootView; + + private $path; + private $dirSource; + private $fileSource; + private $meta; + + private function setup(){ + if (!self::$rootView) { + self::$rootView = new \OC\Files\View(''); + } + } + + public function stream_open($path, $mode, $options, &$opened_path) { + $this->setup(); + $path = substr($path, strlen('oc://')); + $this->path = $path; + $this->fileSource = self::$rootView->fopen($path, $mode); + if (is_resource($this->fileSource)) { + $this->meta = stream_get_meta_data($this->fileSource); + } + return is_resource($this->fileSource); + } + + public function stream_seek($offset, $whence = SEEK_SET) { + fseek($this->fileSource, $offset, $whence); + } + + public function stream_tell() { + return ftell($this->fileSource); + } + + public function stream_read($count) { + return fread($this->fileSource, $count); + } + + public function stream_write($data) { + return fwrite($this->fileSource, $data); + } + + public function stream_set_option($option, $arg1, $arg2) { + switch ($option) { + case STREAM_OPTION_BLOCKING: + stream_set_blocking($this->fileSource, $arg1); + break; + case STREAM_OPTION_READ_TIMEOUT: + stream_set_timeout($this->fileSource, $arg1, $arg2); + break; + case STREAM_OPTION_WRITE_BUFFER: + stream_set_write_buffer($this->fileSource, $arg1, $arg2); + } + } + + public function stream_stat() { + return fstat($this->fileSource); + } + + public function stream_lock($mode) { + flock($this->fileSource, $mode); + } + + public function stream_flush() { + return fflush($this->fileSource); + } + + public function stream_eof() { + return feof($this->fileSource); + } + + public function url_stat($path) { + $this->setup(); + $path = substr($path, strlen('oc://')); + if (self::$rootView->file_exists($path)) { + return self::$rootView->stat($path); + } else { + return false; + } + } + + public function stream_close() { + fclose($this->fileSource); + } + + public function unlink($path) { + $this->setup(); + $path = substr($path, strlen('oc://')); + return self::$rootView->unlink($path); + } + + public function dir_opendir($path, $options) { + $this->setup(); + $path = substr($path, strlen('oc://')); + $this->path = $path; + $this->dirSource = self::$rootView->opendir($path); + if (is_resource($this->dirSource)) { + $this->meta = stream_get_meta_data($this->dirSource); + } + return is_resource($this->dirSource); + } + + public function dir_readdir() { + return readdir($this->dirSource); + } + + public function dir_closedir() { + closedir($this->dirSource); + } + + public function dir_rewinddir() { + rewinddir($this->dirSource); + } +} diff --git a/tests/lib/streamwrappers.php b/tests/lib/streamwrappers.php index e40f2e7612..2237ee7d37 100644 --- a/tests/lib/streamwrappers.php +++ b/tests/lib/streamwrappers.php @@ -75,4 +75,23 @@ class Test_StreamWrappers extends PHPUnit_Framework_TestCase { public static function closeCallBack($path) { throw new Exception($path); } + + public function testOC() { + \OC\Files\Mount::clear(); + $storage = new \OC\Files\Storage\Temporary(array()); + $storage->file_put_contents('foo.txt', 'asd'); + new \OC\Files\Mount($storage, '/'); + + $this->assertTrue(file_exists('oc:///foo.txt')); + $this->assertEquals('asd', file_get_contents('oc:///foo.txt')); + $this->assertEquals(array('.', '..', 'foo.txt'), scandir('oc:///')); + + file_put_contents('oc:///bar.txt', 'qwerty'); + $this->assertEquals('qwerty', $storage->file_get_contents('bar.txt')); + $this->assertEquals(array('.', '..', 'bar.txt', 'foo.txt'), scandir('oc:///')); + $this->assertEquals('qwerty', file_get_contents('oc:///bar.txt')); + + unlink('oc:///foo.txt'); + $this->assertEquals(array('.', '..', 'bar.txt'), scandir('oc:///')); + } } From c00b66fe5bb37403e4dec1ede9d509947b795df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 28 Jan 2013 15:47:57 +0100 Subject: [PATCH 223/262] implement DisplayNamesInGroup for database back-end --- lib/group.php | 2 +- lib/group/backend.php | 2 +- lib/group/database.php | 28 ++++++++++++++++++++++++++++ lib/user.php | 2 +- lib/user/database.php | 10 ++++++---- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/group.php b/lib/group.php index 8ebb698692..5afef76936 100644 --- a/lib/group.php +++ b/lib/group.php @@ -289,7 +289,7 @@ class OC_Group { /** * @brief get a list of all display names in a group - * @returns array with display names (key) and user ids(value) + * @returns array with display names (value) and user ids(key) */ public static function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { $displayNames=array(); diff --git a/lib/group/backend.php b/lib/group/backend.php index ceb2d9242d..4f6570c3be 100644 --- a/lib/group/backend.php +++ b/lib/group/backend.php @@ -140,7 +140,7 @@ abstract class OC_Group_Backend implements OC_Group_Interface { * @param string $search * @param int $limit * @param int $offset - * @return array with display names (key) and user ids (value) + * @return array with display names (value) and user ids (key) */ public function DisplayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { $displayNames = ''; diff --git a/lib/group/database.php b/lib/group/database.php index 6eca98ba01..c5dd402b21 100644 --- a/lib/group/database.php +++ b/lib/group/database.php @@ -208,4 +208,32 @@ class OC_Group_Database extends OC_Group_Backend { } return $users; } + + /** + * @brief get a list of all display names in a group + * @param string $gid + * @param string $search + * @param int $limit + * @param int $offset + * @return array with display names (value) and user ids (key) + */ + public function DisplayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + $displayNames = ''; + /* + + SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo + FROM Persons + INNER JOIN Orders + ON Persons.P_Id=Orders.P_Id + ORDER BY Persons.LastName + */ + $stmt = OC_DB::prepare('SELECT `*PREFIX*users`.`uid`, `*PREFIX*users`.`displayname` FROM `*PREFIX*users` INNER JOIN `*PREFIX*group_user` ON `*PREFIX*group_user`.`uid` = `*PREFIX*users`.`uid` WHERE `gid` = ? AND `*PREFIX*group_user.uid` LIKE ?', $limit, $offset); + $result = $stmt->execute(array($gid, $search.'%')); + $users = array(); + while ($row = $result->fetchRow()) { + $displayName = trim($row['displayname'], ' '); + $displayNames[$row['uid']] = empty($displayName) ? $row['uid'] : $displayName; + } + return $displayNames; + } } diff --git a/lib/user.php b/lib/user.php index b91abd71fe..399a3240c8 100644 --- a/lib/user.php +++ b/lib/user.php @@ -477,7 +477,7 @@ class OC_User { /** * @brief Get a list of all users display name - * @returns associative array with all display names (key) and corresponding uids (value) + * @returns associative array with all display names (value) and corresponding uids (key) * * Get a list of all display names and user ids. */ diff --git a/lib/user/database.php b/lib/user/database.php index 52f11a5e29..bed97f25fd 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -138,8 +138,9 @@ class OC_User_Database extends OC_User_Backend { if( $this->userExists($uid) ) { $query = OC_DB::prepare( 'SELECT displayname FROM `*PREFIX*users` WHERE `uid` = ?' ); $result = $query->execute( array( $uid ))->fetchAll(); - if (!empty($result[0]['displayname'])) { - return $result[0]['displayname']; + $displayName = trim($result[0]['displayname'], ' '); + if ( !empty($displayName) ) { + return $displayName; } else { return $uid; } @@ -157,8 +158,9 @@ class OC_User_Database extends OC_User_Backend { $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); $result = $query->execute(array($search.'%')); $users = array(); - while ($row = $result->fetchRow()) { - $displayNames[$row['uid']] = $row['displayname']; + while ($row = $result->fetchRow()) { + $displayName = trim($row['displayname'], ' '); + $displayNames[$row['uid']] = empty($displayName) ? $row['uid'] : $displayName; } return $displayNames; } From 590c4aa710077ae82a5af0ec4477a00eafe791dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 28 Jan 2013 15:58:40 +0100 Subject: [PATCH 224/262] search display name instead of uid; fix key/value order for array access --- core/ajax/share.php | 2 +- lib/user/database.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/ajax/share.php b/core/ajax/share.php index 231cdc5e24..6704a00c5a 100644 --- a/core/ajax/share.php +++ b/core/ajax/share.php @@ -164,7 +164,7 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo $users = OC_User::getDisplayNames($_GET['search'], $limit, $offset); } $offset += $limit; - foreach ($users as $displayName => $uid) { + foreach ($users as $uid => $displayName) { if ((!isset($_GET['itemShares']) || !is_array($_GET['itemShares'][OCP\Share::SHARE_TYPE_USER]) || !in_array($uid, $_GET['itemShares'][OCP\Share::SHARE_TYPE_USER])) && $uid != OC_User::getUser()) { $shareWith[] = array('label' => $displayName, 'value' => array('shareType' => OCP\Share::SHARE_TYPE_USER, 'shareWith' => $uid)); $count++; diff --git a/lib/user/database.php b/lib/user/database.php index bed97f25fd..7deeb0c469 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -155,7 +155,7 @@ class OC_User_Database extends OC_User_Backend { */ public function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = array(); - $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`uid`) LIKE LOWER(?)', $limit, $offset); + $query = OC_DB::prepare('SELECT `uid`, `displayname` FROM `*PREFIX*users` WHERE LOWER(`displayname`) LIKE LOWER(?)', $limit, $offset); $result = $query->execute(array($search.'%')); $users = array(); while ($row = $result->fetchRow()) { From f3a99f4869ea238822793f89bef14b564c333aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Mon, 28 Jan 2013 17:01:37 +0100 Subject: [PATCH 225/262] show display name in input field --- settings/js/users.js | 3 ++- settings/templates/users.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/settings/js/users.js b/settings/js/users.js index 835f46f6ed..111e3040a3 100644 --- a/settings/js/users.js +++ b/settings/js/users.js @@ -305,7 +305,8 @@ $(document).ready(function () { event.stopPropagation(); var img = $(this); var uid = img.parent().parent().attr('data-uid'); - var input = $(''); + var displayName = img.parent().parent().attr('data-displayName'); + var input = $(''); img.css('display', 'none'); img.parent().children('span').replaceWith(input); input.focus(); diff --git a/settings/templates/users.php b/settings/templates/users.php index 2ba57fb4a7..6407b59883 100644 --- a/settings/templates/users.php +++ b/settings/templates/users.php @@ -91,7 +91,8 @@ var isadmin = ; - "> + " + data-displayName=""> Date: Mon, 28 Jan 2013 17:05:20 +0100 Subject: [PATCH 226/262] rename Name to Login Name --- settings/templates/users.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings/templates/users.php b/settings/templates/users.php index 6407b59883..fa06c9c72e 100644 --- a/settings/templates/users.php +++ b/settings/templates/users.php @@ -18,7 +18,7 @@ var isadmin = ;
- ').attr('data-username', username).attr('data-user-groups', groups); tr.find('td.groups').empty(); if (tr.find('td.subadmins').length > 0) { From 68266e70f283734538499e73a245491a6101f6a3 Mon Sep 17 00:00:00 2001 From: Jenkins for ownCloud Date: Wed, 30 Jan 2013 00:25:41 +0100 Subject: [PATCH 250/262] [tx-robot] updated from transifex --- apps/files/l10n/da.php | 11 +++ apps/files/l10n/de.php | 3 + apps/files/l10n/fr.php | 3 + apps/files/l10n/ja_JP.php | 3 + apps/files/l10n/sv.php | 3 + apps/files/l10n/th_TH.php | 3 + apps/files_encryption/l10n/da.php | 11 +++ apps/files_encryption/l10n/de.php | 11 +++ apps/files_encryption/l10n/de_DE.php | 10 ++- apps/files_encryption/l10n/es.php | 2 + apps/files_encryption/l10n/eu.php | 4 ++ apps/files_encryption/l10n/sk_SK.php | 11 +++ apps/user_ldap/l10n/de.php | 4 ++ apps/user_ldap/l10n/de_DE.php | 2 +- apps/user_ldap/l10n/ru_RU.php | 4 ++ apps/user_webdavauth/l10n/da.php | 4 +- apps/user_webdavauth/l10n/sk_SK.php | 3 +- core/l10n/ca.php | 2 + core/l10n/cs_CZ.php | 2 + core/l10n/da.php | 2 + core/l10n/de.php | 2 + core/l10n/de_DE.php | 2 + core/l10n/eu.php | 2 + core/l10n/fr.php | 2 + core/l10n/it.php | 2 + core/l10n/ja_JP.php | 2 + core/l10n/pt_PT.php | 2 + core/l10n/ru_RU.php | 5 +- core/l10n/sk_SK.php | 2 + core/l10n/sv.php | 2 + core/l10n/th_TH.php | 2 + core/l10n/vi.php | 8 +++ l10n/ar/core.po | 82 ++++++++++++---------- l10n/ar/settings.po | 38 +++++----- l10n/bg_BG/core.po | 82 ++++++++++++---------- l10n/bg_BG/settings.po | 38 +++++----- l10n/bn_BD/core.po | 82 ++++++++++++---------- l10n/bn_BD/settings.po | 38 +++++----- l10n/ca/core.po | 87 ++++++++++++----------- l10n/ca/settings.po | 38 +++++----- l10n/cs_CZ/core.po | 86 ++++++++++++----------- l10n/cs_CZ/settings.po | 38 +++++----- l10n/da/core.po | 88 ++++++++++++----------- l10n/da/files.po | 30 ++++---- l10n/da/files_encryption.po | 29 ++++---- l10n/da/lib.po | 12 ++-- l10n/da/settings.po | 38 +++++----- l10n/da/user_webdavauth.po | 11 +-- l10n/de/core.po | 88 ++++++++++++----------- l10n/de/files.po | 12 ++-- l10n/de/files_encryption.po | 29 ++++---- l10n/de/settings.po | 30 ++++---- l10n/de/user_ldap.po | 15 ++-- l10n/de_DE/core.po | 89 +++++++++++++----------- l10n/de_DE/files_encryption.po | 27 ++++---- l10n/de_DE/settings.po | 30 ++++---- l10n/de_DE/user_ldap.po | 9 +-- l10n/el/core.po | 82 ++++++++++++---------- l10n/el/settings.po | 40 ++++++----- l10n/eo/core.po | 82 ++++++++++++---------- l10n/eo/settings.po | 40 ++++++----- l10n/es/core.po | 82 ++++++++++++---------- l10n/es/files_encryption.po | 11 +-- l10n/es/settings.po | 38 +++++----- l10n/es_AR/core.po | 82 ++++++++++++---------- l10n/es_AR/settings.po | 38 +++++----- l10n/et_EE/core.po | 82 ++++++++++++---------- l10n/et_EE/settings.po | 38 +++++----- l10n/eu/core.po | 86 ++++++++++++----------- l10n/eu/files_encryption.po | 15 ++-- l10n/eu/settings.po | 40 ++++++----- l10n/fa/core.po | 82 ++++++++++++---------- l10n/fa/settings.po | 38 +++++----- l10n/fi_FI/core.po | 82 ++++++++++++---------- l10n/fi_FI/settings.po | 38 +++++----- l10n/fr/core.po | 87 ++++++++++++----------- l10n/fr/files.po | 13 ++-- l10n/fr/settings.po | 38 +++++----- l10n/gl/core.po | 82 ++++++++++++---------- l10n/gl/settings.po | 38 +++++----- l10n/he/core.po | 82 ++++++++++++---------- l10n/he/settings.po | 38 +++++----- l10n/hi/core.po | 82 ++++++++++++---------- l10n/hi/settings.po | 36 +++++----- l10n/hr/core.po | 82 ++++++++++++---------- l10n/hr/settings.po | 38 +++++----- l10n/hu_HU/core.po | 82 ++++++++++++---------- l10n/hu_HU/settings.po | 38 +++++----- l10n/ia/core.po | 82 ++++++++++++---------- l10n/ia/settings.po | 38 +++++----- l10n/id/core.po | 82 ++++++++++++---------- l10n/id/settings.po | 38 +++++----- l10n/is/core.po | 82 ++++++++++++---------- l10n/is/settings.po | 38 +++++----- l10n/it/core.po | 86 ++++++++++++----------- l10n/it/settings.po | 40 ++++++----- l10n/ja_JP/core.po | 86 ++++++++++++----------- l10n/ja_JP/files.po | 12 ++-- l10n/ja_JP/settings.po | 38 +++++----- l10n/ka_GE/core.po | 82 ++++++++++++---------- l10n/ka_GE/settings.po | 38 +++++----- l10n/ko/core.po | 82 ++++++++++++---------- l10n/ko/settings.po | 38 +++++----- l10n/ku_IQ/core.po | 82 ++++++++++++---------- l10n/ku_IQ/settings.po | 38 +++++----- l10n/lb/core.po | 82 ++++++++++++---------- l10n/lb/settings.po | 38 +++++----- l10n/lt_LT/core.po | 82 ++++++++++++---------- l10n/lt_LT/settings.po | 38 +++++----- l10n/lv/core.po | 82 ++++++++++++---------- l10n/lv/settings.po | 28 ++++---- l10n/mk/core.po | 82 ++++++++++++---------- l10n/mk/settings.po | 38 +++++----- l10n/ms_MY/core.po | 82 ++++++++++++---------- l10n/ms_MY/settings.po | 38 +++++----- l10n/nb_NO/core.po | 82 ++++++++++++---------- l10n/nb_NO/settings.po | 38 +++++----- l10n/nl/core.po | 82 ++++++++++++---------- l10n/nl/settings.po | 38 +++++----- l10n/nn_NO/core.po | 82 ++++++++++++---------- l10n/nn_NO/settings.po | 38 +++++----- l10n/oc/core.po | 82 ++++++++++++---------- l10n/oc/settings.po | 38 +++++----- l10n/pl/core.po | 82 ++++++++++++---------- l10n/pl/settings.po | 40 ++++++----- l10n/pl_PL/core.po | 82 ++++++++++++---------- l10n/pl_PL/settings.po | 36 +++++----- l10n/pt_BR/core.po | 82 ++++++++++++---------- l10n/pt_BR/settings.po | 40 ++++++----- l10n/pt_PT/core.po | 87 ++++++++++++----------- l10n/pt_PT/settings.po | 38 +++++----- l10n/ro/core.po | 82 ++++++++++++---------- l10n/ro/settings.po | 34 +++++---- l10n/ru/core.po | 82 ++++++++++++---------- l10n/ru/settings.po | 40 ++++++----- l10n/ru_RU/core.po | 89 +++++++++++++----------- l10n/ru_RU/lib.po | 11 +-- l10n/ru_RU/settings.po | 49 +++++++------ l10n/ru_RU/user_ldap.po | 15 ++-- l10n/si_LK/core.po | 82 ++++++++++++---------- l10n/si_LK/settings.po | 38 +++++----- l10n/sk_SK/core.po | 87 ++++++++++++----------- l10n/sk_SK/files_encryption.po | 29 ++++---- l10n/sk_SK/lib.po | 11 +-- l10n/sk_SK/settings.po | 42 ++++++----- l10n/sk_SK/user_webdavauth.po | 6 +- l10n/sl/core.po | 82 ++++++++++++---------- l10n/sl/settings.po | 38 +++++----- l10n/sr/core.po | 82 ++++++++++++---------- l10n/sr/settings.po | 38 +++++----- l10n/sr@latin/core.po | 82 ++++++++++++---------- l10n/sr@latin/settings.po | 38 +++++----- l10n/sv/core.po | 87 ++++++++++++----------- l10n/sv/files.po | 13 ++-- l10n/sv/settings.po | 38 +++++----- l10n/ta_LK/core.po | 82 ++++++++++++---------- l10n/ta_LK/settings.po | 38 +++++----- l10n/templates/core.pot | 80 +++++++++++---------- l10n/templates/files.pot | 2 +- l10n/templates/files_encryption.pot | 2 +- l10n/templates/files_external.pot | 2 +- l10n/templates/files_sharing.pot | 2 +- l10n/templates/files_versions.pot | 2 +- l10n/templates/lib.pot | 2 +- l10n/templates/settings.pot | 24 ++++--- l10n/templates/user_ldap.pot | 2 +- l10n/templates/user_webdavauth.pot | 2 +- l10n/th_TH/core.po | 86 ++++++++++++----------- l10n/th_TH/files.po | 12 ++-- l10n/th_TH/settings.po | 40 ++++++----- l10n/tr/core.po | 82 ++++++++++++---------- l10n/tr/settings.po | 38 +++++----- l10n/uk/core.po | 82 ++++++++++++---------- l10n/uk/settings.po | 40 ++++++----- l10n/vi/core.po | 100 +++++++++++++++------------ l10n/vi/settings.po | 38 +++++----- l10n/zh_CN.GB2312/core.po | 82 ++++++++++++---------- l10n/zh_CN.GB2312/settings.po | 38 +++++----- l10n/zh_CN/core.po | 82 ++++++++++++---------- l10n/zh_CN/settings.po | 40 ++++++----- l10n/zh_HK/core.po | 82 ++++++++++++---------- l10n/zh_HK/settings.po | 36 +++++----- l10n/zh_TW/core.po | 82 ++++++++++++---------- l10n/zh_TW/settings.po | 38 +++++----- lib/l10n/da.php | 1 + lib/l10n/ru_RU.php | 1 + lib/l10n/sk_SK.php | 1 + settings/l10n/ar.php | 1 - settings/l10n/bg_BG.php | 1 - settings/l10n/bn_BD.php | 1 - settings/l10n/ca.php | 1 - settings/l10n/cs_CZ.php | 1 - settings/l10n/da.php | 1 - settings/l10n/de.php | 1 - settings/l10n/de_DE.php | 1 - settings/l10n/el.php | 1 - settings/l10n/eo.php | 1 - settings/l10n/es.php | 1 - settings/l10n/es_AR.php | 1 - settings/l10n/et_EE.php | 1 - settings/l10n/eu.php | 1 - settings/l10n/fa.php | 1 - settings/l10n/fi_FI.php | 1 - settings/l10n/fr.php | 1 - settings/l10n/gl.php | 1 - settings/l10n/he.php | 1 - settings/l10n/hr.php | 1 - settings/l10n/hu_HU.php | 1 - settings/l10n/ia.php | 1 - settings/l10n/id.php | 1 - settings/l10n/is.php | 1 - settings/l10n/it.php | 1 - settings/l10n/ja_JP.php | 1 - settings/l10n/ka_GE.php | 1 - settings/l10n/ko.php | 1 - settings/l10n/ku_IQ.php | 3 +- settings/l10n/lb.php | 1 - settings/l10n/lt_LT.php | 1 - settings/l10n/lv.php | 1 - settings/l10n/mk.php | 1 - settings/l10n/ms_MY.php | 1 - settings/l10n/nb_NO.php | 1 - settings/l10n/nl.php | 1 - settings/l10n/nn_NO.php | 1 - settings/l10n/oc.php | 1 - settings/l10n/pl.php | 1 - settings/l10n/pt_BR.php | 1 - settings/l10n/pt_PT.php | 1 - settings/l10n/ro.php | 1 - settings/l10n/ru.php | 1 - settings/l10n/ru_RU.php | 6 +- settings/l10n/si_LK.php | 1 - settings/l10n/sk_SK.php | 2 +- settings/l10n/sl.php | 1 - settings/l10n/sr.php | 1 - settings/l10n/sr@latin.php | 1 - settings/l10n/sv.php | 1 - settings/l10n/ta_LK.php | 1 - settings/l10n/th_TH.php | 1 - settings/l10n/tr.php | 1 - settings/l10n/uk.php | 1 - settings/l10n/vi.php | 1 - settings/l10n/zh_CN.GB2312.php | 1 - settings/l10n/zh_CN.php | 1 - settings/l10n/zh_TW.php | 1 - 245 files changed, 4445 insertions(+), 3605 deletions(-) diff --git a/apps/files/l10n/da.php b/apps/files/l10n/da.php index c5e3647a7f..2f9ae8fbb8 100644 --- a/apps/files/l10n/da.php +++ b/apps/files/l10n/da.php @@ -1,4 +1,7 @@ "Kunne ikke flytte %s - der findes allerede en fil med dette navn", +"Could not move %s" => "Kunne ikke flytte %s", +"Unable to rename file" => "Kunne ikke omdøbe fil", "No file was uploaded. Unknown error" => "Ingen fil blev uploadet. Ukendt fejl.", "There is no error, the file uploaded with success" => "Der er ingen fejl, filen blev uploadet med success", "The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "Den uploadede fil overstiger upload_max_filesize direktivet i php.ini", @@ -7,6 +10,8 @@ "No file was uploaded" => "Ingen fil blev uploadet", "Missing a temporary folder" => "Mangler en midlertidig mappe", "Failed to write to disk" => "Fejl ved skrivning til disk.", +"Not enough storage available" => "Der er ikke nok plads til rådlighed", +"Invalid directory." => "Ugyldig mappe.", "Files" => "Filer", "Unshare" => "Fjern deling", "Delete" => "Slet", @@ -20,7 +25,12 @@ "replaced {new_name} with {old_name}" => "erstattede {new_name} med {old_name}", "unshared {files}" => "ikke delte {files}", "deleted {files}" => "slettede {files}", +"'.' is an invalid file name." => "'.' er et ugyldigt filnavn.", +"File name cannot be empty." => "Filnavnet kan ikke stå tomt.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ugyldigt navn, '\\', '/', '<', '>', ':' | '?', '\"', '', og '*' er ikke tilladt.", +"Your storage is full, files can not be updated or synced anymore!" => "Din opbevaringsplads er fyldt op, filer kan ikke opdateres eller synkroniseres længere!", +"Your storage is almost full ({usedSpacePercent}%)" => "Din opbevaringsplads er næsten fyldt op ({usedSpacePercent}%)", +"Your download is being prepared. This might take some time if the files are big." => "Dit download forberedes. Dette kan tage lidt tid ved større filer.", "Unable to upload your file as it is a directory or has 0 bytes" => "Kunne ikke uploade din fil, da det enten er en mappe eller er tom", "Upload Error" => "Fejl ved upload", "Close" => "Luk", @@ -30,6 +40,7 @@ "Upload cancelled." => "Upload afbrudt.", "File upload is in progress. Leaving the page now will cancel the upload." => "Fil upload kører. Hvis du forlader siden nu, vil uploadet blive annuleret.", "URL cannot be empty." => "URLen kan ikke være tom.", +"Invalid folder name. Usage of 'Shared' is reserved by Owncloud" => "Ugyldigt mappenavn. Brug af \"Shared\" er forbeholdt Owncloud", "{count} files scanned" => "{count} filer skannet", "error while scanning" => "fejl under scanning", "Name" => "Navn", diff --git a/apps/files/l10n/de.php b/apps/files/l10n/de.php index 84aed12b5c..db2476865f 100644 --- a/apps/files/l10n/de.php +++ b/apps/files/l10n/de.php @@ -10,6 +10,7 @@ "No file was uploaded" => "Es wurde keine Datei hochgeladen.", "Missing a temporary folder" => "Temporärer Ordner fehlt.", "Failed to write to disk" => "Fehler beim Schreiben auf die Festplatte", +"Not enough storage available" => "Nicht genug Speicherplatz verfügbar", "Invalid directory." => "Ungültiges Verzeichnis", "Files" => "Dateien", "Unshare" => "Nicht mehr freigeben", @@ -27,6 +28,8 @@ "'.' is an invalid file name." => "'.' ist kein gültiger Dateiname", "File name cannot be empty." => "Der Dateiname darf nicht leer sein", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ungültiger Name, '\\', '/', '<', '>', ':', '\"', '|', '?' und '*' sind nicht zulässig.", +"Your storage is full, files can not be updated or synced anymore!" => "Ihr Speicherplatz ist voll, Dateien können nicht mehr aktualisiert oder synchronisiert werden!", +"Your storage is almost full ({usedSpacePercent}%)" => "Ihr Speicherplatz ist fast aufgebraucht ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Dein Download wird vorbereitet. Dies kann bei größeren Dateien etwas dauern.", "Unable to upload your file as it is a directory or has 0 bytes" => "Deine Datei kann nicht hochgeladen werden, da sie entweder ein Verzeichnis oder 0 Bytes groß ist.", "Upload Error" => "Fehler beim Upload", diff --git a/apps/files/l10n/fr.php b/apps/files/l10n/fr.php index 6229b7e3a4..ce8ef959d0 100644 --- a/apps/files/l10n/fr.php +++ b/apps/files/l10n/fr.php @@ -10,6 +10,7 @@ "No file was uploaded" => "Aucun fichier n'a été téléversé", "Missing a temporary folder" => "Il manque un répertoire temporaire", "Failed to write to disk" => "Erreur d'écriture sur le disque", +"Not enough storage available" => "Plus assez d'espace de stockage disponible", "Invalid directory." => "Dossier invalide.", "Files" => "Fichiers", "Unshare" => "Ne plus partager", @@ -27,6 +28,8 @@ "'.' is an invalid file name." => "'.' n'est pas un nom de fichier valide.", "File name cannot be empty." => "Le nom de fichier ne peut être vide.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Nom invalide, les caractères '\\', '/', '<', '>', ':', '\"', '|', '?' et '*' ne sont pas autorisés.", +"Your storage is full, files can not be updated or synced anymore!" => "Votre espage de stockage est plein, les fichiers ne peuvent plus être téléversés ou synchronisés !", +"Your storage is almost full ({usedSpacePercent}%)" => "Votre espace de stockage est presque plein ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Votre téléchargement est cours de préparation. Ceci peut nécessiter un certain temps si les fichiers sont volumineux.", "Unable to upload your file as it is a directory or has 0 bytes" => "Impossible de charger vos fichiers car il s'agit d'un dossier ou le fichier fait 0 octet.", "Upload Error" => "Erreur de chargement", diff --git a/apps/files/l10n/ja_JP.php b/apps/files/l10n/ja_JP.php index 5d4bf93e5e..4a36e8aa42 100644 --- a/apps/files/l10n/ja_JP.php +++ b/apps/files/l10n/ja_JP.php @@ -10,6 +10,7 @@ "No file was uploaded" => "ファイルはアップロードされませんでした", "Missing a temporary folder" => "テンポラリフォルダが見つかりません", "Failed to write to disk" => "ディスクへの書き込みに失敗しました", +"Not enough storage available" => "ストレージに十分な空き容量がありません", "Invalid directory." => "無効なディレクトリです。", "Files" => "ファイル", "Unshare" => "共有しない", @@ -27,6 +28,8 @@ "'.' is an invalid file name." => "'.' は無効なファイル名です。", "File name cannot be empty." => "ファイル名を空にすることはできません。", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "無効な名前、'\\', '/', '<', '>', ':', '\"', '|', '?', '*' は使用できません。", +"Your storage is full, files can not be updated or synced anymore!" => "あなたのストレージは一杯です。ファイルの更新と同期はもうできません!", +"Your storage is almost full ({usedSpacePercent}%)" => "あなたのストレージはほぼ一杯です({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "ダウンロードの準備中です。ファイルサイズが大きい場合は少し時間がかかるかもしれません。", "Unable to upload your file as it is a directory or has 0 bytes" => "ディレクトリもしくは0バイトのファイルはアップロードできません", "Upload Error" => "アップロードエラー", diff --git a/apps/files/l10n/sv.php b/apps/files/l10n/sv.php index 5cb8d58e3a..ebcb4626fc 100644 --- a/apps/files/l10n/sv.php +++ b/apps/files/l10n/sv.php @@ -10,6 +10,7 @@ "No file was uploaded" => "Ingen fil blev uppladdad", "Missing a temporary folder" => "Saknar en tillfällig mapp", "Failed to write to disk" => "Misslyckades spara till disk", +"Not enough storage available" => "Inte tillräckligt med lagringsutrymme tillgängligt", "Invalid directory." => "Felaktig mapp.", "Files" => "Filer", "Unshare" => "Sluta dela", @@ -27,6 +28,8 @@ "'.' is an invalid file name." => "'.' är ett ogiltigt filnamn.", "File name cannot be empty." => "Filnamn kan inte vara tomt.", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "Ogiltigt namn, '\\', '/', '<', '>', ':', '\"', '|', '?' och '*' är inte tillåtet.", +"Your storage is full, files can not be updated or synced anymore!" => "Ditt lagringsutrymme är fullt, filer kan ej längre laddas upp eller synkas!", +"Your storage is almost full ({usedSpacePercent}%)" => "Ditt lagringsutrymme är nästan fullt ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "Din nedladdning förbereds. Det kan ta tid om det är stora filer.", "Unable to upload your file as it is a directory or has 0 bytes" => "Kunde inte ladda upp dina filer eftersom det antingen är en mapp eller har 0 bytes.", "Upload Error" => "Uppladdningsfel", diff --git a/apps/files/l10n/th_TH.php b/apps/files/l10n/th_TH.php index de5c7bec83..d7fcd82a9d 100644 --- a/apps/files/l10n/th_TH.php +++ b/apps/files/l10n/th_TH.php @@ -10,6 +10,7 @@ "No file was uploaded" => "ยังไม่มีไฟล์ที่ถูกอัพโหลด", "Missing a temporary folder" => "แฟ้มเอกสารชั่วคราวเกิดการสูญหาย", "Failed to write to disk" => "เขียนข้อมูลลงแผ่นดิสก์ล้มเหลว", +"Not enough storage available" => "เหลือพื้นที่ไม่เพียงสำหรับใช้งาน", "Invalid directory." => "ไดเร็กทอรี่ไม่ถูกต้อง", "Files" => "ไฟล์", "Unshare" => "ยกเลิกการแชร์ข้อมูล", @@ -27,6 +28,8 @@ "'.' is an invalid file name." => "'.' เป็นชื่อไฟล์ที่ไม่ถูกต้อง", "File name cannot be empty." => "ชื่อไฟล์ไม่สามารถเว้นว่างได้", "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed." => "ชื่อที่ใช้ไม่ถูกต้อง, '\\', '/', '<', '>', ':', '\"', '|', '?' และ '*' ไม่ได้รับอนุญาตให้ใช้งานได้", +"Your storage is full, files can not be updated or synced anymore!" => "พื้นที่จัดเก็บข้อมูลของคุณเต็มแล้ว ไม่สามารถอัพเดทหรือผสานไฟล์ต่างๆได้อีกต่อไป", +"Your storage is almost full ({usedSpacePercent}%)" => "พื้นที่จัดเก็บข้อมูลของคุณใกล้เต็มแล้ว ({usedSpacePercent}%)", "Your download is being prepared. This might take some time if the files are big." => "กำลังเตรียมดาวน์โหลดข้อมูล หากไฟล์มีขนาดใหญ่ อาจใช้เวลาสักครู่", "Unable to upload your file as it is a directory or has 0 bytes" => "ไม่สามารถอัพโหลดไฟล์ของคุณได้ เนื่องจากไฟล์ดังกล่าวเป็นไดเร็กทอรี่หรือมีขนาด 0 ไบต์", "Upload Error" => "เกิดข้อผิดพลาดในการอัพโหลด", diff --git a/apps/files_encryption/l10n/da.php b/apps/files_encryption/l10n/da.php index 1b4664ce1c..d65963f46b 100644 --- a/apps/files_encryption/l10n/da.php +++ b/apps/files_encryption/l10n/da.php @@ -1,4 +1,15 @@ "Skift venligst til din ownCloud-klient og skift krypteringskoden for at fuldføre konverteringen.", +"switched to client side encryption" => "skiftet til kryptering på klientsiden", +"Change encryption password to login password" => "Udskift krypteringskode til login-adgangskode", +"Please check your passwords and try again." => "Check adgangskoder og forsøg igen.", +"Could not change your file encryption password to your login password" => "Kunne ikke udskifte krypteringskode med login-adgangskode", +"Choose encryption mode:" => "Vælg krypteringsform:", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Kryptering på klientsiden (mere sikker, men udelukker adgang til dataene fra webinterfacet)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Kryptering på serversiden (gør det muligt at tilgå filer fra webinterfacet såvel som desktopklienten)", +"None (no encryption at all)" => "Ingen (ingen kryptering)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Vigtigt: Når der er valgt krypteringsform, kan det ikke ændres tilbage igen.", +"User specific (let the user decide)" => "Brugerspecifik (lad brugeren bestemme)", "Encryption" => "Kryptering", "Exclude the following file types from encryption" => "Ekskluder følgende filtyper fra kryptering", "None" => "Ingen" diff --git a/apps/files_encryption/l10n/de.php b/apps/files_encryption/l10n/de.php index 34c596dc4b..e187f72ab5 100644 --- a/apps/files_encryption/l10n/de.php +++ b/apps/files_encryption/l10n/de.php @@ -1,4 +1,15 @@ "Bitte wechseln Sie nun zum ownCloud Client und ändern Sie ihr Verschlüsselungspasswort um die Konvertierung abzuschließen.", +"switched to client side encryption" => "Zur Clientseitigen Verschlüsselung gewechselt", +"Change encryption password to login password" => "Ändern des Verschlüsselungspasswortes zum Anmeldepasswort", +"Please check your passwords and try again." => "Bitte überprüfen sie Ihr Passwort und versuchen Sie es erneut.", +"Could not change your file encryption password to your login password" => "Ihr Verschlüsselungspasswort konnte nicht als Anmeldepasswort gesetzt werden.", +"Choose encryption mode:" => "Wählen Sie die Verschlüsselungsart:", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Clientseitige Verschlüsselung (am sichersten, aber macht es unmöglich auf ihre Daten über das Webinterface zuzugreifen)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Serverseitige Verschlüsselung (erlaubt es ihnen auf ihre Daten über das Webinterface und den Desktop-Client zuzugreifen)", +"None (no encryption at all)" => "Keine (ohne Verschlüsselung)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Wichtig: Sobald sie eine Verschlüsselungsmethode gewählt haben, können Sie diese nicht ändern!", +"User specific (let the user decide)" => "Benutzerspezifisch (der Benutzer kann entscheiden)", "Encryption" => "Verschlüsselung", "Exclude the following file types from encryption" => "Die folgenden Dateitypen von der Verschlüsselung ausnehmen", "None" => "Keine" diff --git a/apps/files_encryption/l10n/de_DE.php b/apps/files_encryption/l10n/de_DE.php index 261c52a75f..be4369ebf0 100644 --- a/apps/files_encryption/l10n/de_DE.php +++ b/apps/files_encryption/l10n/de_DE.php @@ -1,6 +1,14 @@ "Wählen Sie die Verschlüsselungsart:", +"Please switch to your ownCloud client and change your encryption password to complete the conversion." => "Bitte wechseln Sie nun zum ownCloud Client und ändern Sie ihr Verschlüsselungspasswort um die Konvertierung abzuschließen.", +"switched to client side encryption" => "Zur Clientseitigen Verschlüsselung gewechselt", +"Change encryption password to login password" => "Ändern des Verschlüsselungspasswortes zum Anmeldepasswort", +"Please check your passwords and try again." => "Bitte überprüfen sie Ihr Passwort und versuchen Sie es erneut.", +"Could not change your file encryption password to your login password" => "Ihr Verschlüsselungspasswort konnte nicht als Anmeldepasswort gesetzt werden.", +"Choose encryption mode:" => "Wählen Sie die Verschlüsselungsmethode:", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Clientseitige Verschlüsselung (am sichersten, aber macht es unmöglich auf ihre Daten über das Webinterface zuzugreifen)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Serverseitige Verschlüsselung (erlaubt es ihnen auf ihre Daten über das Webinterface und den Desktop-Client zuzugreifen)", "None (no encryption at all)" => "Keine (ohne Verschlüsselung)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Wichtig: Sobald sie eine Verschlüsselungsmethode gewählt haben, können Sie diese nicht ändern!", "User specific (let the user decide)" => "Benutzerspezifisch (der Benutzer kann entscheiden)", "Encryption" => "Verschlüsselung", "Exclude the following file types from encryption" => "Die folgenden Dateitypen von der Verschlüsselung ausnehmen", diff --git a/apps/files_encryption/l10n/es.php b/apps/files_encryption/l10n/es.php index 89ccb85297..6a6f5510db 100644 --- a/apps/files_encryption/l10n/es.php +++ b/apps/files_encryption/l10n/es.php @@ -1,5 +1,7 @@ "Por favor, cambie su cliente de ownCloud y cambie su clave de cifrado para completar la conversión.", "switched to client side encryption" => "Cambiar a encriptación en lado cliente", +"Change encryption password to login password" => "Cambie la clave de cifrado para ingresar su contraseña", "Please check your passwords and try again." => "Por favor revise su contraseña e intentelo de nuevo.", "Choose encryption mode:" => "Elegir el modo de encriptado:", "Encryption" => "Cifrado", diff --git a/apps/files_encryption/l10n/eu.php b/apps/files_encryption/l10n/eu.php index 2bb1a46954..e7372937e4 100644 --- a/apps/files_encryption/l10n/eu.php +++ b/apps/files_encryption/l10n/eu.php @@ -1,4 +1,8 @@ "Mesedez egiaztatu zure pasahitza eta saia zaitez berriro:", +"Choose encryption mode:" => "Hautatu enkriptazio modua:", +"None (no encryption at all)" => "Bat ere ez (enkriptaziorik gabe)", +"User specific (let the user decide)" => "Erabiltzaileak zehaztuta (utzi erabiltzaileari hautatzen)", "Encryption" => "Enkriptazioa", "Exclude the following file types from encryption" => "Ez enkriptatu hurrengo fitxategi motak", "None" => "Bat ere ez" diff --git a/apps/files_encryption/l10n/sk_SK.php b/apps/files_encryption/l10n/sk_SK.php index 5aebb6e35b..355b45a4ce 100644 --- a/apps/files_encryption/l10n/sk_SK.php +++ b/apps/files_encryption/l10n/sk_SK.php @@ -1,4 +1,15 @@ "Prosím, prejdite do svojho klienta ownCloud a zmente šifrovacie heslo na dokončenie konverzie.", +"switched to client side encryption" => "prepnuté na šifrovanie prostredníctvom klienta", +"Change encryption password to login password" => "Zmeniť šifrovacie heslo na prihlasovacie", +"Please check your passwords and try again." => "Skontrolujte si heslo a skúste to znovu.", +"Could not change your file encryption password to your login password" => "Nie je možné zmeniť šifrovacie heslo na prihlasovacie", +"Choose encryption mode:" => "Vyberte režim šifrovania:", +"Client side encryption (most secure but makes it impossible to access your data from the web interface)" => "Šifrovanie prostredníctvom klienta (najbezpečnejšia voľba, neumožňuje však prístup k súborom z webového rozhrania)", +"Server side encryption (allows you to access your files from the web interface and the desktop client)" => "Šifrovanie na serveri (umožňuje pristupovať k súborom z webového rozhrania a desktopového klienta)", +"None (no encryption at all)" => "Žiadne (žiadne šifrovanie)", +"Important: Once you selected an encryption mode there is no way to change it back" => "Dôležité: ak si zvolíte režim šifrovania, nie je možné ho znovu zrušiť", +"User specific (let the user decide)" => "Definovaný používateľom (umožňuje používateľovi vybrať si)", "Encryption" => "Šifrovanie", "Exclude the following file types from encryption" => "Vynechať nasledujúce súbory pri šifrovaní", "None" => "Žiadne" diff --git a/apps/user_ldap/l10n/de.php b/apps/user_ldap/l10n/de.php index 89bda8af97..efc8a80f8c 100644 --- a/apps/user_ldap/l10n/de.php +++ b/apps/user_ldap/l10n/de.php @@ -1,8 +1,10 @@ Warning: Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behaviour. Please ask your system administrator to disable one of them." => "Warnung: Die Anwendungen user_ldap und user_webdavauth sind inkompatibel. Es kann demzufolge zu unerwarteten Verhalten kommen. Bitte Deinen Systemadministator eine der beiden Anwendungen zu deaktivieren.", +"Warning: The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "Warnung: Da das PHP-Modul für LDAP ist nicht installiert, das Backend wird nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren.", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Du kannst das Protokoll auslassen, außer wenn Du SSL benötigst. Beginne dann mit ldaps://", "Base DN" => "Basis-DN", +"One Base DN per line" => "Ein Base DN pro Zeile", "You can specify Base DN for users and groups in the Advanced tab" => "Du kannst Basis-DN für Benutzer und Gruppen in dem \"Erweitert\"-Reiter konfigurieren", "User DN" => "Benutzer-DN", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "Der DN des Benutzers für LDAP-Bind, z.B.: uid=agent,dc=example,dc=com. Für anonymen Zugriff lasse DN und Passwort leer.", @@ -19,7 +21,9 @@ "without any placeholder, e.g. \"objectClass=posixGroup\"." => "ohne Platzhalter, z.B.: \"objectClass=posixGroup\"", "Port" => "Port", "Base User Tree" => "Basis-Benutzerbaum", +"One User Base DN per line" => "Ein Benutzer Base DN pro Zeile", "Base Group Tree" => "Basis-Gruppenbaum", +"One Group Base DN per line" => "Ein Gruppen Base DN pro Zeile", "Group-Member association" => "Assoziation zwischen Gruppe und Benutzer", "Use TLS" => "Nutze TLS", "Do not use it for SSL connections, it will fail." => "Verwende dies nicht für SSL-Verbindungen, es wird fehlschlagen.", diff --git a/apps/user_ldap/l10n/de_DE.php b/apps/user_ldap/l10n/de_DE.php index 1e81601838..843609f8b8 100644 --- a/apps/user_ldap/l10n/de_DE.php +++ b/apps/user_ldap/l10n/de_DE.php @@ -1,6 +1,6 @@ Warning: Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behaviour. Please ask your system administrator to disable one of them." => "Warnung: Die Anwendungen user_ldap und user_webdavauth sind inkompatibel. Es kann demzufolge zu unerwarteten Verhalten kommen. Bitten Sie Ihren Systemadministator eine der beiden Anwendungen zu deaktivieren.", -"Warning: The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "Warnung: Da das PHP-Modul für LDAP nicht installiert ist, wird das Backend nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren.", +"Warning: The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "Warnung: Da das PHP-Modul für LDAP ist nicht installiert, das Backend wird nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren.", "Host" => "Host", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Sie können das Protokoll auslassen, außer wenn Sie SSL benötigen. Beginnen Sie dann mit ldaps://", "Base DN" => "Basis-DN", diff --git a/apps/user_ldap/l10n/ru_RU.php b/apps/user_ldap/l10n/ru_RU.php index 64ba1176f6..03d83b80a4 100644 --- a/apps/user_ldap/l10n/ru_RU.php +++ b/apps/user_ldap/l10n/ru_RU.php @@ -1,8 +1,10 @@ Warning: Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behaviour. Please ask your system administrator to disable one of them." => "Предупреждение: Приложения user_ldap и user_webdavauth несовместимы. Вы можете столкнуться с неожиданным поведением системы. Пожалуйста, обратитесь к системному администратору для отключения одного из них.", +"Warning: The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "Предупреждение: Модуль PHP LDAP не установлен, бэкэнд не будет работать. Пожалуйста, обратитесь к Вашему системному администратору, чтобы установить его.", "Host" => "Хост", "You can omit the protocol, except you require SSL. Then start with ldaps://" => "Вы можете пропустить протокол, если Вам не требуется SSL. Затем начните с ldaps://", "Base DN" => "База DN", +"One Base DN per line" => "Одно базовое DN на линию", "You can specify Base DN for users and groups in the Advanced tab" => "Вы можете задать Base DN для пользователей и групп во вкладке «Дополнительно»", "User DN" => "DN пользователя", "The DN of the client user with which the bind shall be done, e.g. uid=agent,dc=example,dc=com. For anonymous access, leave DN and Password empty." => "DN клиентского пользователя, с которого должна осуществляться привязка, например, uid=agent,dc=example,dc=com. Для анонимного доступа оставьте поля DN и Пароль пустыми.", @@ -19,7 +21,9 @@ "without any placeholder, e.g. \"objectClass=posixGroup\"." => "без каких-либо заполнителей, например, \"objectClass=posixGroup\".", "Port" => "Порт", "Base User Tree" => "Базовое дерево пользователей", +"One User Base DN per line" => "Одно пользовательское базовое DN на линию", "Base Group Tree" => "Базовое дерево групп", +"One Group Base DN per line" => "Одно групповое базовое DN на линию", "Group-Member association" => "Связь член-группа", "Use TLS" => "Использовать TLS", "Do not use it for SSL connections, it will fail." => "Не используйте это SSL-соединений, это не будет выполнено.", diff --git a/apps/user_webdavauth/l10n/da.php b/apps/user_webdavauth/l10n/da.php index 245a510134..b268d3e15d 100644 --- a/apps/user_webdavauth/l10n/da.php +++ b/apps/user_webdavauth/l10n/da.php @@ -1,3 +1,5 @@ "URL: http://" +"WebDAV Authentication" => "WebDAV-godkendelse", +"URL: http://" => "URL: http://", +"ownCloud will send the user credentials to this URL. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud vil sende brugerens oplysninger til denne URL. Plugin'et registrerer responsen og fortolker HTTP-statuskoder 401 og 403 som ugyldige oplysninger, men alle andre besvarelser som gyldige oplysninger." ); diff --git a/apps/user_webdavauth/l10n/sk_SK.php b/apps/user_webdavauth/l10n/sk_SK.php index 6e34b818ed..27f84a24f8 100644 --- a/apps/user_webdavauth/l10n/sk_SK.php +++ b/apps/user_webdavauth/l10n/sk_SK.php @@ -1,4 +1,5 @@ "WebDAV overenie", -"URL: http://" => "URL: http://" +"URL: http://" => "URL: http://", +"ownCloud will send the user credentials to this URL. This plugin checks the response and will interpret the HTTP statuscodes 401 and 403 as invalid credentials, and all other responses as valid credentials." => "ownCloud odošle používateľské údajena zadanú URL. Plugin skontroluje odpoveď a považuje návratovou hodnotu HTTP 401 a 403 za neplatné údaje a všetky ostatné hodnoty ako platné prihlasovacie údaje." ); diff --git a/core/l10n/ca.php b/core/l10n/ca.php index 4d643873f1..c737f9aa42 100644 --- a/core/l10n/ca.php +++ b/core/l10n/ca.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Error en establir la data d'expiració", "Sending ..." => "Enviant...", "Email sent" => "El correu electrónic s'ha enviat", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "L'actualització ha estat incorrecte. Comuniqueu aquest error a la comunitat ownCloud.", +"The update was successful. Redirecting you to ownCloud now." => "L'actualització ha estat correcte. Ara sou redireccionat a ownCloud.", "ownCloud password reset" => "estableix de nou la contrasenya Owncloud", "Use the following link to reset your password: {link}" => "Useu l'enllaç següent per restablir la contrasenya: {link}", "You will receive a link to reset your password via Email." => "Rebreu un enllaç al correu electrònic per reiniciar la contrasenya.", diff --git a/core/l10n/cs_CZ.php b/core/l10n/cs_CZ.php index 16d51032e3..848415d6ea 100644 --- a/core/l10n/cs_CZ.php +++ b/core/l10n/cs_CZ.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Chyba při nastavení data vypršení platnosti", "Sending ..." => "Odesílám...", "Email sent" => "E-mail odeslán", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Aktualizace neproběhla úspěšně. Nahlaste prosím problém do evidence chyb ownCloud", +"The update was successful. Redirecting you to ownCloud now." => "Aktualizace byla úspěšná. Přesměrovávám na ownCloud.", "ownCloud password reset" => "Obnovení hesla pro ownCloud", "Use the following link to reset your password: {link}" => "Heslo obnovíte použitím následujícího odkazu: {link}", "You will receive a link to reset your password via Email." => "Bude Vám e-mailem zaslán odkaz pro obnovu hesla.", diff --git a/core/l10n/da.php b/core/l10n/da.php index 12c4c693c8..3252dcf495 100644 --- a/core/l10n/da.php +++ b/core/l10n/da.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Fejl under sætning af udløbsdato", "Sending ..." => "Sender ...", "Email sent" => "E-mail afsendt", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Opdateringen blev ikke udført korrekt. Rapporter venligst problemet til ownClouds community.", +"The update was successful. Redirecting you to ownCloud now." => "Opdateringen blev udført korrekt. Du bliver nu viderestillet til ownCloud.", "ownCloud password reset" => "Nulstil ownCloud kodeord", "Use the following link to reset your password: {link}" => "Anvend følgende link til at nulstille din adgangskode: {link}", "You will receive a link to reset your password via Email." => "Du vil modtage et link til at nulstille dit kodeord via email.", diff --git a/core/l10n/de.php b/core/l10n/de.php index b7ad57cf4c..b67234189f 100644 --- a/core/l10n/de.php +++ b/core/l10n/de.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Fehler beim Setzen des Ablaufdatums", "Sending ..." => "Sende ...", "Email sent" => "E-Mail wurde verschickt", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Das Update ist fehlgeschlagen. Bitte melden Sie dieses Problem an die ownCloud Gemeinschaft.", +"The update was successful. Redirecting you to ownCloud now." => "Das Update war erfolgreich. Sie werden nun zu ownCloud weitergeleitet.", "ownCloud password reset" => "ownCloud-Passwort zurücksetzen", "Use the following link to reset your password: {link}" => "Nutze den nachfolgenden Link, um Dein Passwort zurückzusetzen: {link}", "You will receive a link to reset your password via Email." => "Du erhältst einen Link per E-Mail, um Dein Passwort zurückzusetzen.", diff --git a/core/l10n/de_DE.php b/core/l10n/de_DE.php index 2e9231c151..59b05bbe7c 100644 --- a/core/l10n/de_DE.php +++ b/core/l10n/de_DE.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Fehler beim Setzen des Ablaufdatums", "Sending ..." => "Sende ...", "Email sent" => "Email gesendet", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Das Update ist fehlgeschlagen. Bitte melden Sie dieses Problem an die ownCloud Gemeinschaft.", +"The update was successful. Redirecting you to ownCloud now." => "Das Update war erfolgreich. Sie werden nun zu ownCloud weitergeleitet.", "ownCloud password reset" => "ownCloud-Passwort zurücksetzen", "Use the following link to reset your password: {link}" => "Nutzen Sie den nachfolgenden Link, um Ihr Passwort zurückzusetzen: {link}", "You will receive a link to reset your password via Email." => "Sie erhalten einen Link per E-Mail, um Ihr Passwort zurückzusetzen.", diff --git a/core/l10n/eu.php b/core/l10n/eu.php index 2bdb8f72b4..da6aad7338 100644 --- a/core/l10n/eu.php +++ b/core/l10n/eu.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Errore bat egon da muga data ezartzean", "Sending ..." => "Bidaltzen ...", "Email sent" => "Eposta bidalia", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Eguneraketa ez da ongi egin. Mesedez egin arazoaren txosten bat ownCloud komunitatearentzako.", +"The update was successful. Redirecting you to ownCloud now." => "Eguneraketa ongi egin da. Orain zure ownClouderea berbideratua izango zara.", "ownCloud password reset" => "ownCloud-en pasahitza berrezarri", "Use the following link to reset your password: {link}" => "Eribili hurrengo lotura zure pasahitza berrezartzeko: {link}", "You will receive a link to reset your password via Email." => "Zure pashitza berrezartzeko lotura bat jasoko duzu Epostaren bidez.", diff --git a/core/l10n/fr.php b/core/l10n/fr.php index e15f69f576..46aac990bd 100644 --- a/core/l10n/fr.php +++ b/core/l10n/fr.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Erreur lors de la spécification de la date d'expiration", "Sending ..." => "En cours d'envoi ...", "Email sent" => "Email envoyé", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "La mise à jour a échoué. Veuillez signaler ce problème à la communauté ownCloud.", +"The update was successful. Redirecting you to ownCloud now." => "La mise à jour a réussi. Vous êtes redirigé maintenant vers ownCloud.", "ownCloud password reset" => "Réinitialisation de votre mot de passe Owncloud", "Use the following link to reset your password: {link}" => "Utilisez le lien suivant pour réinitialiser votre mot de passe : {link}", "You will receive a link to reset your password via Email." => "Vous allez recevoir un e-mail contenant un lien pour réinitialiser votre mot de passe.", diff --git a/core/l10n/it.php b/core/l10n/it.php index 00fbe6a3ed..88749320d5 100644 --- a/core/l10n/it.php +++ b/core/l10n/it.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Errore durante l'impostazione della data di scadenza", "Sending ..." => "Invio in corso...", "Email sent" => "Messaggio inviato", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "L'aggiornamento non è riuscito. Segnala il problema alla comunità di ownCloud.", +"The update was successful. Redirecting you to ownCloud now." => "L'aggiornamento è stato effettuato correttamente. Stai per essere reindirizzato a ownCloud.", "ownCloud password reset" => "Ripristino password di ownCloud", "Use the following link to reset your password: {link}" => "Usa il collegamento seguente per ripristinare la password: {link}", "You will receive a link to reset your password via Email." => "Riceverai un collegamento per ripristinare la tua password via email", diff --git a/core/l10n/ja_JP.php b/core/l10n/ja_JP.php index 7a867834ed..7995147f06 100644 --- a/core/l10n/ja_JP.php +++ b/core/l10n/ja_JP.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "有効期限の設定でエラー発生", "Sending ..." => "送信中...", "Email sent" => "メールを送信しました", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "更新に成功しました。この問題を ownCloud community にレポートしてください。", +"The update was successful. Redirecting you to ownCloud now." => "更新に成功しました。今すぐownCloudにリダイレクトします。", "ownCloud password reset" => "ownCloudのパスワードをリセットします", "Use the following link to reset your password: {link}" => "パスワードをリセットするには次のリンクをクリックして下さい: {link}", "You will receive a link to reset your password via Email." => "メールでパスワードをリセットするリンクが届きます。", diff --git a/core/l10n/pt_PT.php b/core/l10n/pt_PT.php index bfa1c098d1..4f60bf2694 100644 --- a/core/l10n/pt_PT.php +++ b/core/l10n/pt_PT.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Erro ao aplicar a data de expiração", "Sending ..." => "A Enviar...", "Email sent" => "E-mail enviado", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "A actualização falhou. Por favor reporte este incidente seguindo este link ownCloud community.", +"The update was successful. Redirecting you to ownCloud now." => "A actualização foi concluída com sucesso. Vai ser redireccionado para o ownCloud agora.", "ownCloud password reset" => "Reposição da password ownCloud", "Use the following link to reset your password: {link}" => "Use o seguinte endereço para repor a sua password: {link}", "You will receive a link to reset your password via Email." => "Vai receber um endereço para repor a sua password", diff --git a/core/l10n/ru_RU.php b/core/l10n/ru_RU.php index 4ede334828..c706d1c6a1 100644 --- a/core/l10n/ru_RU.php +++ b/core/l10n/ru_RU.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Ошибка при установке даты истечения срока действия", "Sending ..." => "Отправка ...", "Email sent" => "Письмо отправлено", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Обновление прошло неудачно. Пожалуйста, сообщите об этом результате в ownCloud community.", +"The update was successful. Redirecting you to ownCloud now." => "Обновление прошло успешно. Немедленное перенаправление Вас на ownCloud.", "ownCloud password reset" => "Переназначение пароля", "Use the following link to reset your password: {link}" => "Воспользуйтесь следующей ссылкой для переназначения пароля: {link}", "You will receive a link to reset your password via Email." => "Вы получите ссылку для восстановления пароля по электронной почте.", @@ -126,5 +128,6 @@ "remember" => "запомнить", "Log in" => "Войти", "prev" => "предыдущий", -"next" => "следующий" +"next" => "следующий", +"Updating ownCloud to version %s, this may take a while." => "Обновление ownCloud до версии %s, это может занять некоторое время." ); diff --git a/core/l10n/sk_SK.php b/core/l10n/sk_SK.php index 6e373137e4..ba488532f5 100644 --- a/core/l10n/sk_SK.php +++ b/core/l10n/sk_SK.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Chyba pri nastavení dátumu vypršania platnosti", "Sending ..." => "Odosielam ...", "Email sent" => "Email odoslaný", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Aktualizácia nebola úspešná. Problém nahláste na ownCloud community.", +"The update was successful. Redirecting you to ownCloud now." => "Aktualizácia bola úspešná. Presmerovávam na ownCloud.", "ownCloud password reset" => "Obnovenie hesla pre ownCloud", "Use the following link to reset your password: {link}" => "Použite nasledujúci odkaz pre obnovenie vášho hesla: {link}", "You will receive a link to reset your password via Email." => "Odkaz pre obnovenie hesla obdržíte e-mailom.", diff --git a/core/l10n/sv.php b/core/l10n/sv.php index 406d51790b..1e461282c0 100644 --- a/core/l10n/sv.php +++ b/core/l10n/sv.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "Fel vid sättning av utgångsdatum", "Sending ..." => "Skickar ...", "Email sent" => "E-post skickat", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Uppdateringen misslyckades. Rapportera detta problem till ownCloud-gemenskapen.", +"The update was successful. Redirecting you to ownCloud now." => "Uppdateringen lyckades. Du omdirigeras nu till OwnCloud", "ownCloud password reset" => "ownCloud lösenordsåterställning", "Use the following link to reset your password: {link}" => "Använd följande länk för att återställa lösenordet: {link}", "You will receive a link to reset your password via Email." => "Du får en länk att återställa ditt lösenord via e-post.", diff --git a/core/l10n/th_TH.php b/core/l10n/th_TH.php index 4a17eb3b49..9b491d24ea 100644 --- a/core/l10n/th_TH.php +++ b/core/l10n/th_TH.php @@ -82,6 +82,8 @@ "Error setting expiration date" => "เกิดข้อผิดพลาดในการตั้งค่าวันที่หมดอายุ", "Sending ..." => "กำลังส่ง...", "Email sent" => "ส่งอีเมล์แล้ว", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "การอัพเดทไม่เป็นผลสำเร็จ กรุณาแจ้งปัญหาที่เกิดขึ้นไปยัง คอมมูนิตี้ผู้ใช้งาน ownCloud", +"The update was successful. Redirecting you to ownCloud now." => "การอัพเดทเสร็จเรียบร้อยแล้ว กำลังเปลี่ยนเส้นทางไปที่ ownCloud อยู่ในขณะนี้", "ownCloud password reset" => "รีเซ็ตรหัสผ่าน ownCloud", "Use the following link to reset your password: {link}" => "ใช้ลิงค์ต่อไปนี้เพื่อเปลี่ยนรหัสผ่านของคุณใหม่: {link}", "You will receive a link to reset your password via Email." => "คุณจะได้รับลิงค์เพื่อกำหนดรหัสผ่านใหม่ทางอีเมล์", diff --git a/core/l10n/vi.php b/core/l10n/vi.php index 178ac92d5a..1d538e99db 100644 --- a/core/l10n/vi.php +++ b/core/l10n/vi.php @@ -1,4 +1,8 @@ "%s chia sẻ tập tin này cho bạn", +"User %s shared a folder with you" => "%s chia sẻ thư mục này cho bạn", +"User %s shared the file \"%s\" with you. It is available for download here: %s" => "Người dùng %s chia sẻ tập tin \"%s\" cho bạn .Bạn có thể tải tại đây : %s", +"User %s shared the folder \"%s\" with you. It is available for download here: %s" => "Người dùng %s chia sẻ thư mục \"%s\" cho bạn .Bạn có thể tải tại đây : %s", "Category type not provided." => "Kiểu hạng mục không được cung cấp.", "No category to add?" => "Không có danh mục được thêm?", "This category already exists: " => "Danh mục này đã được tạo :", @@ -58,6 +62,7 @@ "Share with link" => "Chia sẻ với liên kết", "Password protect" => "Mật khẩu bảo vệ", "Password" => "Mật khẩu", +"Send" => "Gởi", "Set expiration date" => "Đặt ngày kết thúc", "Expiration date" => "Ngày kết thúc", "Share via email:" => "Chia sẻ thông qua email", @@ -74,6 +79,9 @@ "Password protected" => "Mật khẩu bảo vệ", "Error unsetting expiration date" => "Lỗi không thiết lập ngày kết thúc", "Error setting expiration date" => "Lỗi cấu hình ngày kết thúc", +"Sending ..." => "Đang gởi ...", +"The update was unsuccessful. Please report this issue to the ownCloud community." => "Cập nhật không thành công . Vui lòng thông báo đến Cộng đồng ownCloud .", +"The update was successful. Redirecting you to ownCloud now." => "Cập nhật thành công .Hệ thống sẽ đưa bạn tới ownCloud.", "ownCloud password reset" => "Khôi phục mật khẩu Owncloud ", "Use the following link to reset your password: {link}" => "Dùng đường dẫn sau để khôi phục lại mật khẩu : {link}", "You will receive a link to reset your password via Email." => "Vui lòng kiểm tra Email để khôi phục lại mật khẩu.", diff --git a/l10n/ar/core.po b/l10n/ar/core.po index f4bc70a8a7..0ce541f850 100644 --- a/l10n/ar/core.po +++ b/l10n/ar/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Arabic (http://www.transifex.com/projects/p/owncloud/language/ar/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "خطأ" @@ -252,119 +252,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "حصل خطأ عند عملية المشاركة" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "حصل خطأ عند عملية إزالة المشاركة" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "حصل خطأ عند عملية إعادة تعيين التصريح بالتوصل" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "شورك معك ومع المجموعة {group} من قبل {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "شورك معك من قبل {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "شارك مع" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "شارك مع رابط" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "حماية كلمة السر" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "كلمة السر" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "تعيين تاريخ إنتهاء الصلاحية" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "تاريخ إنتهاء الصلاحية" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "مشاركة عبر البريد الإلكتروني:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "لم يتم العثور على أي شخص" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "لا يسمح بعملية إعادة المشاركة" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "شورك في {item} مع {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "إلغاء مشاركة" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "التحرير مسموح" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "ضبط الوصول" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "إنشاء" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "تحديث" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "حذف" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "مشاركة" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "محمي بكلمة السر" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "حصل خطأ عند عملية إزالة تاريخ إنتهاء الصلاحية" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "حصل خطأ عند عملية تعيين تاريخ إنتهاء الصلاحية" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/ar/settings.po b/l10n/ar/settings.po index 1da68062ef..a2178a82e0 100644 --- a/l10n/ar/settings.po +++ b/l10n/ar/settings.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Arabic (http://www.transifex.com/projects/p/owncloud/language/ar/)\n" "MIME-Version: 1.0\n" @@ -90,7 +90,7 @@ msgstr "تفعيل" msgid "Saving..." msgstr "حفظ" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -102,15 +102,15 @@ msgstr "أضف تطبيقاتك" msgid "More Apps" msgstr "المزيد من التطبيقات" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "إختر تطبيقاً" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "راجع صفحة التطبيق على apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-ترخيص من قبل " @@ -159,7 +159,7 @@ msgstr "تحميل عميل آندرويد" msgid "Download iOS Client" msgstr "تحميل عميل آي أو أس" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "كلمات السر" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "طوّر من قبل ownCloud مجتمع, الـ النص المصدري مرخص بموجب رخصة أفيرو العمومية." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "الاسم" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "مجموعات" @@ -245,26 +245,30 @@ msgstr "انشئ" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "شيء آخر" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "مدير المجموعة" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "حذف" diff --git a/l10n/bg_BG/core.po b/l10n/bg_BG/core.po index 89887ec847..1e66831c05 100644 --- a/l10n/bg_BG/core.po +++ b/l10n/bg_BG/core.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Bulgarian (Bulgaria) (http://www.transifex.com/projects/p/owncloud/language/bg_BG/)\n" "MIME-Version: 1.0\n" @@ -21,24 +21,24 @@ msgstr "" "Language: bg_BG\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -241,8 +241,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Грешка" @@ -254,119 +254,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Парола" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/bg_BG/settings.po b/l10n/bg_BG/settings.po index 4275c1ee1b..71667fa12a 100644 --- a/l10n/bg_BG/settings.po +++ b/l10n/bg_BG/settings.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 18:49+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Bulgarian (Bulgaria) (http://www.transifex.com/projects/p/owncloud/language/bg_BG/)\n" "MIME-Version: 1.0\n" @@ -90,7 +90,7 @@ msgstr "Включено" msgid "Saving..." msgstr "" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "" @@ -102,15 +102,15 @@ msgstr "" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -159,7 +159,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Парола" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Име" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Групи" @@ -245,26 +245,30 @@ msgstr "" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Изтриване" diff --git a/l10n/bn_BD/core.po b/l10n/bn_BD/core.po index b2c45cf075..dcaa8094dc 100644 --- a/l10n/bn_BD/core.po +++ b/l10n/bn_BD/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Bengali (Bangladesh) (http://www.transifex.com/projects/p/owncloud/language/bn_BD/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: bn_BD\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "%s নামের ব্যবহারকারি আপনার সাথে একটা ফাইল ভাগাভাগি করেছেন" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "%s নামের ব্যবহারকারি আপনার সাথে একটা ফোল্ডার ভাগাভাগি করেছেন" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "%s নামের ব্যবহারকারী \"%s\" ফাইলটি আপনার সাথে ভাগাভাগি করেছেন। এটি এখন এখানে ডাউনলোড করার জন্য সুলভঃ %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "অবজেক্টের ধরণটি সুনির্দিষ্ট নয়।" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "সমস্যা" @@ -251,119 +251,127 @@ msgstr "অ্যাপের নামটি সুনির্দিষ্ট msgid "The required file {file} is not installed!" msgstr "আবশ্যিক {file} টি সংস্থাপিত নেই !" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "ভাগাভাগি করতে সমস্যা দেখা দিয়েছে " -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "ভাগাভাগি বাতিল করতে সমস্যা দেখা দিয়েছে" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "অনুমতিসমূহ পরিবর্তন করতে সমস্যা দেখা দিয়েছে" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "{owner} আপনার এবং {group} গোষ্ঠীর সাথে ভাগাভাগি করেছেন" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner} আপনার সাথে ভাগাভাগি করেছেন" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "যাদের সাথে ভাগাভাগি করা হয়েছে" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "লিংকের সাথে ভাগাভাগি কর" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "কূটশব্দ সুরক্ষিত" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "কূটশব্দ" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "ব্যক্তির সাথে ই-মেইল যুক্ত কর" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "পাঠাও" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "মেয়াদোত্তীর্ণ হওয়ার তারিখ নির্ধারণ করুন" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "মেয়াদোত্তীর্ণ হওয়ার তারিখ" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "ই-মেইলের মাধ্যমে ভাগাভাগি করুনঃ" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "কোন ব্যক্তি খুঁজে পাওয়া গেল না" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "পূনঃরায় ভাগাভাগি অনুমোদিত নয়" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "{user} এর সাথে {item} ভাগাভাগি করা হয়েছে" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "ভাগাভাগি বাতিল কর" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "সম্পাদনা করতে পারবেন" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "অধিগম্যতা নিয়ন্ত্রণ" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "তৈরী করুন" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "পরিবর্ধন কর" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "মুছে ফেল" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "ভাগাভাগি কর" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "কূটশব্দদ্বারা সুরক্ষিত" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "মেয়াদোত্তীর্ণ হওয়ার তারিখ নির্ধারণ বাতিল করতে সমস্যা দেখা দিয়েছে" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "মেয়াদোত্তীর্ণ হওয়ার তারিখ নির্ধারণ করতে সমস্যা দেখা দিয়েছে" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "পাঠানো হচ্ছে......" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "ই-মেইল পাঠানো হয়েছে" diff --git a/l10n/bn_BD/settings.po b/l10n/bn_BD/settings.po index 34c75b953e..681984d8be 100644 --- a/l10n/bn_BD/settings.po +++ b/l10n/bn_BD/settings.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Bengali (Bangladesh) (http://www.transifex.com/projects/p/owncloud/language/bn_BD/)\n" "MIME-Version: 1.0\n" @@ -88,7 +88,7 @@ msgstr "সক্রিয় " msgid "Saving..." msgstr "সংরক্ষণ করা হচ্ছে.." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -100,15 +100,15 @@ msgstr "আপনার অ্যাপটি যোগ করুন" msgid "More Apps" msgstr "আরও অ্যাপ" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "অ্যাপ নির্বাচন করুন" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "apps.owncloud.com এ অ্যাপ্লিকেসন পৃষ্ঠা দেখুন" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-লাইসেন্সধারী " @@ -157,7 +157,7 @@ msgstr "অ্যান্ড্রয়েড ক্লায়েন্ট ডা msgid "Download iOS Client" msgstr "iOS ক্লায়েন্ট ডাউনলোড করুন" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "কূটশব্দ" @@ -227,11 +227,11 @@ msgid "" "License\">AGPL." msgstr "তৈলী করেছেন ownCloud সম্প্রদায়, যার উৎস কোডটি AGPL এর অধীনে লাইসেন্সকৃত।" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "রাম" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "গোষ্ঠীসমূহ" @@ -243,26 +243,30 @@ msgstr "তৈরী কর" msgid "Default Storage" msgstr "পূর্বনির্ধারিত সংরক্ষণাগার" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "অসীম" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "অন্যান্য" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "গোষ্ঠী প্রশাসক" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "সংরক্ষণাগার" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "পূর্বনির্ধারিত" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "মুছে ফেল" diff --git a/l10n/ca/core.po b/l10n/ca/core.po index ef804fffc5..3fe5703a2f 100644 --- a/l10n/ca/core.po +++ b/l10n/ca/core.po @@ -4,13 +4,14 @@ # # Translators: # , 2012. +# , 2013. # , 2011-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Catalan (http://www.transifex.com/projects/p/owncloud/language/ca/)\n" "MIME-Version: 1.0\n" @@ -19,24 +20,24 @@ msgstr "" "Language: ca\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "L'usuari %s ha compartit un fitxer amb vós" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "L'usuari %s ha compartit una carpeta amb vós" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "L'usuari %s ha compartit el fitxer \"%s\" amb vós. Està disponible per a la descàrrega a: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +240,8 @@ msgid "The object type is not specified." msgstr "No s'ha especificat el tipus d'objecte." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Error" @@ -252,119 +253,127 @@ msgstr "No s'ha especificat el nom de l'aplicació." msgid "The required file {file} is not installed!" msgstr "El fitxer requerit {file} no està instal·lat!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Error en compartir" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Error en deixar de compartir" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Error en canviar els permisos" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Compartit amb vos i amb el grup {group} per {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Compartit amb vos per {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Comparteix amb" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Comparteix amb enllaç" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Protegir amb contrasenya" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Contrasenya" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Enllaç per correu electrónic amb la persona" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Envia" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Estableix la data d'expiració" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Data d'expiració" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Comparteix per correu electrònic" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "No s'ha trobat ningú" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "No es permet compartir de nou" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Compartit en {item} amb {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Deixa de compartir" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "pot editar" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "control d'accés" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "crea" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "actualitza" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "elimina" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "comparteix" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protegeix amb contrasenya" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Error en eliminar la data d'expiració" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Error en establir la data d'expiració" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Enviant..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "El correu electrónic s'ha enviat" @@ -373,11 +382,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "L'actualització ha estat incorrecte. Comuniqueu aquest error a la comunitat ownCloud." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "L'actualització ha estat correcte. Ara sou redireccionat a ownCloud." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/ca/settings.po b/l10n/ca/settings.po index 4d6dc88360..1efd6df00e 100644 --- a/l10n/ca/settings.po +++ b/l10n/ca/settings.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Catalan (http://www.transifex.com/projects/p/owncloud/language/ca/)\n" "MIME-Version: 1.0\n" @@ -92,7 +92,7 @@ msgstr "Activa" msgid "Saving..." msgstr "S'està desant..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Català" @@ -104,15 +104,15 @@ msgstr "Afegiu la vostra aplicació" msgid "More Apps" msgstr "Més aplicacions" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Seleccioneu una aplicació" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Mireu la pàgina d'aplicacions a apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-propietat de " @@ -161,7 +161,7 @@ msgstr " Baixa el client per Android" msgid "Download iOS Client" msgstr "Baixa el client per iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Contrasenya" @@ -231,11 +231,11 @@ msgid "" "License\">AGPL." msgstr "Desenvolupat per la comunitat ownCloud, el codi font té llicència AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nom" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grups" @@ -247,26 +247,30 @@ msgstr "Crea" msgid "Default Storage" msgstr "Emmagatzemament per defecte" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Il·limitat" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Un altre" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grup Admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Emmagatzemament" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Per defecte" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Suprimeix" diff --git a/l10n/cs_CZ/core.po b/l10n/cs_CZ/core.po index e82615b933..c65ccce2da 100644 --- a/l10n/cs_CZ/core.po +++ b/l10n/cs_CZ/core.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/owncloud/language/cs_CZ/)\n" "MIME-Version: 1.0\n" @@ -21,24 +21,24 @@ msgstr "" "Language: cs_CZ\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Uživatel %s s vámi sdílí soubor" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Uživatel %s s vámi sdílí složku" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Uživatel %s s vámi sdílí soubor \"%s\". Můžete jej stáhnout zde: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -241,8 +241,8 @@ msgid "The object type is not specified." msgstr "Není určen typ objektu." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Chyba" @@ -254,119 +254,127 @@ msgstr "Není určen název aplikace." msgid "The required file {file} is not installed!" msgstr "Požadovaný soubor {file} není nainstalován." -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Chyba při sdílení" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Chyba při rušení sdílení" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Chyba při změně oprávnění" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "S Vámi a skupinou {group} sdílí {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "S Vámi sdílí {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Sdílet s" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Sdílet s odkazem" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Chránit heslem" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Heslo" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Odeslat osobě odkaz e-mailem" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Odeslat" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Nastavit datum vypršení platnosti" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Datum vypršení platnosti" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Sdílet e-mailem:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Žádní lidé nenalezeni" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Sdílení již sdílené položky není povoleno" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Sdíleno v {item} s {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Zrušit sdílení" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "lze upravovat" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "řízení přístupu" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "vytvořit" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "aktualizovat" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "smazat" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "sdílet" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Chráněno heslem" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Chyba při odstraňování data vypršení platnosti" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Chyba při nastavení data vypršení platnosti" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Odesílám..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "E-mail odeslán" @@ -375,11 +383,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Aktualizace neproběhla úspěšně. Nahlaste prosím problém do evidence chyb ownCloud" #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Aktualizace byla úspěšná. Přesměrovávám na ownCloud." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/cs_CZ/settings.po b/l10n/cs_CZ/settings.po index 46a8fc5c51..4157e0094b 100644 --- a/l10n/cs_CZ/settings.po +++ b/l10n/cs_CZ/settings.po @@ -13,8 +13,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Czech (Czech Republic) (http://www.transifex.com/projects/p/owncloud/language/cs_CZ/)\n" "MIME-Version: 1.0\n" @@ -93,7 +93,7 @@ msgstr "Povolit" msgid "Saving..." msgstr "Ukládám..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Česky" @@ -105,15 +105,15 @@ msgstr "Přidat Vaší aplikaci" msgid "More Apps" msgstr "Více aplikací" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Vyberte aplikaci" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Více na stránce s aplikacemi na apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licencováno " @@ -162,7 +162,7 @@ msgstr "Stáhnout klienta pro android" msgid "Download iOS Client" msgstr "Stáhnout klienta pro iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Heslo" @@ -232,11 +232,11 @@ msgid "" "License\">AGPL." msgstr "Vyvinuto komunitou ownCloud, zdrojový kód je licencován pod AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Jméno" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Skupiny" @@ -248,26 +248,30 @@ msgstr "Vytvořit" msgid "Default Storage" msgstr "Výchozí úložiště" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Neomezeně" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Jiná" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Správa skupiny" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Úložiště" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Výchozí" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Smazat" diff --git a/l10n/da/core.po b/l10n/da/core.po index 81b3396d92..4f1fdd3523 100644 --- a/l10n/da/core.po +++ b/l10n/da/core.po @@ -5,7 +5,7 @@ # Translators: # , 2012. # , 2011, 2012. -# Morten Juhl-Johansen Zölde-Fejér , 2011-2012. +# Morten Juhl-Johansen Zölde-Fejér , 2011-2013. # Ole Holm Frandsen , 2012. # Pascal d'Hermilly , 2011. # Rasmus Paasch , 2013. @@ -16,8 +16,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Danish (http://www.transifex.com/projects/p/owncloud/language/da/)\n" "MIME-Version: 1.0\n" @@ -26,24 +26,24 @@ msgstr "" "Language: da\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Bruger %s delte en fil med dig" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Bruger %s delte en mappe med dig" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Bruger %s delte filen \"%s\" med dig. Den kan hentes her: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -246,8 +246,8 @@ msgid "The object type is not specified." msgstr "Objekttypen er ikke angivet." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Fejl" @@ -259,119 +259,127 @@ msgstr "Den app navn er ikke angivet." msgid "The required file {file} is not installed!" msgstr "Den krævede fil {file} er ikke installeret!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Fejl under deling" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Fejl under annullering af deling" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Fejl under justering af rettigheder" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Delt med dig og gruppen {group} af {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Delt med dig af {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Del med" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Del med link" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Beskyt med adgangskode" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Kodeord" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "E-mail link til person" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Send" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Vælg udløbsdato" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Udløbsdato" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Del via email:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Ingen personer fundet" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Videredeling ikke tilladt" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Delt i {item} med {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Fjern deling" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "kan redigere" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "Adgangskontrol" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "opret" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "opdater" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "slet" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "del" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Beskyttet med adgangskode" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Fejl ved fjernelse af udløbsdato" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Fejl under sætning af udløbsdato" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Sender ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "E-mail afsendt" @@ -380,11 +388,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Opdateringen blev ikke udført korrekt. Rapporter venligst problemet til ownClouds community." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Opdateringen blev udført korrekt. Du bliver nu viderestillet til ownCloud." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/da/files.po b/l10n/da/files.po index 1181986247..2654e4e323 100644 --- a/l10n/da/files.po +++ b/l10n/da/files.po @@ -4,7 +4,7 @@ # # Translators: # , 2012. -# Morten Juhl-Johansen Zölde-Fejér , 2011-2012. +# Morten Juhl-Johansen Zölde-Fejér , 2011-2013. # Ole Holm Frandsen , 2012. # , 2012. # Pascal d'Hermilly , 2011. @@ -15,9 +15,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 11:55+0000\n" +"Last-Translator: Morten Juhl-Johansen Zölde-Fejér \n" "Language-Team: Danish (http://www.transifex.com/projects/p/owncloud/language/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -28,16 +28,16 @@ msgstr "" #: ajax/move.php:17 #, php-format msgid "Could not move %s - File with this name already exists" -msgstr "" +msgstr "Kunne ikke flytte %s - der findes allerede en fil med dette navn" #: ajax/move.php:24 #, php-format msgid "Could not move %s" -msgstr "" +msgstr "Kunne ikke flytte %s" #: ajax/rename.php:19 msgid "Unable to rename file" -msgstr "" +msgstr "Kunne ikke omdøbe fil" #: ajax/upload.php:17 msgid "No file was uploaded. Unknown error" @@ -76,11 +76,11 @@ msgstr "Fejl ved skrivning til disk." #: ajax/upload.php:48 msgid "Not enough storage available" -msgstr "" +msgstr "Der er ikke nok plads til rådlighed" #: ajax/upload.php:77 msgid "Invalid directory." -msgstr "" +msgstr "Ugyldig mappe." #: appinfo/app.php:10 msgid "Files" @@ -136,11 +136,11 @@ msgstr "slettede {files}" #: js/files.js:52 msgid "'.' is an invalid file name." -msgstr "" +msgstr "'.' er et ugyldigt filnavn." #: js/files.js:56 msgid "File name cannot be empty." -msgstr "" +msgstr "Filnavnet kan ikke stå tomt." #: js/files.js:64 msgid "" @@ -150,17 +150,17 @@ msgstr "Ugyldigt navn, '\\', '/', '<', '>', ':' | '?', '\"', '', og '*' er ikke #: js/files.js:78 msgid "Your storage is full, files can not be updated or synced anymore!" -msgstr "" +msgstr "Din opbevaringsplads er fyldt op, filer kan ikke opdateres eller synkroniseres længere!" #: js/files.js:82 msgid "Your storage is almost full ({usedSpacePercent}%)" -msgstr "" +msgstr "Din opbevaringsplads er næsten fyldt op ({usedSpacePercent}%)" #: js/files.js:219 msgid "" "Your download is being prepared. This might take some time if the files are " "big." -msgstr "" +msgstr "Dit download forberedes. Dette kan tage lidt tid ved større filer." #: js/files.js:256 msgid "Unable to upload your file as it is a directory or has 0 bytes" @@ -201,7 +201,7 @@ msgstr "URLen kan ikke være tom." #: js/files.js:571 msgid "Invalid folder name. Usage of 'Shared' is reserved by Owncloud" -msgstr "" +msgstr "Ugyldigt mappenavn. Brug af \"Shared\" er forbeholdt Owncloud" #: js/files.js:784 msgid "{count} files scanned" diff --git a/l10n/da/files_encryption.po b/l10n/da/files_encryption.po index 14b94d9d7a..78a06bdcab 100644 --- a/l10n/da/files_encryption.po +++ b/l10n/da/files_encryption.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Morten Juhl-Johansen Zölde-Fejér , 2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 12:03+0000\n" +"Last-Translator: Morten Juhl-Johansen Zölde-Fejér \n" "Language-Team: Danish (http://www.transifex.com/projects/p/owncloud/language/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,53 +23,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Skift venligst til din ownCloud-klient og skift krypteringskoden for at fuldføre konverteringen." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "skiftet til kryptering på klientsiden" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Udskift krypteringskode til login-adgangskode" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Check adgangskoder og forsøg igen." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Kunne ikke udskifte krypteringskode med login-adgangskode" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Vælg krypteringsform:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Kryptering på klientsiden (mere sikker, men udelukker adgang til dataene fra webinterfacet)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Kryptering på serversiden (gør det muligt at tilgå filer fra webinterfacet såvel som desktopklienten)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Ingen (ingen kryptering)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Vigtigt: Når der er valgt krypteringsform, kan det ikke ændres tilbage igen." #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Brugerspecifik (lad brugeren bestemme)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/da/lib.po b/l10n/da/lib.po index c1bdc6f0b9..5596da61c3 100644 --- a/l10n/da/lib.po +++ b/l10n/da/lib.po @@ -4,15 +4,15 @@ # # Translators: # , 2012. -# Morten Juhl-Johansen Zölde-Fejér , 2012. +# Morten Juhl-Johansen Zölde-Fejér , 2012-2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 11:52+0000\n" +"Last-Translator: Morten Juhl-Johansen Zölde-Fejér \n" "Language-Team: Danish (http://www.transifex.com/projects/p/owncloud/language/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -60,9 +60,9 @@ msgstr "Tilbage til Filer" msgid "Selected files too large to generate zip file." msgstr "De markerede filer er for store til at generere en ZIP-fil." -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "kunne ikke fastslås" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/da/settings.po b/l10n/da/settings.po index 314d85e230..6df46a3c46 100644 --- a/l10n/da/settings.po +++ b/l10n/da/settings.po @@ -17,8 +17,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Danish (http://www.transifex.com/projects/p/owncloud/language/da/)\n" "MIME-Version: 1.0\n" @@ -97,7 +97,7 @@ msgstr "Aktiver" msgid "Saving..." msgstr "Gemmer..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Dansk" @@ -109,15 +109,15 @@ msgstr "Tilføj din App" msgid "More Apps" msgstr "Flere Apps" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Vælg en App" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Se applikationens side på apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licenseret af " @@ -166,7 +166,7 @@ msgstr "Hent Android Klient" msgid "Download iOS Client" msgstr "Hent iOS Klient" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Kodeord" @@ -236,11 +236,11 @@ msgid "" "License\">AGPL." msgstr "Udviklet af ownClouds community, og kildekoden er underlagt licensen AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Navn" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupper" @@ -252,26 +252,30 @@ msgstr "Ny" msgid "Default Storage" msgstr "Standard opbevaring" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Ubegrænset" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Andet" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Gruppe Administrator" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Opbevaring" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Standard" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Slet" diff --git a/l10n/da/user_webdavauth.po b/l10n/da/user_webdavauth.po index 16782a7f12..32a2a3729a 100644 --- a/l10n/da/user_webdavauth.po +++ b/l10n/da/user_webdavauth.po @@ -4,13 +4,14 @@ # # Translators: # , 2012. +# Morten Juhl-Johansen Zölde-Fejér , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 23:04+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 12:07+0000\n" +"Last-Translator: Morten Juhl-Johansen Zölde-Fejér \n" "Language-Team: Danish (http://www.transifex.com/projects/p/owncloud/language/da/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,7 +21,7 @@ msgstr "" #: templates/settings.php:3 msgid "WebDAV Authentication" -msgstr "" +msgstr "WebDAV-godkendelse" #: templates/settings.php:4 msgid "URL: http://" @@ -31,4 +32,4 @@ msgid "" "ownCloud will send the user credentials to this URL. This plugin checks the " "response and will interpret the HTTP statuscodes 401 and 403 as invalid " "credentials, and all other responses as valid credentials." -msgstr "" +msgstr "ownCloud vil sende brugerens oplysninger til denne URL. Plugin'et registrerer responsen og fortolker HTTP-statuskoder 401 og 403 som ugyldige oplysninger, men alle andre besvarelser som gyldige oplysninger." diff --git a/l10n/de/core.po b/l10n/de/core.po index 428459ed0e..b9615f97a4 100644 --- a/l10n/de/core.po +++ b/l10n/de/core.po @@ -11,7 +11,7 @@ # I Robot , 2012. # Jan-Christoph Borchardt , 2011. # , 2012. -# Marcel Kühlhorn , 2012. +# Marcel Kühlhorn , 2012-2013. # , 2012. # , 2012. # , 2012. @@ -23,8 +23,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: German (http://www.transifex.com/projects/p/owncloud/language/de/)\n" "MIME-Version: 1.0\n" @@ -33,24 +33,24 @@ msgstr "" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Der Nutzer %s hat eine Datei für Dich freigegeben" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "%s hat ein Verzeichnis für Dich freigegeben" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "%s hat eine Datei \"%s\" für Dich freigegeben. Sie ist zum Download hier ferfügbar: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -253,8 +253,8 @@ msgid "The object type is not specified." msgstr "Der Objekttyp ist nicht angegeben." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Fehler" @@ -266,119 +266,127 @@ msgstr "Der App-Name ist nicht angegeben." msgid "The required file {file} is not installed!" msgstr "Die benötigte Datei {file} ist nicht installiert." -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Fehler beim Freigeben" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Fehler beim Aufheben der Freigabe" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Fehler beim Ändern der Rechte" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "{owner} hat dies für Dich und die Gruppe {group} freigegeben" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner} hat dies für Dich freigegeben" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Freigeben für" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Über einen Link freigeben" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Passwortschutz" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Passwort" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Link per E-Mail verschicken" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Senden" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Setze ein Ablaufdatum" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Ablaufdatum" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Über eine E-Mail freigeben:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Niemand gefunden" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Weiterverteilen ist nicht erlaubt" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Für {user} in {item} freigegeben" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Freigabe aufheben" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "kann bearbeiten" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "Zugriffskontrolle" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "erstellen" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "aktualisieren" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "löschen" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "freigeben" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Durch ein Passwort geschützt" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Fehler beim entfernen des Ablaufdatums" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Fehler beim Setzen des Ablaufdatums" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Sende ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "E-Mail wurde verschickt" @@ -387,11 +395,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Das Update ist fehlgeschlagen. Bitte melden Sie dieses Problem an die ownCloud Gemeinschaft." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Das Update war erfolgreich. Sie werden nun zu ownCloud weitergeleitet." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/de/files.po b/l10n/de/files.po index 99485b6e82..15ecd3bc99 100644 --- a/l10n/de/files.po +++ b/l10n/de/files.po @@ -27,9 +27,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:01+0000\n" +"Last-Translator: Marcel Kühlhorn \n" "Language-Team: German (http://www.transifex.com/projects/p/owncloud/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -88,7 +88,7 @@ msgstr "Fehler beim Schreiben auf die Festplatte" #: ajax/upload.php:48 msgid "Not enough storage available" -msgstr "" +msgstr "Nicht genug Speicherplatz verfügbar" #: ajax/upload.php:77 msgid "Invalid directory." @@ -162,11 +162,11 @@ msgstr "Ungültiger Name, '\\', '/', '<', '>', ':', '\"', '|', '?' und '*' sind #: js/files.js:78 msgid "Your storage is full, files can not be updated or synced anymore!" -msgstr "" +msgstr "Ihr Speicherplatz ist voll, Dateien können nicht mehr aktualisiert oder synchronisiert werden!" #: js/files.js:82 msgid "Your storage is almost full ({usedSpacePercent}%)" -msgstr "" +msgstr "Ihr Speicherplatz ist fast aufgebraucht ({usedSpacePercent}%)" #: js/files.js:219 msgid "" diff --git a/l10n/de/files_encryption.po b/l10n/de/files_encryption.po index ba08625264..934dce6d11 100644 --- a/l10n/de/files_encryption.po +++ b/l10n/de/files_encryption.po @@ -4,13 +4,14 @@ # # Translators: # , 2012. +# Marcel Kühlhorn , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:15+0000\n" +"Last-Translator: Marcel Kühlhorn \n" "Language-Team: German (http://www.transifex.com/projects/p/owncloud/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,53 +23,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Bitte wechseln Sie nun zum ownCloud Client und ändern Sie ihr Verschlüsselungspasswort um die Konvertierung abzuschließen." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "Zur Clientseitigen Verschlüsselung gewechselt" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Ändern des Verschlüsselungspasswortes zum Anmeldepasswort" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Bitte überprüfen sie Ihr Passwort und versuchen Sie es erneut." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Ihr Verschlüsselungspasswort konnte nicht als Anmeldepasswort gesetzt werden." #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Wählen Sie die Verschlüsselungsart:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Clientseitige Verschlüsselung (am sichersten, aber macht es unmöglich auf ihre Daten über das Webinterface zuzugreifen)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Serverseitige Verschlüsselung (erlaubt es ihnen auf ihre Daten über das Webinterface und den Desktop-Client zuzugreifen)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Keine (ohne Verschlüsselung)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Wichtig: Sobald sie eine Verschlüsselungsmethode gewählt haben, können Sie diese nicht ändern!" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Benutzerspezifisch (der Benutzer kann entscheiden)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/de/settings.po b/l10n/de/settings.po index ee2da814b8..c26bb84c09 100644 --- a/l10n/de/settings.po +++ b/l10n/de/settings.po @@ -25,9 +25,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 13:12+0000\n" -"Last-Translator: Mirodin \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" +"Last-Translator: I Robot \n" "Language-Team: German (http://www.transifex.com/projects/p/owncloud/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -174,7 +174,7 @@ msgstr "Android-Client herunterladen" msgid "Download iOS Client" msgstr "iOS-Client herunterladen" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:80 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Passwort" @@ -245,10 +245,10 @@ msgid "" msgstr "Entwickelt von der ownCloud-Community, der Quellcode ist unter der AGPL lizenziert." #: templates/users.php:21 templates/users.php:79 -msgid "Name" -msgstr "Name" +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:81 templates/users.php:101 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Gruppen" @@ -260,26 +260,30 @@ msgstr "Anlegen" msgid "Default Storage" msgstr "Standard-Speicher" -#: templates/users.php:42 templates/users.php:136 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Unbegrenzt" -#: templates/users.php:60 templates/users.php:151 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Andere" -#: templates/users.php:83 templates/users.php:115 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Gruppenadministrator" -#: templates/users.php:85 +#: templates/users.php:86 msgid "Storage" msgstr "Speicher" -#: templates/users.php:131 +#: templates/users.php:137 msgid "Default" msgstr "Standard" -#: templates/users.php:159 +#: templates/users.php:165 msgid "Delete" msgstr "Löschen" diff --git a/l10n/de/user_ldap.po b/l10n/de/user_ldap.po index b706cd2fe2..95aabcd2e6 100644 --- a/l10n/de/user_ldap.po +++ b/l10n/de/user_ldap.po @@ -6,6 +6,7 @@ # , 2012. # I Robot , 2012. # I Robot , 2012. +# Marcel Kühlhorn , 2013. # Maurice Preuß <>, 2012. # , 2012. # Phi Lieb <>, 2012. @@ -15,9 +16,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-16 00:19+0100\n" -"PO-Revision-Date: 2013-01-15 23:20+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:08+0000\n" +"Last-Translator: Marcel Kühlhorn \n" "Language-Team: German (http://www.transifex.com/projects/p/owncloud/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -36,7 +37,7 @@ msgstr "Warnung: Die Anwendungen user_ldap und user_webdavauth sind inkom msgid "" "Warning: The PHP LDAP module is not installed, the backend will not " "work. Please ask your system administrator to install it." -msgstr "" +msgstr "Warnung: Da das PHP-Modul für LDAP ist nicht installiert, das Backend wird nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren." #: templates/settings.php:15 msgid "Host" @@ -53,7 +54,7 @@ msgstr "Basis-DN" #: templates/settings.php:16 msgid "One Base DN per line" -msgstr "" +msgstr "Ein Base DN pro Zeile" #: templates/settings.php:16 msgid "You can specify Base DN for users and groups in the Advanced tab" @@ -128,7 +129,7 @@ msgstr "Basis-Benutzerbaum" #: templates/settings.php:25 msgid "One User Base DN per line" -msgstr "" +msgstr "Ein Benutzer Base DN pro Zeile" #: templates/settings.php:26 msgid "Base Group Tree" @@ -136,7 +137,7 @@ msgstr "Basis-Gruppenbaum" #: templates/settings.php:26 msgid "One Group Base DN per line" -msgstr "" +msgstr "Ein Gruppen Base DN pro Zeile" #: templates/settings.php:27 msgid "Group-Member association" diff --git a/l10n/de_DE/core.po b/l10n/de_DE/core.po index 9b94cdb687..0d1dcf3448 100644 --- a/l10n/de_DE/core.po +++ b/l10n/de_DE/core.po @@ -9,10 +9,11 @@ # , 2012. # , 2012. # , 2011. +# I Robot , 2013. # I Robot , 2012. # Jan-Christoph Borchardt , 2011. # , 2012. -# Marcel Kühlhorn , 2012. +# Marcel Kühlhorn , 2012-2013. # , 2012. # , 2012. # Phi Lieb <>, 2012. @@ -23,8 +24,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: German (Germany) (http://www.transifex.com/projects/p/owncloud/language/de_DE/)\n" "MIME-Version: 1.0\n" @@ -33,24 +34,24 @@ msgstr "" "Language: de_DE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Der Nutzer %s hat eine Datei für Sie freigegeben" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "%s hat ein Verzeichnis für Sie freigegeben" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "%s hat eine Datei \"%s\" für Sie freigegeben. Sie ist zum Download hier ferfügbar: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -253,8 +254,8 @@ msgid "The object type is not specified." msgstr "Der Objekttyp ist nicht angegeben." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Fehler" @@ -266,119 +267,127 @@ msgstr "Der App-Name ist nicht angegeben." msgid "The required file {file} is not installed!" msgstr "Die benötigte Datei {file} ist nicht installiert." -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Fehler bei der Freigabe" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Fehler bei der Aufhebung der Freigabe" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Fehler bei der Änderung der Rechte" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Durch {owner} für Sie und die Gruppe {group} freigegeben." -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Durch {owner} für Sie freigegeben." -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Freigeben für" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Über einen Link freigeben" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Passwortschutz" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Passwort" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Link per E-Mail verschicken" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Senden" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Setze ein Ablaufdatum" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Ablaufdatum" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Mittels einer E-Mail freigeben:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Niemand gefunden" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Das Weiterverteilen ist nicht erlaubt" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Freigegeben in {item} von {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Freigabe aufheben" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "kann bearbeiten" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "Zugriffskontrolle" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "erstellen" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "aktualisieren" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "löschen" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "freigeben" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Durch ein Passwort geschützt" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Fehler beim Entfernen des Ablaufdatums" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Fehler beim Setzen des Ablaufdatums" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Sende ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Email gesendet" @@ -387,11 +396,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Das Update ist fehlgeschlagen. Bitte melden Sie dieses Problem an die ownCloud Gemeinschaft." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Das Update war erfolgreich. Sie werden nun zu ownCloud weitergeleitet." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/de_DE/files_encryption.po b/l10n/de_DE/files_encryption.po index b0c09c8e84..7521754abf 100644 --- a/l10n/de_DE/files_encryption.po +++ b/l10n/de_DE/files_encryption.po @@ -3,15 +3,18 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# , 2013. # Andreas Tangemann , 2013. # , 2012. +# Marc-Andre Husyk , 2013. +# Marcel Kühlhorn , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-26 00:09+0100\n" -"PO-Revision-Date: 2013-01-25 22:03+0000\n" -"Last-Translator: a.tangemann \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:14+0000\n" +"Last-Translator: Marcel Kühlhorn \n" "Language-Team: German (Germany) (http://www.transifex.com/projects/p/owncloud/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,39 +26,39 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Bitte wechseln Sie nun zum ownCloud Client und ändern Sie ihr Verschlüsselungspasswort um die Konvertierung abzuschließen." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "Zur Clientseitigen Verschlüsselung gewechselt" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Ändern des Verschlüsselungspasswortes zum Anmeldepasswort" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Bitte überprüfen sie Ihr Passwort und versuchen Sie es erneut." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Ihr Verschlüsselungspasswort konnte nicht als Anmeldepasswort gesetzt werden." #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "Wählen Sie die Verschlüsselungsart:" +msgstr "Wählen Sie die Verschlüsselungsmethode:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Clientseitige Verschlüsselung (am sichersten, aber macht es unmöglich auf ihre Daten über das Webinterface zuzugreifen)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Serverseitige Verschlüsselung (erlaubt es ihnen auf ihre Daten über das Webinterface und den Desktop-Client zuzugreifen)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" @@ -65,7 +68,7 @@ msgstr "Keine (ohne Verschlüsselung)" msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Wichtig: Sobald sie eine Verschlüsselungsmethode gewählt haben, können Sie diese nicht ändern!" #: templates/settings.php:48 msgid "User specific (let the user decide)" diff --git a/l10n/de_DE/settings.po b/l10n/de_DE/settings.po index 6cfee3b4fb..0c99f26562 100644 --- a/l10n/de_DE/settings.po +++ b/l10n/de_DE/settings.po @@ -25,9 +25,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 13:11+0000\n" -"Last-Translator: Mirodin \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" +"Last-Translator: I Robot \n" "Language-Team: German (Germany) (http://www.transifex.com/projects/p/owncloud/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -174,7 +174,7 @@ msgstr "Android-Client herunterladen" msgid "Download iOS Client" msgstr "iOS-Client herunterladen" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:80 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Passwort" @@ -245,10 +245,10 @@ msgid "" msgstr "Entwickelt von der ownCloud-Community. Der Quellcode ist unter der AGPL lizenziert." #: templates/users.php:21 templates/users.php:79 -msgid "Name" -msgstr "Name" +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:81 templates/users.php:101 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Gruppen" @@ -260,26 +260,30 @@ msgstr "Anlegen" msgid "Default Storage" msgstr "Standard-Speicher" -#: templates/users.php:42 templates/users.php:136 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Unbegrenzt" -#: templates/users.php:60 templates/users.php:151 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Andere" -#: templates/users.php:83 templates/users.php:115 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Gruppenadministrator" -#: templates/users.php:85 +#: templates/users.php:86 msgid "Storage" msgstr "Speicher" -#: templates/users.php:131 +#: templates/users.php:137 msgid "Default" msgstr "Standard" -#: templates/users.php:159 +#: templates/users.php:165 msgid "Delete" msgstr "Löschen" diff --git a/l10n/de_DE/user_ldap.po b/l10n/de_DE/user_ldap.po index 440d30ce2b..e1d07152a6 100644 --- a/l10n/de_DE/user_ldap.po +++ b/l10n/de_DE/user_ldap.po @@ -6,6 +6,7 @@ # Andreas Tangemann , 2013. # , 2012. # I Robot , 2012. +# Marcel Kühlhorn , 2013. # Maurice Preuß <>, 2012. # , 2012. # Phi Lieb <>, 2012. @@ -15,9 +16,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-19 00:04+0100\n" -"PO-Revision-Date: 2013-01-18 21:26+0000\n" -"Last-Translator: a.tangemann \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:08+0000\n" +"Last-Translator: Marcel Kühlhorn \n" "Language-Team: German (Germany) (http://www.transifex.com/projects/p/owncloud/language/de_DE/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -36,7 +37,7 @@ msgstr "Warnung: Die Anwendungen user_ldap und user_webdavauth sind inkom msgid "" "Warning: The PHP LDAP module is not installed, the backend will not " "work. Please ask your system administrator to install it." -msgstr "Warnung: Da das PHP-Modul für LDAP nicht installiert ist, wird das Backend nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren." +msgstr "Warnung: Da das PHP-Modul für LDAP ist nicht installiert, das Backend wird nicht funktionieren. Bitten Sie Ihren Systemadministrator das Modul zu installieren." #: templates/settings.php:15 msgid "Host" diff --git a/l10n/el/core.po b/l10n/el/core.po index bd3d221969..6ad17c2deb 100644 --- a/l10n/el/core.po +++ b/l10n/el/core.po @@ -15,8 +15,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Greek (http://www.transifex.com/projects/p/owncloud/language/el/)\n" "MIME-Version: 1.0\n" @@ -25,24 +25,24 @@ msgstr "" "Language: el\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Ο χρήστης %s διαμοιράστηκε ένα αρχείο με εσάς" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Ο χρήστης %s διαμοιράστηκε ένα φάκελο με εσάς" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Ο χρήστης %s διαμοιράστηκε το αρχείο \"%s\" μαζί σας. Είναι διαθέσιμο για λήψη εδώ: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -245,8 +245,8 @@ msgid "The object type is not specified." msgstr "Δεν καθορίστηκε ο τύπος του αντικειμένου." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Σφάλμα" @@ -258,119 +258,127 @@ msgstr "Δεν καθορίστηκε το όνομα της εφαρμογής. msgid "The required file {file} is not installed!" msgstr "Το απαιτούμενο αρχείο {file} δεν εγκαταστάθηκε!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Σφάλμα κατά τον διαμοιρασμό" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Σφάλμα κατά το σταμάτημα του διαμοιρασμού" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Σφάλμα κατά την αλλαγή των δικαιωμάτων" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Διαμοιράστηκε με σας και με την ομάδα {group} του {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Διαμοιράστηκε με σας από τον {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Διαμοιρασμός με" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Διαμοιρασμός με σύνδεσμο" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Προστασία συνθηματικού" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Συνθηματικό" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Αποστολή συνδέσμου με email " -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Αποστολή" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Ορισμός ημ. λήξης" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Ημερομηνία λήξης" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Διαμοιρασμός μέσω email:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Δεν βρέθηκε άνθρωπος" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Ξαναμοιρασμός δεν επιτρέπεται" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Διαμοιρασμός του {item} με τον {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Σταμάτημα διαμοιρασμού" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "δυνατότητα αλλαγής" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "έλεγχος πρόσβασης" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "δημιουργία" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "ενημέρωση" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "διαγραφή" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "διαμοιρασμός" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Προστασία με συνθηματικό" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Σφάλμα κατά την διαγραφή της ημ. λήξης" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Σφάλμα κατά τον ορισμό ημ. λήξης" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Αποστολή..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Το Email απεστάλη " diff --git a/l10n/el/settings.po b/l10n/el/settings.po index f06ddb0785..4e99eae3d5 100644 --- a/l10n/el/settings.po +++ b/l10n/el/settings.po @@ -19,9 +19,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-18 00:03+0100\n" -"PO-Revision-Date: 2013-01-17 20:41+0000\n" -"Last-Translator: xneo1 \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Greek (http://www.transifex.com/projects/p/owncloud/language/el/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -99,7 +99,7 @@ msgstr "Ενεργοποίηση" msgid "Saving..." msgstr "Αποθήκευση..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__όνομα_γλώσσας__" @@ -111,15 +111,15 @@ msgstr "Πρόσθεστε τη Δικιά σας Εφαρμογή" msgid "More Apps" msgstr "Περισσότερες Εφαρμογές" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Επιλέξτε μια Εφαρμογή" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Δείτε την σελίδα εφαρμογών στο apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-άδεια από " @@ -168,7 +168,7 @@ msgstr "Λήψη Προγράμματος Android" msgid "Download iOS Client" msgstr "Λήψη Προγράμματος iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Συνθηματικό" @@ -238,11 +238,11 @@ msgid "" "License\">AGPL." msgstr "Αναπτύχθηκε από την κοινότητα ownCloud, ο πηγαίος κώδικας είναι υπό άδεια χρήσης AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Όνομα" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Ομάδες" @@ -254,26 +254,30 @@ msgstr "Δημιουργία" msgid "Default Storage" msgstr "Προκαθορισμένη Αποθήκευση " -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Απεριόριστο" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Άλλα" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Ομάδα Διαχειριστών" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Αποθήκευση" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Προκαθορισμένο" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Διαγραφή" diff --git a/l10n/eo/core.po b/l10n/eo/core.po index 6fc85d95d7..01b8ff631d 100644 --- a/l10n/eo/core.po +++ b/l10n/eo/core.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Esperanto (http://www.transifex.com/projects/p/owncloud/language/eo/)\n" "MIME-Version: 1.0\n" @@ -20,24 +20,24 @@ msgstr "" "Language: eo\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "La uzanto %s kunhavigis dosieron kun vi" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "La uzanto %s kunhavigis dosierujon kun vi" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "La uzanto %s kunhavigis la dosieron “%s” kun vi. Ĝi elŝuteblas el tie ĉi: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -240,8 +240,8 @@ msgid "The object type is not specified." msgstr "Ne indikiĝis tipo de la objekto." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Eraro" @@ -253,119 +253,127 @@ msgstr "Ne indikiĝis nomo de la aplikaĵo." msgid "The required file {file} is not installed!" msgstr "La necesa dosiero {file} ne instaliĝis!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Eraro dum kunhavigo" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Eraro dum malkunhavigo" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Eraro dum ŝanĝo de permesoj" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Kunhavigita kun vi kaj la grupo {group} de {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Kunhavigita kun vi de {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Kunhavigi kun" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Kunhavigi per ligilo" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Protekti per pasvorto" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Pasvorto" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Retpoŝti la ligilon al ulo" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Sendi" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Agordi limdaton" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Limdato" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Kunhavigi per retpoŝto:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Ne troviĝis gento" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Rekunhavigo ne permesatas" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Kunhavigita en {item} kun {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Malkunhavigi" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "povas redakti" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "alirkontrolo" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "krei" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "ĝisdatigi" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "forigi" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "kunhavigi" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protektita per pasvorto" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Eraro dum malagordado de limdato" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Eraro dum agordado de limdato" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Sendante..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "La retpoŝtaĵo sendiĝis" diff --git a/l10n/eo/settings.po b/l10n/eo/settings.po index 2be0270b28..4c842f018f 100644 --- a/l10n/eo/settings.po +++ b/l10n/eo/settings.po @@ -10,9 +10,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" -"PO-Revision-Date: 2013-01-20 01:30+0000\n" -"Last-Translator: Mariano \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Esperanto (http://www.transifex.com/projects/p/owncloud/language/eo/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -90,7 +90,7 @@ msgstr "Kapabligi" msgid "Saving..." msgstr "Konservante..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Esperanto" @@ -102,15 +102,15 @@ msgstr "Aldonu vian aplikaĵon" msgid "More Apps" msgstr "Pli da aplikaĵoj" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Elekti aplikaĵon" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Vidu la paĝon pri aplikaĵoj ĉe apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-permesilhavigita de " @@ -159,7 +159,7 @@ msgstr "Elŝuti Android-klienton" msgid "Download iOS Client" msgstr "Elŝuti iOS-klienton" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Pasvorto" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "Ellaborita de la komunumo de ownCloud, la fontokodo publikas laŭ la permesilo AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nomo" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupoj" @@ -245,26 +245,30 @@ msgstr "Krei" msgid "Default Storage" msgstr "Defaŭlta konservejo" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Senlima" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Alia" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupadministranto" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Konservejo" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Defaŭlta" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Forigi" diff --git a/l10n/es/core.po b/l10n/es/core.po index e7260888e0..03aade72af 100644 --- a/l10n/es/core.po +++ b/l10n/es/core.po @@ -18,8 +18,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n" "MIME-Version: 1.0\n" @@ -28,24 +28,24 @@ msgstr "" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "El usuario %s ha compartido un archivo contigo" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "El usuario %s ha compartido una carpeta contigo" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "El usuario %s ha compartido el archivo \"%s\" contigo. Puedes descargarlo aquí: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -248,8 +248,8 @@ msgid "The object type is not specified." msgstr "El tipo de objeto no se ha especificado." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Fallo" @@ -261,119 +261,127 @@ msgstr "El nombre de la app no se ha especificado." msgid "The required file {file} is not installed!" msgstr "El fichero {file} requerido, no está instalado." -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Error compartiendo" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Error descompartiendo" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Error cambiando permisos" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Compartido contigo y el grupo {group} por {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Compartido contigo por {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Compartir con" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Compartir con enlace" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Protegido por contraseña" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Contraseña" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Enviar un enlace por correo electrónico a una persona" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Enviar" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Establecer fecha de caducidad" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Fecha de caducidad" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "compartido via e-mail:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "No se encontró gente" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "No se permite compartir de nuevo" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Compartido en {item} con {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "No compartir" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "puede editar" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "control de acceso" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "crear" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "modificar" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "eliminar" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "compartir" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protegido por contraseña" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Error al eliminar la fecha de caducidad" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Error estableciendo fecha de caducidad" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Enviando..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Correo electrónico enviado" diff --git a/l10n/es/files_encryption.po b/l10n/es/files_encryption.po index cccce7419a..14b030edb0 100644 --- a/l10n/es/files_encryption.po +++ b/l10n/es/files_encryption.po @@ -3,15 +3,16 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Felix Liberio , 2013. # , 2012. # Raul Fernandez Garcia , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 09:47+0000\n" -"Last-Translator: Raul Fernandez Garcia \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 22:40+0000\n" +"Last-Translator: felix.liberio \n" "Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,7 +24,7 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Por favor, cambie su cliente de ownCloud y cambie su clave de cifrado para completar la conversión." #: js/settings-personal.js:17 msgid "switched to client side encryption" @@ -31,7 +32,7 @@ msgstr "Cambiar a encriptación en lado cliente" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Cambie la clave de cifrado para ingresar su contraseña" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." diff --git a/l10n/es/settings.po b/l10n/es/settings.po index d39042253f..d650521c6f 100644 --- a/l10n/es/settings.po +++ b/l10n/es/settings.po @@ -19,8 +19,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n" "MIME-Version: 1.0\n" @@ -99,7 +99,7 @@ msgstr "Activar" msgid "Saving..." msgstr "Guardando..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Castellano" @@ -111,15 +111,15 @@ msgstr "Añade tu aplicación" msgid "More Apps" msgstr "Más aplicaciones" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Seleccionar una aplicación" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Echa un vistazo a la web de aplicaciones apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licenciado por " @@ -168,7 +168,7 @@ msgstr "Descargar cliente para android" msgid "Download iOS Client" msgstr "Descargar cliente para iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Contraseña" @@ -238,11 +238,11 @@ msgid "" "License\">AGPL." msgstr "Desarrollado por la comunidad ownCloud, el código fuente está bajo licencia AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nombre" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupos" @@ -254,26 +254,30 @@ msgstr "Crear" msgid "Default Storage" msgstr "Almacenamiento Predeterminado" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Ilimitado" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Otro" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupo admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Alamacenamiento" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Predeterminado" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Eliminar" diff --git a/l10n/es_AR/core.po b/l10n/es_AR/core.po index c2c7a160ff..6548740840 100644 --- a/l10n/es_AR/core.po +++ b/l10n/es_AR/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Spanish (Argentina) (http://www.transifex.com/projects/p/owncloud/language/es_AR/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: es_AR\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "El usurario %s compartió un archivo con vos." -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "El usurario %s compartió una carpeta con vos." -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "El usuario %s compartió el archivo \"%s\" con vos. Está disponible para su descarga aquí: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "El tipo de objeto no esta especificado. " #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Error" @@ -252,119 +252,127 @@ msgstr "El nombre de la aplicación no esta especificado." msgid "The required file {file} is not installed!" msgstr "¡El archivo requerido {file} no está instalado!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Error al compartir" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Error en el procedimiento de " -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Error al cambiar permisos" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Compartido con vos y el grupo {group} por {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Compartido con vos por {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Compartir con" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Compartir con link" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Proteger con contraseña " -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Contraseña" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Enviar el link por e-mail." -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Enviar" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Asignar fecha de vencimiento" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Fecha de vencimiento" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "compartido a través de e-mail:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "No se encontraron usuarios" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "No se permite volver a compartir" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Compartido en {item} con {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Remover compartir" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "puede editar" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "control de acceso" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "crear" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "actualizar" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "borrar" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "compartir" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protegido por contraseña" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Error al remover la fecha de caducidad" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Error al asignar fecha de vencimiento" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Enviando..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Email enviado" diff --git a/l10n/es_AR/settings.po b/l10n/es_AR/settings.po index 0ebdce38b5..e5e3ae2bc0 100644 --- a/l10n/es_AR/settings.po +++ b/l10n/es_AR/settings.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Spanish (Argentina) (http://www.transifex.com/projects/p/owncloud/language/es_AR/)\n" "MIME-Version: 1.0\n" @@ -89,7 +89,7 @@ msgstr "Activar" msgid "Saving..." msgstr "Guardando..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Castellano (Argentina)" @@ -101,15 +101,15 @@ msgstr "Añadí tu aplicación" msgid "More Apps" msgstr "Más aplicaciones" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Seleccionar una aplicación" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Mirá la web de aplicaciones apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licenciado por " @@ -158,7 +158,7 @@ msgstr "Descargar cliente de Android" msgid "Download iOS Client" msgstr "Descargar cliente de iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Contraseña" @@ -228,11 +228,11 @@ msgid "" "License\">AGPL." msgstr "Desarrollado por la comunidad ownCloud, el código fuente está bajo licencia AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nombre" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupos" @@ -244,26 +244,30 @@ msgstr "Crear" msgid "Default Storage" msgstr "Almacenamiento Predeterminado" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Ilimitado" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Otro" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupo Administrador" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Almacenamiento" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Predeterminado" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Borrar" diff --git a/l10n/et_EE/core.po b/l10n/et_EE/core.po index 808413dbda..62f3fd7015 100644 --- a/l10n/et_EE/core.po +++ b/l10n/et_EE/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Estonian (Estonia) (http://www.transifex.com/projects/p/owncloud/language/et_EE/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: et_EE\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Viga" @@ -251,119 +251,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Viga jagamisel" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Viga jagamise lõpetamisel" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Viga õiguste muutmisel" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Sinuga jagas {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Jaga" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Jaga lingiga" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Parooliga kaitstud" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Parool" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Määra aegumise kuupäev" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Aegumise kuupäev" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Jaga e-postiga:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Ühtegi inimest ei leitud" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Edasijagamine pole lubatud" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Lõpeta jagamine" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "saab muuta" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "ligipääsukontroll" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "loo" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "uuenda" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "kustuta" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "jaga" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Parooliga kaitstud" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Viga aegumise kuupäeva eemaldamisel" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Viga aegumise kuupäeva määramisel" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/et_EE/settings.po b/l10n/et_EE/settings.po index 751dc61daf..3f55c73885 100644 --- a/l10n/et_EE/settings.po +++ b/l10n/et_EE/settings.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Estonian (Estonia) (http://www.transifex.com/projects/p/owncloud/language/et_EE/)\n" "MIME-Version: 1.0\n" @@ -89,7 +89,7 @@ msgstr "Lülita sisse" msgid "Saving..." msgstr "Salvestamine..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Eesti" @@ -101,15 +101,15 @@ msgstr "Lisa oma rakendus" msgid "More Apps" msgstr "Veel rakendusi" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Vali programm" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Vaata rakenduste lehte aadressil apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-litsenseeritud " @@ -158,7 +158,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Parool" @@ -228,11 +228,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nimi" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupid" @@ -244,26 +244,30 @@ msgstr "Lisa" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Muu" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupi admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Kustuta" diff --git a/l10n/eu/core.po b/l10n/eu/core.po index a5f1efdf3e..7bc85012c5 100644 --- a/l10n/eu/core.po +++ b/l10n/eu/core.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Basque (http://www.transifex.com/projects/p/owncloud/language/eu/)\n" "MIME-Version: 1.0\n" @@ -21,24 +21,24 @@ msgstr "" "Language: eu\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "%s erabiltzaileak zurekin fitxategi bat partekatu du " -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "%s erabiltzaileak zurekin karpeta bat partekatu du " -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "%s erabiltzaileak \"%s\" fitxategia zurekin partekatu du. Hemen duzu eskuragarri: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -241,8 +241,8 @@ msgid "The object type is not specified." msgstr "Objetu mota ez dago zehaztuta." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Errorea" @@ -254,119 +254,127 @@ msgstr "App izena ez dago zehaztuta." msgid "The required file {file} is not installed!" msgstr "Beharrezkoa den {file} fitxategia ez dago instalatuta!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Errore bat egon da elkarbanatzean" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Errore bat egon da elkarbanaketa desegitean" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Errore bat egon da baimenak aldatzean" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "{owner}-k zu eta {group} taldearekin partekatuta" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner}-k zurekin partekatuta" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Elkarbanatu honekin" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Elkarbanatu lotura batekin" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Babestu pasahitzarekin" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Pasahitza" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Postaz bidali lotura " -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Bidali" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Ezarri muga data" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Muga data" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Elkarbanatu eposta bidez:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Ez da inor aurkitu" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Berriz elkarbanatzea ez dago baimendua" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "{user}ekin {item}-n partekatuta" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Ez elkarbanatu" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "editatu dezake" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "sarrera kontrola" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "sortu" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "eguneratu" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "ezabatu" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "elkarbanatu" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Pasahitzarekin babestuta" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Errorea izan da muga data kentzean" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Errore bat egon da muga data ezartzean" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Bidaltzen ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Eposta bidalia" @@ -375,11 +383,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Eguneraketa ez da ongi egin. Mesedez egin arazoaren txosten bat ownCloud komunitatearentzako." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Eguneraketa ongi egin da. Orain zure ownClouderea berbideratua izango zara." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/eu/files_encryption.po b/l10n/eu/files_encryption.po index deacd189bf..4e6b0c18e0 100644 --- a/l10n/eu/files_encryption.po +++ b/l10n/eu/files_encryption.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# , 2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 18:40+0000\n" +"Last-Translator: asieriko \n" "Language-Team: Basque (http://www.transifex.com/projects/p/owncloud/language/eu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -34,7 +35,7 @@ msgstr "" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Mesedez egiaztatu zure pasahitza eta saia zaitez berriro:" #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" @@ -42,7 +43,7 @@ msgstr "" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Hautatu enkriptazio modua:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" @@ -58,7 +59,7 @@ msgstr "" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Bat ere ez (enkriptaziorik gabe)" #: templates/settings.php:10 msgid "" @@ -68,7 +69,7 @@ msgstr "" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Erabiltzaileak zehaztuta (utzi erabiltzaileari hautatzen)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/eu/settings.po b/l10n/eu/settings.po index dff5792f80..9ff185b18f 100644 --- a/l10n/eu/settings.po +++ b/l10n/eu/settings.po @@ -11,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-20 00:05+0100\n" -"PO-Revision-Date: 2013-01-19 00:06+0000\n" -"Last-Translator: asieriko \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Basque (http://www.transifex.com/projects/p/owncloud/language/eu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -91,7 +91,7 @@ msgstr "Gaitu" msgid "Saving..." msgstr "Gordetzen..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Euskera" @@ -103,15 +103,15 @@ msgstr "Gehitu zure aplikazioa" msgid "More Apps" msgstr "App gehiago" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Aukeratu programa bat" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Ikusi programen orria apps.owncloud.com en" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-lizentziatua " @@ -160,7 +160,7 @@ msgstr "Deskargatu Android bezeroa" msgid "Download iOS Client" msgstr "Deskargatu iOS bezeroa" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Pasahitza" @@ -230,11 +230,11 @@ msgid "" "License\">AGPL." msgstr "ownCloud komunitateak garatuta, itubruru kodeaAGPL lizentziarekin banatzen da." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Izena" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Taldeak" @@ -246,26 +246,30 @@ msgstr "Sortu" msgid "Default Storage" msgstr "Lehenetsitako Biltegiratzea" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Mugarik gabe" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Besteak" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Talde administradorea" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Biltegiratzea" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Lehenetsia" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Ezabatu" diff --git a/l10n/fa/core.po b/l10n/fa/core.po index b30d0698a4..b14c7903db 100644 --- a/l10n/fa/core.po +++ b/l10n/fa/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Persian (http://www.transifex.com/projects/p/owncloud/language/fa/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: fa\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "کاربر %s یک پرونده را با شما به اشتراک گذاشته است." -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "کاربر %s یک پوشه را با شما به اشتراک گذاشته است." -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "کاربر %s پرونده \"%s\" را با شما به اشتراک گذاشته است. پرونده برای دانلود اینجاست : %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "نوع شی تعیین نشده است." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "خطا" @@ -252,119 +252,127 @@ msgstr "نام برنامه تعیین نشده است." msgid "The required file {file} is not installed!" msgstr "پرونده { پرونده} درخواست شده نصب نشده است !" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "خطا درحال به اشتراک گذاشتن" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "خطا درحال لغو اشتراک" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "خطا در حال تغییر مجوز" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "به اشتراک گذاشته شده با شما و گروه {گروه} توسط {دارنده}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "به اشتراک گذاشته شده با شما توسط { دارنده}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "به اشتراک گذاشتن با" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "به اشتراک گذاشتن با پیوند" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "نگهداری کردن رمز عبور" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "گذرواژه" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "پیوند ایمیل برای شخص." -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "تنظیم تاریخ انقضا" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "تاریخ انقضا" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "از طریق ایمیل به اشتراک بگذارید :" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "کسی یافت نشد" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "اشتراک گذاری مجدد مجاز نمی باشد" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "به اشتراک گذاشته شده در {بخش} با {کاربر}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "لغو اشتراک" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "می توان ویرایش کرد" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "کنترل دسترسی" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "ایجاد" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "به روز" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "پاک کردن" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "به اشتراک گذاشتن" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "نگهداری از رمز عبور" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "خطا در تنظیم نکردن تاریخ انقضا " -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "خطا در تنظیم تاریخ انقضا" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/fa/settings.po b/l10n/fa/settings.po index 20aa22599b..05c6505630 100644 --- a/l10n/fa/settings.po +++ b/l10n/fa/settings.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Persian (http://www.transifex.com/projects/p/owncloud/language/fa/)\n" "MIME-Version: 1.0\n" @@ -91,7 +91,7 @@ msgstr "فعال" msgid "Saving..." msgstr "درحال ذخیره ..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -103,15 +103,15 @@ msgstr "برنامه خود را بیافزایید" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "یک برنامه انتخاب کنید" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "صفحه این اٌپ را در apps.owncloud.com ببینید" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -160,7 +160,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "گذرواژه" @@ -230,11 +230,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "نام" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "گروه ها" @@ -246,26 +246,30 @@ msgstr "ایجاد کردن" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "سایر" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "پاک کردن" diff --git a/l10n/fi_FI/core.po b/l10n/fi_FI/core.po index 2aca3ded67..74a6747f32 100644 --- a/l10n/fi_FI/core.po +++ b/l10n/fi_FI/core.po @@ -14,8 +14,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Finnish (Finland) (http://www.transifex.com/projects/p/owncloud/language/fi_FI/)\n" "MIME-Version: 1.0\n" @@ -24,24 +24,24 @@ msgstr "" "Language: fi_FI\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Käyttäjä %s jakoi tiedoston kanssasi" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Käyttäjä %s jakoi kansion kanssasi" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Käyttäjä %s jakoi tiedoston \"%s\" kanssasi. Se on ladattavissa täältä: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -244,8 +244,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Virhe" @@ -257,119 +257,127 @@ msgstr "Sovelluksen nimeä ei ole määritelty." msgid "The required file {file} is not installed!" msgstr "Vaadittua tiedostoa {file} ei ole asennettu!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Virhe jaettaessa" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Virhe jakoa peruttaessa" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Virhe oikeuksia muuttaessa" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Jaettu sinun ja ryhmän {group} kanssa käyttäjän {owner} toimesta" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Jaettu kanssasi käyttäjän {owner} toimesta" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Jaa" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Jaa linkillä" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Suojaa salasanalla" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Salasana" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Lähetä linkki sähköpostitse" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Lähetä" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Aseta päättymispäivä" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Päättymispäivä" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Jaa sähköpostilla:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Henkilöitä ei löytynyt" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Jakaminen uudelleen ei ole salittu" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Peru jakaminen" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "voi muokata" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "Pääsyn hallinta" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "luo" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "päivitä" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "poista" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "jaa" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Salasanasuojattu" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Virhe purettaessa eräpäivää" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Virhe päättymispäivää asettaessa" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Lähetetään..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Sähköposti lähetetty" diff --git a/l10n/fi_FI/settings.po b/l10n/fi_FI/settings.po index 087d613c68..c662e17898 100644 --- a/l10n/fi_FI/settings.po +++ b/l10n/fi_FI/settings.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Finnish (Finland) (http://www.transifex.com/projects/p/owncloud/language/fi_FI/)\n" "MIME-Version: 1.0\n" @@ -90,7 +90,7 @@ msgstr "Käytä" msgid "Saving..." msgstr "Tallennetaan..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "_kielen_nimi_" @@ -102,15 +102,15 @@ msgstr "Lisää sovelluksesi" msgid "More Apps" msgstr "Lisää sovelluksia" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Valitse sovellus" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Katso sovellussivu osoitteessa apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-lisensoija " @@ -159,7 +159,7 @@ msgstr "Lataa Android-sovellus" msgid "Download iOS Client" msgstr "Lataa iOS-sovellus" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Salasana" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "Kehityksestä on vastannut ownCloud-yhteisö, lähdekoodi on julkaistu lisenssin AGPL alaisena." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nimi" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Ryhmät" @@ -245,26 +245,30 @@ msgstr "Luo" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Rajoittamaton" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Muu" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Ryhmän ylläpitäjä" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Oletus" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Poista" diff --git a/l10n/fr/core.po b/l10n/fr/core.po index 7e1a32b035..14e68eae7e 100644 --- a/l10n/fr/core.po +++ b/l10n/fr/core.po @@ -4,6 +4,7 @@ # # Translators: # Christophe Lherieau , 2012-2013. +# David Basquin , 2013. # , 2013. # , 2012. # , 2012. @@ -18,8 +19,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" @@ -28,24 +29,24 @@ msgstr "" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "L'utilisateur %s a partagé un fichier avec vous" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "L'utilsateur %s a partagé un dossier avec vous" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "L'utilisateur %s a partagé le fichier \"%s\" avec vous. Vous pouvez le télécharger ici : %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -248,8 +249,8 @@ msgid "The object type is not specified." msgstr "Le type d'objet n'est pas spécifié." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Erreur" @@ -261,119 +262,127 @@ msgstr "Le nom de l'application n'est pas spécifié." msgid "The required file {file} is not installed!" msgstr "Le fichier requis {file} n'est pas installé !" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Erreur lors de la mise en partage" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Erreur lors de l'annulation du partage" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Erreur lors du changement des permissions" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Partagé par {owner} avec vous et le groupe {group}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Partagé avec vous par {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Partager avec" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Partager via lien" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Protéger par un mot de passe" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Mot de passe" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Envoyez le lien par email" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Envoyer" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Spécifier la date d'expiration" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Date d'expiration" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Partager via e-mail :" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Aucun utilisateur trouvé" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Le repartage n'est pas autorisé" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Partagé dans {item} avec {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Ne plus partager" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "édition autorisée" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "contrôle des accès" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "créer" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "mettre à jour" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "supprimer" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "partager" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protégé par un mot de passe" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Une erreur est survenue pendant la suppression de la date d'expiration" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Erreur lors de la spécification de la date d'expiration" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "En cours d'envoi ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Email envoyé" @@ -382,11 +391,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "La mise à jour a échoué. Veuillez signaler ce problème à la communauté ownCloud." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "La mise à jour a réussi. Vous êtes redirigé maintenant vers ownCloud." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/fr/files.po b/l10n/fr/files.po index 2f7153c3b1..dd7d5c2635 100644 --- a/l10n/fr/files.po +++ b/l10n/fr/files.po @@ -5,6 +5,7 @@ # Translators: # Christophe Lherieau , 2012-2013. # Cyril Glapa , 2012. +# David Basquin , 2013. # , 2013. # Geoffrey Guerrier , 2012. # , 2012. @@ -19,9 +20,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 09:26+0000\n" +"Last-Translator: dbasquin \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -80,7 +81,7 @@ msgstr "Erreur d'écriture sur le disque" #: ajax/upload.php:48 msgid "Not enough storage available" -msgstr "" +msgstr "Plus assez d'espace de stockage disponible" #: ajax/upload.php:77 msgid "Invalid directory." @@ -154,11 +155,11 @@ msgstr "Nom invalide, les caractères '\\', '/', '<', '>', ':', '\"', '|', '?' e #: js/files.js:78 msgid "Your storage is full, files can not be updated or synced anymore!" -msgstr "" +msgstr "Votre espage de stockage est plein, les fichiers ne peuvent plus être téléversés ou synchronisés !" #: js/files.js:82 msgid "Your storage is almost full ({usedSpacePercent}%)" -msgstr "" +msgstr "Votre espace de stockage est presque plein ({usedSpacePercent}%)" #: js/files.js:219 msgid "" diff --git a/l10n/fr/settings.po b/l10n/fr/settings.po index 9f3a6ceea3..c2827253a3 100644 --- a/l10n/fr/settings.po +++ b/l10n/fr/settings.po @@ -22,8 +22,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: French (http://www.transifex.com/projects/p/owncloud/language/fr/)\n" "MIME-Version: 1.0\n" @@ -102,7 +102,7 @@ msgstr "Activer" msgid "Saving..." msgstr "Sauvegarde..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Français" @@ -114,15 +114,15 @@ msgstr "Ajoutez votre application" msgid "More Apps" msgstr "Plus d'applications…" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Sélectionner une Application" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Voir la page des applications à l'url apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "Distribué sous licence , par " @@ -171,7 +171,7 @@ msgstr "Télécharger le client Android" msgid "Download iOS Client" msgstr "Télécharger le client iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Mot de passe" @@ -241,11 +241,11 @@ msgid "" "License\">AGPL." msgstr "Développé par la communauté ownCloud, le code source est publié sous license AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nom" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Groupes" @@ -257,26 +257,30 @@ msgstr "Créer" msgid "Default Storage" msgstr "Support de stockage par défaut" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Illimité" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Autre" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Groupe Admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Support de stockage" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Défaut" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Supprimer" diff --git a/l10n/gl/core.po b/l10n/gl/core.po index 4793450f69..e2701a3713 100644 --- a/l10n/gl/core.po +++ b/l10n/gl/core.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Galician (http://www.transifex.com/projects/p/owncloud/language/gl/)\n" "MIME-Version: 1.0\n" @@ -20,24 +20,24 @@ msgstr "" "Language: gl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "O usuario %s compartíu un ficheiro con vostede" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "O usuario %s compartíu un cartafol con vostede" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "O usuario %s compartiu o ficheiro «%s» con vostede. Teno dispoñíbel en: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -240,8 +240,8 @@ msgid "The object type is not specified." msgstr "Non se especificou o tipo de obxecto." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Erro" @@ -253,119 +253,127 @@ msgstr "Non se especificou o nome do aplicativo." msgid "The required file {file} is not installed!" msgstr "Non está instalado o ficheiro {file} que se precisa" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Produciuse un erro ao compartir" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Produciuse un erro ao deixar de compartir" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Produciuse un erro ao cambiar os permisos" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Compartido con vostede e co grupo {group} por {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Compartido con vostede por {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Compartir con" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Compartir coa ligazón" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Protexido con contrasinais" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Contrasinal" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Enviar ligazón por correo" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Enviar" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Definir a data de caducidade" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Data de caducidade" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Compartir por correo:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Non se atopou xente" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Non se permite volver a compartir" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Compartido en {item} con {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Deixar de compartir" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "pode editar" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "control de acceso" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "crear" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "actualizar" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "eliminar" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "compartir" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protexido con contrasinal" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Produciuse un erro ao retirar a data de caducidade" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Produciuse un erro ao definir a data de caducidade" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Enviando..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Correo enviado" diff --git a/l10n/gl/settings.po b/l10n/gl/settings.po index 428b5f06cd..d5af9d142a 100644 --- a/l10n/gl/settings.po +++ b/l10n/gl/settings.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Galician (http://www.transifex.com/projects/p/owncloud/language/gl/)\n" "MIME-Version: 1.0\n" @@ -90,7 +90,7 @@ msgstr "Activar" msgid "Saving..." msgstr "Gardando..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Galego" @@ -102,15 +102,15 @@ msgstr "Engada o seu aplicativo" msgid "More Apps" msgstr "Máis aplicativos" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Escolla un aplicativo" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Consulte a páxina do aplicativo en apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licenciado por" @@ -159,7 +159,7 @@ msgstr "Descargar clientes para Android" msgid "Download iOS Client" msgstr "Descargar clientes ra iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Contrasinal" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "Desenvolvido pola comunidade ownCloud, o código fonte está baixo a licenza AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nome" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupos" @@ -245,26 +245,30 @@ msgstr "Crear" msgid "Default Storage" msgstr "Almacenamento predeterminado" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Sen límites" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Outro" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupo Admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Almacenamento" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Predeterminado" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Eliminar" diff --git a/l10n/he/core.po b/l10n/he/core.po index b1f45d8c27..c3ae441a83 100644 --- a/l10n/he/core.po +++ b/l10n/he/core.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Hebrew (http://www.transifex.com/projects/p/owncloud/language/he/)\n" "MIME-Version: 1.0\n" @@ -22,24 +22,24 @@ msgstr "" "Language: he\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "המשתמש %s שיתף אתך קובץ" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "המשתמש %s שיתף אתך תיקייה" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "המשתמש %s שיתף אתך את הקובץ „%s“. ניתן להוריד את הקובץ מכאן: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -242,8 +242,8 @@ msgid "The object type is not specified." msgstr "סוג הפריט לא צוין." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "שגיאה" @@ -255,119 +255,127 @@ msgstr "שם היישום לא צוין." msgid "The required file {file} is not installed!" msgstr "הקובץ הנדרש {file} אינו מותקן!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "שגיאה במהלך השיתוף" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "שגיאה במהלך ביטול השיתוף" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "שגיאה במהלך שינוי ההגדרות" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "שותף אתך ועם הקבוצה {group} שבבעלות {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "שותף אתך על ידי {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "שיתוף עם" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "שיתוף עם קישור" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "הגנה בססמה" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "ססמה" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "שליחת קישור בדוא״ל למשתמש" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "שליחה" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "הגדרת תאריך תפוגה" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "תאריך התפוגה" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "שיתוף באמצעות דוא״ל:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "לא נמצאו אנשים" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "אסור לעשות שיתוף מחדש" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "שותף תחת {item} עם {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "הסר שיתוף" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "ניתן לערוך" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "בקרת גישה" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "יצירה" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "עדכון" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "מחיקה" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "שיתוף" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "מוגן בססמה" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "אירעה שגיאה בביטול תאריך התפוגה" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "אירעה שגיאה בעת הגדרת תאריך התפוגה" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "מתבצעת שליחה ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "הודעת הדוא״ל נשלחה" diff --git a/l10n/he/settings.po b/l10n/he/settings.po index 312975f7b1..53f1026fb7 100644 --- a/l10n/he/settings.po +++ b/l10n/he/settings.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Hebrew (http://www.transifex.com/projects/p/owncloud/language/he/)\n" "MIME-Version: 1.0\n" @@ -91,7 +91,7 @@ msgstr "הפעל" msgid "Saving..." msgstr "שומר.." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "עברית" @@ -103,15 +103,15 @@ msgstr "הוספת היישום שלך" msgid "More Apps" msgstr "יישומים נוספים" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "בחירת יישום" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "צפה בעמוד הישום ב apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "ברישיון לטובת " @@ -160,7 +160,7 @@ msgstr "הורד תוכנה לאנדרואיד" msgid "Download iOS Client" msgstr "הורד תוכנה לiOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "ססמה" @@ -230,11 +230,11 @@ msgid "" "License\">AGPL." msgstr "פותח על די קהילתownCloud, קוד המקור מוגן ברישיון AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "שם" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "קבוצות" @@ -246,26 +246,30 @@ msgstr "יצירה" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "אחר" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "מנהל הקבוצה" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "מחיקה" diff --git a/l10n/hi/core.po b/l10n/hi/core.po index d12a2c0b38..3e666c18c7 100644 --- a/l10n/hi/core.po +++ b/l10n/hi/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Hindi (http://www.transifex.com/projects/p/owncloud/language/hi/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: hi\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "" @@ -252,119 +252,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "पासवर्ड" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/hi/settings.po b/l10n/hi/settings.po index b6697b9482..9af2a15148 100644 --- a/l10n/hi/settings.po +++ b/l10n/hi/settings.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Hindi (http://www.transifex.com/projects/p/owncloud/language/hi/)\n" "MIME-Version: 1.0\n" @@ -87,7 +87,7 @@ msgstr "" msgid "Saving..." msgstr "" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "" @@ -99,15 +99,15 @@ msgstr "" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -156,7 +156,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "पासवर्ड" @@ -226,11 +226,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "" @@ -242,26 +242,30 @@ msgstr "" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "" diff --git a/l10n/hr/core.po b/l10n/hr/core.po index 622aa007c7..2959d09753 100644 --- a/l10n/hr/core.po +++ b/l10n/hr/core.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Croatian (http://www.transifex.com/projects/p/owncloud/language/hr/)\n" "MIME-Version: 1.0\n" @@ -21,24 +21,24 @@ msgstr "" "Language: hr\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -241,8 +241,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Pogreška" @@ -254,119 +254,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Greška prilikom djeljenja" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Greška prilikom isključivanja djeljenja" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Greška prilikom promjena prava" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Djeli sa" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Djeli preko link-a" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Zaštiti lozinkom" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Lozinka" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Postavi datum isteka" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Datum isteka" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Dijeli preko email-a:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Osobe nisu pronađene" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Ponovo dijeljenje nije dopušteno" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Makni djeljenje" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "može mjenjat" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "kontrola pristupa" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "kreiraj" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "ažuriraj" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "izbriši" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "djeli" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Zaštita lozinkom" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Greška prilikom brisanja datuma isteka" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Greška prilikom postavljanja datuma isteka" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/hr/settings.po b/l10n/hr/settings.po index 58d40e8089..a8be98c5af 100644 --- a/l10n/hr/settings.po +++ b/l10n/hr/settings.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Croatian (http://www.transifex.com/projects/p/owncloud/language/hr/)\n" "MIME-Version: 1.0\n" @@ -90,7 +90,7 @@ msgstr "Uključi" msgid "Saving..." msgstr "Spremanje..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__ime_jezika__" @@ -102,15 +102,15 @@ msgstr "Dodajte vašu aplikaciju" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Odaberite Aplikaciju" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Pogledajte stranicu s aplikacijama na apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -159,7 +159,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Lozinka" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Ime" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupe" @@ -245,26 +245,30 @@ msgstr "Izradi" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "ostali" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupa Admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Obriši" diff --git a/l10n/hu_HU/core.po b/l10n/hu_HU/core.po index 9f6c2f15f7..4a9be1afdf 100644 --- a/l10n/hu_HU/core.po +++ b/l10n/hu_HU/core.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" @@ -22,24 +22,24 @@ msgstr "" "Language: hu_HU\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "%s felhasználó megosztott Önnel egy fájlt" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "%s felhasználó megosztott Önnel egy mappát" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "%s felhasználó megosztotta ezt az állományt Önnel: %s. A fájl innen tölthető le: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -242,8 +242,8 @@ msgid "The object type is not specified." msgstr "Az objektum típusa nincs megadva." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Hiba" @@ -255,119 +255,127 @@ msgstr "Az alkalmazás neve nincs megadva." msgid "The required file {file} is not installed!" msgstr "A szükséges fájl: {file} nincs telepítve!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Nem sikerült létrehozni a megosztást" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Nem sikerült visszavonni a megosztást" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Nem sikerült módosítani a jogosultságokat" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Megosztotta Önnel és a(z) {group} csoporttal: {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Megosztotta Önnel: {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Kivel osztom meg" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Link megadásával osztom meg" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Jelszóval is védem" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Jelszó" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Email címre küldjük el" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Küldjük el" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Legyen lejárati idő" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "A lejárati idő" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Megosztás emaillel:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Nincs találat" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Ezt az állományt csak a tulajdonosa oszthatja meg másokkal" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Megosztva {item}-ben {user}-rel" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "A megosztás visszavonása" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "módosíthat" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "jogosultság" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "létrehoz" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "szerkeszt" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "töröl" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "megoszt" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Jelszóval van védve" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Nem sikerült a lejárati időt törölni" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Nem sikerült a lejárati időt beállítani" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Küldés ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Az emailt elküldtük" diff --git a/l10n/hu_HU/settings.po b/l10n/hu_HU/settings.po index 95751d8496..5aa7fcfb01 100644 --- a/l10n/hu_HU/settings.po +++ b/l10n/hu_HU/settings.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Hungarian (Hungary) (http://www.transifex.com/projects/p/owncloud/language/hu_HU/)\n" "MIME-Version: 1.0\n" @@ -90,7 +90,7 @@ msgstr "Engedélyezés" msgid "Saving..." msgstr "Mentés..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -102,15 +102,15 @@ msgstr "Az alkalmazás hozzáadása" msgid "More Apps" msgstr "További alkalmazások" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Válasszon egy alkalmazást" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Lásd apps.owncloud.com, alkalmazások oldal" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-a jogtuladonos " @@ -159,7 +159,7 @@ msgstr "Android kliens letöltése" msgid "Download iOS Client" msgstr "iOS kliens letöltése" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Jelszó" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "A programot az ownCloud közösség fejleszti. A forráskód az AGPL feltételei mellett használható föl." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Név" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Csoportok" @@ -245,26 +245,30 @@ msgstr "Létrehozás" msgid "Default Storage" msgstr "Alapértelmezett tárhely" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Korlátlan" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Más" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Csoportadminisztrátor" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Tárhely" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Alapértelmezett" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Törlés" diff --git a/l10n/ia/core.po b/l10n/ia/core.po index 5877ff0082..0c74f32770 100644 --- a/l10n/ia/core.po +++ b/l10n/ia/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Interlingua (http://www.transifex.com/projects/p/owncloud/language/ia/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: ia\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "" @@ -251,119 +251,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Contrasigno" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/ia/settings.po b/l10n/ia/settings.po index f0ff993fa2..8a5f778dd9 100644 --- a/l10n/ia/settings.po +++ b/l10n/ia/settings.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Interlingua (http://www.transifex.com/projects/p/owncloud/language/ia/)\n" "MIME-Version: 1.0\n" @@ -89,7 +89,7 @@ msgstr "" msgid "Saving..." msgstr "" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Interlingua" @@ -101,15 +101,15 @@ msgstr "Adder tu application" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Selectionar un app" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -158,7 +158,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Contrasigno" @@ -228,11 +228,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nomine" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Gruppos" @@ -244,26 +244,30 @@ msgstr "Crear" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Altere" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Deler" diff --git a/l10n/id/core.po b/l10n/id/core.po index b494779608..e3dcf88b98 100644 --- a/l10n/id/core.po +++ b/l10n/id/core.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/owncloud/language/id/)\n" "MIME-Version: 1.0\n" @@ -21,24 +21,24 @@ msgstr "" "Language: id\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -241,8 +241,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "gagal" @@ -254,119 +254,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "gagal ketika membagikan" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "gagal ketika membatalkan pembagian" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "gagal ketika merubah perijinan" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "dibagikan dengan anda dan grup {group} oleh {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "dibagikan dengan anda oleh {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "bagikan dengan" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "bagikan dengan tautan" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "lindungi dengan kata kunci" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Password" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "set tanggal kadaluarsa" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "tanggal kadaluarsa" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "berbagi memlalui surel:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "tidak ada orang ditemukan" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "berbagi ulang tidak diperbolehkan" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "dibagikan dalam {item} dengan {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "batalkan berbagi" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "dapat merubah" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "kontrol akses" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "buat baru" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "baharui" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "hapus" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "bagikan" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "dilindungi kata kunci" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "gagal melepas tanggal kadaluarsa" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "gagal memasang tanggal kadaluarsa" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/id/settings.po b/l10n/id/settings.po index 72ad4e872a..bcaf1c7afe 100644 --- a/l10n/id/settings.po +++ b/l10n/id/settings.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/owncloud/language/id/)\n" "MIME-Version: 1.0\n" @@ -91,7 +91,7 @@ msgstr "Aktifkan" msgid "Saving..." msgstr "Menyimpan..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -103,15 +103,15 @@ msgstr "Tambahkan App anda" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Pilih satu aplikasi" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Lihat halaman aplikasi di apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -160,7 +160,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Password" @@ -230,11 +230,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nama" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Group" @@ -246,26 +246,30 @@ msgstr "Buat" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Lain-lain" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Admin Grup" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Hapus" diff --git a/l10n/is/core.po b/l10n/is/core.po index c8789af9a9..4916011fc4 100644 --- a/l10n/is/core.po +++ b/l10n/is/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Icelandic (http://www.transifex.com/projects/p/owncloud/language/is/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: is\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Notandinn %s deildi skrá með þér" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Notandinn %s deildi möppu með þér" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Notandinn %s deildi skránni \"%s\" með þér. Hægt er að hlaða henni niður hér: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "Tegund ekki tilgreind" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Villa" @@ -252,119 +252,127 @@ msgstr "Nafn forrits ekki tilgreint" msgid "The required file {file} is not installed!" msgstr "Umbeðina skráin {file} ekki tiltæk!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Villa við deilingu" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Villa við að hætta deilingu" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Villa við að breyta aðgangsheimildum" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Deilt með þér og hópnum {group} af {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Deilt með þér af {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Deila með" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Deila með veftengli" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Verja með lykilorði" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Lykilorð" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Senda vefhlekk í tölvupóstu til notenda" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Senda" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Setja gildistíma" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Gildir til" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Deila með tölvupósti:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Engir notendur fundust" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Endurdeiling er ekki leyfð" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Deilt með {item} ásamt {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Hætta deilingu" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "getur breytt" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "aðgangsstýring" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "mynda" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "uppfæra" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "eyða" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "deila" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Verja með lykilorði" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Villa við að aftengja gildistíma" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Villa við að setja gildistíma" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Sendi ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Tölvupóstur sendur" diff --git a/l10n/is/settings.po b/l10n/is/settings.po index 0c0579cec5..15f488a9b2 100644 --- a/l10n/is/settings.po +++ b/l10n/is/settings.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Icelandic (http://www.transifex.com/projects/p/owncloud/language/is/)\n" "MIME-Version: 1.0\n" @@ -88,7 +88,7 @@ msgstr "Virkja" msgid "Saving..." msgstr "Er að vista ..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__nafn_tungumáls__" @@ -100,15 +100,15 @@ msgstr "Bæta við forriti" msgid "More Apps" msgstr "Fleiri forrit" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Veldu forrit" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Skoða síðu forrits hjá apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-leyfi skráð af " @@ -157,7 +157,7 @@ msgstr "Hlaða niður Andoid hugbúnaði" msgid "Download iOS Client" msgstr "Hlaða niður iOS hugbúnaði" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Lykilorð" @@ -227,11 +227,11 @@ msgid "" "License\">AGPL." msgstr "Þróað af ownCloud samfélaginu, forrita kóðinn er skráðu með AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nafn" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Hópar" @@ -243,26 +243,30 @@ msgstr "Búa til" msgid "Default Storage" msgstr "Sjálfgefin gagnageymsla" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Ótakmarkað" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Annað" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Hópstjóri" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "gagnapláss" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Sjálfgefið" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Eyða" diff --git a/l10n/it/core.po b/l10n/it/core.po index 05f4debbee..77ec770b0d 100644 --- a/l10n/it/core.po +++ b/l10n/it/core.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n" "MIME-Version: 1.0\n" @@ -22,24 +22,24 @@ msgstr "" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "L'utente %s ha condiviso un file con te" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "L'utente %s ha condiviso una cartella con te" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "L'utente %s ha condiviso il file \"%s\" con te. È disponibile per lo scaricamento qui: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -242,8 +242,8 @@ msgid "The object type is not specified." msgstr "Il tipo di oggetto non è specificato." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Errore" @@ -255,119 +255,127 @@ msgstr "Il nome dell'applicazione non è specificato." msgid "The required file {file} is not installed!" msgstr "Il file richiesto {file} non è installato!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Errore durante la condivisione" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Errore durante la rimozione della condivisione" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Errore durante la modifica dei permessi" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Condiviso con te e con il gruppo {group} da {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Condiviso con te da {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Condividi con" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Condividi con collegamento" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Proteggi con password" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Password" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Invia collegamento via email" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Invia" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Imposta data di scadenza" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Data di scadenza" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Condividi tramite email:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Non sono state trovate altre persone" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "La ri-condivisione non è consentita" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Condiviso in {item} con {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Rimuovi condivisione" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "può modificare" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "controllo d'accesso" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "creare" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "aggiornare" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "eliminare" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "condividere" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protetta da password" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Errore durante la rimozione della data di scadenza" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Errore durante l'impostazione della data di scadenza" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Invio in corso..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Messaggio inviato" @@ -376,11 +384,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "L'aggiornamento non è riuscito. Segnala il problema alla comunità di ownCloud." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "L'aggiornamento è stato effettuato correttamente. Stai per essere reindirizzato a ownCloud." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/it/settings.po b/l10n/it/settings.po index b8c1b46912..6f1b11dd3f 100644 --- a/l10n/it/settings.po +++ b/l10n/it/settings.po @@ -14,9 +14,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-18 00:03+0100\n" -"PO-Revision-Date: 2013-01-17 08:30+0000\n" -"Last-Translator: ufic \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -94,7 +94,7 @@ msgstr "Abilita" msgid "Saving..." msgstr "Salvataggio in corso..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Italiano" @@ -106,15 +106,15 @@ msgstr "Aggiungi la tua applicazione" msgid "More Apps" msgstr "Altre applicazioni" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Seleziona un'applicazione" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Vedere la pagina dell'applicazione su apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licenziato da " @@ -163,7 +163,7 @@ msgstr "Scarica client Android" msgid "Download iOS Client" msgstr "Scarica client iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Password" @@ -233,11 +233,11 @@ msgid "" "License\">AGPL." msgstr "Sviluppato dalla comunità di ownCloud, il codice sorgente è licenziato nei termini della AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nome" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Gruppi" @@ -249,26 +249,30 @@ msgstr "Crea" msgid "Default Storage" msgstr "Archiviazione predefinita" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Illimitata" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Altro" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Gruppi amministrati" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Archiviazione" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Predefinito" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Elimina" diff --git a/l10n/ja_JP/core.po b/l10n/ja_JP/core.po index 04a4802e9e..76db5f78f9 100644 --- a/l10n/ja_JP/core.po +++ b/l10n/ja_JP/core.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" @@ -20,24 +20,24 @@ msgstr "" "Language: ja_JP\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "ユーザ %s はあなたとファイルを共有しています" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "ユーザ %s はあなたとフォルダを共有しています" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "ユーザ %s はあなたとファイル \"%s\" を共有しています。こちらからダウンロードできます: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -240,8 +240,8 @@ msgid "The object type is not specified." msgstr "オブジェクタイプが指定されていません。" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "エラー" @@ -253,119 +253,127 @@ msgstr "アプリ名がしていされていません。" msgid "The required file {file} is not installed!" msgstr "必要なファイル {file} がインストールされていません!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "共有でエラー発生" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "共有解除でエラー発生" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "権限変更でエラー発生" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "あなたと {owner} のグループ {group} で共有中" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner} と共有中" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "共有者" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "URLリンクで共有" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "パスワード保護" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "パスワード" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "メールリンク" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "送信" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "有効期限を設定" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "有効期限" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "メール経由で共有:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "ユーザーが見つかりません" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "再共有は許可されていません" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "{item} 内で {user} と共有中" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "共有解除" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "編集可能" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "アクセス権限" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "作成" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "更新" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "削除" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "共有" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "パスワード保護" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "有効期限の未設定エラー" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "有効期限の設定でエラー発生" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "送信中..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "メールを送信しました" @@ -374,11 +382,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "更新に成功しました。この問題を ownCloud community にレポートしてください。" #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "更新に成功しました。今すぐownCloudにリダイレクトします。" #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/ja_JP/files.po b/l10n/ja_JP/files.po index 0c460e04c9..5a4b882085 100644 --- a/l10n/ja_JP/files.po +++ b/l10n/ja_JP/files.po @@ -11,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 01:10+0000\n" +"Last-Translator: Daisuke Deguchi \n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -72,7 +72,7 @@ msgstr "ディスクへの書き込みに失敗しました" #: ajax/upload.php:48 msgid "Not enough storage available" -msgstr "" +msgstr "ストレージに十分な空き容量がありません" #: ajax/upload.php:77 msgid "Invalid directory." @@ -146,11 +146,11 @@ msgstr "無効な名前、'\\', '/', '<', '>', ':', '\"', '|', '?', '*' は使 #: js/files.js:78 msgid "Your storage is full, files can not be updated or synced anymore!" -msgstr "" +msgstr "あなたのストレージは一杯です。ファイルの更新と同期はもうできません!" #: js/files.js:82 msgid "Your storage is almost full ({usedSpacePercent}%)" -msgstr "" +msgstr "あなたのストレージはほぼ一杯です({usedSpacePercent}%)" #: js/files.js:219 msgid "" diff --git a/l10n/ja_JP/settings.po b/l10n/ja_JP/settings.po index 69bbdf54d2..4871013dbf 100644 --- a/l10n/ja_JP/settings.po +++ b/l10n/ja_JP/settings.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Japanese (Japan) (http://www.transifex.com/projects/p/owncloud/language/ja_JP/)\n" "MIME-Version: 1.0\n" @@ -91,7 +91,7 @@ msgstr "有効" msgid "Saving..." msgstr "保存中..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Japanese (日本語)" @@ -103,15 +103,15 @@ msgstr "アプリを追加" msgid "More Apps" msgstr "さらにアプリを表示" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "アプリを選択してください" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "apps.owncloud.com でアプリケーションのページを見てください" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-ライセンス: " @@ -160,7 +160,7 @@ msgstr "Androidクライアントをダウンロード" msgid "Download iOS Client" msgstr "iOSクライアントをダウンロード" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "パスワード" @@ -230,11 +230,11 @@ msgid "" "License\">AGPL." msgstr "ownCloud communityにより開発されています、ソースコードライセンスは、AGPL ライセンスにより提供されています。" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "名前" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "グループ" @@ -246,26 +246,30 @@ msgstr "作成" msgid "Default Storage" msgstr "デフォルトストレージ" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "無制限" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "その他" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "グループ管理者" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "ストレージ" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "デフォルト" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "削除" diff --git a/l10n/ka_GE/core.po b/l10n/ka_GE/core.po index f857fdbb75..87ed1f83cd 100644 --- a/l10n/ka_GE/core.po +++ b/l10n/ka_GE/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Georgian (Georgia) (http://www.transifex.com/projects/p/owncloud/language/ka_GE/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: ka_GE\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "შეცდომა" @@ -251,119 +251,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "შეცდომა გაზიარების დროს" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "შეცდომა გაზიარების გაუქმების დროს" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "შეცდომა დაშვების ცვლილების დროს" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "გაუზიარე" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "გაუზიარე ლინკით" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "პაროლით დაცვა" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "პაროლი" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "მიუთითე ვადის გასვლის დრო" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "ვადის გასვლის დრო" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "გააზიარე მეილზე" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "გვერდი არ არის ნაპოვნი" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "მეორეჯერ გაზიარება არ არის დაშვებული" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "გაზიარების მოხსნა" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "შეგიძლია შეცვლა" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "დაშვების კონტროლი" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "შექმნა" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "განახლება" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "წაშლა" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "გაზიარება" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "პაროლით დაცული" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "შეცდომა ვადის გასვლის მოხსნის დროს" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "შეცდომა ვადის გასვლის მითითების დროს" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/ka_GE/settings.po b/l10n/ka_GE/settings.po index 4fe1200ec3..3f35403cfa 100644 --- a/l10n/ka_GE/settings.po +++ b/l10n/ka_GE/settings.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Georgian (Georgia) (http://www.transifex.com/projects/p/owncloud/language/ka_GE/)\n" "MIME-Version: 1.0\n" @@ -88,7 +88,7 @@ msgstr "ჩართვა" msgid "Saving..." msgstr "შენახვა..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -100,15 +100,15 @@ msgstr "დაამატე შენი აპლიკაცია" msgid "More Apps" msgstr "უფრო მეტი აპლიკაციები" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "აირჩიეთ აპლიკაცია" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "ნახეთ აპლიკაციის გვერდი apps.owncloud.com –ზე" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-ლიცენსირებულია " @@ -157,7 +157,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "პაროლი" @@ -227,11 +227,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "სახელი" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "ჯგუფი" @@ -243,26 +243,30 @@ msgstr "შექმნა" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "სხვა" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "ჯგუფის ადმინისტრატორი" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "წაშლა" diff --git a/l10n/ko/core.po b/l10n/ko/core.po index 5ecb5b45c2..8ba96b125b 100644 --- a/l10n/ko/core.po +++ b/l10n/ko/core.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Korean (http://www.transifex.com/projects/p/owncloud/language/ko/)\n" "MIME-Version: 1.0\n" @@ -21,24 +21,24 @@ msgstr "" "Language: ko\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "User %s 가 당신과 파일을 공유하였습니다." -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "User %s 가 당신과 폴더를 공유하였습니다." -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "User %s 가 파일 \"%s\"를 당신과 공유하였습니다. 다운로드는 여기서 %s 할 수 있습니다." -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -241,8 +241,8 @@ msgid "The object type is not specified." msgstr "객체 유형이 지정되지 않았습니다." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "오류" @@ -254,119 +254,127 @@ msgstr "앱 이름이 지정되지 않았습니다." msgid "The required file {file} is not installed!" msgstr "필요한 파일 {file}이(가) 설치되지 않았습니다!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "공유하는 중 오류 발생" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "공유 해제하는 중 오류 발생" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "권한 변경하는 중 오류 발생" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "{owner} 님이 여러분 및 그룹 {group}와(과) 공유 중" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner} 님이 공유 중" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "다음으로 공유" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "URL 링크로 공유" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "암호 보호" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "암호" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "이메일 주소" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "전송" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "만료 날짜 설정" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "만료 날짜" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "이메일로 공유:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "발견된 사람 없음" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "다시 공유할 수 없습니다" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "{user} 님과 {item}에서 공유 중" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "공유 해제" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "편집 가능" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "접근 제어" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "만들기" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "업데이트" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "삭제" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "공유" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "암호로 보호됨" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "만료 날짜 해제 오류" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "만료 날짜 설정 오류" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "전송 중..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "이메일 발송됨" diff --git a/l10n/ko/settings.po b/l10n/ko/settings.po index cf07cd9528..2236af6d9c 100644 --- a/l10n/ko/settings.po +++ b/l10n/ko/settings.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Korean (http://www.transifex.com/projects/p/owncloud/language/ko/)\n" "MIME-Version: 1.0\n" @@ -92,7 +92,7 @@ msgstr "활성화" msgid "Saving..." msgstr "저장 중..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "한국어" @@ -104,15 +104,15 @@ msgstr "앱 추가" msgid "More Apps" msgstr "더 많은 앱" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "앱 선택" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "apps.owncloud.com에 있는 앱 페이지를 참고하십시오" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-라이선스 보유자 " @@ -161,7 +161,7 @@ msgstr "안드로이드 클라이언트 다운로드" msgid "Download iOS Client" msgstr "iOS 클라이언트 다운로드" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "암호" @@ -231,11 +231,11 @@ msgid "" "License\">AGPL." msgstr "ownCloud 커뮤니티에 의해서 개발되었습니다. 원본 코드AGPL에 따라 사용이 허가됩니다." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "이름" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "그룹" @@ -247,26 +247,30 @@ msgstr "만들기" msgid "Default Storage" msgstr "기본 저장소" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "무제한" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "기타" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "그룹 관리자" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "저장소" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "기본값" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "삭제" diff --git a/l10n/ku_IQ/core.po b/l10n/ku_IQ/core.po index ebd1bfcf4e..b06563d753 100644 --- a/l10n/ku_IQ/core.po +++ b/l10n/ku_IQ/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Kurdish (Iraq) (http://www.transifex.com/projects/p/owncloud/language/ku_IQ/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: ku_IQ\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "هه‌ڵه" @@ -251,119 +251,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "وشەی تێپەربو" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/ku_IQ/settings.po b/l10n/ku_IQ/settings.po index 75dbd11b7b..db582696a9 100644 --- a/l10n/ku_IQ/settings.po +++ b/l10n/ku_IQ/settings.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Kurdish (Iraq) (http://www.transifex.com/projects/p/owncloud/language/ku_IQ/)\n" "MIME-Version: 1.0\n" @@ -87,7 +87,7 @@ msgstr "چالاککردن" msgid "Saving..." msgstr "پاشکه‌وتده‌کات..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "" @@ -99,15 +99,15 @@ msgstr "" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -156,7 +156,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "وشەی تێپەربو" @@ -226,11 +226,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "ناو" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "" @@ -242,26 +242,30 @@ msgstr "" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "" diff --git a/l10n/lb/core.po b/l10n/lb/core.po index 9d252a5e5f..cf61dda08c 100644 --- a/l10n/lb/core.po +++ b/l10n/lb/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Luxembourgish (http://www.transifex.com/projects/p/owncloud/language/lb/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: lb\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Fehler" @@ -252,119 +252,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Passwuert" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Net méi deelen" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "erstellen" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "läschen" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "deelen" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/lb/settings.po b/l10n/lb/settings.po index 2bb5692c23..ffe1d795a6 100644 --- a/l10n/lb/settings.po +++ b/l10n/lb/settings.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Luxembourgish (http://www.transifex.com/projects/p/owncloud/language/lb/)\n" "MIME-Version: 1.0\n" @@ -88,7 +88,7 @@ msgstr "Aschalten" msgid "Saving..." msgstr "Speicheren..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -100,15 +100,15 @@ msgstr "Setz deng App bei" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Wiel eng Applikatioun aus" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Kuck dir d'Applicatioun's Säit op apps.owncloud.com un" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -157,7 +157,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Passwuert" @@ -227,11 +227,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Numm" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Gruppen" @@ -243,26 +243,30 @@ msgstr "Erstellen" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Aner" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Gruppen Admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Läschen" diff --git a/l10n/lt_LT/core.po b/l10n/lt_LT/core.po index 6d984807ac..a6aff9a772 100644 --- a/l10n/lt_LT/core.po +++ b/l10n/lt_LT/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Lithuanian (Lithuania) (http://www.transifex.com/projects/p/owncloud/language/lt_LT/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: lt_LT\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Klaida" @@ -252,119 +252,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Klaida, dalijimosi metu" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Klaida, kai atšaukiamas dalijimasis" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Klaida, keičiant privilegijas" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Pasidalino su Jumis ir {group} grupe {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Pasidalino su Jumis {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Dalintis su" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Dalintis nuoroda" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Apsaugotas slaptažodžiu" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Slaptažodis" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Nustatykite galiojimo laiką" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Galiojimo laikas" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Dalintis per el. paštą:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Žmonių nerasta" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Dalijinasis išnaujo negalimas" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Pasidalino {item} su {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Nesidalinti" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "gali redaguoti" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "priėjimo kontrolė" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "sukurti" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "atnaujinti" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "ištrinti" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "dalintis" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Apsaugota slaptažodžiu" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Klaida nuimant galiojimo laiką" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Klaida nustatant galiojimo laiką" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/lt_LT/settings.po b/l10n/lt_LT/settings.po index 91d9a303f5..4c4d82e432 100644 --- a/l10n/lt_LT/settings.po +++ b/l10n/lt_LT/settings.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Lithuanian (Lithuania) (http://www.transifex.com/projects/p/owncloud/language/lt_LT/)\n" "MIME-Version: 1.0\n" @@ -89,7 +89,7 @@ msgstr "Įjungti" msgid "Saving..." msgstr "Saugoma.." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Kalba" @@ -101,15 +101,15 @@ msgstr "Pridėti programėlę" msgid "More Apps" msgstr "Daugiau aplikacijų" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Pasirinkite programą" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "- autorius" @@ -158,7 +158,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Slaptažodis" @@ -228,11 +228,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Vardas" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupės" @@ -244,26 +244,30 @@ msgstr "Sukurti" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Kita" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Ištrinti" diff --git a/l10n/lv/core.po b/l10n/lv/core.po index 162f927ac5..723dfe3b85 100644 --- a/l10n/lv/core.po +++ b/l10n/lv/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Latvian (http://www.transifex.com/projects/p/owncloud/language/lv/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: lv\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Kļūme" @@ -251,119 +251,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Parole" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Pārtraukt līdzdalīšanu" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/lv/settings.po b/l10n/lv/settings.po index bbb16fb2fa..afc2514715 100644 --- a/l10n/lv/settings.po +++ b/l10n/lv/settings.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-28 00:05+0100\n" -"PO-Revision-Date: 2013-01-27 11:50+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Latvian (http://www.transifex.com/projects/p/owncloud/language/lv/)\n" "MIME-Version: 1.0\n" @@ -158,7 +158,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:80 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Parole" @@ -229,10 +229,10 @@ msgid "" msgstr "IzstrādājusiownCloud kopiena,pirmkodukurš ir licencēts zem AGPL." #: templates/users.php:21 templates/users.php:79 -msgid "Name" -msgstr "Vārds" +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:81 templates/users.php:101 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupas" @@ -244,26 +244,30 @@ msgstr "Izveidot" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:136 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:151 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Cits" -#: templates/users.php:83 templates/users.php:115 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupas administrators" -#: templates/users.php:85 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:131 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:159 +#: templates/users.php:165 msgid "Delete" msgstr "Izdzēst" diff --git a/l10n/mk/core.po b/l10n/mk/core.po index c61a11bf71..a6cc634a95 100644 --- a/l10n/mk/core.po +++ b/l10n/mk/core.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Macedonian (http://www.transifex.com/projects/p/owncloud/language/mk/)\n" "MIME-Version: 1.0\n" @@ -20,24 +20,24 @@ msgstr "" "Language: mk\n" "Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Корисникот %s сподели датотека со Вас" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Корисникот %s сподели папка со Вас" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Корисникот %s ја сподели датотека „%s“ со Вас. Достапна е за преземање тука: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -240,8 +240,8 @@ msgid "The object type is not specified." msgstr "Не е специфициран типот на објект." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Грешка" @@ -253,119 +253,127 @@ msgstr "Името на апликацијата не е специфицира msgid "The required file {file} is not installed!" msgstr "Задолжителната датотека {file} не е инсталирана!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Грешка при споделување" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Грешка при прекин на споделување" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Грешка при промена на привилегии" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Споделено со Вас и групата {group} од {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Споделено со Вас од {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Сподели со" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Сподели со врска" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Заштити со лозинка" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Лозинка" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Прати врска по е-пошта на личност" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Прати" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Постави рок на траење" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Рок на траење" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Сподели по е-пошта:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Не се најдени луѓе" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Повторно споделување не е дозволено" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Споделено во {item} со {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Не споделувај" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "може да се измени" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "контрола на пристап" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "креирај" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "ажурирај" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "избриши" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "сподели" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Заштитено со лозинка" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Грешка при тргање на рокот на траење" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Грешка при поставување на рок на траење" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Праќање..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Е-порака пратена" diff --git a/l10n/mk/settings.po b/l10n/mk/settings.po index 4a9325a566..8468db8e1a 100644 --- a/l10n/mk/settings.po +++ b/l10n/mk/settings.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Macedonian (http://www.transifex.com/projects/p/owncloud/language/mk/)\n" "MIME-Version: 1.0\n" @@ -90,7 +90,7 @@ msgstr "Овозможи" msgid "Saving..." msgstr "Снимам..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -102,15 +102,15 @@ msgstr "Додадете ја Вашата апликација" msgid "More Apps" msgstr "Повеќе аппликации" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Избери аппликација" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Види ја страницата со апликации на apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-лиценцирано од " @@ -159,7 +159,7 @@ msgstr "Преземи клиент за Андроид" msgid "Download iOS Client" msgstr "Преземи iOS клиент" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Лозинка" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "Развој од ownCloud заедницата, изворниот код е лиценциран соAGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Име" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Групи" @@ -245,26 +245,30 @@ msgstr "Создај" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Останато" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Администратор на група" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Избриши" diff --git a/l10n/ms_MY/core.po b/l10n/ms_MY/core.po index fdf1f32abf..3a62b70434 100644 --- a/l10n/ms_MY/core.po +++ b/l10n/ms_MY/core.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Malay (Malaysia) (http://www.transifex.com/projects/p/owncloud/language/ms_MY/)\n" "MIME-Version: 1.0\n" @@ -20,24 +20,24 @@ msgstr "" "Language: ms_MY\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -240,8 +240,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Ralat" @@ -253,119 +253,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Kata laluan" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/ms_MY/settings.po b/l10n/ms_MY/settings.po index 72694ffcb9..020c1d29f4 100644 --- a/l10n/ms_MY/settings.po +++ b/l10n/ms_MY/settings.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Malay (Malaysia) (http://www.transifex.com/projects/p/owncloud/language/ms_MY/)\n" "MIME-Version: 1.0\n" @@ -91,7 +91,7 @@ msgstr "Aktif" msgid "Saving..." msgstr "Simpan..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "_nama_bahasa_" @@ -103,15 +103,15 @@ msgstr "Tambah apps anda" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Pilih aplikasi" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Lihat halaman applikasi di apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -160,7 +160,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Kata laluan " @@ -230,11 +230,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nama" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Kumpulan" @@ -246,26 +246,30 @@ msgstr "Buat" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Lain" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Padam" diff --git a/l10n/nb_NO/core.po b/l10n/nb_NO/core.po index ed2239b920..cf8ff804cf 100644 --- a/l10n/nb_NO/core.po +++ b/l10n/nb_NO/core.po @@ -14,8 +14,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Norwegian Bokmål (Norway) (http://www.transifex.com/projects/p/owncloud/language/nb_NO/)\n" "MIME-Version: 1.0\n" @@ -24,24 +24,24 @@ msgstr "" "Language: nb_NO\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -244,8 +244,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Feil" @@ -257,119 +257,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Feil under deling" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Del med" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Del med link" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Passordbeskyttet" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Passord" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Send" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Set utløpsdato" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Utløpsdato" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Del på epost" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Ingen personer funnet" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Avslutt deling" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "kan endre" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "tilgangskontroll" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "opprett" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "oppdater" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "slett" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "del" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Passordbeskyttet" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Kan ikke sette utløpsdato" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Sender..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "E-post sendt" diff --git a/l10n/nb_NO/settings.po b/l10n/nb_NO/settings.po index 90871dc382..15ea0f7eb6 100644 --- a/l10n/nb_NO/settings.po +++ b/l10n/nb_NO/settings.po @@ -15,8 +15,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Norwegian Bokmål (Norway) (http://www.transifex.com/projects/p/owncloud/language/nb_NO/)\n" "MIME-Version: 1.0\n" @@ -95,7 +95,7 @@ msgstr "Slå på" msgid "Saving..." msgstr "Lagrer..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -107,15 +107,15 @@ msgstr "Legg til din App" msgid "More Apps" msgstr "Flere Apps" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Velg en app" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Se applikasjonens side på apps.owncloud.org" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -164,7 +164,7 @@ msgstr "Last ned Android-klient" msgid "Download iOS Client" msgstr "Last ned iOS-klient" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Passord" @@ -234,11 +234,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Navn" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupper" @@ -250,26 +250,30 @@ msgstr "Opprett" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Annet" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Gruppeadministrator" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Slett" diff --git a/l10n/nl/core.po b/l10n/nl/core.po index a232fc131b..e331b66a8d 100644 --- a/l10n/nl/core.po +++ b/l10n/nl/core.po @@ -21,8 +21,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Dutch (http://www.transifex.com/projects/p/owncloud/language/nl/)\n" "MIME-Version: 1.0\n" @@ -31,24 +31,24 @@ msgstr "" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Gebruiker %s deelde een bestand met u" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Gebruiker %s deelde een map met u" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Gebruiker %s deelde bestand \"%s\" met u. Het is hier te downloaden: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -251,8 +251,8 @@ msgid "The object type is not specified." msgstr "Het object type is niet gespecificeerd." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Fout" @@ -264,119 +264,127 @@ msgstr "De app naam is niet gespecificeerd." msgid "The required file {file} is not installed!" msgstr "Het vereiste bestand {file} is niet geïnstalleerd!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Fout tijdens het delen" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Fout tijdens het stoppen met delen" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Fout tijdens het veranderen van permissies" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Gedeeld met u en de groep {group} door {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Gedeeld met u door {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Deel met" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Deel met link" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Wachtwoord beveiliging" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Wachtwoord" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "E-mail link naar persoon" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Versturen" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Stel vervaldatum in" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Vervaldatum" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Deel via email:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Geen mensen gevonden" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Verder delen is niet toegestaan" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Gedeeld in {item} met {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Stop met delen" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "kan wijzigen" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "toegangscontrole" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "maak" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "bijwerken" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "verwijderen" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "deel" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Wachtwoord beveiligd" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Fout tijdens het verwijderen van de verval datum" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Fout tijdens het instellen van de vervaldatum" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Versturen ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "E-mail verzonden" diff --git a/l10n/nl/settings.po b/l10n/nl/settings.po index 792081672e..d3d08ece02 100644 --- a/l10n/nl/settings.po +++ b/l10n/nl/settings.po @@ -18,8 +18,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Dutch (http://www.transifex.com/projects/p/owncloud/language/nl/)\n" "MIME-Version: 1.0\n" @@ -98,7 +98,7 @@ msgstr "Inschakelen" msgid "Saving..." msgstr "Aan het bewaren....." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Nederlands" @@ -110,15 +110,15 @@ msgstr "App toevoegen" msgid "More Apps" msgstr "Meer apps" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Selecteer een app" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Zie de applicatiepagina op apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-Gelicenseerd door " @@ -167,7 +167,7 @@ msgstr "Download Android Client" msgid "Download iOS Client" msgstr "Download iOS Client" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Wachtwoord" @@ -237,11 +237,11 @@ msgid "" "License\">AGPL." msgstr "Ontwikkeld door de ownCloud gemeenschap, de bron code is gelicenseerd onder de AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Naam" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Groepen" @@ -253,26 +253,30 @@ msgstr "Creëer" msgid "Default Storage" msgstr "Default opslag" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Ongelimiteerd" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Andere" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Groep beheerder" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Opslag" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Default" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "verwijderen" diff --git a/l10n/nn_NO/core.po b/l10n/nn_NO/core.po index 80e254ec6c..f50e25d950 100644 --- a/l10n/nn_NO/core.po +++ b/l10n/nn_NO/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Norwegian Nynorsk (Norway) (http://www.transifex.com/projects/p/owncloud/language/nn_NO/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: nn_NO\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Feil" @@ -252,119 +252,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Passord" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/nn_NO/settings.po b/l10n/nn_NO/settings.po index 3eb12c318a..cb70f810e6 100644 --- a/l10n/nn_NO/settings.po +++ b/l10n/nn_NO/settings.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Norwegian Nynorsk (Norway) (http://www.transifex.com/projects/p/owncloud/language/nn_NO/)\n" "MIME-Version: 1.0\n" @@ -89,7 +89,7 @@ msgstr "Slå på" msgid "Saving..." msgstr "" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Nynorsk" @@ -101,15 +101,15 @@ msgstr "" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Vel ein applikasjon" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -158,7 +158,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Passord" @@ -228,11 +228,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Namn" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupper" @@ -244,26 +244,30 @@ msgstr "Lag" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Anna" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Slett" diff --git a/l10n/oc/core.po b/l10n/oc/core.po index 42a51ae831..11903a2bbc 100644 --- a/l10n/oc/core.po +++ b/l10n/oc/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Occitan (post 1500) (http://www.transifex.com/projects/p/owncloud/language/oc/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: oc\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Error" @@ -251,119 +251,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Error al partejar" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Error al non partejar" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Error al cambiar permissions" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Parteja amb" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Parteja amb lo ligam" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Parat per senhal" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Senhal" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Met la data d'expiracion" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Data d'expiracion" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Parteja tras corrièl :" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Deguns trobat" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Tornar partejar es pas permis" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Non parteje" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "pòt modificar" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "Contraròtle d'acces" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "crea" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "met a jorn" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "escafa" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "parteja" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Parat per senhal" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Error al metre de la data d'expiracion" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Error setting expiration date" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/oc/settings.po b/l10n/oc/settings.po index df76be9ca6..624ac3293f 100644 --- a/l10n/oc/settings.po +++ b/l10n/oc/settings.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Occitan (post 1500) (http://www.transifex.com/projects/p/owncloud/language/oc/)\n" "MIME-Version: 1.0\n" @@ -88,7 +88,7 @@ msgstr "Activa" msgid "Saving..." msgstr "Enregistra..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -100,15 +100,15 @@ msgstr "Ajusta ton App" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Selecciona una applicacion" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Agacha la pagina d'applications en cò de apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licençiat per " @@ -157,7 +157,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Senhal" @@ -227,11 +227,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nom" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grops" @@ -243,26 +243,30 @@ msgstr "Crea" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Autres" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grop Admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Escafa" diff --git a/l10n/pl/core.po b/l10n/pl/core.po index 52a8115b6f..ba00a2aa5f 100644 --- a/l10n/pl/core.po +++ b/l10n/pl/core.po @@ -17,8 +17,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Polish (http://www.transifex.com/projects/p/owncloud/language/pl/)\n" "MIME-Version: 1.0\n" @@ -27,24 +27,24 @@ msgstr "" "Language: pl\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Użytkownik %s współdzieli plik z tobą" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Uzytkownik %s wspóldzieli folder z toba" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Użytkownik %s współdzieli plik \"%s\" z tobą. Jest dostępny tutaj: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -247,8 +247,8 @@ msgid "The object type is not specified." msgstr "Typ obiektu nie jest określony." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Błąd" @@ -260,119 +260,127 @@ msgstr "Nazwa aplikacji nie jest określona." msgid "The required file {file} is not installed!" msgstr "Żądany plik {file} nie jest zainstalowany!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Błąd podczas współdzielenia" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Błąd podczas zatrzymywania współdzielenia" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Błąd przy zmianie uprawnień" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Udostępnione Tobie i grupie {group} przez {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Udostępnione Ci przez {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Współdziel z" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Współdziel z link" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Zabezpieczone hasłem" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Hasło" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Email do osoby" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Wyślij" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Ustaw datę wygaśnięcia" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Data wygaśnięcia" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Współdziel poprzez maila" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Nie znaleziono ludzi" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Współdzielenie nie jest możliwe" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Współdzielone w {item} z {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Zatrzymaj współdzielenie" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "można edytować" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "kontrola dostępu" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "utwórz" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "uaktualnij" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "usuń" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "współdziel" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Zabezpieczone hasłem" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Błąd niszczenie daty wygaśnięcia" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Błąd podczas ustawiania daty wygaśnięcia" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Wysyłanie..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Wyślij Email" diff --git a/l10n/pl/settings.po b/l10n/pl/settings.po index e54af3f5f7..3bca8654b8 100644 --- a/l10n/pl/settings.po +++ b/l10n/pl/settings.po @@ -18,9 +18,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" -"PO-Revision-Date: 2013-01-20 19:42+0000\n" -"Last-Translator: b13n1u \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Polish (http://www.transifex.com/projects/p/owncloud/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -98,7 +98,7 @@ msgstr "Włącz" msgid "Saving..." msgstr "Zapisywanie..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Polski" @@ -110,15 +110,15 @@ msgstr "Dodaj aplikacje" msgid "More Apps" msgstr "Więcej aplikacji" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Zaznacz aplikacje" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Zobacz stronę aplikacji na apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licencjonowane przez " @@ -167,7 +167,7 @@ msgstr "Pobierz klienta dla Androida" msgid "Download iOS Client" msgstr "Pobierz klienta dla iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Hasło" @@ -237,11 +237,11 @@ msgid "" "License\">AGPL." msgstr "Stworzone przez społeczność ownCloud, the kod źródłowy na licencji AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nazwa" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupy" @@ -253,26 +253,30 @@ msgstr "Utwórz" msgid "Default Storage" msgstr "Domyślny magazyn" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Bez limitu" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Inne" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupa Admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Magazyn" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Domyślny" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Usuń" diff --git a/l10n/pl_PL/core.po b/l10n/pl_PL/core.po index 76d2832d70..7f8272bc08 100644 --- a/l10n/pl_PL/core.po +++ b/l10n/pl_PL/core.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Polish (Poland) (http://www.transifex.com/projects/p/owncloud/language/pl_PL/)\n" "MIME-Version: 1.0\n" @@ -17,24 +17,24 @@ msgstr "" "Language: pl_PL\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -237,8 +237,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "" @@ -250,119 +250,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/pl_PL/settings.po b/l10n/pl_PL/settings.po index 5689bcb950..3bf2e6878b 100644 --- a/l10n/pl_PL/settings.po +++ b/l10n/pl_PL/settings.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Polish (Poland) (http://www.transifex.com/projects/p/owncloud/language/pl_PL/)\n" "MIME-Version: 1.0\n" @@ -87,7 +87,7 @@ msgstr "" msgid "Saving..." msgstr "" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "" @@ -99,15 +99,15 @@ msgstr "" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -156,7 +156,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "" @@ -226,11 +226,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "" @@ -242,26 +242,30 @@ msgstr "" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "" diff --git a/l10n/pt_BR/core.po b/l10n/pt_BR/core.po index ce6840b2ee..843960355d 100644 --- a/l10n/pt_BR/core.po +++ b/l10n/pt_BR/core.po @@ -17,8 +17,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/owncloud/language/pt_BR/)\n" "MIME-Version: 1.0\n" @@ -27,24 +27,24 @@ msgstr "" "Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -247,8 +247,8 @@ msgid "The object type is not specified." msgstr "O tipo de objeto não foi especificado." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Erro" @@ -260,119 +260,127 @@ msgstr "O nome do app não foi especificado." msgid "The required file {file} is not installed!" msgstr "O arquivo {file} necessário não está instalado!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Erro ao compartilhar" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Erro ao descompartilhar" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Erro ao mudar permissões" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Compartilhado com você e com o grupo {group} por {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Compartilhado com você por {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Compartilhar com" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Compartilhar com link" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Proteger com senha" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Senha" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Definir data de expiração" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Data de expiração" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Compartilhar via e-mail:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Nenhuma pessoa encontrada" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Não é permitido re-compartilhar" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Compartilhado em {item} com {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Descompartilhar" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "pode editar" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "controle de acesso" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "criar" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "atualizar" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "remover" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "compartilhar" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protegido com senha" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Erro ao remover data de expiração" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Erro ao definir data de expiração" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/pt_BR/settings.po b/l10n/pt_BR/settings.po index 30c7088ec9..06a011df78 100644 --- a/l10n/pt_BR/settings.po +++ b/l10n/pt_BR/settings.po @@ -17,9 +17,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-21 00:04+0100\n" -"PO-Revision-Date: 2013-01-20 20:18+0000\n" -"Last-Translator: rodrigost23 \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/owncloud/language/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -97,7 +97,7 @@ msgstr "Habilitado" msgid "Saving..." msgstr "Gravando..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Português do Brasil" @@ -109,15 +109,15 @@ msgstr "Adicione seu Aplicativo" msgid "More Apps" msgstr "Mais Apps" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Selecione uma Aplicação" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Ver página do aplicativo em apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licenciado por " @@ -166,7 +166,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Senha" @@ -236,11 +236,11 @@ msgid "" "License\">AGPL." msgstr "Desenvolvido pela comunidade ownCloud, o código fonte está licenciado sob AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nome" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupos" @@ -252,26 +252,30 @@ msgstr "Criar" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Outro" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupo Administrativo" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Apagar" diff --git a/l10n/pt_PT/core.po b/l10n/pt_PT/core.po index 095cb39729..afaa00874d 100644 --- a/l10n/pt_PT/core.po +++ b/l10n/pt_PT/core.po @@ -4,6 +4,7 @@ # # Translators: # , 2012-2013. +# Daniel Pinto , 2013. # , 2013. # Duarte Velez Grilo , 2012. # , 2011, 2012. @@ -14,8 +15,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/owncloud/language/pt_PT/)\n" "MIME-Version: 1.0\n" @@ -24,24 +25,24 @@ msgstr "" "Language: pt_PT\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "O utilizador %s partilhou um ficheiro consigo." -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "O utilizador %s partilhou uma pasta consigo." -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "O utilizador %s partilhou o ficheiro \"%s\" consigo. Está disponível para download aqui: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -244,8 +245,8 @@ msgid "The object type is not specified." msgstr "O tipo de objecto não foi especificado" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Erro" @@ -257,119 +258,127 @@ msgstr "O nome da aplicação não foi especificado" msgid "The required file {file} is not installed!" msgstr "O ficheiro necessário {file} não está instalado!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Erro ao partilhar" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Erro ao deixar de partilhar" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Erro ao mudar permissões" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Partilhado consigo e com o grupo {group} por {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Partilhado consigo por {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Partilhar com" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Partilhar com link" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Proteger com palavra-passe" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Palavra chave" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Enviar o link por e-mail" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Enviar" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Especificar data de expiração" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Data de expiração" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Partilhar via email:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Não foi encontrado ninguém" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Não é permitido partilhar de novo" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Partilhado em {item} com {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Deixar de partilhar" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "pode editar" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "Controlo de acesso" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "criar" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "actualizar" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "apagar" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "partilhar" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protegido com palavra-passe" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Erro ao retirar a data de expiração" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Erro ao aplicar a data de expiração" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "A Enviar..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "E-mail enviado" @@ -378,11 +387,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "A actualização falhou. Por favor reporte este incidente seguindo este link ownCloud community." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "A actualização foi concluída com sucesso. Vai ser redireccionado para o ownCloud agora." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/pt_PT/settings.po b/l10n/pt_PT/settings.po index 3d663773c5..a2de9c1e4c 100644 --- a/l10n/pt_PT/settings.po +++ b/l10n/pt_PT/settings.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/owncloud/language/pt_PT/)\n" "MIME-Version: 1.0\n" @@ -92,7 +92,7 @@ msgstr "Activar" msgid "Saving..." msgstr "A guardar..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -104,15 +104,15 @@ msgstr "Adicione a sua aplicação" msgid "More Apps" msgstr "Mais Aplicações" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Selecione uma aplicação" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Ver a página da aplicação em apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licenciado por " @@ -161,7 +161,7 @@ msgstr "Transferir o cliente android" msgid "Download iOS Client" msgstr "Transferir o cliente iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Palavra-chave" @@ -231,11 +231,11 @@ msgid "" "License\">AGPL." msgstr "Desenvolvido pela comunidade ownCloud, ocódigo fonte está licenciado sob a AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nome" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupos" @@ -247,26 +247,30 @@ msgstr "Criar" msgid "Default Storage" msgstr "Armazenamento Padrão" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Ilimitado" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Outro" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupo Administrador" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Armazenamento" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Padrão" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Apagar" diff --git a/l10n/ro/core.po b/l10n/ro/core.po index 3d027cef26..8bf554fdbe 100644 --- a/l10n/ro/core.po +++ b/l10n/ro/core.po @@ -13,8 +13,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Romanian (http://www.transifex.com/projects/p/owncloud/language/ro/)\n" "MIME-Version: 1.0\n" @@ -23,24 +23,24 @@ msgstr "" "Language: ro\n" "Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Utilizatorul %s a partajat un fișier cu tine" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Utilizatorul %s a partajat un dosar cu tine" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Utilizatorul %s a partajat fișierul \"%s\" cu tine. Îl poți descărca de aici: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -243,8 +243,8 @@ msgid "The object type is not specified." msgstr "Tipul obiectului nu a fost specificat" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Eroare" @@ -256,119 +256,127 @@ msgstr "Numele aplicației nu a fost specificat" msgid "The required file {file} is not installed!" msgstr "Fișierul obligatoriu {file} nu este instalat!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Eroare la partajare" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Eroare la anularea partajării" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Eroare la modificarea permisiunilor" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Distribuie cu tine si grupul {group} de {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Distribuie cu tine de {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Partajat cu" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Partajare cu legătură" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Protejare cu parolă" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Parola" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Expediază legătura prin poșta electronică" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Expediază" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Specifică data expirării" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Data expirării" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Distribuie prin email:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Nici o persoană găsită" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Repartajarea nu este permisă" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Distribuie in {item} si {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Anulare partajare" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "poate edita" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "control acces" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "creare" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "actualizare" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "ștergere" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "partajare" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Protejare cu parolă" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Eroare la anularea datei de expirare" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Eroare la specificarea datei de expirare" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Se expediază..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Mesajul a fost expediat" diff --git a/l10n/ro/settings.po b/l10n/ro/settings.po index 4852a519d3..9773ea8fce 100644 --- a/l10n/ro/settings.po +++ b/l10n/ro/settings.po @@ -14,9 +14,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-26 00:09+0100\n" -"PO-Revision-Date: 2013-01-25 23:00+0000\n" -"Last-Translator: Dimon Pockemon <>\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Romanian (http://www.transifex.com/projects/p/owncloud/language/ro/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -94,7 +94,7 @@ msgstr "Activați" msgid "Saving..." msgstr "Salvez..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "_language_name_" @@ -163,7 +163,7 @@ msgstr "Descarcă client Android" msgid "Download iOS Client" msgstr "Descarcă client iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Parolă" @@ -233,11 +233,11 @@ msgid "" "License\">AGPL." msgstr "Dezvoltat de the comunitatea ownCloud, codul sursă este licențiat sub AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Nume" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupuri" @@ -249,26 +249,30 @@ msgstr "Crează" msgid "Default Storage" msgstr "Stocare implicită" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Nelimitată" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Altele" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Grupul Admin " -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Stocare" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Implicită" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Șterge" diff --git a/l10n/ru/core.po b/l10n/ru/core.po index 365f4aa446..bcc0d34627 100644 --- a/l10n/ru/core.po +++ b/l10n/ru/core.po @@ -17,8 +17,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Russian (http://www.transifex.com/projects/p/owncloud/language/ru/)\n" "MIME-Version: 1.0\n" @@ -27,24 +27,24 @@ msgstr "" "Language: ru\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Пользователь %s поделился с вами файлом" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Пользователь %s открыл вам доступ к папке" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Пользователь %s открыл вам доступ к файлу \"%s\". Он доступен для загрузки здесь: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -247,8 +247,8 @@ msgid "The object type is not specified." msgstr "Тип объекта не указан" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Ошибка" @@ -260,119 +260,127 @@ msgstr "Имя приложения не указано" msgid "The required file {file} is not installed!" msgstr "Необходимый файл {file} не установлен!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Ошибка при открытии доступа" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Ошибка при закрытии доступа" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Ошибка при смене разрешений" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "{owner} открыл доступ для Вас и группы {group} " -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner} открыл доступ для Вас" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Поделиться с" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Поделиться с ссылкой" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Защитить паролем" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Пароль" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Почтовая ссылка на персону" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Отправить" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Установить срок доступа" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Дата окончания" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Поделится через электронную почту:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Ни один человек не найден" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Общий доступ не разрешен" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Общий доступ к {item} с {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Закрыть общий доступ" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "может редактировать" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "контроль доступа" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "создать" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "обновить" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "удалить" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "открыть доступ" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Защищено паролем" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Ошибка при отмене срока доступа" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Ошибка при установке срока доступа" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Отправляется ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Письмо отправлено" diff --git a/l10n/ru/settings.po b/l10n/ru/settings.po index e3155d76a8..23d54be85f 100644 --- a/l10n/ru/settings.po +++ b/l10n/ru/settings.po @@ -19,9 +19,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-13 00:08+0100\n" -"PO-Revision-Date: 2013-01-12 11:55+0000\n" -"Last-Translator: adol \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Russian (http://www.transifex.com/projects/p/owncloud/language/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -99,7 +99,7 @@ msgstr "Включить" msgid "Saving..." msgstr "Сохранение..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Русский " @@ -111,15 +111,15 @@ msgstr "Добавить приложение" msgid "More Apps" msgstr "Больше приложений" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Выберите приложение" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Смотрите дополнения на apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr " лицензия. Автор " @@ -168,7 +168,7 @@ msgstr "Загрузка Android-приложения" msgid "Download iOS Client" msgstr "Загрузка iOS-приложения" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Пароль" @@ -238,11 +238,11 @@ msgid "" "License\">AGPL." msgstr "Разрабатывается сообществом ownCloud, исходный код доступен под лицензией AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Имя" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Группы" @@ -254,26 +254,30 @@ msgstr "Создать" msgid "Default Storage" msgstr "Хранилище по-умолчанию" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Неограниченно" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Другое" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Группа Администраторы" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Хранилище" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "По-умолчанию" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Удалить" diff --git a/l10n/ru_RU/core.po b/l10n/ru_RU/core.po index e9d2d73107..ad1e6dddba 100644 --- a/l10n/ru_RU/core.po +++ b/l10n/ru_RU/core.po @@ -3,13 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# , 2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/owncloud/language/ru_RU/)\n" "MIME-Version: 1.0\n" @@ -18,24 +19,24 @@ msgstr "" "Language: ru_RU\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Пользователь %s открыл Вам доступ к файлу" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Пользователь %s открыл Вам доступ к папке" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Пользователь %s открыл Вам доступ к файлу \"%s\". Он доступен для загрузки здесь: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +239,8 @@ msgid "The object type is not specified." msgstr "Тип объекта не указан." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Ошибка" @@ -251,119 +252,127 @@ msgstr "Имя приложения не указано." msgid "The required file {file} is not installed!" msgstr "Требуемый файл {файл} не установлен!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Ошибка создания общего доступа" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Ошибка отключения общего доступа" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Ошибка при изменении прав доступа" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Опубликовано для Вас и группы {группа} {собственник}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Опубликовано для Вас {собственник}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Сделать общим с" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Опубликовать с ссылкой" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Защитить паролем" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Пароль" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Ссылка на адрес электронной почты" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Отправить" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Установить срок действия" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Дата истечения срока действия" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Сделать общедоступным посредством email:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Не найдено людей" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Рекурсивный общий доступ не разрешен" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Совместное использование в {объект} с {пользователь}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Отключить общий доступ" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "возможно редактирование" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "контроль доступа" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "создать" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "обновить" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "удалить" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "сделать общим" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Пароль защищен" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Ошибка при отключении даты истечения срока действия" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Ошибка при установке даты истечения срока действия" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Отправка ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Письмо отправлено" @@ -372,11 +381,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Обновление прошло неудачно. Пожалуйста, сообщите об этом результате в ownCloud community." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Обновление прошло успешно. Немедленное перенаправление Вас на ownCloud." #: lostpassword/controller.php:47 msgid "ownCloud password reset" @@ -574,4 +583,4 @@ msgstr "следующий" #: templates/update.php:3 #, php-format msgid "Updating ownCloud to version %s, this may take a while." -msgstr "" +msgstr "Обновление ownCloud до версии %s, это может занять некоторое время." diff --git a/l10n/ru_RU/lib.po b/l10n/ru_RU/lib.po index be65ac1f02..34e58324fb 100644 --- a/l10n/ru_RU/lib.po +++ b/l10n/ru_RU/lib.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# , 2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 10:41+0000\n" +"Last-Translator: AnnaSch \n" "Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/owncloud/language/ru_RU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -58,9 +59,9 @@ msgstr "Обратно к файлам" msgid "Selected files too large to generate zip file." msgstr "Выбранные файлы слишком велики для генерации zip-архива." -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "не может быть определено" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/ru_RU/settings.po b/l10n/ru_RU/settings.po index bf961ac7a0..8722c9ae95 100644 --- a/l10n/ru_RU/settings.po +++ b/l10n/ru_RU/settings.po @@ -3,13 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# , 2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/owncloud/language/ru_RU/)\n" "MIME-Version: 1.0\n" @@ -88,7 +89,7 @@ msgstr "Включить" msgid "Saving..." msgstr "Сохранение" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__язык_имя__" @@ -100,15 +101,15 @@ msgstr "Добавить Ваше приложение" msgid "More Apps" msgstr "Больше приложений" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Выбрать приложение" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Обратитесь к странице приложений на apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licensed by " @@ -147,7 +148,7 @@ msgstr "Клиенты" #: templates/personal.php:13 msgid "Download Desktop Clients" -msgstr "" +msgstr "Загрузка десктопных клиентов" #: templates/personal.php:14 msgid "Download Android Client" @@ -157,7 +158,7 @@ msgstr "Загрузить клиент под Android " msgid "Download iOS Client" msgstr "Загрузить клиент под iOS " -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Пароль" @@ -227,11 +228,11 @@ msgid "" "License\">AGPL." msgstr "Разработанный ownCloud community, the source code is licensed under the AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Имя" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Группы" @@ -241,28 +242,32 @@ msgstr "Создать" #: templates/users.php:35 msgid "Default Storage" -msgstr "" +msgstr "Хранилище по умолчанию" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" -msgstr "" +msgstr "Неограниченный" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Другой" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Группа Admin" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" -msgstr "" +msgstr "Хранилище" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" -msgstr "" +msgstr "По умолчанию" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Удалить" diff --git a/l10n/ru_RU/user_ldap.po b/l10n/ru_RU/user_ldap.po index ef2d84ebcb..cd5c6be490 100644 --- a/l10n/ru_RU/user_ldap.po +++ b/l10n/ru_RU/user_ldap.po @@ -3,14 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# , 2013. # , 2012. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-16 00:19+0100\n" -"PO-Revision-Date: 2013-01-15 23:20+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 10:56+0000\n" +"Last-Translator: AnnaSch \n" "Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/owncloud/language/ru_RU/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -29,7 +30,7 @@ msgstr "Предупреждение: Приложения user_ldap и u msgid "" "Warning: The PHP LDAP module is not installed, the backend will not " "work. Please ask your system administrator to install it." -msgstr "" +msgstr "Предупреждение: Модуль PHP LDAP не установлен, бэкэнд не будет работать. Пожалуйста, обратитесь к Вашему системному администратору, чтобы установить его." #: templates/settings.php:15 msgid "Host" @@ -46,7 +47,7 @@ msgstr "База DN" #: templates/settings.php:16 msgid "One Base DN per line" -msgstr "" +msgstr "Одно базовое DN на линию" #: templates/settings.php:16 msgid "You can specify Base DN for users and groups in the Advanced tab" @@ -121,7 +122,7 @@ msgstr "Базовое дерево пользователей" #: templates/settings.php:25 msgid "One User Base DN per line" -msgstr "" +msgstr "Одно пользовательское базовое DN на линию" #: templates/settings.php:26 msgid "Base Group Tree" @@ -129,7 +130,7 @@ msgstr "Базовое дерево групп" #: templates/settings.php:26 msgid "One Group Base DN per line" -msgstr "" +msgstr "Одно групповое базовое DN на линию" #: templates/settings.php:27 msgid "Group-Member association" diff --git a/l10n/si_LK/core.po b/l10n/si_LK/core.po index 19dcaff2a0..0d0fd472df 100644 --- a/l10n/si_LK/core.po +++ b/l10n/si_LK/core.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Sinhala (Sri Lanka) (http://www.transifex.com/projects/p/owncloud/language/si_LK/)\n" "MIME-Version: 1.0\n" @@ -20,24 +20,24 @@ msgstr "" "Language: si_LK\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -240,8 +240,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "දෝෂයක්" @@ -253,119 +253,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "බෙදාගන්න" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "යොමුවක් මඟින් බෙදාගන්න" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "මුර පදයකින් ආරක්ශාකරන්න" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "මුර පදය " -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "කල් ඉකුත් විමේ දිනය දමන්න" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "කල් ඉකුත් විමේ දිනය" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "විද්‍යුත් තැපෑල මඟින් බෙදාගන්න: " -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "නොබෙදු" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "සංස්කරණය කළ හැක" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "ප්‍රවේශ පාලනය" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "සදන්න" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "යාවත්කාලීන කරන්න" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "මකන්න" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "බෙදාහදාගන්න" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "මුර පදයකින් ආරක්ශාකර ඇත" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "කල් ඉකුත් දිනය ඉවත් කිරීමේ දෝෂයක්" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "කල් ඉකුත් දිනය ස්ථාපනය කිරීමේ දෝෂයක්" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/si_LK/settings.po b/l10n/si_LK/settings.po index 7997041c93..f5d3776192 100644 --- a/l10n/si_LK/settings.po +++ b/l10n/si_LK/settings.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Sinhala (Sri Lanka) (http://www.transifex.com/projects/p/owncloud/language/si_LK/)\n" "MIME-Version: 1.0\n" @@ -90,7 +90,7 @@ msgstr "ක්‍රියත්මක කරන්න" msgid "Saving..." msgstr "සුරැකෙමින් පවතී..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "" @@ -102,15 +102,15 @@ msgstr "යෙදුමක් එක් කිරීම" msgid "More Apps" msgstr "තවත් යෙදුම්" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "යෙදුමක් තොරන්න" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -159,7 +159,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "මුරපදය" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "නිපදන ලද්දේ ownCloud සමාජයෙන්, the මුල් කේතය ලයිසන්ස් කර ඇත්තේ AGPL යටතේ." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "නාමය" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "සමූහය" @@ -245,26 +245,30 @@ msgstr "තනන්න" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "වෙනත්" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "කාණ්ඩ පරිපාලක" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "මකා දමනවා" diff --git a/l10n/sk_SK/core.po b/l10n/sk_SK/core.po index 2f61413f62..de52d7a52d 100644 --- a/l10n/sk_SK/core.po +++ b/l10n/sk_SK/core.po @@ -4,6 +4,7 @@ # # Translators: # , 2011, 2012. +# Marián Hvolka , 2013. # , 2012. # , 2013. # Roman Priesol , 2012. @@ -12,8 +13,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" @@ -22,24 +23,24 @@ msgstr "" "Language: sk_SK\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Používateľ %s zdieľa s Vami súbor" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Používateľ %s zdieľa s Vami adresár" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Používateľ %s zdieľa s Vami súbor \"%s\". Môžete si ho stiahnuť tu: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -242,8 +243,8 @@ msgid "The object type is not specified." msgstr "Nešpecifikovaný typ objektu." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Chyba" @@ -255,119 +256,127 @@ msgstr "Nešpecifikované meno aplikácie." msgid "The required file {file} is not installed!" msgstr "Požadovaný súbor {file} nie je inštalovaný!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Chyba počas zdieľania" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Chyba počas ukončenia zdieľania" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Chyba počas zmeny oprávnení" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Zdieľané s vami a so skupinou {group} používateľom {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Zdieľané s vami používateľom {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Zdieľať s" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Zdieľať cez odkaz" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Chrániť heslom" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Heslo" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Odoslať odkaz osobe e-mailom" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Odoslať" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Nastaviť dátum expirácie" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Dátum expirácie" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Zdieľať cez e-mail:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Užívateľ nenájdený" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Zdieľanie už zdieľanej položky nie je povolené" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Zdieľané v {item} s {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Zrušiť zdieľanie" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "môže upraviť" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "riadenie prístupu" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "vytvoriť" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "aktualizácia" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "zmazať" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "zdieľať" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Chránené heslom" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Chyba pri odstraňovaní dátumu vypršania platnosti" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Chyba pri nastavení dátumu vypršania platnosti" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Odosielam ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Email odoslaný" @@ -376,11 +385,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Aktualizácia nebola úspešná. Problém nahláste na ownCloud community." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Aktualizácia bola úspešná. Presmerovávam na ownCloud." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/sk_SK/files_encryption.po b/l10n/sk_SK/files_encryption.po index 813c05deb3..d2847e30d9 100644 --- a/l10n/sk_SK/files_encryption.po +++ b/l10n/sk_SK/files_encryption.po @@ -4,13 +4,14 @@ # # Translators: # , 2012. +# Marián Hvolka , 2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 14:49+0000\n" +"Last-Translator: mhh \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,53 +23,53 @@ msgstr "" msgid "" "Please switch to your ownCloud client and change your encryption password to" " complete the conversion." -msgstr "" +msgstr "Prosím, prejdite do svojho klienta ownCloud a zmente šifrovacie heslo na dokončenie konverzie." #: js/settings-personal.js:17 msgid "switched to client side encryption" -msgstr "" +msgstr "prepnuté na šifrovanie prostredníctvom klienta" #: js/settings-personal.js:21 msgid "Change encryption password to login password" -msgstr "" +msgstr "Zmeniť šifrovacie heslo na prihlasovacie" #: js/settings-personal.js:25 msgid "Please check your passwords and try again." -msgstr "" +msgstr "Skontrolujte si heslo a skúste to znovu." #: js/settings-personal.js:25 msgid "Could not change your file encryption password to your login password" -msgstr "" +msgstr "Nie je možné zmeniť šifrovacie heslo na prihlasovacie" #: templates/settings-personal.php:3 templates/settings.php:5 msgid "Choose encryption mode:" -msgstr "" +msgstr "Vyberte režim šifrovania:" #: templates/settings-personal.php:20 templates/settings.php:24 msgid "" "Client side encryption (most secure but makes it impossible to access your " "data from the web interface)" -msgstr "" +msgstr "Šifrovanie prostredníctvom klienta (najbezpečnejšia voľba, neumožňuje však prístup k súborom z webového rozhrania)" #: templates/settings-personal.php:30 templates/settings.php:36 msgid "" "Server side encryption (allows you to access your files from the web " "interface and the desktop client)" -msgstr "" +msgstr "Šifrovanie na serveri (umožňuje pristupovať k súborom z webového rozhrania a desktopového klienta)" #: templates/settings-personal.php:41 templates/settings.php:60 msgid "None (no encryption at all)" -msgstr "" +msgstr "Žiadne (žiadne šifrovanie)" #: templates/settings.php:10 msgid "" "Important: Once you selected an encryption mode there is no way to change it" " back" -msgstr "" +msgstr "Dôležité: ak si zvolíte režim šifrovania, nie je možné ho znovu zrušiť" #: templates/settings.php:48 msgid "User specific (let the user decide)" -msgstr "" +msgstr "Definovaný používateľom (umožňuje používateľovi vybrať si)" #: templates/settings.php:65 msgid "Encryption" diff --git a/l10n/sk_SK/lib.po b/l10n/sk_SK/lib.po index 07b4a92591..693d9535e4 100644 --- a/l10n/sk_SK/lib.po +++ b/l10n/sk_SK/lib.po @@ -3,6 +3,7 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Marián Hvolka , 2013. # , 2012. # Roman Priesol , 2012. # , 2012. @@ -10,9 +11,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-17 00:26+0100\n" -"PO-Revision-Date: 2013-01-16 23:26+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 16:07+0000\n" +"Last-Translator: mhh \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -60,9 +61,9 @@ msgstr "Späť na súbory" msgid "Selected files too large to generate zip file." msgstr "Zvolené súbory sú príliž veľké na vygenerovanie zip súboru." -#: helper.php:228 +#: helper.php:229 msgid "couldn't be determined" -msgstr "" +msgstr "nedá sa zistiť" #: json.php:28 msgid "Application is not enabled" diff --git a/l10n/sk_SK/settings.po b/l10n/sk_SK/settings.po index dec1e38009..74bc6b025b 100644 --- a/l10n/sk_SK/settings.po +++ b/l10n/sk_SK/settings.po @@ -13,9 +13,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-25 00:05+0100\n" -"PO-Revision-Date: 2013-01-24 18:54+0000\n" -"Last-Translator: mhh \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -93,7 +93,7 @@ msgstr "Povoliť" msgid "Saving..." msgstr "Ukladám..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Slovensky" @@ -105,15 +105,15 @@ msgstr "Pridať vašu aplikáciu" msgid "More Apps" msgstr "Viac aplikácií" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Vyberte aplikáciu" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Pozrite si stránku aplikácií na apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licencované " @@ -135,7 +135,7 @@ msgstr "Fórum" #: templates/help.php:9 msgid "Bugtracker" -msgstr "" +msgstr "Bugtracker" #: templates/help.php:11 msgid "Commercial Support" @@ -162,7 +162,7 @@ msgstr "Stiahnuť Android klienta" msgid "Download iOS Client" msgstr "Stiahnuť iOS klienta" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Heslo" @@ -232,11 +232,11 @@ msgid "" "License\">AGPL." msgstr "Vyvinuté komunitou ownCloud,zdrojový kód je licencovaný pod AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Meno" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Skupiny" @@ -248,26 +248,30 @@ msgstr "Vytvoriť" msgid "Default Storage" msgstr "Predvolené úložisko" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Nelimitované" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Iné" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Správca skupiny" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Úložisko" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Predvolené" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Odstrániť" diff --git a/l10n/sk_SK/user_webdavauth.po b/l10n/sk_SK/user_webdavauth.po index 8adac5f827..4e77a87a39 100644 --- a/l10n/sk_SK/user_webdavauth.po +++ b/l10n/sk_SK/user_webdavauth.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-25 00:05+0100\n" -"PO-Revision-Date: 2013-01-24 19:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 16:01+0000\n" "Last-Translator: mhh \n" "Language-Team: Slovak (Slovakia) (http://www.transifex.com/projects/p/owncloud/language/sk_SK/)\n" "MIME-Version: 1.0\n" @@ -32,4 +32,4 @@ msgid "" "ownCloud will send the user credentials to this URL. This plugin checks the " "response and will interpret the HTTP statuscodes 401 and 403 as invalid " "credentials, and all other responses as valid credentials." -msgstr "" +msgstr "ownCloud odošle používateľské údajena zadanú URL. Plugin skontroluje odpoveď a považuje návratovou hodnotu HTTP 401 a 403 za neplatné údaje a všetky ostatné hodnoty ako platné prihlasovacie údaje." diff --git a/l10n/sl/core.po b/l10n/sl/core.po index faa7abda52..e489f98a6c 100644 --- a/l10n/sl/core.po +++ b/l10n/sl/core.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Slovenian (http://www.transifex.com/projects/p/owncloud/language/sl/)\n" "MIME-Version: 1.0\n" @@ -21,24 +21,24 @@ msgstr "" "Language: sl\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Uporanik %s je dal datoteko v souporabo z vami" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Uporanik %s je dal mapo v souporabo z vami" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Uporanik %s je dal datoteko \"%s\" v souporabo z vami. Prenesete jo lahko tukaj: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -241,8 +241,8 @@ msgid "The object type is not specified." msgstr "Vrsta predmeta ni podana." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Napaka" @@ -254,119 +254,127 @@ msgstr "Ime aplikacije ni podano." msgid "The required file {file} is not installed!" msgstr "Zahtevana datoteka {file} ni nameščena!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Napaka med souporabo" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Napaka med odstranjevanjem souporabe" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Napaka med spreminjanjem dovoljenj" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "V souporabi z vami in skupino {group}. Lastnik je {owner}." -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "V souporabi z vami. Lastnik je {owner}." -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Omogoči souporabo z" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Omogoči souporabo s povezavo" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Zaščiti z geslom" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Geslo" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Posreduj povezavo po e-pošti" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Pošlji" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Nastavi datum preteka" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Datum preteka" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Souporaba preko elektronske pošte:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Ni najdenih uporabnikov" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Ponovna souporaba ni omogočena" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "V souporabi v {item} z {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Odstrani souporabo" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "lahko ureja" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "nadzor dostopa" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "ustvari" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "posodobi" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "izbriše" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "določi souporabo" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Zaščiteno z geslom" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Napaka brisanja datuma preteka" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Napaka med nastavljanjem datuma preteka" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Pošiljam ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "E-pošta je bila poslana" diff --git a/l10n/sl/settings.po b/l10n/sl/settings.po index 4e336bf871..225f4e3a20 100644 --- a/l10n/sl/settings.po +++ b/l10n/sl/settings.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Slovenian (http://www.transifex.com/projects/p/owncloud/language/sl/)\n" "MIME-Version: 1.0\n" @@ -91,7 +91,7 @@ msgstr "Omogoči" msgid "Saving..." msgstr "Poteka shranjevanje ..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__ime_jezika__" @@ -103,15 +103,15 @@ msgstr "Dodaj program" msgid "More Apps" msgstr "Več programov" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Izberite program" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Obiščite spletno stran programa na apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-z dovoljenjem s strani " @@ -160,7 +160,7 @@ msgstr "Prenesi Android odjemalec" msgid "Download iOS Client" msgstr "Prenesi iOS odjemalec" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Geslo" @@ -230,11 +230,11 @@ msgid "" "License\">AGPL." msgstr "Programski paket razvija skupnost ownCloud. Izvorna koda je objavljena pod pogoji dovoljenja AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Ime" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Skupine" @@ -246,26 +246,30 @@ msgstr "Ustvari" msgid "Default Storage" msgstr "Privzeta shramba" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Neomejeno" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Drugo" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Skrbnik skupine" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Shramba" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Privzeto" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Izbriši" diff --git a/l10n/sr/core.po b/l10n/sr/core.po index b20cc90c58..80d0ec2de4 100644 --- a/l10n/sr/core.po +++ b/l10n/sr/core.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Serbian (http://www.transifex.com/projects/p/owncloud/language/sr/)\n" "MIME-Version: 1.0\n" @@ -20,24 +20,24 @@ msgstr "" "Language: sr\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Корисник %s дели са вама датотеку" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Корисник %s дели са вама директоријум" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -240,8 +240,8 @@ msgid "The object type is not specified." msgstr "Врста објекта није подешена." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Грешка" @@ -253,119 +253,127 @@ msgstr "Име програма није унето." msgid "The required file {file} is not installed!" msgstr "Потребна датотека {file} није инсталирана." -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Грешка у дељењу" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Грешка код искључења дељења" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Грешка код промене дозвола" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Дељено са вама и са групом {group}. Поделио {owner}." -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Поделио са вама {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Подели са" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Подели линк" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Заштићено лозинком" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Лозинка" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Пошаљи" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Постави датум истека" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Датум истека" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Подели поштом:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Особе нису пронађене." -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Поновно дељење није дозвољено" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Подељено унутар {item} са {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Не дели" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "може да мења" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "права приступа" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "направи" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "ажурирај" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "обриши" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "подели" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Заштићено лозинком" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Грешка код поништавања датума истека" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Грешка код постављања датума истека" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Шаљем..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Порука је послата" diff --git a/l10n/sr/settings.po b/l10n/sr/settings.po index dca5c1ac46..2d04a03138 100644 --- a/l10n/sr/settings.po +++ b/l10n/sr/settings.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Serbian (http://www.transifex.com/projects/p/owncloud/language/sr/)\n" "MIME-Version: 1.0\n" @@ -89,7 +89,7 @@ msgstr "Укључи" msgid "Saving..." msgstr "Чување у току..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -101,15 +101,15 @@ msgstr "Додајте ваш програм" msgid "More Apps" msgstr "Више програма" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Изаберите програм" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Погледајте страницу са програмима на apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-лиценцирао " @@ -158,7 +158,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Лозинка" @@ -228,11 +228,11 @@ msgid "" "License\">AGPL." msgstr "Развијају Оунклауд (ownCloud) заједница, изворни код је издат под АГПЛ лиценцом." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Име" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Групе" @@ -244,26 +244,30 @@ msgstr "Направи" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Друго" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Управник групе" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Обриши" diff --git a/l10n/sr@latin/core.po b/l10n/sr@latin/core.po index 3b5e12b70b..fd54f215b9 100644 --- a/l10n/sr@latin/core.po +++ b/l10n/sr@latin/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Serbian (Latin) (http://www.transifex.com/projects/p/owncloud/language/sr@latin/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: sr@latin\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "" @@ -251,119 +251,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Lozinka" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/sr@latin/settings.po b/l10n/sr@latin/settings.po index c11e3c37bf..e22f8796d2 100644 --- a/l10n/sr@latin/settings.po +++ b/l10n/sr@latin/settings.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Serbian (Latin) (http://www.transifex.com/projects/p/owncloud/language/sr@latin/)\n" "MIME-Version: 1.0\n" @@ -88,7 +88,7 @@ msgstr "" msgid "Saving..." msgstr "" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "" @@ -100,15 +100,15 @@ msgstr "" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Izaberite program" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -157,7 +157,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Lozinka" @@ -227,11 +227,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Ime" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupe" @@ -243,26 +243,30 @@ msgstr "Napravi" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Drugo" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Obriši" diff --git a/l10n/sv/core.po b/l10n/sv/core.po index 9ed140b856..0df2d492ca 100644 --- a/l10n/sv/core.po +++ b/l10n/sv/core.po @@ -3,6 +3,7 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# André , 2013. # Christer Eriksson , 2012. # Daniel Sandman , 2012. # , 2011. @@ -13,8 +14,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" @@ -23,24 +24,24 @@ msgstr "" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Användare %s delade en fil med dig" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Användare %s delade en mapp med dig" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Användare %s delade filen \"%s\" med dig. Den finns att ladda ner här: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -243,8 +244,8 @@ msgid "The object type is not specified." msgstr "Objekttypen är inte specificerad." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Fel" @@ -256,119 +257,127 @@ msgstr " Namnet på appen är inte specificerad." msgid "The required file {file} is not installed!" msgstr "Den nödvändiga filen {file} är inte installerad!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Fel vid delning" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Fel när delning skulle avslutas" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Fel vid ändring av rättigheter" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Delad med dig och gruppen {group} av {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Delad med dig av {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Delad med" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Delad med länk" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Lösenordsskydda" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Lösenord" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "E-posta länk till person" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Skicka" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Sätt utgångsdatum" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Utgångsdatum" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Dela via e-post:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Hittar inga användare" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Dela vidare är inte tillåtet" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Delad i {item} med {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Sluta dela" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "kan redigera" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "åtkomstkontroll" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "skapa" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "uppdatera" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "radera" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "dela" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Lösenordsskyddad" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Fel vid borttagning av utgångsdatum" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Fel vid sättning av utgångsdatum" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Skickar ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "E-post skickat" @@ -377,11 +386,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Uppdateringen misslyckades. Rapportera detta problem till ownCloud-gemenskapen." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Uppdateringen lyckades. Du omdirigeras nu till OwnCloud" #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/sv/files.po b/l10n/sv/files.po index c37b292851..8ad64f646e 100644 --- a/l10n/sv/files.po +++ b/l10n/sv/files.po @@ -3,6 +3,7 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# André , 2013. # Christer Eriksson , 2012. # Daniel Sandman , 2012. # Magnus Höglund , 2012-2013. @@ -13,9 +14,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 09:25+0000\n" +"Last-Translator: Lokal_Profil \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -74,7 +75,7 @@ msgstr "Misslyckades spara till disk" #: ajax/upload.php:48 msgid "Not enough storage available" -msgstr "" +msgstr "Inte tillräckligt med lagringsutrymme tillgängligt" #: ajax/upload.php:77 msgid "Invalid directory." @@ -148,11 +149,11 @@ msgstr "Ogiltigt namn, '\\', '/', '<', '>', ':', '\"', '|', '?' och '*' är inte #: js/files.js:78 msgid "Your storage is full, files can not be updated or synced anymore!" -msgstr "" +msgstr "Ditt lagringsutrymme är fullt, filer kan ej längre laddas upp eller synkas!" #: js/files.js:82 msgid "Your storage is almost full ({usedSpacePercent}%)" -msgstr "" +msgstr "Ditt lagringsutrymme är nästan fullt ({usedSpacePercent}%)" #: js/files.js:219 msgid "" diff --git a/l10n/sv/settings.po b/l10n/sv/settings.po index b51b40b342..3b39b6e231 100644 --- a/l10n/sv/settings.po +++ b/l10n/sv/settings.po @@ -15,8 +15,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Swedish (http://www.transifex.com/projects/p/owncloud/language/sv/)\n" "MIME-Version: 1.0\n" @@ -95,7 +95,7 @@ msgstr "Aktivera" msgid "Saving..." msgstr "Sparar..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -107,15 +107,15 @@ msgstr "Lägg till din applikation" msgid "More Apps" msgstr "Fler Appar" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Välj en App" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Se programsida på apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licensierad av " @@ -164,7 +164,7 @@ msgstr "Ladda ner klient för Android" msgid "Download iOS Client" msgstr "Ladda ner klient för iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Lösenord" @@ -234,11 +234,11 @@ msgid "" "License\">AGPL." msgstr "Utvecklad av ownCloud kommunity, källkoden är licenserad under AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Namn" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Grupper" @@ -250,26 +250,30 @@ msgstr "Skapa" msgid "Default Storage" msgstr "Förvald lagring" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Obegränsad" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Annat" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Gruppadministratör" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Lagring" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "Förvald" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Radera" diff --git a/l10n/ta_LK/core.po b/l10n/ta_LK/core.po index e4affb5240..ec703bdcd4 100644 --- a/l10n/ta_LK/core.po +++ b/l10n/ta_LK/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Tamil (Sri-Lanka) (http://www.transifex.com/projects/p/owncloud/language/ta_LK/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: ta_LK\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "பொருள் வகை குறிப்பிடப்படவில்லை." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "வழு" @@ -251,119 +251,127 @@ msgstr "செயலி பெயர் குறிப்பிடப்பட msgid "The required file {file} is not installed!" msgstr "தேவைப்பட்ட கோப்பு {கோப்பு} நிறுவப்படவில்லை!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "பகிரும் போதான வழு" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "பகிராமல் உள்ளப்போதான வழு" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "அனுமதிகள் மாறும்போதான வழு" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "உங்களுடனும் குழுவுக்கிடையிலும் {குழு} பகிரப்பட்டுள்ளது {உரிமையாளர்}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "உங்களுடன் பகிரப்பட்டுள்ளது {உரிமையாளர்}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "பகிர்தல்" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "இணைப்புடன் பகிர்தல்" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "கடவுச்சொல்லை பாதுகாத்தல்" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "கடவுச்சொல்" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "காலாவதி தேதியை குறிப்பிடுக" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "காலவதியாகும் திகதி" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "மின்னஞ்சலினூடான பகிர்வு: " -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "நபர்கள் யாரும் இல்லை" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "மீள்பகிர்வதற்கு அனுமதி இல்லை " -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "{பயனாளர்} உடன் {உருப்படி} பகிரப்பட்டுள்ளது" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "பகிரமுடியாது" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "தொகுக்க முடியும்" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "கட்டுப்பாடான அணுகல்" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "படைத்தல்" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "இற்றைப்படுத்தல்" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "நீக்குக" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "பகிர்தல்" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "கடவுச்சொல் பாதுகாக்கப்பட்டது" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "காலாவதியாகும் திகதியை குறிப்பிடாமைக்கான வழு" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "காலாவதியாகும் திகதியை குறிப்பிடுவதில் வழு" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/ta_LK/settings.po b/l10n/ta_LK/settings.po index 841dd03141..9853ea2645 100644 --- a/l10n/ta_LK/settings.po +++ b/l10n/ta_LK/settings.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Tamil (Sri-Lanka) (http://www.transifex.com/projects/p/owncloud/language/ta_LK/)\n" "MIME-Version: 1.0\n" @@ -88,7 +88,7 @@ msgstr "செயலற்றதாக்குக" msgid "Saving..." msgstr "இயலுமைப்படுத்துக" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "_மொழி_பெயர்_" @@ -100,15 +100,15 @@ msgstr "உங்களுடைய செயலியை சேர்க்க" msgid "More Apps" msgstr "மேலதிக செயலிகள்" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "செயலி ஒன்றை தெரிவுசெய்க" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "apps.owncloud.com இல் செயலி பக்கத்தை பார்க்க" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-அனுமதி பெற்ற " @@ -157,7 +157,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "கடவுச்சொல்" @@ -227,11 +227,11 @@ msgid "" "License\">AGPL." msgstr "Developed by the ownCloud community, the source code is licensed under the AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "பெயர்" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "குழுக்கள்" @@ -243,26 +243,30 @@ msgstr "உருவாக்குக" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "மற்றவை" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "குழு நிர்வாகி" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "அழிக்க" diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot index 3d943223f0..459384f62c 100644 --- a/l10n/templates/core.pot +++ b/l10n/templates/core.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,24 +17,24 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -237,8 +237,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "" @@ -250,119 +250,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/templates/files.pot b/l10n/templates/files.pot index 45cf84e08b..385f79bc97 100644 --- a/l10n/templates/files.pot +++ b/l10n/templates/files.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_encryption.pot b/l10n/templates/files_encryption.pot index b955d636f9..ce76225fda 100644 --- a/l10n/templates/files_encryption.pot +++ b/l10n/templates/files_encryption.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_external.pot b/l10n/templates/files_external.pot index 29b5017ca9..a46c86e0b6 100644 --- a/l10n/templates/files_external.pot +++ b/l10n/templates/files_external.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_sharing.pot b/l10n/templates/files_sharing.pot index 18e05f2daf..fa7fe27829 100644 --- a/l10n/templates/files_sharing.pot +++ b/l10n/templates/files_sharing.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/files_versions.pot b/l10n/templates/files_versions.pot index 792abeb9ba..5af79d543f 100644 --- a/l10n/templates/files_versions.pot +++ b/l10n/templates/files_versions.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/lib.pot b/l10n/templates/lib.pot index 17fa0f989d..01f7eb678c 100644 --- a/l10n/templates/lib.pot +++ b/l10n/templates/lib.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:05+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot index 109d0cad53..c07b99aab7 100644 --- a/l10n/templates/settings.pot +++ b/l10n/templates/settings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:05+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -157,7 +157,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:80 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "" @@ -227,10 +227,10 @@ msgid "" msgstr "" #: templates/users.php:21 templates/users.php:79 -msgid "Name" +msgid "Login Name" msgstr "" -#: templates/users.php:26 templates/users.php:81 templates/users.php:101 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "" @@ -242,26 +242,30 @@ msgstr "" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:136 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:151 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "" -#: templates/users.php:83 templates/users.php:115 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:85 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:131 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:159 +#: templates/users.php:165 msgid "Delete" msgstr "" diff --git a/l10n/templates/user_ldap.pot b/l10n/templates/user_ldap.pot index c40719bb38..002852e202 100644 --- a/l10n/templates/user_ldap.pot +++ b/l10n/templates/user_ldap.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/templates/user_webdavauth.pot b/l10n/templates/user_webdavauth.pot index 203606678f..4687e50a63 100644 --- a/l10n/templates/user_webdavauth.pot +++ b/l10n/templates/user_webdavauth.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/l10n/th_TH/core.po b/l10n/th_TH/core.po index 92d06694d1..e218f60d9a 100644 --- a/l10n/th_TH/core.po +++ b/l10n/th_TH/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: th_TH\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "ผู้ใช้งาน %s ได้แชร์ไฟล์ให้กับคุณ" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "ผู้ใช้งาน %s ได้แชร์โฟลเดอร์ให้กับคุณ" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "ผู้ใช้งาน %s ได้แชร์ไฟล์ \"%s\" ให้กับคุณ และคุณสามารถสามารถดาวน์โหลดไฟล์ดังกล่าวได้จากที่นี่: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "ชนิดของวัตถุยังไม่ได้รับการระบุ" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "พบข้อผิดพลาด" @@ -252,119 +252,127 @@ msgstr "ชื่อของแอปยังไม่ได้รับกา msgid "The required file {file} is not installed!" msgstr "ไฟล์ {file} ซึ่งเป็นไฟล์ที่จำเป็นต้องได้รับการติดตั้งไว้ก่อน ยังไม่ได้ถูกติดตั้ง" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "เกิดข้อผิดพลาดในระหว่างการแชร์ข้อมูล" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "เกิดข้อผิดพลาดในการยกเลิกการแชร์ข้อมูล" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "เกิดข้อผิดพลาดในการเปลี่ยนสิทธิ์การเข้าใช้งาน" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "ได้แชร์ให้กับคุณ และกลุ่ม {group} โดย {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "ถูกแชร์ให้กับคุณโดย {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "แชร์ให้กับ" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "แชร์ด้วยลิงก์" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "ใส่รหัสผ่านไว้" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "รหัสผ่าน" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "ส่งลิงก์ให้ทางอีเมล" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "ส่ง" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "กำหนดวันที่หมดอายุ" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "วันที่หมดอายุ" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "แชร์ผ่านทางอีเมล" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "ไม่พบบุคคลที่ต้องการ" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "ไม่อนุญาตให้แชร์ข้อมูลซ้ำได้" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "ได้แชร์ {item} ให้กับ {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "ยกเลิกการแชร์" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "สามารถแก้ไข" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "ระดับควบคุมการเข้าใช้งาน" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "สร้าง" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "อัพเดท" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "ลบ" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "แชร์" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "ใส่รหัสผ่านไว้" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "เกิดข้อผิดพลาดในการยกเลิกการตั้งค่าวันที่หมดอายุ" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "เกิดข้อผิดพลาดในการตั้งค่าวันที่หมดอายุ" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "กำลังส่ง..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "ส่งอีเมล์แล้ว" @@ -373,11 +381,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "การอัพเดทไม่เป็นผลสำเร็จ กรุณาแจ้งปัญหาที่เกิดขึ้นไปยัง คอมมูนิตี้ผู้ใช้งาน ownCloud" #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "การอัพเดทเสร็จเรียบร้อยแล้ว กำลังเปลี่ยนเส้นทางไปที่ ownCloud อยู่ในขณะนี้" #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/th_TH/files.po b/l10n/th_TH/files.po index fd5d4b8ee8..3bde97a7e0 100644 --- a/l10n/th_TH/files.po +++ b/l10n/th_TH/files.po @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-27 00:04+0100\n" -"PO-Revision-Date: 2013-01-26 23:05+0000\n" -"Last-Translator: I Robot \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 17:20+0000\n" +"Last-Translator: AriesAnywhere Anywhere \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -70,7 +70,7 @@ msgstr "เขียนข้อมูลลงแผ่นดิสก์ล้ #: ajax/upload.php:48 msgid "Not enough storage available" -msgstr "" +msgstr "เหลือพื้นที่ไม่เพียงสำหรับใช้งาน" #: ajax/upload.php:77 msgid "Invalid directory." @@ -144,11 +144,11 @@ msgstr "ชื่อที่ใช้ไม่ถูกต้อง, '\\', '/', #: js/files.js:78 msgid "Your storage is full, files can not be updated or synced anymore!" -msgstr "" +msgstr "พื้นที่จัดเก็บข้อมูลของคุณเต็มแล้ว ไม่สามารถอัพเดทหรือผสานไฟล์ต่างๆได้อีกต่อไป" #: js/files.js:82 msgid "Your storage is almost full ({usedSpacePercent}%)" -msgstr "" +msgstr "พื้นที่จัดเก็บข้อมูลของคุณใกล้เต็มแล้ว ({usedSpacePercent}%)" #: js/files.js:219 msgid "" diff --git a/l10n/th_TH/settings.po b/l10n/th_TH/settings.po index 9e7676e802..238a91cd1d 100644 --- a/l10n/th_TH/settings.po +++ b/l10n/th_TH/settings.po @@ -10,9 +10,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-23 00:05+0100\n" -"PO-Revision-Date: 2013-01-22 00:59+0000\n" -"Last-Translator: AriesAnywhere Anywhere \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Thai (Thailand) (http://www.transifex.com/projects/p/owncloud/language/th_TH/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -90,7 +90,7 @@ msgstr "เปิดใช้งาน" msgid "Saving..." msgstr "กำลังบันทึุกข้อมูล..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "ภาษาไทย" @@ -102,15 +102,15 @@ msgstr "เพิ่มแอปของคุณ" msgid "More Apps" msgstr "แอปฯอื่นเพิ่มเติม" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "เลือก App" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "ดูหน้าแอพพลิเคชั่นที่ apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-ลิขสิทธิ์การใช้งานโดย " @@ -159,7 +159,7 @@ msgstr "ดาวน์โหลดโปรแกรมไคลเอนต์ msgid "Download iOS Client" msgstr "ดาวน์โหลดโปรแกรมไคลเอนต์สำหรับ iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "รหัสผ่าน" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "พัฒนาโดย the ชุมชนผู้ใช้งาน ownCloud, the ซอร์สโค้ดอยู่ภายใต้สัญญาอนุญาตของ AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "ชื่อ" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "กลุ่ม" @@ -245,26 +245,30 @@ msgstr "สร้าง" msgid "Default Storage" msgstr "พื้นที่จำกัดข้อมูลเริ่มต้น" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "ไม่จำกัดจำนวน" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "อื่นๆ" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "ผู้ดูแลกลุ่ม" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "พื้นที่จัดเก็บข้อมูล" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "ค่าเริ่มต้น" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "ลบ" diff --git a/l10n/tr/core.po b/l10n/tr/core.po index 8827a9587d..1f3b9f92bc 100644 --- a/l10n/tr/core.po +++ b/l10n/tr/core.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Turkish (http://www.transifex.com/projects/p/owncloud/language/tr/)\n" "MIME-Version: 1.0\n" @@ -22,24 +22,24 @@ msgstr "" "Language: tr\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "%s kullanıcısı sizinle bir dosyayı paylaştı" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "%s kullanıcısı sizinle bir dizini paylaştı" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "%s kullanıcısı \"%s\" dosyasını sizinle paylaştı. %s adresinden indirilebilir" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -242,8 +242,8 @@ msgid "The object type is not specified." msgstr "Nesne türü belirtilmemiş." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Hata" @@ -255,119 +255,127 @@ msgstr "uygulama adı belirtilmedi." msgid "The required file {file} is not installed!" msgstr "İhtiyaç duyulan {file} dosyası kurulu değil." -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Paylaşım sırasında hata " -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Paylaşım iptal ediliyorken hata" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "İzinleri değiştirirken hata oluştu" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr " {owner} tarafından sizinle ve {group} ile paylaştırılmış" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner} trafından sizinle paylaştırıldı" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "ile Paylaş" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Bağlantı ile paylaş" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Şifre korunması" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Parola" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Kişiye e-posta linki" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Gönder" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Son kullanma tarihini ayarla" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Son kullanım tarihi" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Eposta ile paylaş" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Kişi bulunamadı" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Tekrar paylaşmaya izin verilmiyor" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr " {item} içinde {user} ile paylaşılanlarlar" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Paylaşılmayan" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "düzenleyebilir" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "erişim kontrolü" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "oluştur" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "güncelle" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "sil" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "paylaş" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Paralo korumalı" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Geçerlilik tarihi tanımlama kaldırma hatası" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Geçerlilik tarihi tanımlama hatası" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Gönderiliyor..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Eposta gönderildi" diff --git a/l10n/tr/settings.po b/l10n/tr/settings.po index 0e563c6d4f..0fb46fd329 100644 --- a/l10n/tr/settings.po +++ b/l10n/tr/settings.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Turkish (http://www.transifex.com/projects/p/owncloud/language/tr/)\n" "MIME-Version: 1.0\n" @@ -91,7 +91,7 @@ msgstr "Etkin" msgid "Saving..." msgstr "Kaydediliyor..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__dil_adı__" @@ -103,15 +103,15 @@ msgstr "Uygulamanı Ekle" msgid "More Apps" msgstr "Daha fazla App" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Bir uygulama seçin" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Uygulamanın sayfasına apps.owncloud.com adresinden bakın " -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -160,7 +160,7 @@ msgstr "Android İstemcisini İndir" msgid "Download iOS Client" msgstr "iOS İstemcisini İndir" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Parola" @@ -230,11 +230,11 @@ msgid "" "License\">AGPL." msgstr "Geliştirilen TarafownCloud community, the source code is altında lisanslanmıştır AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Ad" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Gruplar" @@ -246,26 +246,30 @@ msgstr "Oluştur" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Diğer" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Yönetici Grubu " -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Sil" diff --git a/l10n/uk/core.po b/l10n/uk/core.po index c6bfb2dcd9..55b74a2fc0 100644 --- a/l10n/uk/core.po +++ b/l10n/uk/core.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Ukrainian (http://www.transifex.com/projects/p/owncloud/language/uk/)\n" "MIME-Version: 1.0\n" @@ -22,24 +22,24 @@ msgstr "" "Language: uk\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "Користувач %s поділився файлом з вами" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "Користувач %s поділився текою з вами" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "Користувач %s поділився файлом \"%s\" з вами. Він доступний для завантаження звідси: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -242,8 +242,8 @@ msgid "The object type is not specified." msgstr "Не визначено тип об'єкту." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Помилка" @@ -255,119 +255,127 @@ msgstr "Не визначено ім'я програми." msgid "The required file {file} is not installed!" msgstr "Необхідний файл {file} не встановлено!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Помилка під час публікації" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Помилка під час відміни публікації" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Помилка при зміні повноважень" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr " {owner} опублікував для Вас та для групи {group}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner} опублікував для Вас" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Опублікувати для" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Опублікувати через посилання" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Захистити паролем" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Пароль" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "Ел. пошта належить Пану" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "Надіслати" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Встановити термін дії" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Термін дії" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Опублікувати через Ел. пошту:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Жодної людини не знайдено" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Пере-публікація не дозволяється" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Опубліковано {item} для {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Заборонити доступ" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "може редагувати" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "контроль доступу" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "створити" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "оновити" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "видалити" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "опублікувати" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Захищено паролем" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Помилка при відміні терміна дії" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Помилка при встановленні терміна дії" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "Надсилання..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Ел. пошта надіслана" diff --git a/l10n/uk/settings.po b/l10n/uk/settings.po index 5d40f09fac..ff129914fe 100644 --- a/l10n/uk/settings.po +++ b/l10n/uk/settings.po @@ -10,9 +10,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-18 00:03+0100\n" -"PO-Revision-Date: 2013-01-17 13:26+0000\n" -"Last-Translator: volodya327 \n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Ukrainian (http://www.transifex.com/projects/p/owncloud/language/uk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -90,7 +90,7 @@ msgstr "Включити" msgid "Saving..." msgstr "Зберігаю..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__language_name__" @@ -102,15 +102,15 @@ msgstr "Додати свою програму" msgid "More Apps" msgstr "Більше програм" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Вибрати додаток" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Перегляньте сторінку програм на apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-licensed by " @@ -159,7 +159,7 @@ msgstr "Завантажити клієнт для Android" msgid "Download iOS Client" msgstr "Завантажити клієнт для iOS" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Пароль" @@ -229,11 +229,11 @@ msgid "" "License\">AGPL." msgstr "Розроблено ownCloud громадою, вихідний код має ліцензію AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Ім'я" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Групи" @@ -245,26 +245,30 @@ msgstr "Створити" msgid "Default Storage" msgstr "сховище за замовчуванням" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "Необмежено" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Інше" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Адміністратор групи" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "Сховище" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "За замовчуванням" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Видалити" diff --git a/l10n/vi/core.po b/l10n/vi/core.po index 3323b30d4b..7f3635025e 100644 --- a/l10n/vi/core.po +++ b/l10n/vi/core.po @@ -7,13 +7,13 @@ # , 2012. # , 2012. # Son Nguyen , 2012. -# Sơn Nguyễn , 2012. +# Sơn Nguyễn , 2012-2013. msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n" "MIME-Version: 1.0\n" @@ -22,29 +22,29 @@ msgstr "" "Language: vi\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" -msgstr "" +msgstr "%s chia sẻ tập tin này cho bạn" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" -msgstr "" +msgstr "%s chia sẻ thư mục này cho bạn" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" -msgstr "" +msgstr "Người dùng %s chia sẻ tập tin \"%s\" cho bạn .Bạn có thể tải tại đây : %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " "here: %s" -msgstr "" +msgstr "Người dùng %s chia sẻ thư mục \"%s\" cho bạn .Bạn có thể tải tại đây : %s" #: ajax/vcategories/add.php:26 ajax/vcategories/edit.php:25 msgid "Category type not provided." @@ -242,8 +242,8 @@ msgid "The object type is not specified." msgstr "Loại đối tượng không được chỉ định." #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "Lỗi" @@ -255,119 +255,127 @@ msgstr "Tên ứng dụng không được chỉ định." msgid "The required file {file} is not installed!" msgstr "Tập tin cần thiết {file} không được cài đặt!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "Lỗi trong quá trình chia sẻ" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "Lỗi trong quá trình gỡ chia sẻ" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "Lỗi trong quá trình phân quyền" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "Đã được chia sẽ với bạn và nhóm {group} bởi {owner}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "Đã được chia sẽ bởi {owner}" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "Chia sẻ với" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "Chia sẻ với liên kết" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "Mật khẩu bảo vệ" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "Mật khẩu" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" -msgstr "" +msgstr "Gởi" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "Đặt ngày kết thúc" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "Ngày kết thúc" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "Chia sẻ thông qua email" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "Không tìm thấy người nào" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "Chia sẻ lại không được cho phép" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "Đã được chia sẽ trong {item} với {user}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "Gỡ bỏ chia sẻ" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "có thể chỉnh sửa" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "quản lý truy cập" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "tạo" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "cập nhật" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "xóa" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "chia sẻ" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "Mật khẩu bảo vệ" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "Lỗi không thiết lập ngày kết thúc" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "Lỗi cấu hình ngày kết thúc" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." -msgstr "" +msgstr "Đang gởi ..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" @@ -376,11 +384,11 @@ msgid "" "The update was unsuccessful. Please report this issue to the ownCloud " "community." -msgstr "" +msgstr "Cập nhật không thành công . Vui lòng thông báo đến Cộng đồng ownCloud ." #: js/update.js:18 msgid "The update was successful. Redirecting you to ownCloud now." -msgstr "" +msgstr "Cập nhật thành công .Hệ thống sẽ đưa bạn tới ownCloud." #: lostpassword/controller.php:47 msgid "ownCloud password reset" diff --git a/l10n/vi/settings.po b/l10n/vi/settings.po index d7c48f81a4..3cb4e519b6 100644 --- a/l10n/vi/settings.po +++ b/l10n/vi/settings.po @@ -13,8 +13,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n" "MIME-Version: 1.0\n" @@ -93,7 +93,7 @@ msgstr "Bật" msgid "Saving..." msgstr "Đang tiến hành lưu ..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__Ngôn ngữ___" @@ -105,15 +105,15 @@ msgstr "Thêm ứng dụng của bạn" msgid "More Apps" msgstr "Nhiều ứng dụng hơn" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "Chọn một ứng dụng" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "Xem nhiều ứng dụng hơn tại apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-Giấy phép được cấp bởi " @@ -162,7 +162,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "Mật khẩu" @@ -232,11 +232,11 @@ msgid "" "License\">AGPL." msgstr "Được phát triển bởi cộng đồng ownCloud, mã nguồn đã được cấp phép theo chuẩn AGPL." -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "Tên" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "Nhóm" @@ -248,26 +248,30 @@ msgstr "Tạo" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "Khác" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "Nhóm quản trị" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "Xóa" diff --git a/l10n/zh_CN.GB2312/core.po b/l10n/zh_CN.GB2312/core.po index 01f36a1abd..54ee264a5a 100644 --- a/l10n/zh_CN.GB2312/core.po +++ b/l10n/zh_CN.GB2312/core.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Chinese (China) (GB2312) (http://www.transifex.com/projects/p/owncloud/language/zh_CN.GB2312/)\n" "MIME-Version: 1.0\n" @@ -19,24 +19,24 @@ msgstr "" "Language: zh_CN.GB2312\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -239,8 +239,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "错误" @@ -252,119 +252,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "分享出错" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "取消分享出错" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "变更权限出错" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "由 {owner} 与您和 {group} 群组分享" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "由 {owner} 与您分享" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "分享" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "分享链接" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "密码保护" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "密码" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "设置失效日期" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "失效日期" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "通过电子邮件分享:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "查无此人" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "不允许重复分享" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "已经与 {user} 在 {item} 中分享" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "取消分享" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "可编辑" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "访问控制" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "创建" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "更新" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "删除" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "分享" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "密码保护" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "取消设置失效日期出错" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "设置失效日期出错" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/zh_CN.GB2312/settings.po b/l10n/zh_CN.GB2312/settings.po index 78eea9c890..deb922c37f 100644 --- a/l10n/zh_CN.GB2312/settings.po +++ b/l10n/zh_CN.GB2312/settings.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Chinese (China) (GB2312) (http://www.transifex.com/projects/p/owncloud/language/zh_CN.GB2312/)\n" "MIME-Version: 1.0\n" @@ -89,7 +89,7 @@ msgstr "启用" msgid "Saving..." msgstr "保存中..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "Chinese" @@ -101,15 +101,15 @@ msgstr "添加你的应用程序" msgid "More Apps" msgstr "更多应用" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "选择一个程序" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "在owncloud.com上查看应用程序" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "授权协议 " @@ -158,7 +158,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "密码" @@ -228,11 +228,11 @@ msgid "" "License\">AGPL." msgstr "由 ownCloud 社区开发,s源代码AGPL 许可协议发布。" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "名字" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "组" @@ -244,26 +244,30 @@ msgstr "新建" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "其他的" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "群组管理员" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "删除" diff --git a/l10n/zh_CN/core.po b/l10n/zh_CN/core.po index 2608be5983..f7c192f722 100644 --- a/l10n/zh_CN/core.po +++ b/l10n/zh_CN/core.po @@ -13,8 +13,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Chinese (China) (http://www.transifex.com/projects/p/owncloud/language/zh_CN/)\n" "MIME-Version: 1.0\n" @@ -23,24 +23,24 @@ msgstr "" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "用户 %s 与您共享了一个文件" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "用户 %s 与您共享了一个文件夹" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "用户 %s 与您共享了文件\"%s\"。文件下载地址:%s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -243,8 +243,8 @@ msgid "The object type is not specified." msgstr "未指定对象类型。" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "错误" @@ -256,119 +256,127 @@ msgstr "未指定App名称。" msgid "The required file {file} is not installed!" msgstr "所需文件{file}未安装!" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "共享时出错" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "取消共享时出错" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "修改权限时出错" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "{owner}共享给您及{group}组" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr " {owner}与您共享" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "共享" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "共享链接" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "密码保护" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "密码" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "发送链接到个人" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "发送" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "设置过期日期" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "过期日期" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "通过Email共享" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "未找到此人" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "不允许二次共享" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "在{item} 与 {user}共享。" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "取消共享" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "可以修改" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "访问控制" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "创建" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "更新" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "删除" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "共享" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "密码已受保护" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "取消设置过期日期时出错" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "设置过期日期时出错" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "正在发送..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "邮件已发送" diff --git a/l10n/zh_CN/settings.po b/l10n/zh_CN/settings.po index a0a2353d6d..53b7fa6a2c 100644 --- a/l10n/zh_CN/settings.po +++ b/l10n/zh_CN/settings.po @@ -13,9 +13,9 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-15 00:03+0100\n" -"PO-Revision-Date: 2013-01-14 12:51+0000\n" -"Last-Translator: Dianjin Wang <1132321739qq@gmail.com>\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" +"Last-Translator: I Robot \n" "Language-Team: Chinese (China) (http://www.transifex.com/projects/p/owncloud/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -93,7 +93,7 @@ msgstr "启用" msgid "Saving..." msgstr "正在保存" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "简体中文" @@ -105,15 +105,15 @@ msgstr "添加应用" msgid "More Apps" msgstr "更多应用" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "选择一个应用" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "查看在 app.owncloud.com 的应用程序页面" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-核准: " @@ -162,7 +162,7 @@ msgstr "下载 Android 客户端" msgid "Download iOS Client" msgstr "下载 iOS 客户端" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "密码" @@ -232,11 +232,11 @@ msgid "" "License\">AGPL." msgstr "由ownCloud社区开发, 源代码AGPL许可证下发布。" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "名称" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "组" @@ -248,26 +248,30 @@ msgstr "创建" msgid "Default Storage" msgstr "默认存储" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "无限" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "其它" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "组管理员" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "存储" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "默认" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "删除" diff --git a/l10n/zh_HK/core.po b/l10n/zh_HK/core.po index b3e778f0b2..d6ed742922 100644 --- a/l10n/zh_HK/core.po +++ b/l10n/zh_HK/core.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Chinese (Hong Kong) (http://www.transifex.com/projects/p/owncloud/language/zh_HK/)\n" "MIME-Version: 1.0\n" @@ -18,24 +18,24 @@ msgstr "" "Language: zh_HK\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -238,8 +238,8 @@ msgid "The object type is not specified." msgstr "" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "" @@ -251,119 +251,127 @@ msgstr "" msgid "The required file {file} is not installed!" msgstr "" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "" -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "" diff --git a/l10n/zh_HK/settings.po b/l10n/zh_HK/settings.po index db5e3f915b..bbba342f38 100644 --- a/l10n/zh_HK/settings.po +++ b/l10n/zh_HK/settings.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Chinese (Hong Kong) (http://www.transifex.com/projects/p/owncloud/language/zh_HK/)\n" "MIME-Version: 1.0\n" @@ -87,7 +87,7 @@ msgstr "" msgid "Saving..." msgstr "" -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "" @@ -99,15 +99,15 @@ msgstr "" msgid "More Apps" msgstr "" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "" @@ -156,7 +156,7 @@ msgstr "" msgid "Download iOS Client" msgstr "" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "" @@ -226,11 +226,11 @@ msgid "" "License\">AGPL." msgstr "" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "" @@ -242,26 +242,30 @@ msgstr "" msgid "Default Storage" msgstr "" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "" diff --git a/l10n/zh_TW/core.po b/l10n/zh_TW/core.po index 7033b0e597..ee734ce272 100644 --- a/l10n/zh_TW/core.po +++ b/l10n/zh_TW/core.po @@ -11,8 +11,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-29 00:04+0100\n" -"PO-Revision-Date: 2013-01-28 23:05+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:23+0000\n" "Last-Translator: I Robot \n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/owncloud/language/zh_TW/)\n" "MIME-Version: 1.0\n" @@ -21,24 +21,24 @@ msgstr "" "Language: zh_TW\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ajax/share.php:84 +#: ajax/share.php:85 #, php-format msgid "User %s shared a file with you" msgstr "用戶 %s 與您分享了一個檔案" -#: ajax/share.php:86 +#: ajax/share.php:87 #, php-format msgid "User %s shared a folder with you" msgstr "用戶 %s 與您分享了一個資料夾" -#: ajax/share.php:88 +#: ajax/share.php:89 #, php-format msgid "" "User %s shared the file \"%s\" with you. It is available for download here: " "%s" msgstr "用戶 %s 與您分享了檔案 \"%s\" ,您可以從這裡下載它: %s" -#: ajax/share.php:90 +#: ajax/share.php:91 #, php-format msgid "" "User %s shared the folder \"%s\" with you. It is available for download " @@ -241,8 +241,8 @@ msgid "The object type is not specified." msgstr "未指定物件類型。" #: js/oc-vcategories.js:95 js/oc-vcategories.js:125 js/oc-vcategories.js:136 -#: js/oc-vcategories.js:195 js/share.js:135 js/share.js:142 js/share.js:554 -#: js/share.js:566 +#: js/oc-vcategories.js:195 js/share.js:152 js/share.js:159 js/share.js:571 +#: js/share.js:583 msgid "Error" msgstr "錯誤" @@ -254,119 +254,127 @@ msgstr "沒有指定 app 名稱。" msgid "The required file {file} is not installed!" msgstr "沒有安裝所需的檔案 {file} !" -#: js/share.js:124 js/share.js:594 +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Share" +msgstr "" + +#: js/share.js:29 js/share.js:43 js/share.js:90 js/share.js:93 +msgid "Shared" +msgstr "" + +#: js/share.js:141 js/share.js:611 msgid "Error while sharing" msgstr "分享時發生錯誤" -#: js/share.js:135 +#: js/share.js:152 msgid "Error while unsharing" msgstr "取消分享時發生錯誤" -#: js/share.js:142 +#: js/share.js:159 msgid "Error while changing permissions" msgstr "修改權限時發生錯誤" -#: js/share.js:151 +#: js/share.js:168 msgid "Shared with you and the group {group} by {owner}" msgstr "由 {owner} 分享給您和 {group}" -#: js/share.js:153 +#: js/share.js:170 msgid "Shared with you by {owner}" msgstr "{owner} 已經和您分享" -#: js/share.js:158 +#: js/share.js:175 msgid "Share with" msgstr "與...分享" -#: js/share.js:163 +#: js/share.js:180 msgid "Share with link" msgstr "使用連結分享" -#: js/share.js:166 +#: js/share.js:183 msgid "Password protect" msgstr "密碼保護" -#: js/share.js:168 templates/installation.php:44 templates/login.php:35 +#: js/share.js:185 templates/installation.php:44 templates/login.php:35 msgid "Password" msgstr "密碼" -#: js/share.js:172 +#: js/share.js:189 msgid "Email link to person" msgstr "將連結 email 給別人" -#: js/share.js:173 +#: js/share.js:190 msgid "Send" msgstr "寄出" -#: js/share.js:177 +#: js/share.js:194 msgid "Set expiration date" msgstr "設置到期日" -#: js/share.js:178 +#: js/share.js:195 msgid "Expiration date" msgstr "到期日" -#: js/share.js:210 +#: js/share.js:227 msgid "Share via email:" msgstr "透過 email 分享:" -#: js/share.js:212 +#: js/share.js:229 msgid "No people found" msgstr "沒有找到任何人" -#: js/share.js:239 +#: js/share.js:256 msgid "Resharing is not allowed" msgstr "不允許重新分享" -#: js/share.js:275 +#: js/share.js:292 msgid "Shared in {item} with {user}" msgstr "已和 {user} 分享 {item}" -#: js/share.js:296 +#: js/share.js:313 msgid "Unshare" msgstr "取消共享" -#: js/share.js:308 +#: js/share.js:325 msgid "can edit" msgstr "可編輯" -#: js/share.js:310 +#: js/share.js:327 msgid "access control" msgstr "存取控制" -#: js/share.js:313 +#: js/share.js:330 msgid "create" msgstr "建立" -#: js/share.js:316 +#: js/share.js:333 msgid "update" msgstr "更新" -#: js/share.js:319 +#: js/share.js:336 msgid "delete" msgstr "刪除" -#: js/share.js:322 +#: js/share.js:339 msgid "share" msgstr "分享" -#: js/share.js:356 js/share.js:541 +#: js/share.js:373 js/share.js:558 msgid "Password protected" msgstr "受密碼保護" -#: js/share.js:554 +#: js/share.js:571 msgid "Error unsetting expiration date" msgstr "解除過期日設定失敗" -#: js/share.js:566 +#: js/share.js:583 msgid "Error setting expiration date" msgstr "錯誤的到期日設定" -#: js/share.js:581 +#: js/share.js:598 msgid "Sending ..." msgstr "正在寄出..." -#: js/share.js:592 +#: js/share.js:609 msgid "Email sent" msgstr "Email 已寄出" diff --git a/l10n/zh_TW/settings.po b/l10n/zh_TW/settings.po index 36a92e308c..e657008a0c 100644 --- a/l10n/zh_TW/settings.po +++ b/l10n/zh_TW/settings.po @@ -14,8 +14,8 @@ msgid "" msgstr "" "Project-Id-Version: ownCloud\n" "Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n" -"POT-Creation-Date: 2013-01-12 00:09+0100\n" -"PO-Revision-Date: 2013-01-11 23:09+0000\n" +"POT-Creation-Date: 2013-01-30 00:23+0100\n" +"PO-Revision-Date: 2013-01-29 23:24+0000\n" "Last-Translator: I Robot \n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/owncloud/language/zh_TW/)\n" "MIME-Version: 1.0\n" @@ -94,7 +94,7 @@ msgstr "啟用" msgid "Saving..." msgstr "儲存中..." -#: personal.php:42 personal.php:43 +#: personal.php:34 personal.php:35 msgid "__language_name__" msgstr "__語言_名稱__" @@ -106,15 +106,15 @@ msgstr "添加你的 App" msgid "More Apps" msgstr "更多Apps" -#: templates/apps.php:27 +#: templates/apps.php:24 msgid "Select an App" msgstr "選擇一個應用程式" -#: templates/apps.php:31 +#: templates/apps.php:28 msgid "See application page at apps.owncloud.com" msgstr "查看應用程式頁面於 apps.owncloud.com" -#: templates/apps.php:32 +#: templates/apps.php:29 msgid "-licensed by " msgstr "-核准: " @@ -163,7 +163,7 @@ msgstr "下載 Android 客戶端" msgid "Download iOS Client" msgstr "下載 iOS 客戶端" -#: templates/personal.php:21 templates/users.php:23 templates/users.php:82 +#: templates/personal.php:21 templates/users.php:23 templates/users.php:81 msgid "Password" msgstr "密碼" @@ -233,11 +233,11 @@ msgid "" "License\">AGPL." msgstr "由ownCloud 社區開發,源代碼AGPL許可證下發布。" -#: templates/users.php:21 templates/users.php:81 -msgid "Name" -msgstr "名稱" +#: templates/users.php:21 templates/users.php:79 +msgid "Login Name" +msgstr "" -#: templates/users.php:26 templates/users.php:83 templates/users.php:103 +#: templates/users.php:26 templates/users.php:82 templates/users.php:107 msgid "Groups" msgstr "群組" @@ -249,26 +249,30 @@ msgstr "創造" msgid "Default Storage" msgstr "預設儲存區" -#: templates/users.php:42 templates/users.php:138 +#: templates/users.php:42 templates/users.php:142 msgid "Unlimited" msgstr "無限制" -#: templates/users.php:60 templates/users.php:153 +#: templates/users.php:60 templates/users.php:157 msgid "Other" msgstr "其他" -#: templates/users.php:85 templates/users.php:117 +#: templates/users.php:80 +msgid "Display Name" +msgstr "" + +#: templates/users.php:84 templates/users.php:121 msgid "Group Admin" msgstr "群組 管理員" -#: templates/users.php:87 +#: templates/users.php:86 msgid "Storage" msgstr "儲存區" -#: templates/users.php:133 +#: templates/users.php:137 msgid "Default" msgstr "預設" -#: templates/users.php:161 +#: templates/users.php:165 msgid "Delete" msgstr "刪除" diff --git a/lib/l10n/da.php b/lib/l10n/da.php index a0ab1f1701..8f22be5e82 100644 --- a/lib/l10n/da.php +++ b/lib/l10n/da.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "Filer skal downloades en for en.", "Back to Files" => "Tilbage til Filer", "Selected files too large to generate zip file." => "De markerede filer er for store til at generere en ZIP-fil.", +"couldn't be determined" => "kunne ikke fastslås", "Application is not enabled" => "Programmet er ikke aktiveret", "Authentication error" => "Adgangsfejl", "Token expired. Please reload page." => "Adgang er udløbet. Genindlæs siden.", diff --git a/lib/l10n/ru_RU.php b/lib/l10n/ru_RU.php index ba7d39f9eb..03da09236e 100644 --- a/lib/l10n/ru_RU.php +++ b/lib/l10n/ru_RU.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "Файлы должны быть загружены один за другим.", "Back to Files" => "Обратно к файлам", "Selected files too large to generate zip file." => "Выбранные файлы слишком велики для генерации zip-архива.", +"couldn't be determined" => "не может быть определено", "Application is not enabled" => "Приложение не запущено", "Authentication error" => "Ошибка аутентификации", "Token expired. Please reload page." => "Маркер истек. Пожалуйста, перезагрузите страницу.", diff --git a/lib/l10n/sk_SK.php b/lib/l10n/sk_SK.php index 98a5b5ca67..81f23ffdc5 100644 --- a/lib/l10n/sk_SK.php +++ b/lib/l10n/sk_SK.php @@ -9,6 +9,7 @@ "Files need to be downloaded one by one." => "Súbory musia byť nahrávané jeden za druhým.", "Back to Files" => "Späť na súbory", "Selected files too large to generate zip file." => "Zvolené súbory sú príliž veľké na vygenerovanie zip súboru.", +"couldn't be determined" => "nedá sa zistiť", "Application is not enabled" => "Aplikácia nie je zapnutá", "Authentication error" => "Chyba autentifikácie", "Token expired. Please reload page." => "Token vypršal. Obnovte, prosím, stránku.", diff --git a/settings/l10n/ar.php b/settings/l10n/ar.php index 20d4cced23..2870527781 100644 --- a/settings/l10n/ar.php +++ b/settings/l10n/ar.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "إستخدم هذا العنوان للإتصال بـ ownCloud في مدير الملفات", "Version" => "إصدار", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "طوّر من قبل ownCloud مجتمع, الـ النص المصدري مرخص بموجب رخصة أفيرو العمومية.", -"Name" => "الاسم", "Groups" => "مجموعات", "Create" => "انشئ", "Other" => "شيء آخر", diff --git a/settings/l10n/bg_BG.php b/settings/l10n/bg_BG.php index dc4c1cf643..bee057a998 100644 --- a/settings/l10n/bg_BG.php +++ b/settings/l10n/bg_BG.php @@ -4,7 +4,6 @@ "Enable" => "Включено", "Password" => "Парола", "Email" => "E-mail", -"Name" => "Име", "Groups" => "Групи", "Delete" => "Изтриване" ); diff --git a/settings/l10n/bn_BD.php b/settings/l10n/bn_BD.php index bab6d9ec19..fc85e70575 100644 --- a/settings/l10n/bn_BD.php +++ b/settings/l10n/bn_BD.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "আপনার ownCloud এ সংযুক্ত হতে এই ঠিকানাটি আপনার ফাইল ব্যবস্থাপকে ব্যবহার করুন", "Version" => "ভার্সন", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "তৈলী করেছেন ownCloud সম্প্রদায়, যার উৎস কোডটি AGPL এর অধীনে লাইসেন্সকৃত।", -"Name" => "রাম", "Groups" => "গোষ্ঠীসমূহ", "Create" => "তৈরী কর", "Default Storage" => "পূর্বনির্ধারিত সংরক্ষণাগার", diff --git a/settings/l10n/ca.php b/settings/l10n/ca.php index 3595247525..1f23c2cfd6 100644 --- a/settings/l10n/ca.php +++ b/settings/l10n/ca.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Useu aquesta adreça per connectar amb ownCloud des del gestor de fitxers", "Version" => "Versió", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Desenvolupat per la comunitat ownCloud, el codi font té llicència AGPL.", -"Name" => "Nom", "Groups" => "Grups", "Create" => "Crea", "Default Storage" => "Emmagatzemament per defecte", diff --git a/settings/l10n/cs_CZ.php b/settings/l10n/cs_CZ.php index d20861764a..be75a679c6 100644 --- a/settings/l10n/cs_CZ.php +++ b/settings/l10n/cs_CZ.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Použijte tuto adresu pro připojení k vašemu ownCloud skrze správce souborů", "Version" => "Verze", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Vyvinuto komunitou ownCloud, zdrojový kód je licencován pod AGPL.", -"Name" => "Jméno", "Groups" => "Skupiny", "Create" => "Vytvořit", "Default Storage" => "Výchozí úložiště", diff --git a/settings/l10n/da.php b/settings/l10n/da.php index 021d7f814b..f0842922d6 100644 --- a/settings/l10n/da.php +++ b/settings/l10n/da.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Brug denne adresse til at oprette forbindelse til din ownCloud i din filstyring", "Version" => "Version", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Udviklet af ownClouds community, og kildekoden er underlagt licensen AGPL.", -"Name" => "Navn", "Groups" => "Grupper", "Create" => "Ny", "Default Storage" => "Standard opbevaring", diff --git a/settings/l10n/de.php b/settings/l10n/de.php index ad3043a4aa..d2a9a826aa 100644 --- a/settings/l10n/de.php +++ b/settings/l10n/de.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Verwende diese Adresse, um Deinen Dateimanager mit Deiner ownCloud zu verbinden", "Version" => "Version", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Entwickelt von der ownCloud-Community, der Quellcode ist unter der AGPL lizenziert.", -"Name" => "Name", "Groups" => "Gruppen", "Create" => "Anlegen", "Default Storage" => "Standard-Speicher", diff --git a/settings/l10n/de_DE.php b/settings/l10n/de_DE.php index f394a333a6..cb735adfdf 100644 --- a/settings/l10n/de_DE.php +++ b/settings/l10n/de_DE.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Verwenden Sie diese Adresse, um Ihren Dateimanager mit Ihrer ownCloud zu verbinden", "Version" => "Version", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Entwickelt von der ownCloud-Community. Der Quellcode ist unter der AGPL lizenziert.", -"Name" => "Name", "Groups" => "Gruppen", "Create" => "Anlegen", "Default Storage" => "Standard-Speicher", diff --git a/settings/l10n/el.php b/settings/l10n/el.php index ffd6d2a60b..beacb5e614 100644 --- a/settings/l10n/el.php +++ b/settings/l10n/el.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Χρήση αυτής της διεύθυνσης για σύνδεση στο ownCloud με τον διαχειριστή αρχείων σας", "Version" => "Έκδοση", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Αναπτύχθηκε από την κοινότητα ownCloud, ο πηγαίος κώδικας είναι υπό άδεια χρήσης AGPL.", -"Name" => "Όνομα", "Groups" => "Ομάδες", "Create" => "Δημιουργία", "Default Storage" => "Προκαθορισμένη Αποθήκευση ", diff --git a/settings/l10n/eo.php b/settings/l10n/eo.php index ef8615e24e..e17380441c 100644 --- a/settings/l10n/eo.php +++ b/settings/l10n/eo.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Uzu ĉi tiun adreson por konekti al via ownCloud vian dosieradministrilon", "Version" => "Eldono", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Ellaborita de la komunumo de ownCloud, la fontokodo publikas laŭ la permesilo AGPL.", -"Name" => "Nomo", "Groups" => "Grupoj", "Create" => "Krei", "Default Storage" => "Defaŭlta konservejo", diff --git a/settings/l10n/es.php b/settings/l10n/es.php index 5434da7f98..2bc2a12a5a 100644 --- a/settings/l10n/es.php +++ b/settings/l10n/es.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Use esta dirección para conectarse a su cuenta de ownCloud en el administrador de archivos", "Version" => "Version", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Desarrollado por la comunidad ownCloud, el código fuente está bajo licencia AGPL.", -"Name" => "Nombre", "Groups" => "Grupos", "Create" => "Crear", "Default Storage" => "Almacenamiento Predeterminado", diff --git a/settings/l10n/es_AR.php b/settings/l10n/es_AR.php index a652ee1310..bbf45bc562 100644 --- a/settings/l10n/es_AR.php +++ b/settings/l10n/es_AR.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Utiliza esta dirección para conectarte con ownCloud en tu Administrador de Archivos", "Version" => "Versión", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Desarrollado por la comunidad ownCloud, el código fuente está bajo licencia AGPL.", -"Name" => "Nombre", "Groups" => "Grupos", "Create" => "Crear", "Default Storage" => "Almacenamiento Predeterminado", diff --git a/settings/l10n/et_EE.php b/settings/l10n/et_EE.php index 53f6171728..751c88ecb5 100644 --- a/settings/l10n/et_EE.php +++ b/settings/l10n/et_EE.php @@ -34,7 +34,6 @@ "Fill in an email address to enable password recovery" => "Parooli taastamise sisse lülitamiseks sisesta e-posti aadress", "Language" => "Keel", "Help translate" => "Aita tõlkida", -"Name" => "Nimi", "Groups" => "Grupid", "Create" => "Lisa", "Other" => "Muu", diff --git a/settings/l10n/eu.php b/settings/l10n/eu.php index c122f3b1cd..29e3a810ca 100644 --- a/settings/l10n/eu.php +++ b/settings/l10n/eu.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Erabili helbide hau zure fitxategi kudeatzailean zure ownCloudera konektatzeko", "Version" => "Bertsioa", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "ownCloud komunitateak garatuta, itubruru kodeaAGPL lizentziarekin banatzen da.", -"Name" => "Izena", "Groups" => "Taldeak", "Create" => "Sortu", "Default Storage" => "Lehenetsitako Biltegiratzea", diff --git a/settings/l10n/fa.php b/settings/l10n/fa.php index 44872e28f0..59865c697c 100644 --- a/settings/l10n/fa.php +++ b/settings/l10n/fa.php @@ -25,7 +25,6 @@ "Fill in an email address to enable password recovery" => "پست الکترونیکی را پرکنید تا بازیابی گذرواژه فعال شود", "Language" => "زبان", "Help translate" => "به ترجمه آن کمک کنید", -"Name" => "نام", "Groups" => "گروه ها", "Create" => "ایجاد کردن", "Other" => "سایر", diff --git a/settings/l10n/fi_FI.php b/settings/l10n/fi_FI.php index dbab88b97a..84b18902b9 100644 --- a/settings/l10n/fi_FI.php +++ b/settings/l10n/fi_FI.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Käytä tätä osoitetta yhdistäessäsi ownCloudiisi tiedostonhallintaa käyttäen", "Version" => "Versio", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Kehityksestä on vastannut ownCloud-yhteisö, lähdekoodi on julkaistu lisenssin AGPL alaisena.", -"Name" => "Nimi", "Groups" => "Ryhmät", "Create" => "Luo", "Unlimited" => "Rajoittamaton", diff --git a/settings/l10n/fr.php b/settings/l10n/fr.php index 03a61c69cf..5b9495b566 100644 --- a/settings/l10n/fr.php +++ b/settings/l10n/fr.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Utiliser cette adresse pour vous connecter à ownCloud dans votre gestionnaire de fichiers", "Version" => "Version", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Développé par la communauté ownCloud, le code source est publié sous license AGPL.", -"Name" => "Nom", "Groups" => "Groupes", "Create" => "Créer", "Default Storage" => "Support de stockage par défaut", diff --git a/settings/l10n/gl.php b/settings/l10n/gl.php index ddd5661fe7..d3359f1951 100644 --- a/settings/l10n/gl.php +++ b/settings/l10n/gl.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Utilice este enderezo para conectarse ao seu ownCloud co administrador de ficheiros", "Version" => "Versión", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Desenvolvido pola comunidade ownCloud, o código fonte está baixo a licenza AGPL.", -"Name" => "Nome", "Groups" => "Grupos", "Create" => "Crear", "Default Storage" => "Almacenamento predeterminado", diff --git a/settings/l10n/he.php b/settings/l10n/he.php index bbfe437ba3..b7e76fbaed 100644 --- a/settings/l10n/he.php +++ b/settings/l10n/he.php @@ -47,7 +47,6 @@ "Use this address to connect to your ownCloud in your file manager" => "השתמש בכתובת זאת על מנת להתחבר אל ownCloud דרך סייר קבצים.", "Version" => "גרסא", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "פותח על די קהילתownCloud, קוד המקור מוגן ברישיון AGPL.", -"Name" => "שם", "Groups" => "קבוצות", "Create" => "יצירה", "Other" => "אחר", diff --git a/settings/l10n/hr.php b/settings/l10n/hr.php index 14053cb98a..010303eb44 100644 --- a/settings/l10n/hr.php +++ b/settings/l10n/hr.php @@ -24,7 +24,6 @@ "Fill in an email address to enable password recovery" => "Ispunite vase e-mail adresa kako bi se omogućilo oporavak lozinke", "Language" => "Jezik", "Help translate" => "Pomoć prevesti", -"Name" => "Ime", "Groups" => "Grupe", "Create" => "Izradi", "Other" => "ostali", diff --git a/settings/l10n/hu_HU.php b/settings/l10n/hu_HU.php index 35c59bdb2d..2e09609936 100644 --- a/settings/l10n/hu_HU.php +++ b/settings/l10n/hu_HU.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Ennek a címnek a megadásával a WebDAV-protokollon keresztül saját gépének fájlkezelőjével is is elérheti az állományait.", "Version" => "Verzió", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "A programot az ownCloud közösség fejleszti. A forráskód az AGPL feltételei mellett használható föl.", -"Name" => "Név", "Groups" => "Csoportok", "Create" => "Létrehozás", "Default Storage" => "Alapértelmezett tárhely", diff --git a/settings/l10n/ia.php b/settings/l10n/ia.php index 1842870909..121a1175e7 100644 --- a/settings/l10n/ia.php +++ b/settings/l10n/ia.php @@ -15,7 +15,6 @@ "Your email address" => "Tu adresse de e-posta", "Language" => "Linguage", "Help translate" => "Adjuta a traducer", -"Name" => "Nomine", "Groups" => "Gruppos", "Create" => "Crear", "Other" => "Altere", diff --git a/settings/l10n/id.php b/settings/l10n/id.php index 132920a7a0..0f04563fa3 100644 --- a/settings/l10n/id.php +++ b/settings/l10n/id.php @@ -23,7 +23,6 @@ "Fill in an email address to enable password recovery" => "Masukkan alamat email untuk mengaktifkan pemulihan password", "Language" => "Bahasa", "Help translate" => "Bantu menerjemahkan", -"Name" => "Nama", "Groups" => "Group", "Create" => "Buat", "Other" => "Lain-lain", diff --git a/settings/l10n/is.php b/settings/l10n/is.php index d978957ab4..5873057534 100644 --- a/settings/l10n/is.php +++ b/settings/l10n/is.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Notaðu þessa vefslóð til að tengjast ownCloud svæðinu þínu", "Version" => "Útgáfa", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Þróað af ownCloud samfélaginu, forrita kóðinn er skráðu með AGPL.", -"Name" => "Nafn", "Groups" => "Hópar", "Create" => "Búa til", "Default Storage" => "Sjálfgefin gagnageymsla", diff --git a/settings/l10n/it.php b/settings/l10n/it.php index 4980d58544..2199f7d8db 100644 --- a/settings/l10n/it.php +++ b/settings/l10n/it.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Usa questo indirizzo per connetterti al tuo ownCloud dal tuo gestore file", "Version" => "Versione", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Sviluppato dalla comunità di ownCloud, il codice sorgente è licenziato nei termini della AGPL.", -"Name" => "Nome", "Groups" => "Gruppi", "Create" => "Crea", "Default Storage" => "Archiviazione predefinita", diff --git a/settings/l10n/ja_JP.php b/settings/l10n/ja_JP.php index a660d21c78..dbf8d7d13e 100644 --- a/settings/l10n/ja_JP.php +++ b/settings/l10n/ja_JP.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "ファイルマネージャでownCloudに接続する際はこのアドレスを利用してください", "Version" => "バージョン", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "ownCloud communityにより開発されています、ソースコードライセンスは、AGPL ライセンスにより提供されています。", -"Name" => "名前", "Groups" => "グループ", "Create" => "作成", "Default Storage" => "デフォルトストレージ", diff --git a/settings/l10n/ka_GE.php b/settings/l10n/ka_GE.php index 68dbc736dc..2bc2e7d5de 100644 --- a/settings/l10n/ka_GE.php +++ b/settings/l10n/ka_GE.php @@ -34,7 +34,6 @@ "Fill in an email address to enable password recovery" => "შეავსეთ იმეილ მისამართის ველი პაროლის აღსადგენად", "Language" => "ენა", "Help translate" => "თარგმნის დახმარება", -"Name" => "სახელი", "Groups" => "ჯგუფი", "Create" => "შექმნა", "Other" => "სხვა", diff --git a/settings/l10n/ko.php b/settings/l10n/ko.php index 4a7817b840..3a794eb3ce 100644 --- a/settings/l10n/ko.php +++ b/settings/l10n/ko.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "파일 매니저에서 사용자의 ownCloud에 접속하기 위해 이 주소를 사용하십시요.", "Version" => "버젼", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "ownCloud 커뮤니티에 의해서 개발되었습니다. 원본 코드AGPL에 따라 사용이 허가됩니다.", -"Name" => "이름", "Groups" => "그룹", "Create" => "만들기", "Default Storage" => "기본 저장소", diff --git a/settings/l10n/ku_IQ.php b/settings/l10n/ku_IQ.php index 6a4996e825..ef9e806e59 100644 --- a/settings/l10n/ku_IQ.php +++ b/settings/l10n/ku_IQ.php @@ -3,6 +3,5 @@ "Saving..." => "پاشکه‌وتده‌کات...", "Password" => "وشەی تێپەربو", "New password" => "وشەی نهێنی نوێ", -"Email" => "ئیمه‌یل", -"Name" => "ناو" +"Email" => "ئیمه‌یل" ); diff --git a/settings/l10n/lb.php b/settings/l10n/lb.php index 1f9ea35e88..04acf53de4 100644 --- a/settings/l10n/lb.php +++ b/settings/l10n/lb.php @@ -24,7 +24,6 @@ "Fill in an email address to enable password recovery" => "Gëff eng Email Adress an fir d'Passwuert recovery ze erlaben", "Language" => "Sprooch", "Help translate" => "Hëllef iwwersetzen", -"Name" => "Numm", "Groups" => "Gruppen", "Create" => "Erstellen", "Other" => "Aner", diff --git a/settings/l10n/lt_LT.php b/settings/l10n/lt_LT.php index 73af4f3b27..e8c1577c7f 100644 --- a/settings/l10n/lt_LT.php +++ b/settings/l10n/lt_LT.php @@ -27,7 +27,6 @@ "Fill in an email address to enable password recovery" => "Pamiršto slaptažodžio atkūrimui įveskite savo el. pašto adresą", "Language" => "Kalba", "Help translate" => "Padėkite išversti", -"Name" => "Vardas", "Groups" => "Grupės", "Create" => "Sukurti", "Other" => "Kita", diff --git a/settings/l10n/lv.php b/settings/l10n/lv.php index ddc480f348..4cafe3ab71 100644 --- a/settings/l10n/lv.php +++ b/settings/l10n/lv.php @@ -36,7 +36,6 @@ "Language" => "Valoda", "Help translate" => "Palīdzi tulkot", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "IzstrādājusiownCloud kopiena,pirmkodukurš ir licencēts zem AGPL.", -"Name" => "Vārds", "Groups" => "Grupas", "Create" => "Izveidot", "Other" => "Cits", diff --git a/settings/l10n/mk.php b/settings/l10n/mk.php index 52fafc5647..b041d41923 100644 --- a/settings/l10n/mk.php +++ b/settings/l10n/mk.php @@ -48,7 +48,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Користете ја оваа адреса да ", "Version" => "Верзија", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Развој од ownCloud заедницата, изворниот код е лиценциран соAGPL.", -"Name" => "Име", "Groups" => "Групи", "Create" => "Создај", "Other" => "Останато", diff --git a/settings/l10n/ms_MY.php b/settings/l10n/ms_MY.php index 87f45d3c9a..e2537679a6 100644 --- a/settings/l10n/ms_MY.php +++ b/settings/l10n/ms_MY.php @@ -23,7 +23,6 @@ "Fill in an email address to enable password recovery" => "Isi alamat emel anda untuk membolehkan pemulihan kata laluan", "Language" => "Bahasa", "Help translate" => "Bantu terjemah", -"Name" => "Nama", "Groups" => "Kumpulan", "Create" => "Buat", "Other" => "Lain", diff --git a/settings/l10n/nb_NO.php b/settings/l10n/nb_NO.php index 52cfc92040..ecd1466e7e 100644 --- a/settings/l10n/nb_NO.php +++ b/settings/l10n/nb_NO.php @@ -42,7 +42,6 @@ "Help translate" => "Bidra til oversettelsen", "WebDAV" => "WebDAV", "Version" => "Versjon", -"Name" => "Navn", "Groups" => "Grupper", "Create" => "Opprett", "Other" => "Annet", diff --git a/settings/l10n/nl.php b/settings/l10n/nl.php index 2b6fdbd608..af76f37668 100644 --- a/settings/l10n/nl.php +++ b/settings/l10n/nl.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Gebruik dit adres om te verbinden met uw ownCloud in uw bestandsbeheer", "Version" => "Versie", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Ontwikkeld door de ownCloud gemeenschap, de bron code is gelicenseerd onder de AGPL.", -"Name" => "Naam", "Groups" => "Groepen", "Create" => "Creëer", "Default Storage" => "Default opslag", diff --git a/settings/l10n/nn_NO.php b/settings/l10n/nn_NO.php index 923f5481d5..778e7afc26 100644 --- a/settings/l10n/nn_NO.php +++ b/settings/l10n/nn_NO.php @@ -21,7 +21,6 @@ "Fill in an email address to enable password recovery" => "Fyll inn din e-post addresse for og kunne motta passord tilbakestilling", "Language" => "Språk", "Help translate" => "Hjelp oss å oversett", -"Name" => "Namn", "Groups" => "Grupper", "Create" => "Lag", "Other" => "Anna", diff --git a/settings/l10n/oc.php b/settings/l10n/oc.php index 39445570fd..e8ed2d5275 100644 --- a/settings/l10n/oc.php +++ b/settings/l10n/oc.php @@ -33,7 +33,6 @@ "Fill in an email address to enable password recovery" => "Emplena una adreiça de corrièl per permetre lo mandadís del senhal perdut", "Language" => "Lenga", "Help translate" => "Ajuda a la revirada", -"Name" => "Nom", "Groups" => "Grops", "Create" => "Crea", "Other" => "Autres", diff --git a/settings/l10n/pl.php b/settings/l10n/pl.php index ae4d335c72..656636b258 100644 --- a/settings/l10n/pl.php +++ b/settings/l10n/pl.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Użyj tego adresu aby podłączyć zasób ownCloud w menedżerze plików", "Version" => "Wersja", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Stworzone przez społeczność ownCloud, the kod źródłowy na licencji AGPL.", -"Name" => "Nazwa", "Groups" => "Grupy", "Create" => "Utwórz", "Default Storage" => "Domyślny magazyn", diff --git a/settings/l10n/pt_BR.php b/settings/l10n/pt_BR.php index ebb9b72b19..f14233d7e5 100644 --- a/settings/l10n/pt_BR.php +++ b/settings/l10n/pt_BR.php @@ -37,7 +37,6 @@ "Language" => "Idioma", "Help translate" => "Ajude a traduzir", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Desenvolvido pela comunidade ownCloud, o código fonte está licenciado sob AGPL.", -"Name" => "Nome", "Groups" => "Grupos", "Create" => "Criar", "Other" => "Outro", diff --git a/settings/l10n/pt_PT.php b/settings/l10n/pt_PT.php index 6bccb49d64..af5dfbf6e4 100644 --- a/settings/l10n/pt_PT.php +++ b/settings/l10n/pt_PT.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Use este endereço no seu gestor de ficheiros para ligar à sua ownCloud", "Version" => "Versão", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Desenvolvido pela comunidade ownCloud, ocódigo fonte está licenciado sob a AGPL.", -"Name" => "Nome", "Groups" => "Grupos", "Create" => "Criar", "Default Storage" => "Armazenamento Padrão", diff --git a/settings/l10n/ro.php b/settings/l10n/ro.php index 1166f9587e..17a091c569 100644 --- a/settings/l10n/ro.php +++ b/settings/l10n/ro.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Folosește această adresă pentru a conecta ownCloud cu managerul de fișiere", "Version" => "Versiunea", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Dezvoltat de the comunitatea ownCloud, codul sursă este licențiat sub AGPL.", -"Name" => "Nume", "Groups" => "Grupuri", "Create" => "Crează", "Default Storage" => "Stocare implicită", diff --git a/settings/l10n/ru.php b/settings/l10n/ru.php index 5c05f32636..2194c886f1 100644 --- a/settings/l10n/ru.php +++ b/settings/l10n/ru.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Используйте этот URL для подключения файлового менеджера к Вашему хранилищу", "Version" => "Версия", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Разрабатывается сообществом ownCloud, исходный код доступен под лицензией AGPL.", -"Name" => "Имя", "Groups" => "Группы", "Create" => "Создать", "Default Storage" => "Хранилище по-умолчанию", diff --git a/settings/l10n/ru_RU.php b/settings/l10n/ru_RU.php index 26179eeb32..50c3b136c4 100644 --- a/settings/l10n/ru_RU.php +++ b/settings/l10n/ru_RU.php @@ -30,6 +30,7 @@ "Commercial Support" => "Коммерческая поддержка", "You have used %s of the available %s" => "Вы использовали %s из возможных %s", "Clients" => "Клиенты", +"Download Desktop Clients" => "Загрузка десктопных клиентов", "Download Android Client" => "Загрузить клиент под Android ", "Download iOS Client" => "Загрузить клиент под iOS ", "Password" => "Пароль", @@ -48,10 +49,13 @@ "Use this address to connect to your ownCloud in your file manager" => "Используйте этот адрес для подключения к ownCloud в Вашем файловом менеджере", "Version" => "Версия", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Разработанный ownCloud community, the source code is licensed under the AGPL.", -"Name" => "Имя", "Groups" => "Группы", "Create" => "Создать", +"Default Storage" => "Хранилище по умолчанию", +"Unlimited" => "Неограниченный", "Other" => "Другой", "Group Admin" => "Группа Admin", +"Storage" => "Хранилище", +"Default" => "По умолчанию", "Delete" => "Удалить" ); diff --git a/settings/l10n/si_LK.php b/settings/l10n/si_LK.php index 45cb9a4a4f..8d7bc7adf5 100644 --- a/settings/l10n/si_LK.php +++ b/settings/l10n/si_LK.php @@ -31,7 +31,6 @@ "Language" => "භාෂාව", "Help translate" => "පරිවර්ථන සහය", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "නිපදන ලද්දේ ownCloud සමාජයෙන්, the මුල් කේතය ලයිසන්ස් කර ඇත්තේ AGPL යටතේ.", -"Name" => "නාමය", "Groups" => "සමූහය", "Create" => "තනන්න", "Other" => "වෙනත්", diff --git a/settings/l10n/sk_SK.php b/settings/l10n/sk_SK.php index 884e785ad8..3941bd51ae 100644 --- a/settings/l10n/sk_SK.php +++ b/settings/l10n/sk_SK.php @@ -26,6 +26,7 @@ "Administrator Documentation" => "Príručka správcu", "Online Documentation" => "Online príručka", "Forum" => "Fórum", +"Bugtracker" => "Bugtracker", "Commercial Support" => "Komerčná podpora", "You have used %s of the available %s" => "Použili ste %s z %s dostupných ", "Clients" => "Klienti", @@ -48,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Použite túto adresu pre pripojenie vášho ownCloud k súborovému správcovi", "Version" => "Verzia", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Vyvinuté komunitou ownCloud,zdrojový kód je licencovaný pod AGPL.", -"Name" => "Meno", "Groups" => "Skupiny", "Create" => "Vytvoriť", "Default Storage" => "Predvolené úložisko", diff --git a/settings/l10n/sl.php b/settings/l10n/sl.php index 24bea14799..98d3451847 100644 --- a/settings/l10n/sl.php +++ b/settings/l10n/sl.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Uporabite ta naslov za povezavo do ownCloud v vašem upravljalniku datotek.", "Version" => "Različica", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Programski paket razvija skupnost ownCloud. Izvorna koda je objavljena pod pogoji dovoljenja AGPL.", -"Name" => "Ime", "Groups" => "Skupine", "Create" => "Ustvari", "Default Storage" => "Privzeta shramba", diff --git a/settings/l10n/sr.php b/settings/l10n/sr.php index d230adb927..9f0d428c2e 100644 --- a/settings/l10n/sr.php +++ b/settings/l10n/sr.php @@ -37,7 +37,6 @@ "Language" => "Језик", "Help translate" => " Помозите у превођењу", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Развијају Оунклауд (ownCloud) заједница, изворни код је издат под АГПЛ лиценцом.", -"Name" => "Име", "Groups" => "Групе", "Create" => "Направи", "Other" => "Друго", diff --git a/settings/l10n/sr@latin.php b/settings/l10n/sr@latin.php index 7677fbcf33..942594eb02 100644 --- a/settings/l10n/sr@latin.php +++ b/settings/l10n/sr@latin.php @@ -12,7 +12,6 @@ "Change password" => "Izmeni lozinku", "Email" => "E-mail", "Language" => "Jezik", -"Name" => "Ime", "Groups" => "Grupe", "Create" => "Napravi", "Other" => "Drugo", diff --git a/settings/l10n/sv.php b/settings/l10n/sv.php index e99fad9617..4c30873b3c 100644 --- a/settings/l10n/sv.php +++ b/settings/l10n/sv.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Använd denna adress för att ansluta till ownCloud i din filhanterare", "Version" => "Version", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Utvecklad av ownCloud kommunity, källkoden är licenserad under AGPL.", -"Name" => "Namn", "Groups" => "Grupper", "Create" => "Skapa", "Default Storage" => "Förvald lagring", diff --git a/settings/l10n/ta_LK.php b/settings/l10n/ta_LK.php index 9771e167e4..84f6026ca3 100644 --- a/settings/l10n/ta_LK.php +++ b/settings/l10n/ta_LK.php @@ -36,7 +36,6 @@ "Language" => "மொழி", "Help translate" => "மொழிபெயர்க்க உதவி", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Developed by the ownCloud community, the source code is licensed under the AGPL.", -"Name" => "பெயர்", "Groups" => "குழுக்கள்", "Create" => "உருவாக்குக", "Other" => "மற்றவை", diff --git a/settings/l10n/th_TH.php b/settings/l10n/th_TH.php index c0c606662e..3ef68cf7fe 100644 --- a/settings/l10n/th_TH.php +++ b/settings/l10n/th_TH.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "ใช้ที่อยู่นี้เพื่อเชื่อมต่อกับ ownCloud ในโปรแกรมจัดการไฟล์ของคุณ", "Version" => "รุ่น", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "พัฒนาโดย the ชุมชนผู้ใช้งาน ownCloud, the ซอร์สโค้ดอยู่ภายใต้สัญญาอนุญาตของ AGPL.", -"Name" => "ชื่อ", "Groups" => "กลุ่ม", "Create" => "สร้าง", "Default Storage" => "พื้นที่จำกัดข้อมูลเริ่มต้น", diff --git a/settings/l10n/tr.php b/settings/l10n/tr.php index f754bb90fc..281e01e116 100644 --- a/settings/l10n/tr.php +++ b/settings/l10n/tr.php @@ -44,7 +44,6 @@ "WebDAV" => "WebDAV", "Version" => "Sürüm", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Geliştirilen TarafownCloud community, the source code is altında lisanslanmıştır AGPL.", -"Name" => "Ad", "Groups" => "Gruplar", "Create" => "Oluştur", "Other" => "Diğer", diff --git a/settings/l10n/uk.php b/settings/l10n/uk.php index 19b84edfc7..dc2c537b4f 100644 --- a/settings/l10n/uk.php +++ b/settings/l10n/uk.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "Використовуйте цю адресу для під'єднання до вашого ownCloud у вашому файловому менеджері", "Version" => "Версія", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Розроблено ownCloud громадою, вихідний код має ліцензію AGPL.", -"Name" => "Ім'я", "Groups" => "Групи", "Create" => "Створити", "Default Storage" => "сховище за замовчуванням", diff --git a/settings/l10n/vi.php b/settings/l10n/vi.php index 2354ba2a16..39b09aa938 100644 --- a/settings/l10n/vi.php +++ b/settings/l10n/vi.php @@ -37,7 +37,6 @@ "Language" => "Ngôn ngữ", "Help translate" => "Hỗ trợ dịch thuật", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "Được phát triển bởi cộng đồng ownCloud, mã nguồn đã được cấp phép theo chuẩn AGPL.", -"Name" => "Tên", "Groups" => "Nhóm", "Create" => "Tạo", "Other" => "Khác", diff --git a/settings/l10n/zh_CN.GB2312.php b/settings/l10n/zh_CN.GB2312.php index b34b20d5ae..f8e37ac749 100644 --- a/settings/l10n/zh_CN.GB2312.php +++ b/settings/l10n/zh_CN.GB2312.php @@ -35,7 +35,6 @@ "Language" => "语言", "Help translate" => "帮助翻译", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "由 ownCloud 社区开发,s源代码AGPL 许可协议发布。", -"Name" => "名字", "Groups" => "组", "Create" => "新建", "Other" => "其他的", diff --git a/settings/l10n/zh_CN.php b/settings/l10n/zh_CN.php index 407177d2ac..dfcf7bf7bf 100644 --- a/settings/l10n/zh_CN.php +++ b/settings/l10n/zh_CN.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "用该地址来连接文件管理器中的 ownCloud", "Version" => "版本", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "由ownCloud社区开发, 源代码AGPL许可证下发布。", -"Name" => "名称", "Groups" => "组", "Create" => "创建", "Default Storage" => "默认存储", diff --git a/settings/l10n/zh_TW.php b/settings/l10n/zh_TW.php index 7681b10aff..5fe555d14f 100644 --- a/settings/l10n/zh_TW.php +++ b/settings/l10n/zh_TW.php @@ -49,7 +49,6 @@ "Use this address to connect to your ownCloud in your file manager" => "在您的檔案管理員中使用這個地址來連線到 ownCloud", "Version" => "版本", "Developed by the ownCloud community, the source code is licensed under the AGPL." => "由ownCloud 社區開發,源代碼AGPL許可證下發布。", -"Name" => "名稱", "Groups" => "群組", "Create" => "創造", "Default Storage" => "預設儲存區", From 8fd263ef63ad122211eca90567a741c7e18d51f2 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 23 Jan 2013 18:20:55 +0100 Subject: [PATCH 251/262] LDAP: update quota on every uncached userExists, i.e. also on every isLoggedIn, fixes #1278 --- apps/user_ldap/user_ldap.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 4928ad2e27..b3180e1135 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -156,6 +156,7 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface { } $this->connection->writeToCache('userExists'.$uid, true); + $this->updateQuota($dn); return true; } From 0089b17749fa3d8bb0b7eaa7abf493e49b9a7e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 18 Jan 2013 21:49:38 +0100 Subject: [PATCH 252/262] add multselect dnd --- apps/files/css/files.css | 11 ++++ apps/files/js/files.js | 135 ++++++++++++++++++++++++++++++++------- 2 files changed, 122 insertions(+), 24 deletions(-) diff --git a/apps/files/css/files.css b/apps/files/css/files.css index e65f724f68..9ff550189d 100644 --- a/apps/files/css/files.css +++ b/apps/files/css/files.css @@ -122,3 +122,14 @@ a.action>img { max-height:16px; max-width:16px; vertical-align:text-bottom; } #scanning-message{ top:40%; left:40%; position:absolute; display:none; } div.crumb a{ padding:0.9em 0 0.7em 0; } + +table.dragshadow { + width:auto; +} +table.dragshadow td.filename { + padding-left:36px; + padding-right:16px; +} +table.dragshadow td.size { + padding-right:8px; +} \ No newline at end of file diff --git a/apps/files/js/files.js b/apps/files/js/files.js index c817d8431e..0088778457 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -813,32 +813,102 @@ function updateBreadcrumb(breadcrumbHtml) { $('p.nav').empty().html(breadcrumbHtml); } -//options for file drag/dropp +var createDragShadow = function(event){ + //select dragged file + $(event.target).parents('tr').find('td input:first').prop('checked', true); + + var selectedFiles = getSelectedFiles(); + + //also update class when we dragged more than one file + if (selectedFiles.length > 1) { + $(event.target).parents('tr').addClass('selected'); + } + + // build dragshadow + var dragshadow = $('
'); + var tbody = $(''); + dragshadow.append(tbody); + + var dir=$('#dir').val(); + + $(selectedFiles).each(function(i,elem){ + var selected= $(event.target).parents('tr').hasClass('selected'); + var newtr = $('' + +''+elem.name+''+humanFileSize(elem.size)+'' + +''); + tbody.append(newtr); + if (elem.type === 'dir') { + newtr.find('td.filename').attr('style','background-image:url('+OC.imagePath('core', 'filetypes/folder.png')+')'); + } else { + getMimeIcon(elem.mime,function(path){ + newtr.find('td.filename').attr('style','background-image:url('+path+')'); + }); + } + }); + + return dragshadow; +} + +//options for file drag/drop var dragOptions={ - distance: 20, revert: 'invalid', opacity: 0.7, helper: 'clone', + revert: 'invalid', opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: -5, top: -5 }, + helper: createDragShadow, cursor: 'move', stop: function(event, ui) { $('#fileList tr td.filename').addClass('ui-draggable'); - } -}; -var folderDropOptions={ - drop: function( event, ui ) { - var file=ui.draggable.parent().data('file'); - var target=$(this).find('.nametext').text().trim(); - var dir=$('#dir').val(); - $.ajax({ - url: OC.filePath('files', 'ajax', 'move.php'), - data: "dir="+encodeURIComponent(dir)+"&file="+encodeURIComponent(file)+'&target='+encodeURIComponent(dir)+'/'+encodeURIComponent(target), - complete: function(data){boolOperationFinished(data, function(){ - var el = $('#fileList tr').filterAttr('data-file',file).find('td.filename'); - el.draggable('destroy'); - FileList.remove(file); - });} + //reset selection + $(ui.helper.find('tr')).each(function(i,row){ + var file = $(row).data('filename'); + var selected = $(row).data('selected'); + $('#fileList tr').filterAttr('data-file',file).find('td input:first').prop('checked',selected); }); } } + +var folderDropOptions={ + drop: function( event, ui ) { + //don't allow moving a file into a selected folder + if ($(event.target).parents('tr').find('td input:first').prop('checked') === true) { + return false; + } + + var target=$(this).find('.nametext').text().trim(); + + var files = ui.helper.find('tr'); + $(files).each(function(i,row){ + var dir = $(row).data('dir'); + var file = $(row).data('filename'); + $.get(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: dir+'/'+target }, function(result) { + if (result) { + if (result.status === 'success') { + //recalculate folder size + var oldSize = $('#fileList tr').filterAttr('data-file',target).data('size'); + var newSize = oldSize + $('#fileList tr').filterAttr('data-file',file).data('size'); + $('#fileList tr').filterAttr('data-file',target).data('size', newSize); + $('#fileList tr').filterAttr('data-file',target).find('td.filesize').text(humanFileSize(newSize)); + + FileList.remove(file); + procesSelection(); + $('#notification').hide(); + } else { + $('#notification').hide(); + $('#notification').text(result.data.message); + $('#notification').fadeIn(); + } + } else { + OC.dialogs.alert(t('Error moving file')); + } + }); + }); + //reset checkbox if we dragged a single file + if (files.length == 1) { + $(event.target).parents('tr').find('td input:first').prop('checked', $(event.target).parents('tr').hasClass('selected')); + } + }, + tolerance: 'pointer' +} + var crumbDropOptions={ drop: function( event, ui ) { - var file=ui.draggable.parent().data('file'); var target=$(this).data('dir'); var dir=$('#dir').val(); while(dir.substr(0,1)=='/'){//remove extra leading /'s @@ -851,13 +921,30 @@ var crumbDropOptions={ if(target==dir || target+'/'==dir){ return; } - $.ajax({ - url: OC.filePath('files', 'ajax', 'move.php'), - data: "dir="+encodeURIComponent(dir)+"&file="+encodeURIComponent(file)+'&target='+encodeURIComponent(target), - complete: function(data){boolOperationFinished(data, function(){ - FileList.remove(file); - });} + var files = ui.helper.find('tr'); + $(files).each(function(i,row){ + var dir = $(row).data('dir'); + var file = $(row).data('filename'); + $.get(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: target }, function(result) { + if (result) { + if (result.status === 'success') { + FileList.remove(file); + procesSelection(); + $('#notification').hide(); + } else { + $('#notification').hide(); + $('#notification').text(result.data.message); + $('#notification').fadeIn(); + } + } else { + OC.dialogs.alert(t('Error moving file')); + } + }); }); + //reset checkbox if we dragged a single file + if (files.length == 1) { + $(event.target).parents('tr').find('td input:first').prop('checked', $(event.target).parents('tr').hasClass('selected')); + } }, tolerance: 'pointer' } From 1d0ee61f3a136372b26e90fa35f726c77aa95416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 18 Jan 2013 22:16:04 +0100 Subject: [PATCH 253/262] use post instead of get --- apps/files/ajax/move.php | 6 +++--- apps/files/js/files.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/files/ajax/move.php b/apps/files/ajax/move.php index 4ebc3f42d9..74374c57b8 100644 --- a/apps/files/ajax/move.php +++ b/apps/files/ajax/move.php @@ -7,9 +7,9 @@ OCP\JSON::checkLoggedIn(); OCP\JSON::callCheck(); // Get data -$dir = stripslashes($_GET["dir"]); -$file = stripslashes($_GET["file"]); -$target = stripslashes(rawurldecode($_GET["target"])); +$dir = stripslashes($_POST["dir"]); +$file = stripslashes($_POST["file"]); +$target = stripslashes(rawurldecode($_POST["target"])); $l=OC_L10N::get('files'); diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 0088778457..34772915a6 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -877,7 +877,7 @@ var folderDropOptions={ $(files).each(function(i,row){ var dir = $(row).data('dir'); var file = $(row).data('filename'); - $.get(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: dir+'/'+target }, function(result) { + $.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: dir+'/'+target }, function(result) { if (result) { if (result.status === 'success') { //recalculate folder size @@ -925,7 +925,7 @@ var crumbDropOptions={ $(files).each(function(i,row){ var dir = $(row).data('dir'); var file = $(row).data('filename'); - $.get(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: target }, function(result) { + $.post(OC.filePath('files', 'ajax', 'move.php'), { dir: dir, file: file, target: target }, function(result) { if (result) { if (result.status === 'success') { FileList.remove(file); From 99dfaee1f616c6ffdba8007badc9b5afe427c653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Mon, 21 Jan 2013 14:58:55 +0100 Subject: [PATCH 254/262] reset checkbox after getting selected files instead of ofter dragging, speed up revert --- apps/files/js/files.js | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 34772915a6..288a87c7e3 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -815,10 +815,19 @@ function updateBreadcrumb(breadcrumbHtml) { var createDragShadow = function(event){ //select dragged file - $(event.target).parents('tr').find('td input:first').prop('checked', true); + var isDragSelected = $(event.target).parents('tr').find('td input:first').prop('checked'); + if (!isDragSelected) { + //select dragged file + $(event.target).parents('tr').find('td input:first').prop('checked',true); + } var selectedFiles = getSelectedFiles(); + if (!isDragSelected && selectedFiles.length == 1) { + //revert the selection + $(event.target).parents('tr').find('td input:first').prop('checked',false); + } + //also update class when we dragged more than one file if (selectedFiles.length > 1) { $(event.target).parents('tr').addClass('selected'); @@ -832,8 +841,7 @@ var createDragShadow = function(event){ var dir=$('#dir').val(); $(selectedFiles).each(function(i,elem){ - var selected= $(event.target).parents('tr').hasClass('selected'); - var newtr = $('' + var newtr = $('' +''+elem.name+''+humanFileSize(elem.size)+'' +''); tbody.append(newtr); @@ -851,16 +859,11 @@ var createDragShadow = function(event){ //options for file drag/drop var dragOptions={ - revert: 'invalid', opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: -5, top: -5 }, + revert: 'invalid', revertDuration: 300, + opacity: 0.7, zIndex: 100, appendTo: 'body', cursorAt: { left: -5, top: -5 }, helper: createDragShadow, cursor: 'move', stop: function(event, ui) { $('#fileList tr td.filename').addClass('ui-draggable'); - //reset selection - $(ui.helper.find('tr')).each(function(i,row){ - var file = $(row).data('filename'); - var selected = $(row).data('selected'); - $('#fileList tr').filterAttr('data-file',file).find('td input:first').prop('checked',selected); - }); } } @@ -899,10 +902,6 @@ var folderDropOptions={ } }); }); - //reset checkbox if we dragged a single file - if (files.length == 1) { - $(event.target).parents('tr').find('td input:first').prop('checked', $(event.target).parents('tr').hasClass('selected')); - } }, tolerance: 'pointer' } @@ -941,10 +940,6 @@ var crumbDropOptions={ } }); }); - //reset checkbox if we dragged a single file - if (files.length == 1) { - $(event.target).parents('tr').find('td input:first').prop('checked', $(event.target).parents('tr').hasClass('selected')); - } }, tolerance: 'pointer' } From 81a398c22c1bf43c72b91c7639671c4eb5729ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Wed, 30 Jan 2013 13:29:24 +0100 Subject: [PATCH 255/262] use $.trim() for IE8 --- apps/files/js/files.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 288a87c7e3..13367b3362 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -874,7 +874,7 @@ var folderDropOptions={ return false; } - var target=$(this).find('.nametext').text().trim(); + var target=$.trim($(this).find('.nametext').text()); var files = ui.helper.find('tr'); $(files).each(function(i,row){ @@ -1045,7 +1045,7 @@ function getUniqueName(name){ num=parseInt(numMatch[numMatch.length-1])+1; base=base.split('(') base.pop(); - base=base.join('(').trim(); + base=$.trim(base.join('(')); } name=base+' ('+num+')'; if (extension) { From 0bce22966cf6a003ad8273373383300ebc94f52a Mon Sep 17 00:00:00 2001 From: irgsmirx Date: Wed, 30 Jan 2013 14:27:08 +0100 Subject: [PATCH 256/262] Update lib/base.php Correction of typo "locate" -> "locale". --- lib/base.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/base.php b/lib/base.php index f9818d3514..ebaf33814e 100644 --- a/lib/base.php +++ b/lib/base.php @@ -502,7 +502,7 @@ class OC // write error into log if locale can't be set if (OC_Util::issetlocaleworking() == false) { - OC_Log::write('core', 'setting locate to en_US.UTF-8 failed. Support is probably not installed on your system', OC_Log::ERROR); + OC_Log::write('core', 'setting locale to en_US.UTF-8 failed. Support is probably not installed on your system', OC_Log::ERROR); } if (OC_Config::getValue('installed', false)) { if (OC_Appconfig::getValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') { From 92921ceefd66f49ecf0915fe87997caefa24c6bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schie=C3=9Fle?= Date: Wed, 30 Jan 2013 16:28:41 +0100 Subject: [PATCH 257/262] make strings translatable --- settings/templates/users.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings/templates/users.php b/settings/templates/users.php index f30c21efae..4d7c29678c 100644 --- a/settings/templates/users.php +++ b/settings/templates/users.php @@ -94,11 +94,11 @@ $_['subadmingroups'] = array_flip($items); change display name + alt="t("change display name")?>" title="t("change display name")?>"/> ●●●●●●● set new password + alt="t("set new password")?>" title="t("set new password")?>"/>