Merge gitorious.org:owncloud/owncloud into tanghus_contacts

This commit is contained in:
Thomas Tanghus 2012-02-09 19:07:54 +01:00
commit 25f1263c11
43 changed files with 1495 additions and 1081 deletions

View File

@ -668,8 +668,18 @@ $(document).ready(function(){
agenda: agendatime, agenda: agendatime,
'': defaulttime '': defaulttime
}, },
columnFormat: {
month: t('calendar', 'ddd'), // Mon
week: t('calendar', 'ddd M/d'), // Mon 9/7
day: t('calendar', 'dddd M/d') // Monday 9/7
},
titleFormat: { titleFormat: {
list: 'yyyy/MMM/d dddd' month: t('calendar', 'MMMM yyyy'),
// September 2009
week: t('calendar', "MMM d[ yyyy]{ '—'[ MMM] d yyyy}"),
// Sep 7 - 13 2009
day: t('calendar', 'dddd, MMM d, yyyy'),
// Tuesday, Sep 8, 2009
}, },
axisFormat: defaulttime, axisFormat: defaulttime,
monthNames: monthNames, monthNames: monthNames,

View File

@ -49,6 +49,7 @@ showPDFviewer.lastTitle='';
showPDFviewer.loaded=false; showPDFviewer.loaded=false;
$(document).ready(function(){ $(document).ready(function(){
if(!$.browser.msie){//doesnt work on IE
if(location.href.indexOf("files")!=-1) { if(location.href.indexOf("files")!=-1) {
PDFJS.workerSrc = OC.filePath('files_pdfviewer','js','pdfjs/build/pdf.js'); PDFJS.workerSrc = OC.filePath('files_pdfviewer','js','pdfjs/build/pdf.js');
if(typeof FileActions!=='undefined'){ if(typeof FileActions!=='undefined'){
@ -58,4 +59,5 @@ $(document).ready(function(){
FileActions.setDefault('application/pdf','Edit'); FileActions.setDefault('application/pdf','Edit');
} }
} }
}
}); });

View File

@ -6,7 +6,6 @@ OC::$CLASSPATH['OC_Share'] = "apps/files_sharing/lib_share.php";
OC_Hook::connect("OC_Filesystem", "post_delete", "OC_Share", "deleteItem"); OC_Hook::connect("OC_Filesystem", "post_delete", "OC_Share", "deleteItem");
OC_Hook::connect("OC_Filesystem", "post_rename", "OC_Share", "renameItem"); OC_Hook::connect("OC_Filesystem", "post_rename", "OC_Share", "renameItem");
OC_Hook::connect("OC_Filesystem", "post_write", "OC_Share", "updateItem"); OC_Hook::connect("OC_Filesystem", "post_write", "OC_Share", "updateItem");
OC_Filesystem::registerStorageType("shared", "OC_Filestorage_Shared", array("datadir" => "string"));
OC_Util::addScript("files_sharing", "share"); OC_Util::addScript("files_sharing", "share");
OC_Util::addScript("3rdparty", "chosen/chosen.jquery.min"); OC_Util::addScript("3rdparty", "chosen/chosen.jquery.min");
OC_Util::addStyle( 'files_sharing', 'sharing' ); OC_Util::addStyle( 'files_sharing', 'sharing' );

View File

@ -2,6 +2,7 @@ $(document).ready(function() {
var shared_status = {}; var shared_status = {};
if (typeof FileActions !== 'undefined') { if (typeof FileActions !== 'undefined') {
FileActions.register('all', 'Share', function(filename) { FileActions.register('all', 'Share', function(filename) {
if (scanFiles.scanning){return;}//workaround to prevent aditional http request block scanning feedback
var icon; var icon;
var file = $('#dir').val()+'/'+filename; var file = $('#dir').val()+'/'+filename;
if(shared_status[file]) if(shared_status[file])

View File

@ -89,8 +89,8 @@ class OC_Share {
} }
$query->execute(array($uid_owner, $uid, $source, $target, $permissions)); $query->execute(array($uid_owner, $uid, $source, $target, $permissions));
// Clear the folder size cache for the 'Shared' folder // Clear the folder size cache for the 'Shared' folder
$clearFolderSize = OC_DB::prepare("DELETE FROM *PREFIX*foldersize WHERE path = ?"); // $clearFolderSize = OC_DB::prepare("DELETE FROM *PREFIX*foldersize WHERE path = ?");
$clearFolderSize->execute(array($sharedFolder)); // $clearFolderSize->execute(array($sharedFolder));
// Emit post_create and post_write hooks to notify of a new file in the user's filesystem // Emit post_create and post_write hooks to notify of a new file in the user's filesystem
OC_Hook::emit("OC_Filesystem", "post_create", array('path' => $target)); OC_Hook::emit("OC_Filesystem", "post_create", array('path' => $target));
OC_Hook::emit("OC_Filesystem", "post_write", array('path' => $target)); OC_Hook::emit("OC_Filesystem", "post_write", array('path' => $target));

View File

@ -22,10 +22,10 @@
require_once( 'lib_share.php' ); require_once( 'lib_share.php' );
if (!OC_Filesystem::is_dir('/Shared')) { if (OC_Filesystem::$loaded and !OC_Filesystem::is_dir('/Shared')) {
OC_Filesystem::mkdir('/Shared'); OC_Filesystem::mkdir('/Shared');
} }
OC_Filesystem::mount('shared',array('datadir'=>'/'.OC_User::getUser().'/files/Shared'),'/'.OC_User::getUser().'/files/Shared/'); OC_Filesystem::mount('OC_Filestorage_Shared',array('datadir'=>'/'.OC_User::getUser().'/files/Shared'),'/'.OC_User::getUser().'/files/Shared/');
/** /**
* Convert target path to source path and pass the function call to the correct storage provider * Convert target path to source path and pass the function call to the correct storage provider
@ -168,19 +168,9 @@ class OC_Filestorage_Shared extends OC_Filestorage {
// TODO fill in other components of array // TODO fill in other components of array
public function stat($path) { public function stat($path) {
if ($path == "" || $path == "/") { if ($path == "" || $path == "/") {
$stat["dev"] = "";
$stat["ino"] = "";
$stat["mode"] = "";
$stat["nlink"] = "";
$stat["uid"] = "";
$stat["gid"] = "";
$stat["rdev"] = "";
$stat["size"] = $this->filesize($path); $stat["size"] = $this->filesize($path);
$stat["atime"] = $this->fileatime($path);
$stat["mtime"] = $this->filemtime($path); $stat["mtime"] = $this->filemtime($path);
$stat["ctime"] = $this->filectime($path); $stat["ctime"] = $this->filectime($path);
$stat["blksize"] = "";
$stat["blocks"] = "";
return $stat; return $stat;
} else { } else {
$source = $this->getSource($path); $source = $this->getSource($path);
@ -217,18 +207,7 @@ class OC_Filestorage_Shared extends OC_Filestorage {
} }
public function getFolderSize($path) { public function getFolderSize($path) {
// Shared folder sizes are cached separately from the source folder sizes because folders can have different names return 0; //depricated
$path = rtrim($path, "/");
$path = ltrim($path, "/");
$path = preg_replace('{(/)\1+}', "/", $path);
$dbpath = rtrim($this->datadir.$path, "/");
$query = OC_DB::prepare("SELECT size FROM *PREFIX*foldersize WHERE path = ?");
$size = $query->execute(array($dbpath))->fetchAll();
if (count($size) > 0) {
return $size[0]['size'];
} else {
return $this->calculateFolderSize($path);
}
} }
private function calculateFolderSize($path) { private function calculateFolderSize($path) {
@ -249,8 +228,8 @@ class OC_Filestorage_Shared extends OC_Filestorage {
} }
if ($size > 0) { if ($size > 0) {
$dbpath = rtrim($this->datadir.$path, "/"); $dbpath = rtrim($this->datadir.$path, "/");
$query = OC_DB::prepare("INSERT INTO *PREFIX*foldersize VALUES(?,?)"); // $query = OC_DB::prepare("INSERT INTO *PREFIX*foldersize VALUES(?,?)");
$result = $query->execute(array($dbpath, $size)); // $result = $query->execute(array($dbpath, $size));
} }
} }
return $size; return $size;
@ -263,8 +242,8 @@ class OC_Filestorage_Shared extends OC_Filestorage {
$path = dirname($path); $path = dirname($path);
} }
$dbpath = rtrim($this->datadir.$path, "/"); $dbpath = rtrim($this->datadir.$path, "/");
$query = OC_DB::prepare("DELETE FROM *PREFIX*foldersize WHERE path = ?"); // $query = OC_DB::prepare("DELETE FROM *PREFIX*/*foldersize*/ WHERE path = ?");
$result = $query->execute(array($dbpath)); // $result = $query->execute(array($dbpath));
if ($path != "/" && $path != "") { if ($path != "/" && $path != "") {
$parts = explode("/", $path); $parts = explode("/", $path);
$part = array_pop($parts); $part = array_pop($parts);
@ -280,7 +259,7 @@ class OC_Filestorage_Shared extends OC_Filestorage {
return true; return true;
} }
public function is_writeable($path) { public function is_writable($path) {
if($path == "" || $path == "/"){ if($path == "" || $path == "/"){
return false; return false;
}elseif (OC_Share::getPermissions($this->datadir.$path) & OC_Share::WRITE) { }elseif (OC_Share::getPermissions($this->datadir.$path) & OC_Share::WRITE) {
@ -320,8 +299,8 @@ class OC_Filestorage_Shared extends OC_Filestorage {
$ctime = $tempctime; $ctime = $tempctime;
} }
} }
return $ctime;
} }
return $ctime;
} else { } else {
$source = $this->getSource($path); $source = $this->getSource($path);
if ($source) { if ($source) {
@ -341,8 +320,8 @@ class OC_Filestorage_Shared extends OC_Filestorage {
$mtime = $tempmtime; $mtime = $tempmtime;
} }
} }
return $mtime;
} }
return $mtime;
} else { } else {
$source = $this->getSource($path); $source = $this->getSource($path);
if ($source) { if ($source) {
@ -352,27 +331,6 @@ class OC_Filestorage_Shared extends OC_Filestorage {
} }
} }
public function fileatime($path) {
if ($path == "" || $path == "/") {
$atime = 0;
if ($dh = $this->opendir($path)) {
while (($filename = readdir($dh)) !== false) {
$tempatime = $this->fileatime($filename);
if ($tempatime > $atime) {
$atime = $tempatime;
}
}
return $atime;
}
} else {
$source = $this->getSource($path);
if ($source) {
$storage = OC_Filesystem::getStorage($source);
return $storage->fileatime($this->getInternalPath($source));
}
}
}
public function file_get_contents($path) { public function file_get_contents($path) {
$source = $this->getSource($path); $source = $this->getSource($path);
if ($source) { if ($source) {
@ -382,7 +340,7 @@ class OC_Filestorage_Shared extends OC_Filestorage {
} }
public function file_put_contents($path, $data) { public function file_put_contents($path, $data) {
if ($this->is_writeable($path)) { if ($this->is_writable($path)) {
$source = $this->getSource($path); $source = $this->getSource($path);
if ($source) { if ($source) {
$storage = OC_Filesystem::getStorage($source); $storage = OC_Filesystem::getStorage($source);
@ -426,7 +384,7 @@ class OC_Filestorage_Shared extends OC_Filestorage {
if ($root1 !== $root2) { if ($root1 !== $root2) {
return false; return false;
// Check if both paths have write permission // Check if both paths have write permission
} else if ($this->is_writeable($path1) && $this->is_writeable($path2)) { } else if ($this->is_writable($path1) && $this->is_writable($path2)) {
$oldSource = $this->getSource($path1); $oldSource = $this->getSource($path1);
$newSource = $folders['source'].substr($newTarget, strlen($folders['target'])); $newSource = $folders['source'].substr($newTarget, strlen($folders['target']));
if ($oldSource) { if ($oldSource) {
@ -456,7 +414,7 @@ class OC_Filestorage_Shared extends OC_Filestorage {
if ($path2 == "" || $path2 == "/") { if ($path2 == "" || $path2 == "/") {
// TODO Construct new shared item or should this not be allowed? // TODO Construct new shared item or should this not be allowed?
} else { } else {
if ($this->is_writeable($path2)) { if ($this->is_writable($path2)) {
$tmpFile = $this->toTmpFile($path1); $tmpFile = $this->toTmpFile($path1);
$result = $this->fromTmpFile($tmpFile, $path2); $result = $this->fromTmpFile($tmpFile, $path2);
if ($result) { if ($result) {
@ -486,7 +444,7 @@ class OC_Filestorage_Shared extends OC_Filestorage {
} }
public function fromTmpFile($tmpFile, $path) { public function fromTmpFile($tmpFile, $path) {
if ($this->is_writeable($path)) { if ($this->is_writable($path)) {
$source = $this->getSource($path); $source = $this->getSource($path);
if ($source) { if ($source) {
$storage = OC_Filesystem::getStorage($source); $storage = OC_Filesystem::getStorage($source);
@ -501,23 +459,10 @@ class OC_Filestorage_Shared extends OC_Filestorage {
} }
} }
public function fromUploadedFile($tmpFile, $path) {
if ($this->is_writeable($path)) {
$source = $this->getSource($path);
if ($source) {
$storage = OC_Filesystem::getStorage($source);
$result = $storage->fromUploadedFile($tmpFile, $this->getInternalPath($source));
if ($result) {
$this->clearFolderSizeCache($path);
}
return $result;
}
} else {
return false;
}
}
public function getMimeType($path) { public function getMimeType($path) {
if ($path == "" || $path == "/") {
return 'httpd/unix-directory';
}
$source = $this->getSource($path); $source = $this->getSource($path);
if ($source) { if ($source) {
$storage = OC_Filesystem::getStorage($source); $storage = OC_Filesystem::getStorage($source);

View File

@ -33,7 +33,7 @@ $filename = isset($_GET['file']) ? $_GET['file'] : '';
if(!empty($filename)) if(!empty($filename))
{ {
$path = $dir.'/'.$filename; $path = $dir.'/'.$filename;
if(OC_Filesystem::is_writeable($path)) if(OC_Filesystem::is_writable($path))
{ {
$mtime = OC_Filesystem::filemtime($path); $mtime = OC_Filesystem::filemtime($path);
$filecontents = OC_Filesystem::file_get_contents($path); $filecontents = OC_Filesystem::file_get_contents($path);

View File

@ -32,7 +32,6 @@ $filecontents = htmlspecialchars_decode($_POST['filecontents']);
$path = isset($_POST['path']) ? $_POST['path'] : ''; $path = isset($_POST['path']) ? $_POST['path'] : '';
$mtime = isset($_POST['mtime']) ? $_POST['mtime'] : ''; $mtime = isset($_POST['mtime']) ? $_POST['mtime'] : '';
if($path != '' && $mtime != '') if($path != '' && $mtime != '')
{ {
// Get file mtime // Get file mtime
@ -47,7 +46,7 @@ if($path != '' && $mtime != '')
{ {
// File same as when opened // File same as when opened
// Save file // Save file
if(OC_Filesystem::is_writeable($path)) if(OC_Filesystem::is_writable($path))
{ {
OC_Filesystem::file_put_contents($path, $filecontents); OC_Filesystem::file_put_contents($path, $filecontents);
// Clear statcache // Clear statcache

View File

@ -45,6 +45,11 @@ function handleGetThumbnails($albumname) {
OC_JSON::checkLoggedIn(); OC_JSON::checkLoggedIn();
$photo = new OC_Image(); $photo = new OC_Image();
$photo->loadFromFile(OC::$CONFIG_DATADIRECTORY.'/../gallery/'.$albumname.'.png'); $photo->loadFromFile(OC::$CONFIG_DATADIRECTORY.'/../gallery/'.$albumname.'.png');
$offset = 3600 * 24; // 24 hour
// calc the string in GMT not localtime and add the offset
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
header('Cache-Control: max-age='.$offset.', must-revalidate');
header('Pragma: public');
$photo->show(); $photo->show();
} }
@ -69,7 +74,7 @@ function handlePartialCreate($path) {
if (!OC_Filesystem::is_dir($path)) OC_JSON::error(array('cause' => 'Invalid path given')); if (!OC_Filesystem::is_dir($path)) OC_JSON::error(array('cause' => 'Invalid path given'));
$album = OC_Gallery_Album::find(OC_User::getUser(), null, $path); $album = OC_Gallery_Album::find(OC_User::getUser(), null, $path);
$albums; $albums = array();
OC_Gallery_Scanner::scanDir($path, $albums); OC_Gallery_Scanner::scanDir($path, $albums);
OC_JSON::success(array('album_details' => $albums)); OC_JSON::success(array('album_details' => $albums));
} }

View File

@ -25,65 +25,14 @@ require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn(); OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('gallery'); OC_JSON::checkAppEnabled('gallery');
function CroppedThumbnail($imgSrc,$thumbnail_width,$thumbnail_height) { //$imgSrc is a FILE - Returns an image resource.
//getting the image dimensions
if(! function_exists('imagecreatefromjpeg'))
OC_Log::write('gallery','GD module not installed',OC_Log::ERROR);
list($width_orig, $height_orig) = getimagesize($imgSrc);
switch (strtolower(substr($imgSrc, strrpos($imgSrc, '.')+1))) {
case "jpeg":
case "jpg":
case "tiff":
$myImage = imagecreatefromjpeg($imgSrc);
break;
case "png":
$myImage = imagecreatefrompng($imgSrc);
break;
default:
exit();
}
if(!$myImage) exit();
$ratio_orig = $width_orig/$height_orig;
if ($thumbnail_width/$thumbnail_height > $ratio_orig) {
$new_height = $thumbnail_width/$ratio_orig;
$new_width = $thumbnail_width;
} else {
$new_width = $thumbnail_height*$ratio_orig;
$new_height = $thumbnail_height;
}
$x_mid = $new_width/2; //horizontal middle
$y_mid = $new_height/2; //vertical middle
$process = imagecreatetruecolor(round($new_width), round($new_height));
imagecopyresampled($process, $myImage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
$thumb = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumbnail_width/2)), ($y_mid-($thumbnail_height/2)), $thumbnail_width, $thumbnail_height, $thumbnail_width, $thumbnail_height);
imagedestroy($process);
imagedestroy($myImage);
return $thumb;
}
$box_size = 200;
$img = $_GET['img']; $img = $_GET['img'];
$imagePath = OC_Filesystem::getLocalFile($img); $image = OC_Gallery_Photo::getThumbnail($img);
if ($image) {
if(file_exists($imagePath)) $offset = 3600 * 24; // 24 hour
{
$image = CroppedThumbnail($imagePath, $box_size, $box_size);
header('Content-Type: image/png');
$offset = 3600 * 24;
// calc the string in GMT not localtime and add the offset // calc the string in GMT not localtime and add the offset
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT"); header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
header('Cache-Control: max-age='.$offset.', must-revalidate'); header('Cache-Control: max-age='.$offset.', must-revalidate');
header('Pragma: public'); header('Pragma: public');
$image->show();
imagepng($image);
imagedestroy($image);
} }

View File

@ -21,7 +21,7 @@
* *
*/ */
class OC_Gallery_Photo{ class OC_Gallery_Photo {
public static function create($albumId, $img){ public static function create($albumId, $img){
$stmt = OC_DB::prepare('INSERT INTO *PREFIX*gallery_photos (album_id, file_path) VALUES (?, ?)'); $stmt = OC_DB::prepare('INSERT INTO *PREFIX*gallery_photos (album_id, file_path) VALUES (?, ?)');
$stmt->execute(array($albumId, $img)); $stmt->execute(array($albumId, $img));
@ -65,5 +65,34 @@ class OC_Gallery_Photo{
$stmt = OC_DB::prepare("UPDATE *PREFIX*gallery_photos SET file_path = ?, album_id = ? WHERE album_id = ? and file_path = ?"); $stmt = OC_DB::prepare("UPDATE *PREFIX*gallery_photos SET file_path = ?, album_id = ? WHERE album_id = ? and file_path = ?");
$stmt->execute(array($newpath, $newAlbumId, $oldAlbumId, $oldpath)); $stmt->execute(array($newpath, $newAlbumId, $oldAlbumId, $oldpath));
} }
}
public static function getThumbnail($image_name) {
$imagePath = OC_Filesystem::getLocalFile($image_name);
if(!file_exists($imagePath)) {
return null;
}
$save_dir = OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/';
$save_dir .= dirname($image_name). '/';
$image_name = basename($image_name);
$thumb_file = $save_dir . $image_name;
if (file_exists($thumb_file)) {
$image = new OC_Image($thumb_file);
} else {
$image = new OC_Image($imagePath);
if ($image->valid()) {
$image->centerCrop();
$image->resize(200);
$image->fixOrientation();
if (!is_dir($save_dir)) {
mkdir($save_dir, 0777, true);
}
$image->save($thumb_file);
}
}
if ($image->valid()) {
//var_dump($image, $image->resource());
return $image;
}
return null;
}
}

View File

@ -89,8 +89,11 @@ class OC_Gallery_Scanner {
$file_count = min(count($files), 10); $file_count = min(count($files), 10);
$thumbnail = imagecreatetruecolor($file_count*200, 200); $thumbnail = imagecreatetruecolor($file_count*200, 200);
for ($i = 0; $i < $file_count; $i++) { for ($i = 0; $i < $file_count; $i++) {
$imagePath = OC_Filesystem::getLocalFile($files[$i]); $image = OC_Gallery_Photo::getThumbnail($files[$i]);
CroppedThumbnail($imagePath, 200, 200, $thumbnail, $i*200); if ($image && $image->valid()) {
imagecopyresampled($thumbnail, $image->resource(), $i*200, 0, 0, 0, 200, 200, 200, 200);
}
unset($image); // unset $image here to control the lifetime of image::$resource
} }
imagepng($thumbnail, OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/' . $albumName.'.png'); imagepng($thumbnail, OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/' . $albumName.'.png');
} }

View File

@ -70,10 +70,10 @@ if($arguments['action']){
case 'scan': case 'scan':
OC_DB::beginTransaction(); OC_DB::beginTransaction();
set_time_limit(0); //recursive scan can take a while set_time_limit(0); //recursive scan can take a while
$path=$arguments['path']; $eventSource=new OC_EventSource();
echo OC_MEDIA_SCANNER::scanFolder($path); OC_MEDIA_SCANNER::scanCollection($eventSource);
$eventSource->close();
OC_DB::commit(); OC_DB::commit();
flush();
break; break;
case 'scanFile': case 'scanFile':
echo (OC_MEDIA_SCANNER::scanFile($arguments['path']))?'true':'false'; echo (OC_MEDIA_SCANNER::scanFile($arguments['path']))?'true':'false';
@ -127,29 +127,9 @@ if($arguments['action']){
OC_Filesystem::readfile($arguments['path']); OC_Filesystem::readfile($arguments['path']);
exit; exit;
case 'find_music': case 'find_music':
OC_JSON::encodedPrint(findMusic()); OC_JSON::encodedPrint(OC_FileCache::searchByMime('audio'));
exit; exit;
} }
} }
function findMusic($path=''){
$music=array();
$dh=OC_Filesystem::opendir($path);
if($dh){
while($filename=readdir($dh)){
if($filename[0]!='.'){
$file=$path.'/'.$filename;
if(OC_Filesystem::is_dir($file)){
$music=array_merge($music,findMusic($file));
}else{
if(OC_MEDIA_SCANNER::isMusic($filename)){
$music[]=$file;
}
}
}
}
}
return $music;
}
?> ?>

View File

@ -1,90 +1,44 @@
Scanner={ Scanner={
songsFound:0, songsFound:0,
eventSource:null,
songsScanned:0, songsScanned:0,
songsChecked:0,
startTime:null,
endTime:null,
stopScanning:false,
currentIndex:0,
songs:[],
findSongs:function(ready){ findSongs:function(ready){
$.getJSON(OC.linkTo('media','ajax/api.php')+'?action=find_music',function(songs){ $.getJSON(OC.linkTo('media','ajax/api.php')+'?action=find_music',function(songs){
Scanner.songsFound=songs.length; Scanner.songsFound=songs.length;
Scanner.currentIndex=-1
if(ready){ if(ready){
ready(songs) ready(songs)
} }
}); });
}, },
scanFile:function(path,ready){
path=encodeURIComponent(path);
$.getJSON(OC.linkTo('media','ajax/api.php')+'?action=get_path_info&path='+path,function(song){
Scanner.songsChecked++;
if(ready){
ready(song);
}
if(song){//do this after the ready call so we dont hold up the next ajax call
var artistId=song.song_artist;
Scanner.songsScanned++;
$('#scan span.songCount').text(Scanner.songsScanned);
var progress=(Scanner.songsChecked/Scanner.songsFound)*100;
$('#scanprogressbar').progressbar('value',progress)
Collection.addSong(song);
}
});
},
scanCollection:function(ready){ scanCollection:function(ready){
$('#scanprogressbar').progressbar({ $('#scanprogressbar').progressbar({
value:0, value:0,
}); });
$('#scanprogressbar').show(); $('#scanprogressbar').show();
Scanner.songsChecked=0;
Scanner.currentIndex=0;
Scanner.songsScanned=0; Scanner.songsScanned=0;
Scanner.startTime=new Date().getTime()/1000; Scanner.eventSource=new OC.EventSource(OC.linkTo('media','ajax/api.php'),{action:'scan'});
Scanner.findSongs(function(songs){ Scanner.eventSource.listen('count',function(total){
Scanner.songs=songs; Scanner.songsFound=total;
Scanner.start(function(){ });
Scanner.eventSource.listen('scanned',function(data){
Scanner.songsScanned=data.count;
$('#scan span.songCount').text(Scanner.songsScanned);
var progress=(Scanner.songsScanned/Scanner.songsFound)*100;
$('#scanprogressbar').progressbar('value',progress)
});
Scanner.eventSource.listen('done',function(count){
$('#scan input.start').show(); $('#scan input.start').show();
$('#scan input.stop').hide(); $('#scan input.stop').hide();
$('#scanprogressbar').hide(); $('#scanprogressbar').hide();
Collection.display(); Collection.load(Collection.display)
if(ready){ if(ready){
ready(); ready();
} }
}); });
}); $('#scancount').show();
}, },
stop:function(){ stop:function(){
Scanner.stopScanning=true; Scanner.close();
}, },
start:function(ready){
Scanner.stopScanning=false;
$('#scancount').show();
var scanSong=function(){
if(!Scanner.stopScanning && Scanner.currentIndex<=Scanner.songs.length){
Scanner.scanFile(Scanner.songs[Scanner.currentIndex],scanSong)
}else if(!Scanner.stopScanning){
Scanner.endTime=new Date().getTime()/1000;
if(ready){
ready();
ready=null;//only call ready once
}
}
Scanner.currentIndex++;
}
scanSong();
scanSong();
},
toggle:function(){
if(Scanner.stopScanning){
Scanner.start();
$('#scan input.stop').val(t('media','Pause'));
}else{
Scanner.stop();
$('#scan input.stop').val(t('media','Resume'));
}
}
} }

View File

@ -33,32 +33,22 @@ class OC_MEDIA_SCANNER{
/** /**
* scan a folder for music * scan a folder for music
* @param string $path * @param OC_EventSource eventSource (optional)
* @return int the number of songs found * @return int the number of songs found
*/ */
public static function scanFolder($path){ public static function scanCollection($eventSource=null){
if (OC_Filesystem::is_dir($path)) { $music=OC_FileCache::searchByMime('audio');
$eventSource->send('count',count($music));
$songs=0; $songs=0;
if ($dh = OC_Filesystem::opendir($path)) { foreach($music as $file){
while (($filename = readdir($dh)) !== false) { self::scanFile($file);
if($filename<>'.' and $filename<>'..' and substr($filename,0,1)!='.'){
$file=$path.'/'.$filename;
if(OC_Filesystem::is_dir($file)){
$songs+=self::scanFolder($file);
}elseif(OC_Filesystem::is_file($file)){
$data=self::scanFile($file);
if($data){
$songs++; $songs++;
if($eventSource){
$eventSource->send('scanned',array('file'=>$file,'count'=>$songs));
} }
} }
} if($eventSource){
} $eventSource->send('done',$songs);
}
}elseif(OC_Filesystem::is_file($path)){
$songs=1;
self::scanFile($path);
}else{
$songs=0;
} }
return $songs; return $songs;
} }

View File

@ -43,10 +43,19 @@
<table> <table>
<name>*dbprefix*foldersize</name> <name>*dbprefix*fscache</name>
<declaration> <declaration>
<field>
<name>id</name>
<autoincrement>1</autoincrement>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>4</length>
</field>
<field> <field>
<name>path</name> <name>path</name>
<type>text</type> <type>text</type>
@ -55,6 +64,33 @@
<length>512</length> <length>512</length>
</field> </field>
<field>
<name>parent</name>
<type>integer</type>
<default>
</default>
<notnull>true</notnull>
<length>4</length>
</field>
<field>
<name>name</name>
<type>text</type>
<default>
</default>
<notnull>true</notnull>
<length>512</length>
</field>
<field>
<name>user</name>
<type>text</type>
<default>
</default>
<notnull>true</notnull>
<length>64</length>
</field>
<field> <field>
<name>size</name> <name>size</name>
<type>integer</type> <type>integer</type>
@ -63,12 +99,93 @@
<length>4</length> <length>4</length>
</field> </field>
<index> <field>
<name>path_index</name> <name>ctime</name>
<type>integer</type>
<default>
</default>
<notnull>true</notnull>
<length>4</length>
</field>
<field>
<name>mtime</name>
<type>integer</type>
<default>
</default>
<notnull>true</notnull>
<length>4</length>
</field>
<field>
<name>mimetype</name>
<type>text</type>
<default>
</default>
<notnull>true</notnull>
<length>32</length>
</field>
<field>
<name>mimepart</name>
<type>text</type>
<default>
</default>
<notnull>true</notnull>
<length>32</length>
</field>
<field>
<name>encrypted</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>1</length>
</field>
<field>
<name>versioned</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>1</length>
</field>
<field>
<name>writable</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>1</length>
</field>
<!--<index>
<name>fscache_path_index</name>
<unique>true</unique>
<field> <field>
<name>path</name> <name>path</name>
<sorting>ascending</sorting> <sorting>ascending</sorting>
</field> </field>
</index>-->
<index>
<name>parent_index</name>
<field>
<name>parent</name>
<sorting>ascending</sorting>
</field>
</index>
<index>
<name>parent_name_index</name>
<field>
<name>parent</name>
<sorting>ascending</sorting>
</field>
<field>
<name>name</name>
<sorting>ascending</sorting>
</field>
</index> </index>
</declaration> </declaration>

37
files/ajax/scan.php Normal file
View File

@ -0,0 +1,37 @@
<?php
require_once '../../lib/base.php';
set_time_limit(0);//scanning can take ages
$force=isset($_GET['force']) and $_GET['force']=='true';
$checkOnly=isset($_GET['checkonly']) and $_GET['checkonly']=='true';
if(!$checkOnly){
$eventSource=new OC_EventSource();
}
//create the file cache if necesary
if($force or !OC_FileCache::inCache('')){
if(!$checkOnly){
OC_DB::beginTransaction();
OC_FileCache::scan('',$eventSource);
OC_DB::commit();
$eventSource->send('success',true);
}else{
OC_JSON::success(array('data'=>array('done'=>true)));
exit;
}
}else{
if($checkOnly){
OC_JSON::success(array('data'=>array('done'=>false)));
exit;
}
if(isset($eventSource)){
$eventSource->send('success',false);
}else{
exit;
}
}
$eventSource->close();

View File

@ -47,7 +47,7 @@ if(strpos($dir,'..') === false){
$fileCount=count($files['name']); $fileCount=count($files['name']);
for($i=0;$i<$fileCount;$i++){ for($i=0;$i<$fileCount;$i++){
$target=stripslashes($dir) . $files['name'][$i]; $target=stripslashes($dir) . $files['name'][$i];
if(OC_Filesystem::fromUploadedFile($files['tmp_name'][$i],$target)){ if(is_uploaded_file($files['tmp_name'][$i]) and OC_Filesystem::fromTmpFile($files['tmp_name'][$i],$target)){
$result[]=array( "status" => "success", 'mime'=>OC_Filesystem::getMimeType($target),'size'=>OC_Filesystem::filesize($target),'name'=>$files['name'][$i]); $result[]=array( "status" => "success", 'mime'=>OC_Filesystem::getMimeType($target),'size'=>OC_Filesystem::filesize($target),'name'=>$files['name'][$i]);
} }
} }

View File

@ -77,3 +77,5 @@ a.action>img{ max-height:16px; max-width:16px; }
/* add breadcrumb divider to the File item in navigation panel */ /* add breadcrumb divider to the File item in navigation panel */
#navigation>ul>li:first-child { background:url('../../core/img/breadcrumb-start.svg') no-repeat 12.5em 0px; width:12.5em; padding-right:1em; position:fixed; } #navigation>ul>li:first-child { background:url('../../core/img/breadcrumb-start.svg') no-repeat 12.5em 0px; width:12.5em; padding-right:1em; position:fixed; }
#navigation>ul>li:first-child+li { padding-top:2.9em; } #navigation>ul>li:first-child+li { padding-top:2.9em; }
#scanning-message{ top:40%; left:40%; position:absolute; display:none }

View File

@ -94,7 +94,7 @@ $tmpl = new OC_Template( "files", "index", "user" );
$tmpl->assign( "fileList", $list->fetchPage() ); $tmpl->assign( "fileList", $list->fetchPage() );
$tmpl->assign( "breadcrumb", $breadcrumbNav->fetchPage() ); $tmpl->assign( "breadcrumb", $breadcrumbNav->fetchPage() );
$tmpl->assign( 'dir', $dir); $tmpl->assign( 'dir', $dir);
$tmpl->assign( 'readonly', !OC_Filesystem::is_writeable($dir)); $tmpl->assign( 'readonly', !OC_Filesystem::is_writable($dir));
$tmpl->assign( "files", $files ); $tmpl->assign( "files", $files );
$tmpl->assign( 'uploadMaxFilesize', $maxUploadFilesize); $tmpl->assign( 'uploadMaxFilesize', $maxUploadFilesize);
$tmpl->assign( 'uploadMaxHumanFilesize', OC_Helper::humanFileSize($maxUploadFilesize)); $tmpl->assign( 'uploadMaxHumanFilesize', OC_Helper::humanFileSize($maxUploadFilesize));

View File

@ -336,8 +336,37 @@ $(document).ready(function() {
$('#new>a').click(); $('#new>a').click();
}); });
}); });
//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");
}); });
function scanFiles(force){
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});
scanFiles.cancel=scannerEventSource.close.bind(scannerEventSource);
scannerEventSource.listen('scanning',function(data){
$('#scan-count').text(data.count+' files scanned');
$('#scan-current').text(data.file+'/');
});
scannerEventSource.listen('success',function(success){
scanFiles.scanning=false;
if(success){
window.location.reload();
}else{
alert('error while scanning');
}
});
}
scanFiles.scanning=false;
function boolOperationFinished(data, callback) { function boolOperationFinished(data, callback) {
result = jQuery.parseJSON(data.responseText); result = jQuery.parseJSON(data.responseText);
if(result.status == 'success'){ if(result.status == 'success'){

View File

@ -57,3 +57,11 @@
<?php echo $l->t('The files you are trying to upload exceed the maximum size for file uploads on this server.');?> <?php echo $l->t('The files you are trying to upload exceed the maximum size for file uploads on this server.');?>
</p> </p>
</div> </div>
<div id="scanning-message">
<h3>
<?php echo $l->t('Files are being scanned, please wait.');?> <span id='scan-count'></spann>
</h3>
<p>
<?php echo $l->t('Current scanning');?> <span id='scan-current'></spann>
</p>
</div>

View File

@ -1,5 +1,5 @@
<?php foreach($_['files'] as $file): <?php foreach($_['files'] as $file):
$write = ($file['writeable']) ? 'true' : 'false'; $write = ($file['writable']) ? 'true' : 'false';
$simple_file_size = simple_file_size($file['size']); $simple_file_size = simple_file_size($file['size']);
$simple_size_color = intval(200-$file['size']/(1024*1024)*2); // the bigger the file, the darker the shade of grey; megabytes*2 $simple_size_color = intval(200-$file['size']/(1024*1024)*2); // the bigger the file, the darker the shade of grey; megabytes*2
if($simple_size_color<0) $simple_size_color = 0; if($simple_size_color<0) $simple_size_color = 0;
@ -10,8 +10,8 @@
$name = str_replace('%2F','/', $name); $name = str_replace('%2F','/', $name);
$directory = str_replace('+','%20',urlencode($file['directory'])); $directory = str_replace('+','%20',urlencode($file['directory']));
$directory = str_replace('%2F','/', $directory); ?> $directory = str_replace('%2F','/', $directory); ?>
<tr data-file="<?php echo $name;?>" data-type="<?php echo ($file['type'] == 'dir')?'dir':'file'?>" data-mime="<?php echo $file['mime']?>" data-size='<?php echo $file['size'];?>' data-write='<?php echo $write;?>'> <tr data-file="<?php echo $name;?>" data-type="<?php echo ($file['type'] == 'dir')?'dir':'file'?>" data-mime="<?php echo $file['mimetype']?>" data-size='<?php echo $file['size'];?>' data-write='<?php echo $write;?>'>
<td class="filename svg" style="background-image:url(<?php if($file['type'] == 'dir') echo mimetype_icon('dir'); else echo mimetype_icon($file['mime']); ?>)"> <td class="filename svg" style="background-image:url(<?php if($file['type'] == 'dir') echo mimetype_icon('dir'); else echo mimetype_icon($file['mimetype']); ?>)">
<?php if(!isset($_['readonly']) || !$_['readonly']) { ?><input type="checkbox" /><?php } ?> <?php if(!isset($_['readonly']) || !$_['readonly']) { ?><input type="checkbox" /><?php } ?>
<a class="name" href="<?php if($file['type'] == 'dir') echo $_['baseURL'].$directory.'/'.$name; else echo $_['downloadURL'].$directory.'/'.$name; ?>" title=""> <a class="name" href="<?php if($file['type'] == 'dir') echo $_['baseURL'].$directory.'/'.$name; else echo $_['downloadURL'].$directory.'/'.$name; ?>" title="">
<span class="nametext"> <span class="nametext">

View File

@ -403,4 +403,22 @@ class OC_App{
include OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php'; include OC::$SERVERROOT.'/apps/'.$appid.'/appinfo/update.php';
} }
} }
/**
* @param string appid
* @return OC_FilesystemView
*/
public static function getStorage($appid){
if(OC_App::isEnabled($appid)){//sanity check
if(OC_User::isLoggedIn()){
return new OC_FilesystemView('/'.OC_User::getUser().'/'.$appid);
}else{
OC_Log::write('core','Can\'t get app storage, app, user not logged in',OC_Log::ERROR);
return false;
}
}else{
OC_Log::write('core','Can\'t get app storage, app '.$appid.' not enabled',OC_Log::ERROR);
false;
}
}
} }

View File

@ -216,9 +216,6 @@ class OC{
OC_User::useBackend( OC_Config::getValue( "userbackend", "database" )); OC_User::useBackend( OC_Config::getValue( "userbackend", "database" ));
OC_Group::setBackend( OC_Config::getValue( "groupbackend", "database" )); OC_Group::setBackend( OC_Config::getValue( "groupbackend", "database" ));
// Was in required file ... put it here
OC_Filesystem::registerStorageType('local','OC_Filestorage_Local',array('datadir'=>'string'));
// Set up file system unless forbidden // Set up file system unless forbidden
global $RUNTIME_NOSETUPFS; global $RUNTIME_NOSETUPFS;
if(!$RUNTIME_NOSETUPFS ){ if(!$RUNTIME_NOSETUPFS ){

View File

@ -116,9 +116,9 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
* @return array * @return array
*/ */
public function getQuotaInfo() { public function getQuotaInfo() {
$rootInfo=OC_FileCache::get('');
return array( return array(
OC_Filesystem::filesize('/'), $rootInfo['size'],
OC_Filesystem::free_space() OC_Filesystem::free_space()
); );

582
lib/filecache.php Normal file
View File

@ -0,0 +1,582 @@
<?php
/**
* @author Robin Appelman
* @copyright 2011 Robin Appelman icewind1991@gmail.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* 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 assiciative array with the following keys:
* - size
* - mtime
* - ctime
* - mimetype
* - encrypted
* - versioned
*/
public static function get($path,$root=''){
if(self::isUpdated($path,$root)){
if(!$root){//filesystem hooks are only valid for the default root
OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$path));
}else{
self::fileSystemWatcherWrite(array('path'=>$path),$root);
}
}
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$path=$root.$path;
$query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path))->fetchRow();
if(is_array($result)){
return $result;
}else{
OC_Log::write('file not found in cache ('.$path.')','core',OC_Log::DEBUG);
return false;
}
}
/**
* 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=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$path=$root.$path;
if($path=='/'){
$parent=-1;
}else{
$parent=self::getFileId(dirname($path));
}
$id=self::getFileId($path);
if($id!=-1){
self::update($id,$data);
return;
}
if(!isset($data['encrypted'])){
$data['encrypted']=false;
}
if(!isset($data['versioned'])){
$data['versioned']=false;
}
$mimePart=dirname($data['mimetype']);
$user=OC_User::getUser();
$query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, size, mtime, ctime, mimetype, mimepart,user,writable) VALUES(?,?,?,?,?,?,?,?,?,?)');
$query->execute(array($parent,basename($path),$path,$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable']));
}
/**
* 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])){
$arguments[]=$data[$attribute];
$queryParts[]=$attribute.'=?';
}
}
if(isset($data['mimetype'])){
$arguments[]=dirname($data['mimetype']);
$queryParts[]='mimepart=?';
}
$arguments[]=$id;
$query=OC_DB::prepare('UPDATE *PREFIX*fscache SET '.implode(' , ',$queryParts).' WHERE id=?');
$query->execute($arguments);
}
/**
* register a file move in the cache
* @param string oldPath
* @param string newPath
* @param string root (optional)
*/
public static function move($oldPath,$newPath,$root=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$oldPath=$root.$oldPath;
$newPath=$root.$newPath;
$newParent=self::getParentId($newPath);
$query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=? WHERE path=?');
$query->execute(array($newParent,basename($newPath),$newPath,$oldPath));
}
/**
* delete info from the cache
* @param string $path
* @param string root (optional)
*/
public static function delete($path,$root=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$path=$root.$path;
$query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE path=?');
$query->execute(array($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=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$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=''){
if(self::isUpdated($path,$root)){
self::updateFolder($path,$root);
}
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$path=$root.$path;
$parent=self::getFileId($path);
$query=OC_DB::prepare('SELECT name,ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE parent=?');
$result=$query->execute(array($parent))->fetchAll();
if(is_array($result)){
return $result;
}else{
OC_Log::write('file not found in cache ('.$path.')','core',OC_Log::DEBUG);
return false;
}
}
/**
* 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=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$path=$root.$path;
return self::getFileId($path)!=-1;
}
/**
* get the file id as used in the cache
* @param string $path
* @return int
*/
private static function getFileId($path){
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path))->fetchRow();
if(is_array($result)){
return $result['id'];
}else{
OC_Log::write('file not found in cache ('.$path.')','core',OC_Log::DEBUG);
return -1;
}
}
/**
* 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::getFileId(dirname($path));
}
}
/**
* called when changes are made to files
* @param array $params
* @param string root (optional)
*/
public static function fileSystemWatcherWrite($params,$root=''){
if(!$root){
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView(($root=='/')?'':$root);
}
$path=$params['path'];
$fullPath=$view->getRoot().$path;
$mimetype=$view->getMimeType($path);
//dont use self::get here, we don't want inifinte loops when a file has changed
$cachedSize=self::getCachedSize($path,$root);
$size=0;
if($mimetype=='httpd/unix-directory'){
if(self::inCache($path,$root)){
$parent=self::getFileId($fullPath);
$query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE parent=?');
$result=$query->execute(array($parent));
while($row=$result->fetchRow()){
$size+=$row['size'];
}
$mtime=$view->filemtime($path);
$ctime=$view->filectime($path);
$writable=$view->is_writable($path);
self::put($path,array('size'=>$size,'mtime'=>$mtime,'ctime'=>$ctime,'mimetype'=>$mimetype,'writable'=>$writable));
}else{
$count=0;
self::scan($path,null,$count,$root);
}
}else{
$size=self::scanFile($path,$root);
}
self::increaseSize(dirname($fullPath),$size-$cachedSize);
}
private static function getCachedSize($path,$root){
if(!$root){
$root=OC_Filesystem::getRoot();
}else{
if($root=='/'){
$root='';
}
}
$query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path));
if($row=$result->fetchRow()){
return $row['size'];
}else{//file not in cache
return 0;
}
}
/**
* called when files are deleted
* @param array $params
* @param string root (optional)
*/
public static function fileSystemWatcherDelete($params,$root=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$path=$params['path'];
$fullPath=$root.$path;
if(self::getFileId($fullPath)==-1){
return;
}
$size=self::getCachedSize($path,$root);
self::increaseSize(dirname($fullPath),-$size);
self::delete($path);
}
/**
* called when files are deleted
* @param array $params
* @param string root (optional)
*/
public static function fileSystemWatcherRename($params,$root=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}
if($root=='/'){
$root='';
}
$oldPath=$params['oldpath'];
$newPath=$params['newpath'];
$fullOldPath=$root.$oldPath;
$fullNewPath=$root.$newPath;
if(($id=self::getFileId($fullOldPath))!=-1){
$oldInfo=self::get($fullOldPath);
$oldSize=$oldInfo['size'];
}else{
return;
}
$size=OC_Filesystem::filesize($oldPath);
self::increaseSize(dirname($fullOldPath),-$oldSize);
self::increaseSize(dirname($fullNewPath),$oldSize);
self::move($oldPath,$newPath);
}
/**
* adjust the size of the parent folders
* @param string $path
* @param int $sizeDiff
*/
private static function increaseSize($path,$sizeDiff){
if($sizeDiff==0) return;
while(($id=self::getFileId($path))!=-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));
$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 (optionak)
*/
public static function scan($path,$eventSource=false,&$count=0,$root=''){
if(!$root){
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView(($root=='/')?'':$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)){
if($eventSource){
$eventSource->send('scanning',array('file'=>$file,'count'=>$count));
}
self::scan($file,$eventSource,$count,$root);
}else{
$totalSize+=self::scanFile($file,$root);
$count++;
}
}
}
}
self::increaseSize($view->getRoot().$path,$totalSize);
}
/**
* scan a single file
* @param string path
* @param string root (optional)
* @return int size of the scanned file
*/
public static function scanFile($path,$root=''){
if(!$root){
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView(($root=='/')?'':$root);
}
if(!$view->is_readable($path)) return; //cant read, nothing we can do
$stat=$view->stat($path);
$mimetype=$view->getMimeType($path);
$writable=$view->is_writable($path);
$stat['mimetype']=$mimetype;
$stat['writable']=$writable;
if($path=='/'){
$path='';
}
self::put($path,$stat,$root);
return $stat['size'];
}
/**
* fine 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='',$root=''){
if(!$root){
$root=OC_Filesystem::getRoot();
}elseif($root='/'){
$root='';
}
$rootLen=strlen($root);
$user=OC_User::getUser();
if(!$part2){
$query=OC_DB::prepare('SELECT path FROM *PREFIX*fscache WHERE mimepart=? AND user=?');
$result=$query->execute(array($part1,$user));
}else{
$query=OC_DB::prepare('SELECT path FROM *PREFIX*fscache WHERE mimetype=? AND user=?');
$result=$query->execute(array($part1.'/'.$part2,$user));
}
$names=array();
while($row=$result->fetchRow()){
$names[]=substr($row['path'],$rootLen);
}
return $names;
}
/**
* check if a file or folder is updated outside owncloud
* @param string path
* @param string root (optional)
* @return bool
*/
public static function isUpdated($path,$root=''){
if(!$root){
$root=OC_Filesystem::getRoot();
$view=OC_Filesystem::getView();
}else{
if($root=='/'){
$root='';
}
$view=new OC_FilesystemView($root);
}
$mtime=$view->filemtime($path);
$isDir=$view->is_dir($path);
$path=$root.$path;
$query=OC_DB::prepare('SELECT mtime FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path));
if($row=$result->fetchRow()){
$cachedMTime=$row['mtime'];
return ($mtime>$cachedMTime);
}else{//file not in cache, so it has to be updated
return !($isDir);//new folders are handeled sperate
}
}
/**
* update the cache according to changes in the folder
* @param string path
* @param string root (optional)
*/
private static function updateFolder($path,$root=''){
if(!$root){
$view=OC_Filesystem::getView();
}else{
$view=new OC_FilesystemView(($root=='/')?'':$root);
}
$dh=$view->opendir($path);
if($dh){//check for changed/new files
while (($filename = readdir($dh)) !== false) {
if($filename != '.' and $filename != '..'){
$file=$path.'/'.$filename;
if(self::isUpdated($file,$root)){
if(!$root){//filesystem hooks are only valid for the default root
OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$file));
}else{
self::fileSystemWatcherWrite(array('path'=>$file),$root);
}
}
}
}
}
//check for removed files, not using getFolderContent to prevent loops
$parent=self::getFileId($view->getRoot().$path);
$query=OC_DB::prepare('SELECT name FROM *PREFIX*fscache WHERE parent=?');
$result=$query->execute(array($parent));
while($row=$result->fetchRow()){
$file=$path.'/'.$row['name'];
if(!$view->file_exists($file)){
if(!$root){//filesystem hooks are only valid for the default root
OC_Hook::emit('OC_Filesystem','post_delete',array('path'=>$file));
}else{
self::fileSystemWatcherDelete(array('path'=>$file),$root);
}
}
}
//update the folder last, so we can calculate the size correctly
if(!$root){//filesystem hooks are only valid for the default root
OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$path));
}else{
self::fileSystemWatcherWrite(array('path'=>$path),$root);
}
}
}
//watch for changes and try to keep the cache up to date
OC_Hook::connect('OC_Filesystem','post_write','OC_FileCache','fileSystemWatcherWrite');
OC_Hook::connect('OC_Filesystem','post_delete','OC_FileCache','fileSystemWatcherDelete');
OC_Hook::connect('OC_Filesystem','post_rename','OC_FileCache','fileSystemWatcherRename');

View File

@ -34,7 +34,7 @@
* A post-proxy recieves 2 arguments, the filepath and the result of the operation. * A post-proxy recieves 2 arguments, the filepath and the result of the operation.
* The return calue of the post-proxy will be used as the new result of the operation * The return calue of the post-proxy will be used as the new result of the operation
* The operations that have a post-proxy are * 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, getMimeType, hash, free_space and search * file_get_contents, is_file, is_dir, file_exists, stat, is_readable, is_writable, filemtime, filectime, file_get_contents, getMimeType, hash, free_space and search
*/ */
class OC_FileProxy{ class OC_FileProxy{

View File

@ -27,8 +27,10 @@
class OC_FileProxy_Quota extends OC_FileProxy{ class OC_FileProxy_Quota extends OC_FileProxy{
private function getFreeSpace(){ private function getFreeSpace(){
$usedSpace=OC_Filesystem::filesize(''); $rootInfo=OC_FileCache::get('');
$usedSpace=$rootInfo['size'];
$totalSpace=OC_Preferences::getValue(OC_User::getUser(),'files','quota',0); $totalSpace=OC_Preferences::getValue(OC_User::getUser(),'files','quota',0);
$totalSpace=OC_Helper::computerFileSize($totalSpace);
if($totalSpace==0){ if($totalSpace==0){
return 0; return 0;
} }

View File

@ -36,44 +36,13 @@ class OC_Files {
if(strpos($directory,OC::$CONFIG_DATADIRECTORY)===0){ if(strpos($directory,OC::$CONFIG_DATADIRECTORY)===0){
$directory=substr($directory,strlen(OC::$CONFIG_DATADIRECTORY)); $directory=substr($directory,strlen(OC::$CONFIG_DATADIRECTORY));
} }
$filesfound=true; $files=OC_FileCache::getFolderContent($directory);
$content=array(); foreach($files as &$file){
$dirs=array();
$file=array();
$files=array();
if(OC_Filesystem::is_dir($directory)) {
if ($dh = OC_Filesystem::opendir($directory)) {
while (($filename = readdir($dh)) !== false) {
if($filename<>'.' and $filename<>'..' and substr($filename,0,1)!='.'){
$file=array();
$filesfound=true;
$file['name']=$filename;
$file['directory']=$directory; $file['directory']=$directory;
$stat=OC_Filesystem::stat($directory.'/'.$filename); $file['type']=($file['mimetype']=='httpd/unix-directory')?'dir':'file';
$file=array_merge($file,$stat);
$file['size']=OC_Filesystem::filesize($directory.'/'.$filename);
$file['mime']=OC_Files::getMimeType($directory .'/'. $filename);
$file['readable']=OC_Filesystem::is_readable($directory .'/'. $filename);
$file['writeable']=OC_Filesystem::is_writeable($directory .'/'. $filename);
$file['type']=OC_Filesystem::filetype($directory .'/'. $filename);
if($file['type']=='dir'){
$dirs[$file['name']]=$file;
}else{
$files[$file['name']]=$file;
}
}
}
closedir($dh);
}
}
uksort($dirs, "strnatcasecmp");
uksort($files, "strnatcasecmp");
$content=array_merge($dirs,$files);
if($filesfound){
return $content;
}else{
return false;
} }
usort($files, "fileCmp");//TODO: remove this once ajax is merged
return $files;
} }
@ -321,3 +290,13 @@ class OC_Files {
return $path; return $path;
} }
} }
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']);
}
}

View File

@ -34,12 +34,11 @@ class OC_Filestorage{
public function filetype($path){} public function filetype($path){}
public function filesize($path){} public function filesize($path){}
public function is_readable($path){} public function is_readable($path){}
public function is_writeable($path){} public function is_writable($path){}
public function file_exists($path){} public function file_exists($path){}
public function readfile($path){} public function readfile($path){}
public function filectime($path){} public function filectime($path){}
public function filemtime($path){} public function filemtime($path){}
public function fileatime($path){}
public function file_get_contents($path){} public function file_get_contents($path){}
public function file_put_contents($path,$data){} public function file_put_contents($path,$data){}
public function unlink($path){} public function unlink($path){}
@ -48,7 +47,6 @@ class OC_Filestorage{
public function fopen($path,$mode){} public function fopen($path,$mode){}
public function toTmpFile($path){}//copy the file to a temporary file, used for cross-storage file actions public function toTmpFile($path){}//copy the file to a temporary file, used for cross-storage file actions
public function fromTmpFile($tmpPath,$path){}//copy a file from a temporary file, used for cross-storage file actions public function fromTmpFile($tmpPath,$path){}//copy a file from a temporary file, used for cross-storage file actions
public function fromUploadedFile($tmpPath,$path){}//copy a file from a temporary file, used for cross-storage file actions
public function getMimeType($path){} public function getMimeType($path){}
public function hash($type,$path,$raw){} public function hash($type,$path,$raw){}
public function free_space($path){} public function free_space($path){}

View File

@ -13,13 +13,11 @@ class OC_Filestorage_Local extends OC_Filestorage{
} }
public function mkdir($path){ public function mkdir($path){
if($return=mkdir($this->datadir.$path)){ if($return=mkdir($this->datadir.$path)){
$this->clearFolderSizeCache($path);
} }
return $return; return $return;
} }
public function rmdir($path){ public function rmdir($path){
if($return=rmdir($this->datadir.$path)){ if($return=rmdir($this->datadir.$path)){
$this->clearFolderSizeCache($path);
} }
return $return; return $return;
} }
@ -52,7 +50,7 @@ class OC_Filestorage_Local extends OC_Filestorage{
public function is_readable($path){ public function is_readable($path){
return is_readable($this->datadir.$path); return is_readable($this->datadir.$path);
} }
public function is_writeable($path){ public function is_writable($path){
return is_writable($this->datadir.$path); return is_writable($this->datadir.$path);
} }
public function file_exists($path){ public function file_exists($path){
@ -67,20 +65,15 @@ class OC_Filestorage_Local extends OC_Filestorage{
public function filemtime($path){ public function filemtime($path){
return filemtime($this->datadir.$path); return filemtime($this->datadir.$path);
} }
public function fileatime($path){
return fileatime($this->datadir.$path);
}
public function file_get_contents($path){ public function file_get_contents($path){
return file_get_contents($this->datadir.$path); return file_get_contents($this->datadir.$path);
} }
public function file_put_contents($path,$data){ public function file_put_contents($path,$data){
if($return=file_put_contents($this->datadir.$path,$data)){ if($return=file_put_contents($this->datadir.$path,$data)){
$this->clearFolderSizeCache($path);
} }
} }
public function unlink($path){ public function unlink($path){
$return=$this->delTree($path); $return=$this->delTree($path);
$this->clearFolderSizeCache($path);
return $return; return $return;
} }
public function rename($path1,$path2){ public function rename($path1,$path2){
@ -90,8 +83,6 @@ class OC_Filestorage_Local extends OC_Filestorage{
} }
if($return=rename($this->datadir.$path1,$this->datadir.$path2)){ if($return=rename($this->datadir.$path1,$this->datadir.$path2)){
$this->clearFolderSizeCache($path1);
$this->clearFolderSizeCache($path2);
} }
return $return; return $return;
} }
@ -104,7 +95,6 @@ class OC_Filestorage_Local extends OC_Filestorage{
$path2.=$source; $path2.=$source;
} }
if($return=copy($this->datadir.$path1,$this->datadir.$path2)){ if($return=copy($this->datadir.$path1,$this->datadir.$path2)){
$this->clearFolderSizeCache($path2);
} }
return $return; return $return;
} }
@ -117,12 +107,10 @@ class OC_Filestorage_Local extends OC_Filestorage{
case 'w+': case 'w+':
case 'x+': case 'x+':
case 'a+': case 'a+':
$this->clearFolderSizeCache($path);
break; break;
case 'w': case 'w':
case 'x': case 'x':
case 'a': case 'a':
$this->clearFolderSizeCache($path);
break; break;
} }
} }
@ -192,18 +180,6 @@ class OC_Filestorage_Local extends OC_Filestorage{
$fileStats = stat($tmpFile); $fileStats = stat($tmpFile);
if(rename($tmpFile,$this->datadir.$path)){ if(rename($tmpFile,$this->datadir.$path)){
touch($this->datadir.$path, $fileStats['mtime'], $fileStats['atime']); touch($this->datadir.$path, $fileStats['mtime'], $fileStats['atime']);
$this->clearFolderSizeCache($path);
return true;
}else{
return false;
}
}
public function fromUploadedFile($tmpFile,$path){
$fileStats = stat($tmpFile);
if(move_uploaded_file($tmpFile,$this->datadir.$path)){
touch($this->datadir.$path, $fileStats['mtime'], $fileStats['atime']);
$this->clearFolderSizeCache($path);
return true; return true;
}else{ }else{
return false; return false;
@ -219,7 +195,6 @@ class OC_Filestorage_Local extends OC_Filestorage{
if ($item == '.' || $item == '..') continue; if ($item == '.' || $item == '..') continue;
if(is_file($dir.'/'.$item)){ if(is_file($dir.'/'.$item)){
if(unlink($dir.'/'.$item)){ if(unlink($dir.'/'.$item)){
$this->clearFolderSizeCache($dir);
} }
}elseif(is_dir($dir.'/'.$item)){ }elseif(is_dir($dir.'/'.$item)){
if (!$this->delTree($dirRelative. "/" . $item)){ if (!$this->delTree($dirRelative. "/" . $item)){
@ -228,7 +203,6 @@ class OC_Filestorage_Local extends OC_Filestorage{
} }
} }
if($return=rmdir($dir)){ if($return=rmdir($dir)){
$this->clearFolderSizeCache($dir);
} }
return $return; return $return;
} }
@ -268,75 +242,6 @@ class OC_Filestorage_Local extends OC_Filestorage{
* @return int size of folder and it's content * @return int size of folder and it's content
*/ */
public function getFolderSize($path){ public function getFolderSize($path){
$path=str_replace('//','/',$path); return 0;//depricated, use OC_FileCach instead
if($this->is_dir($path) and substr($path,-1)!='/'){
$path.='/';
}
$query=OC_DB::prepare("SELECT size FROM *PREFIX*foldersize WHERE path=?");
$size=$query->execute(array($path))->fetchAll();
if(count($size)>0){// we already the size, just return it
return $size[0]['size'];
}else{//the size of the folder isn't know, calulate it
return $this->calculateFolderSize($path);
}
}
/**
* @brief calulate the size of folder and it's content and cache it
* @param string $path file path
* @return int size of folder and it's content
*/
public function calculateFolderSize($path){
if($this->is_file($path)){
$path=dirname($path);
}
$path=str_replace('//','/',$path);
if($this->is_dir($path) and substr($path,-1)!='/'){
$path.='/';
}
$size=0;
if ($dh = $this->opendir($path)) {
while (($filename = readdir($dh)) !== false) {
if($filename!='.' and $filename!='..'){
$subFile=$path.'/'.$filename;
if($this->is_file($subFile)){
$size+=$this->filesize($subFile);
}else{
$size+=$this->getFolderSize($subFile);
}
}
}
if($size>0){
$query=OC_DB::prepare("INSERT INTO *PREFIX*foldersize VALUES(?,?)");
$result=$query->execute(array($path,$size));
}
}
return $size;
}
/**
* @brief clear the folder size cache of folders containing a file
* @param string $path
*/
public function clearFolderSizeCache($path){
if($this->is_file($path)){
$path=dirname($path);
}
$path=str_replace('//','/',$path);
if($this->is_dir($path) and substr($path,-1)!='/'){
$path.='/';
}
$query=OC_DB::prepare("DELETE FROM *PREFIX*foldersize WHERE path = ?");
$result=$query->execute(array($path));
if($path!='/' and $path!=''){
$parts=explode('/',$path);
//pop empty part
$part=array_pop($parts);
if(empty($part)){
array_pop($parts);
}
$parent=implode('/',$parts);
$this->clearFolderSizeCache($parent);
}
} }
} }

View File

@ -1,350 +0,0 @@
<?php
/**
* ownCloud
*
* @author Frank Karlitschek
* @copyright 2010 Frank Karlitschek karlitschek@kde.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 <http://www.gnu.org/licenses/>.
*
*/
class OC_Filestorage_Remote extends OC_Filestorage{
private $url;
private $username;
private $password;
private $remote=false;
private $statCache;
private $statCacheDir=false;
private $changed=array();
private function cacheDir($dir){
if($this->statCacheDir!=$dir or $this->statCacheDir===false){
$this->statCache=$this->remote->getFiles($dir);
$keys=array_keys($this->statCache);
$this->statCacheDir=$dir;
}
}
public function __construct($arguments){
$this->url=$arguments['url'];
$this->username=$arguments['username'];
$this->password=$arguments['password'];
}
private function connect(){
if($this->remote===false){
$this->remote=OC_Connect::connect($this->url,$this->username,$this->password);
}
}
public function mkdir($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$return=$this->remote->newFile($parent,$name,'dir');
if($return){
$this->notifyObservers($path,OC_FILEACTION_CREATE);
}
return $return;
}
public function rmdir($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$return=$this->remote->delete($parent,$name);
if($return){
$this->notifyObservers($path,OC_FILEACTION_DELETE);
}
return $return;
}
public function opendir($path){
$this->connect();
$this->cacheDir($path);
$dirs=array_keys($this->statCache);
$id=uniqid();
global $FAKEDIRS;
$FAKEDIRS[$id]=$dirs;
if($return=opendir("fakedir://$id")){
$this->notifyObservers($path,OC_FILEACTION_READ);
}
return $return;
}
public function is_dir($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($path);
if($path=='' or $path=='/'){
return true;
}
if(!isset($this->statCache[$name])){
return false;
}
return ($this->statCache[$name]['type'=='dir']);
}
public function is_file($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return false;
}
return ($this->statCache[$name]['type'!='dir']);
}
public function stat($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return $false;
}
return $this->statCache[$name];
}
public function filetype($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return false;
}
return $this->statCache[$name]['type'];
}
public function filesize($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return $false;
}
return $this->statCache[$name]['size'];
}
public function is_readable($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return false;
}
return $this->statCache[$name]['readable'];
}
public function is_writeable($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return false;
}
return $this->statCache[$name]['writeable'];
}
public function file_exists($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
return isset($this->statCache[$name]);
}
public function readfile($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$file=$this->remote->getFile($parent,$name);
readfile($file);
unlink($file);
}
public function filectime($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return false;
}
return $this->statCache[$name]['ctime'];
}
public function filemtime($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return false;
}
return $this->statCache[$name]['mtime'];
}
public function fileatime($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return false;
}
return $this->statCache[$name]['atime'];
}
public function file_get_contents($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$file=$this->remote->getFile($parent,$name);
file_get_contents($file);
unlink($file);
}
public function file_put_contents($path,$data){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$file=$this->remote->getFile($parent,$name);
$file=tempnam(get_temp_dir(),'oc_');
file_put_contents($file,$data);
if($return=$this->remote->sendTmpFile($file,$parent,$name)){
$this->notifyObservers($path,OC_FILEACTION_WRITE);
}
}
public function unlink($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
if($return=$this->remote->delete($paren,$name)){
$this->notifyObservers($path,OC_FILEACTION_DELETE);
}
return $return;
}
public function rename($path1,$path2){
$this->connect();
$parent1=dirname($path1);
$name1=substr($path1,strlen($parent1)+1);
$parent2=dirname($path2);
$name2=substr($path2,strlen($parent2)+1);
if($return=$this->remote->move($parent1,$name1,$parent2,$name2)){
$this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME);
}
return $return;
}
public function copy($path1,$path2){
$this->connect();
$parent1=dirname($path1);
$name1=substr($path1,strlen($parent1)+1);
$parent2=dirname($path2);
$name2=substr($path2,strlen($parent2)+1);
if($return=$this->copy->rename($parent1,$name1,$parent2,$name2)){
$this->notifyObservers($path1.'->'.$path2,OC_FILEACTION_RENAME);
}
return $return;
}
public function fopen($path,$mode){
$this->connect();
$changed=false;
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
$file=$this->remote->getFile($parent,$name);
if($return=fopen($file,$mode)){
switch($mode){
case 'r':
$this->notifyObservers($path,OC_FILEACTION_READ);
break;
case 'r+':
case 'w+':
case 'x+':
case 'a+':
$this->notifyObservers($path,OC_FILEACTION_READ | OC_FILEACTION_WRITE);
$this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file);
break;
case 'w':
case 'x':
case 'a':
$this->notifyObservers($path,OC_FILEACTION_WRITE);
$this->changed[]=array('dir'=>$parent,'file'=>$name,'tmp'=>$file);
break;
}
}
return $return;
}
public function getMimeType($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
if(substr($name,0,1)=='/'){
$name=substr($name,1);
}
$this->cacheDir($parent);
if(!isset($this->statCache[$name])){
return false;
}
return $this->statCache[$name]['mime'];
}
public function toTmpFile($path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
if(substr($name,0,1)=='/'){
$name=substr($name,1);
}
$filename=$this->remote->getFile($parent,$name);
if($filename){
$this->notifyObservers($path,OC_FILEACTION_READ);
return $filename;
}else{
return false;
}
}
public function fromTmpFile($tmpFile,$path){
$this->connect();
$parent=dirname($path);
$name=substr($path,strlen($parent)+1);
if($this->remote->sendTmpFile($tmpFile,$parent,$name)){
$this->notifyObservers($path,OC_FILEACTION_CREATE);
return true;
}else{
return false;
}
}
public function delTree($dir) {
$this->connect();
$parent=dirname($dir);
$name=substr($dir,strlen($parent)+1);
$return=$this->remote->delete($parent,$name);
if($return=rmdir($dir)){
$this->notifyObservers($dir,OC_FILEACTION_DELETE);
}
return $return;
}
public function find($path){
return $this->getTree($path);
}
public function getTree($dir) {
$this->connect();
if($return=$this->remote->getTree($dir)){
$this->notifyObservers($dir,OC_FILEACTION_READ);
}
return $return;
}
public function __destruct(){
foreach($this->changed as $changed){
$this->remote->sendTmpFile($changed['tmp'],$changed['dir'],$changed['file']);
}
}
}

83
lib/filestoragecommon.php Normal file
View File

@ -0,0 +1,83 @@
<?php
/**
* ownCloud
*
* @author Michael Gapczynski
* @copyright 2012 Michael Gapczynski GapczynskiM@gmail.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
class OC_Filestorage_Common extends OC_Filestorage {
public function __construct($parameters){}
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) {
$stat = $this->stat($path);
return $stat['size'];
}
public function is_readable($path){}
public function is_writable($path){}
public function file_exists($path){}
public function readfile($path) {
$handle = $this->fopen($path, "r");
$chunk = 1024;
while (!feof($handle)) {
echo fread($handle, $chunk);
}
return $this->filesize($path);
}
public function filectime($path) {
$stat = $this->stat($path);
return $stat['ctime'];
}
public function filemtime($path) {
$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");
return fread($handle, $this->filesize($path));
}
public function file_put_contents($path,$data) {
$handle = $this->fopen($path, "w");
return fwrite($handle, $data);
}
public function unlink($path){}
public function rename($path1,$path2){}
public function copy($path1,$path2) {
$data = $this->file_get_contents($path1);
return $this->file_put_contents($path2, $data);
}
public function fopen($path,$mode){}
public function toTmpFile($path){}
public function fromTmpFile($tmpPath,$path){}
public function fromUploadedFile($tmpPath,$path){}
public function getMimeType($path){}
public function hash($type,$path,$raw){}
public function free_space($path){}
public function search($query){}
public function getLocalFile($path){}
}

View File

@ -42,11 +42,15 @@
* *
* 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 occuring
*/ */
class OC_Filesystem{ class OC_Filesystem{
static private $storages=array(); static private $storages=array();
static private $mounts=array(); static private $mounts=array();
static private $fakeRoot='';
static private $storageTypes=array(); static private $storageTypes=array();
public static $loaded=false;
private $fakeRoot='';
static private $defaultInstance;
/** /**
* classname which used for hooks handling * classname which used for hooks handling
@ -135,30 +139,77 @@ class OC_Filesystem{
const signal_param_run = 'run'; const signal_param_run = 'run';
/** /**
* register a storage type * get the mountpoint of the storage object for a path
* @param string type ( 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 classname *
* @param array arguments an associative array in the form of name=>type (eg array('datadir'=>'string')) * @param string path
* @return string
*/ */
static public function registerStorageType($type,$classname,$arguments){ static public function getMountPoint($path){
self::$storageTypes[$type]=array('type'=>$type,'classname'=>$classname,'arguments'=>$arguments); if(!$path){
$path='/';
}
if(substr($path,0,1)!=='/'){
$path='/'.$path;
}
if(substr($path,-1)!=='/'){
$path=$path.'/';
}
$foundMountPoint='';
foreach(OC_Filesystem::$mounts as $mountpoint=>$storage){
if(substr($mountpoint,-1)!=='/'){
$mountpoint=$mountpoint.'/';
}
if($mountpoint==$path){
return $mountpoint;
}
if(strpos($path,$mountpoint)===0 and strlen($mountpoint)>strlen($foundMountPoint)){
$foundMountPoint=$mountpoint;
}
}
return $foundMountPoint;
} }
/** /**
* check if the filesystem supports a specific storagetype * get the part of the path relative to the mountpoint of the storage it's stored in
* @param string type * @param string path
* @return bool * @return bool
*/ */
static public function hasStorageType($type){ static public function getInternalPath($path){
return isset(self::$storageTypes[$type]); $mountPoint=self::getMountPoint($path);
$internalPath=substr($path,strlen($mountPoint));
return $internalPath;
}
/**
* get the storage object for a path
* @param string path
* @return OC_Filestorage
*/
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];
}
}
static public function init($root){
if(self::$defaultInstance){
return false;
}
self::$defaultInstance=new OC_FilesystemView($root);
self::$loaded=true;
} }
/** /**
* get the list of names of storagetypes that the filesystem supports * get the default filesystem view
* @return array * @return OC_FilesystemView
*/ */
static public function getStorageTypeNames(){ static public function getView(){
return array_keys(self::$storageTypes); return self::$defaultInstance;
} }
/** /**
@ -177,13 +228,9 @@ class OC_Filesystem{
* @param array arguments * @param array arguments
* @return OC_Filestorage * @return OC_Filestorage
*/ */
static private function createStorage($type,$arguments){ static private function createStorage($class,$arguments){
if(!self::hasStorageType($type)){ if(class_exists($class)){
return false; return new $class($arguments);
}
$className=self::$storageTypes[$type]['classname'];
if(class_exists($className)){
return new $className($arguments);
}else{ }else{
return false; return false;
} }
@ -195,24 +242,15 @@ class OC_Filesystem{
* @return bool * @return bool
*/ */
static public function chroot($fakeRoot){ static public function chroot($fakeRoot){
if(!$fakeRoot==''){ return self::$defaultInstance->chroot($path);
if($fakeRoot[0]!=='/'){
$fakeRoot='/'.$fakeRoot;
}
}
self::$fakeRoot=$fakeRoot;
} }
/** /**
* get the part of the path relative to the mountpoint of the storage it's stored in * get the fake root
* @param string path * @return string
* @return bool
*/ */
static public function getInternalPath($path){ static public function getRoot(){
$mountPoint=self::getMountPoint($path); return self::$defaultInstance->getRoot();
$path=self::$fakeRoot.$path;
$internalPath=substr($path,strlen($mountPoint));
return $internalPath;
} }
/** /**
@ -220,11 +258,11 @@ class OC_Filesystem{
* @param OC_Filestorage storage * @param OC_Filestorage storage
* @param string mountpoint * @param string mountpoint
*/ */
static public function mount($type,$arguments,$mountpoint){ static public function mount($class,$arguments,$mountpoint){
if(substr($mountpoint,0,1)!=='/'){ if(substr($mountpoint,0,1)!=='/'){
$mountpoint='/'.$mountpoint; $mountpoint='/'.$mountpoint;
} }
self::$mounts[$mountpoint]=array('type'=>$type,'arguments'=>$arguments); self::$mounts[$mountpoint]=array('class'=>$class,'arguments'=>$arguments);
} }
/** /**
@ -238,55 +276,6 @@ class OC_Filesystem{
} }
} }
/**
* get the storage object for a path
* @param string path
* @return OC_Filestorage
*/
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['type'],$mount['arguments']);
}
return self::$storages[$mountpoint];
}
}
/**
* 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){
if(!$path){
$path='/';
}
if(substr($path,0,1)!=='/'){
$path='/'.$path;
}
if(substr($path,-1)!=='/'){
$path=$path.'/';
}
$path=self::$fakeRoot.$path;
$foundMountPoint='';
foreach(self::$mounts as $mountpoint=>$storage){
if(substr($mountpoint,-1)!=='/'){
$mountpoint=$mountpoint.'/';
}
if($mountpoint==$path){
return $mountpoint;
}
if(strpos($path,$mountpoint)===0 and strlen($mountpoint)>strlen($foundMountPoint)){
$foundMountPoint=$mountpoint;
}
}
return $foundMountPoint;
}
/** /**
* return the path to a local version of the file * 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 * 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
@ -294,10 +283,7 @@ class OC_Filesystem{
* @return string * @return string
*/ */
static public function getLocalFile($path){ static public function getLocalFile($path){
$parent=substr($path,0,strrpos($path,'/')); return self::$defaultInstance->getLocalFile($path);
if(self::isValidPath($parent) and $storage=self::getStorage($path)){
return $storage->getLocalFile(self::getInternalPath($path));
}
} }
/** /**
@ -314,262 +300,90 @@ class OC_Filesystem{
} }
return true; return true;
} }
/**
* following functions are equivilent to their php buildin equivilents for arguments/return values.
*/
static public function mkdir($path){ static public function mkdir($path){
return self::basicOperation('mkdir',$path,array('create','write')); return self::$defaultInstance->mkdir($path);
} }
static public function rmdir($path){ static public function rmdir($path){
return self::basicOperation('rmdir',$path,array('delete')); return self::$defaultInstance->rmdir($path);
} }
static public function opendir($path){ static public function opendir($path){
return self::basicOperation('opendir',$path,array('read')); return self::$defaultInstance->opendir($path);
} }
static public function is_dir($path){ static public function is_dir($path){
if($path=='/'){ return self::$defaultInstance->is_dir($path);
return true;
}
return self::basicOperation('is_dir',$path);
} }
static public function is_file($path){ static public function is_file($path){
if($path=='/'){ return self::$defaultInstance->is_file($path);
return false;
}
return self::basicOperation('is_file',$path);
} }
static public function stat($path){ static public function stat($path){
return self::basicOperation('stat',$path); return self::$defaultInstance->stat($path);
} }
static public function filetype($path){ static public function filetype($path){
return self::basicOperation('filetype',$path); return self::$defaultInstance->filetype($path);
} }
static public function filesize($path){ static public function filesize($path){
return self::basicOperation('filesize',$path); return self::$defaultInstance->filesize($path);
} }
static public function readfile($path){ static public function readfile($path){
return self::basicOperation('readfile',$path,array('read')); return self::$defaultInstance->readfile($path);
} }
static public function is_readable($path){ static public function is_readable($path){
return self::basicOperation('is_readable',$path); return self::$defaultInstance->is_readable($path);
} }
static public function is_writeable($path){ static public function is_writable($path){
return self::basicOperation('is_writeable',$path); return self::$defaultInstance->is_writable($path);
} }
static public function file_exists($path){ static public function file_exists($path){
if($path=='/'){ return self::$defaultInstance->file_exists($path);
return true;
}
return self::basicOperation('file_exists',$path);
} }
static public function filectime($path){ static public function filectime($path){
return self::basicOperation('filectime',$path); return self::$defaultInstance->filectime($path);
} }
static public function filemtime($path){ static public function filemtime($path){
return self::basicOperation('filemtime',$path); return self::$defaultInstance->filemtime($path);
}
static public function fileatime($path){
return self::basicOperation('fileatime',$path);
} }
static public function file_get_contents($path){ static public function file_get_contents($path){
return self::basicOperation('file_get_contents',$path,array('read')); return self::$defaultInstance->file_get_contents($path);
} }
static public function file_put_contents($path,$data){ static public function file_put_contents($path,$data){
return self::basicOperation('file_put_contents',$path,array('create','write'),$data); return self::$defaultInstance->file_put_contents($path,$data);
} }
static public function unlink($path){ static public function unlink($path){
return self::basicOperation('unlink',$path,array('delete')); return self::$defaultInstance->unlink($path);
} }
static public function rename($path1,$path2){ static public function rename($path1,$path2){
if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and self::is_writeable($path1) and self::isValidPath($path2)){ return self::$defaultInstance->rename($path1,$path2);
$run=true;
OC_Hook::emit( self::CLASSNAME, self::signal_rename, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2, self::signal_param_run => &$run));
if($run){
$mp1=self::getMountPoint($path1);
$mp2=self::getMountPoint($path2);
if($mp1==$mp2){
if($storage=self::getStorage($path1)){
$result=$storage->rename(self::getInternalPath($path1),self::getInternalPath($path2));
}
}elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){
$tmpFile=$storage1->toTmpFile(self::getInternalPath($path1));
$result=$storage2->fromTmpFile($tmpFile,self::getInternalPath($path2));
$storage1->unlink(self::getInternalPath($path1));
}
OC_Hook::emit( self::CLASSNAME, self::signal_post_rename, array( self::signal_param_oldpath => $path1, self::signal_param_newpath=>$path2));
return $result;
}
}
} }
static public function copy($path1,$path2){ static public function copy($path1,$path2){
if(OC_FileProxy::runPreProxies('copy',$path1,$path2) and self::is_readable($path1) and self::isValidPath($path2)){ return self::$defaultInstance->copy($path1,$path2);
$run=true;
OC_Hook::emit( self::CLASSNAME, self::signal_copy, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2, self::signal_param_run => &$run));
$exists=self::file_exists($path2);
if($run and !$exists){
OC_Hook::emit( self::CLASSNAME, self::signal_create, array( self::signal_param_path => $path2, self::signal_param_run => &$run));
}
if($run){
OC_Hook::emit( self::CLASSNAME, self::signal_write, array( self::signal_param_path => $path2, self::signal_param_run => &$run));
}
if($run){
$mp1=self::getMountPoint($path1);
$mp2=self::getMountPoint($path2);
if($mp1==$mp2){
if($storage=self::getStorage($path1)){
$result=$storage->copy(self::getInternalPath($path1),self::getInternalPath($path2));
}
}elseif($storage1=self::getStorage($path1) and $storage2=self::getStorage($path2)){
$tmpFile=$storage1->toTmpFile(self::getInternalPath($path1));
$result=$storage2->fromTmpFile($tmpFile,self::getInternalPath($path2));
}
OC_Hook::emit( self::CLASSNAME, self::signal_post_copy, array( self::signal_param_oldpath => $path1 , self::signal_param_newpath=>$path2));
if(!$exists){
OC_Hook::emit( self::CLASSNAME, self::signal_post_create, array( self::signal_param_path => $path2));
}
OC_Hook::emit( self::CLASSNAME, self::signal_post_write, array( self::signal_param_path => $path2));
return $result;
}
}
} }
static public function fopen($path,$mode){ static public function fopen($path,$mode){
$hooks=array(); return self::$defaultInstance->fopen($path,$mode);
switch($mode){
case 'r':
$hooks[]='read';
break;
case 'r+':
case 'w+':
case 'x+':
case 'a+':
$hooks[]='read';
$hooks[]='write';
break;
case 'w':
case 'x':
case 'a':
$hooks[]='write';
break;
default:
OC_Log::write('core','invalid mode ('.$mode.') for '.$path,OC_Log::ERROR);
}
return self::basicOperation('fopen',$path,$hooks,$mode);
} }
static public function toTmpFile($path){ static public function toTmpFile($path){
if(OC_FileProxy::runPreProxies('toTmpFile',$path) and self::isValidPath($path) and $storage=self::getStorage($path)){ return self::$defaultInstance->toTmpFile($path);
OC_Hook::emit( self::CLASSNAME, self::signal_read, array( self::signal_param_path => $path));
return $storage->toTmpFile(self::getInternalPath($path));
}
} }
static public function fromTmpFile($tmpFile,$path){ static public function fromTmpFile($tmpFile,$path){
if(OC_FileProxy::runPreProxies('copy',$tmpFile,$path) and self::isValidPath($path) and $storage=self::getStorage($path)){ return self::$defaultInstance->fromTmpFile($tmpFile,$path);
$run=true;
$exists=self::file_exists($path);
if(!$exists){
OC_Hook::emit( self::CLASSNAME, self::signal_create, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}
if($run){
OC_Hook::emit( self::CLASSNAME, self::signal_write, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}
if($run){
$result=$storage->fromTmpFile($tmpFile,self::getInternalPath($path));
if(!$exists){
OC_Hook::emit( self::CLASSNAME, self::signal_post_create, array( self::signal_param_path => $path));
}
OC_Hook::emit( self::CLASSNAME, self::signal_post_write, array( self::signal_param_path => $path));
return $result;
}
}
}
static public function fromUploadedFile($tmpFile,$path){
if(OC_FileProxy::runPreProxies('fromUploadedFile',$tmpFile,$path) and self::isValidPath($path) and $storage=self::getStorage($path)){
$run=true;
$exists=self::file_exists($path);
if(!$exists){
OC_Hook::emit( self::CLASSNAME, self::signal_create, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}
if($run){
OC_Hook::emit( self::CLASSNAME, self::signal_write, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}
if($run){
$result=$storage->fromUploadedFile($tmpFile,self::getInternalPath($path));
if(!$exists){
OC_Hook::emit( self::CLASSNAME, self::signal_post_create, array( self::signal_param_path => $path));
}
OC_Hook::emit( self::CLASSNAME, self::signal_post_write, array( self::signal_param_path => $path));
return $result;
}
}
} }
static public function getMimeType($path){ static public function getMimeType($path){
return self::basicOperation('getMimeType',$path); return self::$defaultInstance->getMimeType($path);
} }
static public function hash($type,$path){ static public function hash($type,$path){
return self::basicOperation('hash',$path,array('read')); return self::$defaultInstance->hash($type,$path);
} }
static public function free_space($path='/'){ static public function free_space($path='/'){
return self::basicOperation('free_space',$path); return self::$defaultInstance->free_space($path);
} }
static public function search($query){ static public function search($query){
self::mountAll(); return OC_FileCache::search($query);
$files=array();
$fakeRoot=self::$fakeRoot;
$fakeRootLength=strlen($fakeRoot);
foreach(self::$storages as $mountpoint=>$storage){
$results=$storage->search($query);
if(is_array($results)){
foreach($results as $result){
$file=str_replace('//','/',$mountpoint.$result);
if(substr($file,0,$fakeRootLength)==$fakeRoot){
$file=substr($file,$fakeRootLength);
$files[]=$file;
}
}
}
}
return $files;
}
static public function update_session_file_hash($sessionname,$sessionvalue){
$_SESSION[$sessionname] = $sessionvalue;
}
/**
* abstraction for running most basic operations
* @param string $operation
* @param string #path
* @param array (optional) hooks
* @param mixed (optional) $extraParam
* @return mixed
*/
private static function basicOperation($operation,$path,$hooks=array(),$extraParam=null){
if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and self::isValidPath($path) and $storage=self::getStorage($path)){
$interalPath=self::getInternalPath($path);
$run=true;
foreach($hooks as $hook){
if($hook!='read'){
OC_Hook::emit( self::CLASSNAME, $hook, array( self::signal_param_path => $path, self::signal_param_run => &$run));
}else{
OC_Hook::emit( self::CLASSNAME, $hook, array( self::signal_param_path => $path));
}
}
if($run){
if($extraParam){
$result=$storage->$operation($interalPath,$extraParam);
}else{
$result=$storage->$operation($interalPath);
}
$result=OC_FileProxy::runPostProxies($operation,$path,$result);
foreach($hooks as $hook){
if($hook!='read'){
OC_Hook::emit( self::CLASSNAME, 'post_'.$hook, array( self::signal_param_path => $path));
}
}
return $result;
}
}
return null;
} }
} }
require_once('filecache.php');

318
lib/filesystemview.php Normal file
View File

@ -0,0 +1,318 @@
<?php
/**
* ownCloud
*
* @author Frank Karlitschek
* @copyright 2010 Frank Karlitschek karlitschek@kde.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 <http://www.gnu.org/licenses/>.
*
*/
class OC_FilesystemView {
private $fakeRoot='';
public function __construct($root){
$this->fakeRoot=$root;
}
public function getAbsolutePath($path){
if(!$path){
$path='/';
}
if(substr($path,0,1)!=='/'){
$path='/'.$path;
}
return $this->fakeRoot.$path;
}
/**
* change the root to a fake toor
* @param string fakeRoot
* @return bool
*/
public function chroot($fakeRoot){
if(!$fakeRoot==''){
if($fakeRoot[0]!=='/'){
$fakeRoot='/'.$fakeRoot;
}
}
$this->fakeRoot=$fakeRoot;
}
/**
* get the fake root
* @return string
*/
public function getRoot(){
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){
return OC_Filesystem::getInternalPath($this->getAbsolutePath($path));
}
/**
* get the storage object for a path
* @param string path
* @return OC_Filestorage
*/
public function getStorage($path){
return OC_Filesystem::getStorage($this->getAbsolutePath($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
*/
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
*/
public function getLocalFile($path){
$parent=substr($path,0,strrpos($path,'/'));
if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)){
return $storage->getLocalFile($this->getInternalPath($path));
}
}
/**
* following functions are equivilent to their php buildin equivilents for arguments/return values.
*/
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 is_dir($path){
if($path=='/'){
return true;
}
return $this->basicOperation('is_dir',$path);
}
public function is_file($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){
return $this->basicOperation('readfile',$path,array('read'));
}
public function is_readable($path){
return $this->basicOperation('is_readable',$path);
}
public function is_writable($path){
return $this->basicOperation('is_writable',$path);
}
public function file_exists($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 file_get_contents($path){
return $this->basicOperation('file_get_contents',$path,array('read'));
}
public function file_put_contents($path,$data){
return $this->basicOperation('file_put_contents',$path,array('create','write'),$data);
}
public function unlink($path){
return $this->basicOperation('unlink',$path,array('delete'));
}
public function rename($path1,$path2){
if(OC_FileProxy::runPreProxies('rename',$path1,$path2) and $this->is_writable($path1) and OC_Filesystem::isValidPath($path2)){
$run=true;
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));
if($run){
$mp1=$this->getMountPoint($path1);
$mp2=$this->getMountPoint($path2);
if($mp1==$mp2){
if($storage=$this->getStorage($path1)){
$result=$storage->rename($this->getInternalPath($path1),$this->getInternalPath($path2));
}
}elseif($storage1=$this->getStorage($path1) and $storage2=$this->getStorage($path2)){
$tmpFile=$storage1->toTmpFile($this->getInternalPath($path1));
$result=$storage2->fromTmpFile($tmpFile,$this->getInternalPath($path2));
$storage1->unlink($this->getInternalPath($path1));
}
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, array( OC_Filesystem::signal_param_oldpath => $path1, OC_Filesystem::signal_param_newpath=>$path2));
return $result;
}
}
}
public function copy($path1,$path2){
if(OC_FileProxy::runPreProxies('copy',$path1,$path2) and $this->is_readable($path1) and OC_Filesystem::isValidPath($path2)){
$run=true;
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_run => &$run));
$exists=$this->file_exists($path2);
if($run and !$exists){
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run));
}
if($run){
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run));
}
if($run){
$mp1=$this->getMountPoint($path1);
$mp2=$this->getMountPoint($path2);
if($mp1==$mp2){
if($storage=$this->getStorage($path1)){
$result=$storage->copy($this->getInternalPath($path1),$this->getInternalPath($path2));
}
}elseif($storage1=$this->getStorage($path1) and $storage2=$this->getStorage($path2)){
$tmpFile=$storage1->toTmpFile($this->getInternalPath($path1));
$result=$storage2->fromTmpFile($tmpFile,$this->getInternalPath($path2));
}
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_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( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path2));
return $result;
}
}
}
public function fopen($path,$mode){
$hooks=array();
switch($mode){
case 'r':
$hooks[]='read';
break;
case 'r+':
case 'w+':
case 'x+':
case 'a+':
$hooks[]='read';
$hooks[]='write';
break;
case 'w':
case 'x':
case 'a':
$hooks[]='write';
break;
default:
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_FileProxy::runPreProxies('toTmpFile',$path) and OC_Filesystem::isValidPath($path) and $storage=$this->getStorage($path)){
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_read, array( OC_Filesystem::signal_param_path => $path));
return $storage->toTmpFile($this->getInternalPath($path));
}
}
public function fromTmpFile($tmpFile,$path){
if(OC_FileProxy::runPreProxies('copy',$tmpFile,$path) and OC_Filesystem::isValidPath($path) and $storage=$this->getStorage($path)){
$run=true;
$exists=$this->file_exists($path);
if(!$exists){
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
}
if($run){
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
}
if($run){
$result=$storage->fromTmpFile($tmpFile,$this->getInternalPath($path));
if(!$exists){
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, 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));
return $result;
}
}
}
public function getMimeType($path){
return $this->basicOperation('getMimeType',$path);
}
public function hash($type,$path){
return $this->basicOperation('hash',$path,array('read'));
}
public function free_space($path='/'){
return $this->basicOperation('free_space',$path);
}
/**
* abstraction for running most basic operations
* @param string $operation
* @param string #path
* @param array (optional) hooks
* @param mixed (optional) $extraParam
* @return mixed
*/
private function basicOperation($operation,$path,$hooks=array(),$extraParam=null){
if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and OC_Filesystem::isValidPath($path) and $storage=$this->getStorage($path)){
$interalPath=$this->getInternalPath($path);
$run=true;
foreach($hooks as $hook){
if($hook!='read'){
OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
}else{
OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path));
}
}
if($run){
if($extraParam){
$result=$storage->$operation($interalPath,$extraParam);
}else{
$result=$storage->$operation($interalPath);
}
$result=OC_FileProxy::runPostProxies($operation,$path,$result);
foreach($hooks as $hook){
if($hook!='read'){
OC_Hook::emit( OC_Filesystem::CLASSNAME, 'post_'.$hook, array( OC_Filesystem::signal_param_path => $path));
}
}
return $result;
}
}
return null;
}
}

View File

@ -147,6 +147,10 @@ class OC_Image {
return false; return false;
} }
} }
if (!$this->valid()) {
return false;
}
$retval = false; $retval = false;
switch(self::$imagetype) { switch(self::$imagetype) {
case IMAGETYPE_GIF: case IMAGETYPE_GIF:
@ -257,7 +261,7 @@ class OC_Image {
$flip = true; $flip = true;
break; break;
case 8: case 8:
$rotate = 270; $rotate = 90;
$flip = false; $flip = false;
break; break;
} }

View File

@ -2,14 +2,15 @@
class OC_Search_Provider_File extends OC_Search_Provider{ class OC_Search_Provider_File extends OC_Search_Provider{
function search($query){ function search($query){
$files=OC_Filesystem::search($query); $files=OC_FileCache::search($query,true);
$results=array(); $results=array();
foreach($files as $file){ foreach($files as $fileData){
if(OC_Filesystem::is_dir($file)){ $file=$fileData['path'];
if($fileData['mime']=='httpd/unix-directory'){
$results[]=new OC_Search_Result(basename($file),'',OC_Helper::linkTo( 'files', 'index.php?dir='.$file ),'Files'); $results[]=new OC_Search_Result(basename($file),'',OC_Helper::linkTo( 'files', 'index.php?dir='.$file ),'Files');
}else{ }else{
$mime=OC_Filesystem::getMimeType($file); $mime=$fileData['mime'];
$mimeBase=substr($mime,0,strpos($mime,'/')); $mimeBase=$fileData['mimepart'];
switch($mimeBase){ switch($mimeBase){
case 'audio': case 'audio':
break; break;

View File

@ -37,7 +37,7 @@ class OC_Util {
if( $user != "" ){ //if we aren't logged in, there is no use to set up the filesystem if( $user != "" ){ //if we aren't logged in, there is no use to set up the filesystem
//first set up the local "root" storage //first set up the local "root" storage
OC_Filesystem::mount('local',array('datadir'=>$CONFIG_DATADIRECTORY_ROOT),'/'); OC_Filesystem::mount('OC_Filestorage_Local',array('datadir'=>$CONFIG_DATADIRECTORY_ROOT),'/');
OC::$CONFIG_DATADIRECTORY = $CONFIG_DATADIRECTORY_ROOT."/$user/$root"; OC::$CONFIG_DATADIRECTORY = $CONFIG_DATADIRECTORY_ROOT."/$user/$root";
if( !is_dir( OC::$CONFIG_DATADIRECTORY )){ if( !is_dir( OC::$CONFIG_DATADIRECTORY )){
@ -45,7 +45,7 @@ class OC_Util {
} }
//jail the user into his "home" directory //jail the user into his "home" directory
OC_Filesystem::chroot("/$user/$root"); OC_Filesystem::init('/'.$user.'/'.$root);
$quotaProxy=new OC_FileProxy_Quota(); $quotaProxy=new OC_FileProxy_Quota();
OC_FileProxy::register($quotaProxy); OC_FileProxy::register($quotaProxy);
self::$fsSetup=true; self::$fsSetup=true;
@ -62,7 +62,7 @@ class OC_Util {
* @return array * @return array
*/ */
public static function getVersion(){ public static function getVersion(){
return array(3,00,0); return array(3,00,1);
} }
/** /**
@ -110,7 +110,7 @@ class OC_Util {
/** /**
* @brief Add a custom element to the header * @brief Add a custom element to the header
* @param string tag tag name of the element * @param string tag tag name of the element
* @param array $attributes array of attrobutes for the element * @param array $attributes array of attributes for the element
* @param string $text the text content for the element * @param string $text the text content for the element
*/ */
public static function addHeader( $tag, $attributes, $text=''){ public static function addHeader( $tag, $attributes, $text=''){
@ -226,7 +226,7 @@ class OC_Util {
$errors[]=array('error'=>'PHP module ctype is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.'); $errors[]=array('error'=>'PHP module ctype is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.');
} }
if(file_exists(OC::$SERVERROOT."/config/config.php") and !is_writeable(OC::$SERVERROOT."/config/config.php")){ if(file_exists(OC::$SERVERROOT."/config/config.php") and !is_writable(OC::$SERVERROOT."/config/config.php")){
$errors[]=array('error'=>"Can't write into config directory 'config'",'hint'=>"You can usually fix this by giving the webserver use write access to the config directory in owncloud"); $errors[]=array('error'=>"Can't write into config directory 'config'",'hint'=>"You can usually fix this by giving the webserver use write access to the config directory in owncloud");
} }

BIN
owncloud.db.filesystem Normal file

Binary file not shown.

View File

@ -6,10 +6,13 @@ require_once('../../lib/base.php');
OC_JSON::checkAdminUser(); OC_JSON::checkAdminUser();
$username = $_POST["username"]; $username = $_POST["username"];
//make sure the quota is in the expected format
$quota= OC_Helper::computerFileSize($_POST["quota"]); $quota= OC_Helper::computerFileSize($_POST["quota"]);
$quota=OC_Helper::humanFileSize($quota);
// Return Success story // Return Success story
OC_Preferences::setValue($username,'files','quota',$quota); OC_Preferences::setValue($username,'files','quota',$quota);
OC_JSON::success(array("data" => array( "username" => $username ,'quota'=>OC_Helper::humanFileSize($quota)))); OC_JSON::success(array("data" => array( "username" => $username ,'quota'=>$quota)));
?> ?>

View File

@ -16,7 +16,8 @@ OC_Util::addStyle( '3rdparty', 'chosen' );
OC_App::setActiveNavigationEntry( 'personal' ); OC_App::setActiveNavigationEntry( 'personal' );
// calculate the disc space // calculate the disc space
$used=OC_Filesystem::filesize('/'); $rootInfo=OC_FileCache::get('');
$used=$rootInfo['size'];
$free=OC_Filesystem::free_space(); $free=OC_Filesystem::free_space();
$total=$free+$used; $total=$free+$used;
$relative=round(($used/$total)*10000)/100; $relative=round(($used/$total)*10000)/100;

View File

@ -18,7 +18,7 @@ $users = array();
$groups = array(); $groups = array();
foreach( OC_User::getUsers() as $i ){ foreach( OC_User::getUsers() as $i ){
$users[] = array( "name" => $i, "groups" => join( ", ", OC_Group::getUserGroups( $i ) ),'quota'=>OC_Helper::humanFileSize(OC_Preferences::getValue($i,'files','quota',0))); $users[] = array( "name" => $i, "groups" => join( ", ", OC_Group::getUserGroups( $i ) ),'quota'=>OC_Preferences::getValue($i,'files','quota',0));
} }
foreach( OC_Group::getGroups() as $i ){ foreach( OC_Group::getGroups() as $i ){