Merge branch 'master' into migration

This commit is contained in:
Tom Needham 2012-03-31 22:44:50 +00:00
commit f7d8a8c571
64 changed files with 2910 additions and 438 deletions

1954
3rdparty/Archive/Tar.php vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@ ob_start();
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_Util::checkAppEnabled('calendar');
$nl = "\n";
$nl = "\n\r";
$progressfile = OC::$APPSROOT . '/apps/calendar/import_tmp/' . md5(session_id()) . '.txt';
if(is_writable('import_tmp/')){
$progressfopen = fopen($progressfile, 'w');

View file

@ -11,7 +11,7 @@ OC_Util::checkLoggedIn();
OC_Util::checkAppEnabled('calendar');
$cal = isset($_GET['calid']) ? $_GET['calid'] : NULL;
$event = isset($_GET['eventid']) ? $_GET['eventid'] : NULL;
$nl = "\n";
$nl = "\n\r";
if(isset($cal)){
$calendar = OC_Calendar_App::getCalendar($cal);
$calobjects = OC_Calendar_Object::all($cal);

View file

@ -19,6 +19,11 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('contacts','ajax/saveproperty.php: '.$msg, OC_Log::DEBUG);
exit();
}
// Init owncloud
require_once('../../../lib/base.php');
@ -27,7 +32,10 @@ require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$id = $_GET['id'];
$id = isset($_GET['id'])?$_GET['id']:null;
if(!$id) {
bailOut(OC_Contacts_App::$l10n->t('id is not set.'));
}
$card = OC_Contacts_App::getContactObject( $id );
OC_Contacts_VCard::delete($id);

View file

@ -10,8 +10,6 @@
#contacts_propertymenu_button { position:absolute;top:15px;right:150px; background:url('../../../core/img/actions/add.svg') no-repeat center; }
#contacts_propertymenu { background-color: #fff; position:absolute;top:40px;right:150px; overflow:hidden; text-overflow:ellipsis; /*border: thin solid #1d2d44;*/ -moz-box-shadow:0 0 10px #000; -webkit-box-shadow:0 0 10px #000; box-shadow:0 0 10px #000; -moz-border-radius:0.5em; -webkit-border-radius:0.5em; border-radius:0.5em; -moz-border-radius:0.5em; -webkit-border-radius:0.5em; border-radius:0.5em; }
#contacts_propertymenu li { display: block; font-weight: bold; height: 20px; width: 100px; }
/*#contacts_propertymenu li:first-child { border-top: thin solid #1d2d44; -moz-border-radius-topleft:0.5em; -webkit-border-top-left-radius:0.5em; border-top-left-radius:0.5em; -moz-border-radius-topright:0.5em; -webkit-border-top-right-radius:0.5em; border-top-right-radius:0.5em; }
#contacts_propertymenu li:last-child { border-bottom: thin solid #1d2d44; -moz-border-radius-bottomleft:0.5em; -webkit-border-bottom-left-radius:0.5em; border-bottom-left-radius:0.5em; -moz-border-radius-bottomright:0.5em; -webkit-border-bottom-right-radius:0.5em; border-bottom-right-radius:0.5em; }*/
#contacts_propertymenu li a { padding: 3px; display: block }
#contacts_propertymenu li:hover { background-color: #1d2d44; }
#contacts_propertymenu li a:hover { color: #fff }
@ -25,54 +23,12 @@
#card input[type="text"],input[type="email"],input[type="tel"],input[type="date"], select { background-color: #f8f8f8; border: 0 !important; -webkit-appearance:none !important; -moz-appearance:none !important; -webkit-box-sizing:none !important; -moz-box-sizing:none !important; box-sizing:none !important; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; float: left; }
#card input[type="text"]:hover, input[type="text"]:focus, input[type="text"]:active,input[type="email"]:hover,input[type="tel"]:hover,input[type="date"]:hover,input[type="date"],input[type="date"]:hover,input[type="date"]:active,input[type="date"]:active,input[type="date"]:active,input[type="email"]:active,input[type="tel"]:active, select:hover, select:focus, select:active { border: 0 !important; -webkit-appearance:textfield; -moz-appearance:textfield; -webkit-box-sizing:content-box; -moz-box-sizing:content-box; box-sizing:content-box; background:#fff; color:#333; border:1px solid #ddd; -moz-box-shadow:0 1px 1px #fff, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; outline:none; float: left; }
input[type="text"]:invalid,input[type="email"]:invalid,input[type="tel"]:invalid,input[type="date"]:invalid { background-color: #ffc0c0 !important; }
/*input[type="text"]:valid,input[type="email"]:valid,input[type="tel"]:valid,input[type="date"]:valid { background-color: #b1d28f !important; }*/
dl.form
{
width: 100%;
float: left;
clear: right;
margin: 0;
padding: 0;
}
.form dt
{
display: table-cell;
clear: left;
float: left;
width: 7em;
/*overflow: hidden;*/
margin: 0;
padding: 0.8em 0.5em 0 0;
font-weight: bold;
text-align:right;
text-overflow:ellipsis;
o-text-overflow: ellipsis;
vertical-align: text-bottom;
/*
white-space: pre-wrap;
white-space: -moz-pre-wrap !important;
white-space: -pre-wrap;
white-space: -o-pre-wrap;*/
}
.form dd
{
display: table-cell;
clear: right;
float: left;
margin: 0;
padding: 0px;
white-space: nowrap;
vertical-align: text-bottom;
/*min-width: 20em;*/
/*background-color: yellow;*/
}
dl.form { width: 100%; float: left; clear: right; margin: 0; padding: 0; }
.form dt { display: table-cell; clear: left; float: left; width: 7em; margin: 0; padding: 0.8em 0.5em 0 0; font-weight: bold; text-align:right; text-overflow:ellipsis; o-text-overflow: ellipsis; vertical-align: text-bottom;/* white-space: pre-wrap; white-space: -moz-pre-wrap !important; white-space: -pre-wrap; white-space: -o-pre-wrap;*/ }
.form dd { display: table-cell; clear: right; float: left; margin: 0; padding: 0px; white-space: nowrap; vertical-align: text-bottom; }
.loading { background: url('../../../core/img/loading.gif') no-repeat center !important; /*cursor: progress; */ cursor: wait; }
/*.add { cursor: pointer; width: 25px; height: 25px; margin: 0px; float: right; position:relative; content: "\+"; font-weight: bold; color: #666; font-size: large; bottom: 0px; right: 0px; clear: both; text-align: center; vertical-align: bottom; display: none; }*/
.listactions { height: 1em; width:60px; float: left; clear: right; }
.add,.edit,.delete,.mail, .globe { cursor: pointer; width: 20px; height: 20px; margin: 0; float: left; position:relative; display: none; }
.add { background:url('../../../core/img/actions/add.svg') no-repeat center; clear: both; }
@ -82,75 +38,21 @@ dl.form
/*.globe { background:url('../img/globe.svg') no-repeat center; }*/
.globe { background:url('../../../core/img/actions/public.svg') no-repeat center; }
#messagebox_msg { font-weight: bold; font-size: 1.2em; }
/* Name editor */
#edit_name_dialog {
/*width: 25em;*/
padding:0;
}
#edit_name_dialog > input {
width: 15em;
}
/* Address editor */
#edit_address_dialog {
/*width: 30em;*/
}
#edit_address_dialog > input {
width: 15em;
}
#edit_name_dialog { padding:0; }
#edit_name_dialog > input { width: 15em; }
#edit_address_dialog { /*width: 30em;*/ }
#edit_address_dialog > input { width: 15em; }
#edit_photo_dialog_img { display: block; width: 150; height: 200; border: thin solid black; }
#fn { float: left; }
/**
* Create classes form, floateven and floatodd which flows left and right respectively.
*/
.contactsection {
float: left;
min-width: 30em;
max-width: 40em;
margin: 0.5em;
border: thin solid lightgray;
-webkit-border-radius: 0.5em;
-moz-border-radius: 0.5em;
border-radius: 0.5em;
background-color: #f8f8f8;
}
.contactsection { float: left; min-width: 30em; max-width: 40em; margin: 0.5em; border: thin solid lightgray; -webkit-border-radius: 0.5em; -moz-border-radius: 0.5em; border-radius: 0.5em; background-color: #f8f8f8; }
.contactpart legend {
/*background: #fff;
font-weight: bold;
left: 1em;
border: thin solid gray;
-webkit-border-radius: 0.5em;
-moz-border-radius: 0.5em;
border-radius: 0.5em;
padding: 3px;*/
width:auto; padding:.3em; border:1px solid #ddd; font-weight:bold; cursor:pointer; background:#f8f8f8; color:#555; text-shadow:#fff 0 1px 0; -moz-box-shadow:0 1px 1px #fff, 0 1px 1px #fff inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 1px #fff inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em;
}
/*#contacts_details_photo {
cursor: pointer;
z-index:1;
margin: auto;
}
*/
#cropbox {
margin: auto;
}
.contactpart legend { width:auto; padding:.3em; border:1px solid #ddd; font-weight:bold; cursor:pointer; background:#f8f8f8; color:#555; text-shadow:#fff 0 1px 0; -moz-box-shadow:0 1px 1px #fff, 0 1px 1px #fff inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 1px #fff inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; }
#cropbox { margin: auto; }
/* Photo editor */
/*#contacts_details_photo_wrapper {
z-index: 1000;
}*/
#contacts_details_photo {
border-radius: 0.5em;
border: thin solid #bbb;
padding: 0.5em;
margin: 1em 1em 1em 7em;
cursor: pointer;
/*background: #f8f8f8;*/
background: url(../../../core/img/loading.gif) no-repeat center center;
clear: right;
}
#contacts_details_photo { border-radius: 0.5em; border: thin solid #bbb; padding: 0.5em; margin: 1em 1em 1em 7em; cursor: pointer; background: url(../../../core/img/loading.gif) no-repeat center center; clear: right; }
#contacts_details_photo:hover { background: #fff; }
#contacts_details_photo_progress { margin: 0.3em 0.3em 0.3em 7em; clear: left; }
/* Address editor */
@ -168,13 +70,6 @@ dl.addresscard dd > ul { margin: 0.3em; padding: 0.3em; }
#adr_zipcode {}
#adr_country {}
.delimiter {
height: 10px;
clear: both;
}
/*input[type="text"] { float: left; max-width: 15em; }
input[type="radio"] { float: left; -khtml-appearance: none; width: 20px; height: 20px; vertical-align: middle; }*/
#file_upload_target, #crop_target { display:none; }
#file_upload_start { opacity:0; filter:alpha(opacity=0); z-index:1; position:absolute; left:0; top:0; cursor:pointer; width:0; height:0;}

View file

@ -213,19 +213,27 @@ Contacts={
honpre:'',
honsuf:'',
data:undefined,
update:function() {
update:function(id) {
// Make sure proper DOM is loaded.
console.log('Card.update(), #n: ' + $('#n').length);
var newid;
console.log('Card.update(), id: ' + id);
console.log('Card.update(), #contacts: ' + $('#contacts li').length);
if($('#n').length == 0 && $('#contacts li').length > 0) {
if(id == undefined) {
newid = $('#contacts li:first-child').data('id');
} else {
newid = id;
}
if($('#contacts li').length > 0) {
$.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{},function(jsondata){
if(jsondata.status == 'success'){
$('#rightcontent').html(jsondata.data.page);
Contacts.UI.loadHandlers();
if($('#contacts li').length > 0) {
var firstid = $('#contacts li:first-child').data('id');
console.log('trying to load: ' + firstid);
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':firstid},function(jsondata){
//var newid = $('#contacts li:first-child').data('id');
//$('#contacts li:first-child').addClass('active');
$('#leftcontent li[data-id="'+newid+'"]').addClass('active');
console.log('trying to load: ' + newid);
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':newid},function(jsondata){
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data);
} else{
@ -300,35 +308,49 @@ Contacts={
}
});
},
delete: function() {
delete:function() {
$('#contacts_deletecard').tipsy('hide');
$.getJSON('ajax/deletecard.php',{'id':this.id},function(jsondata){
if(jsondata.status == 'success'){
$('#leftcontent [data-id="'+jsondata.data.id+'"]').remove();
$('#rightcontent').data('id','');
//$('#rightcontent').empty();
this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = '';
this.data = undefined;
// Load first in list.
if($('#contacts li').length > 0) {
Contacts.UI.Card.update();
} else {
// load intro page
$.getJSON('ajax/loadintro.php',{},function(jsondata){
if(jsondata.status == 'success'){
id = '';
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page);
OC.dialogs.confirm(t('contacts', 'Are you sure you want to delete this contact?'), t('contacts', 'Warning'), function(answer) {
if(answer == true) {
$.getJSON('ajax/deletecard.php',{'id':Contacts.UI.Card.id},function(jsondata){
if(jsondata.status == 'success'){
var newid = '';
var curlistitem = $('#leftcontent [data-id="'+jsondata.data.id+'"]');
var newlistitem = curlistitem.prev();
console.log('Previous: ' + newlistitem);
if(newlistitem == undefined) {
newlistitem = curlistitem.next();
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
curlistitem.remove();
if(newlistitem != undefined) {
newid = newlistitem.data('id');
}
});
}
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
$('#rightcontent').data('id',newid);
//$('#rightcontent').empty();
this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = '';
this.data = undefined;
// Load first in list.
if($('#contacts li').length > 0) {
Contacts.UI.Card.update(newid);
} else {
// load intro page
$.getJSON('ajax/loadintro.php',{},function(jsondata){
if(jsondata.status == 'success'){
id = '';
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page);
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
}
});
return false;
@ -1232,6 +1254,7 @@ $(document).ready(function(){
*/
$('#leftcontent li').live('click',function(){
var id = $(this).data('id');
$(this).addClass('active');
var oldid = $('#rightcontent').data('id');
if(oldid != 0){
$('#leftcontent li[data-id="'+oldid+'"]').removeClass('active');

View file

@ -56,13 +56,6 @@ $id = isset($_['id']) ? $_['id'] : '';
<dd style="display:none;" class="propertycontainer" id="nickname_value" data-element="NICKNAME"><input id="nickname" required="required" name="value[NICKNAME]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Enter nickname'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dt style="display:none;" id="bday_label" data-element="BDAY"><label for="bday"><?php echo $l->t('Birthday'); ?></label></dt>
<dd style="display:none;" class="propertycontainer" id="bday_value" data-element="BDAY"><input id="bday" required="required" name="value" type="text" class="contacts_property" value="" placeholder="<?php echo $l->t('dd-mm-yyyy'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<!-- dt id="categories_label" data-element="CATEGORIES"><label for="categories"><?php echo $l->t('Categories'); ?></label></dt>
<dd class="propertycontainer" id="categories_value" data-element="CATEGORIES">
<select class="contacts_property" multiple="multiple" id="categories" name="value[]">
<?php echo html_select_options($_['categories'], array(), array('combine'=>true)) ?>
</select>
<a class="action edit" onclick="$(this).tipsy('hide');OCCategories.edit();" title="<?php echo $l->t('Edit categories'); ?>"></a>
</dd -->
<dt style="display:none;" id="categories_label" data-element="CATEGORIES"><label for="categories"><?php echo $l->t('Categories'); ?></label></dt>
<dd style="display:none;" class="propertycontainer" id="categories_value" data-element="CATEGORIES"><input id="categories" required="required" name="value[CATEGORIES]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Categories'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a><a class="action edit" onclick="$(this).tipsy('hide');OCCategories.edit();" title="<?php echo $l->t('Edit categories'); ?>"></a></dd>
</dl>
@ -131,6 +124,7 @@ $(document).ready(function(){
if('<?php echo $id; ?>'!='') {
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':'<?php echo $id; ?>'},function(jsondata){
if(jsondata.status == 'success'){
$('#leftcontent li[data-id="<?php echo $id; ?>"]').addClass('active');
Contacts.UI.Card.loadContact(jsondata.data);
}
else{

View file

@ -7,7 +7,8 @@
*/
OC::$CLASSPATH['OC_Archive'] = 'apps/files_archive/lib/archive.php';
foreach(array('ZIP') as $type){
OC::$CLASSPATH['Archive_Tar'] = '3rdparty/Archive/Tar.php';
foreach(array('ZIP','TAR') as $type){
OC::$CLASSPATH['OC_Archive_'.$type] = 'apps/files_archive/lib/'.strtolower($type).'.php';
}

View file

@ -7,4 +7,7 @@
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
<types>
<filesystem/>
</types>
</info>

View file

@ -11,5 +11,9 @@ $(document).ready(function() {
window.location='index.php?dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
});
FileActions.setDefault('application/zip','Open');
FileActions.register('application/x-gzip','Open','',function(filename){
window.location='index.php?dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
});
FileActions.setDefault('application/x-gzip','Open');
}
});

View file

@ -17,6 +17,15 @@ abstract class OC_Archive{
switch($ext){
case '.zip':
return new OC_Archive_ZIP($path);
case '.gz':
case '.bz':
case '.bz2':
if(strpos($path,'.tar.')){
return new OC_Archive_TAR($path);
}
break;
case '.tgz':
return new OC_Archive_TAR($path);
}
}
@ -77,6 +86,13 @@ abstract class OC_Archive{
* @return bool
*/
abstract function extractFile($path,$dest);
/**
* extract the archive
* @param string path
* @param string dest
* @return bool
*/
abstract function extract($dest);
/**
* check if a file or folder exists in the archive
* @param string path

View file

@ -125,7 +125,7 @@ class OC_Filestorage_Archive extends OC_Filestorage_Common{
self::$rootView=new OC_FilesystemView('');
}
self::$enableAutomount=false;//prevent recursion
$supported=array('zip');
$supported=array('zip','tar.gz','tar.bz2','tgz');
foreach($supported as $type){
$ext='.'.$type.'/';
if(($pos=strpos(strtolower($path),$ext))!==false){
@ -139,4 +139,8 @@ class OC_Filestorage_Archive extends OC_Filestorage_Common{
}
self::$enableAutomount=true;
}
public function rename($path1,$path2){
return $this->archive->rename($path1,$path2);
}
}

View file

@ -0,0 +1,277 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Archive_TAR extends OC_Archive{
const PLAIN=0;
const GZIP=1;
const BZIP=2;
/**
* @var Archive_Tar tar
*/
private $tar=null;
private $path;
function __construct($source){
$types=array(null,'gz','bz');
$this->path=$source;
$this->tar=new Archive_Tar($source,$types[self::getTarType($source)]);
}
/**
* try to detect the type of tar compression
* @param string file
* @return str
*/
static public function getTarType($file){
if(strpos($file,'.')){
$extention=substr($file,strrpos($file,'.'));
switch($extention){
case 'gz':
case 'tgz':
return self::GZIP;
case 'bz':
case 'bz2':
return self::BZIP;
default:
return self::PLAIN;
}
}else{
return self::PLAIN;
}
}
/**
* add an empty folder to the archive
* @param string path
* @return bool
*/
function addFolder($path){
$tmpBase=get_temp_dir().'/';
if(substr($path,-1,1)!='/'){
$path.='/';
}
if($this->fileExists($path)){
return false;
}
mkdir($tmpBase.$path);
$result=$this->tar->addModify(array($tmpBase.$path),'',$tmpBase);
rmdir($tmpBase.$path);
return $result;
}
/**
* add a file to the archive
* @param string path
* @param string source either a local file or string data
* @return bool
*/
function addFile($path,$source=''){
if($this->fileExists($path)){
$this->remove($path);
}
if(file_exists($source)){
$header=array();
$dummy='';
$this->tar->_openAppend();
$result=$this->tar->_addfile($source,$header,$dummy,$dummy,$path);
}else{
$result=$this->tar->addString($path,$source);
}
return $result;
}
/**
* rename a file or folder in the archive
* @param string source
* @param string dest
* @return bool
*/
function rename($source,$dest){
//no proper way to delete, rename entire archive, rename file and remake archive
$tmp=OC_Helper::tmpFolder();
$this->tar->extract($tmp);
rename($tmp.$source,$tmp.$dest);
$this->tar=null;
unlink($this->path);
$types=array(null,'gz','bz');
$this->tar=new Archive_Tar($this->path,$types[self::getTarType($this->path)]);
$this->tar->createModify(array($tmp),'',$tmp.'/');
}
private function getHeader($file){
$headers=$this->tar->listContent();
foreach($headers as $header){
if($file==$header['filename'] or $file.'/'==$header['filename']){
return $header;
}
}
return null;
}
/**
* get the uncompressed size of a file in the archive
* @param string path
* @return int
*/
function filesize($path){
$stat=$this->getHeader($path);
return $stat['size'];
}
/**
* get the last modified time of a file in the archive
* @param string path
* @return int
*/
function mtime($path){
$stat=$this->getHeader($path);
return $stat['mtime'];
}
/**
* get the files in a folder
* @param path
* @return array
*/
function getFolder($path){
$files=$this->getFiles();
$folderContent=array();
$pathLength=strlen($path);
foreach($files as $file){
if(substr($file,0,$pathLength)==$path and $file!=$path){
if(strrpos(substr($file,0,-1),'/')<=$pathLength){
$folderContent[]=substr($file,$pathLength);
}
}
}
return $folderContent;
}
/**
*get all files in the archive
* @return array
*/
function getFiles(){
$headers=$this->tar->listContent();
$files=array();
foreach($headers as $header){
$files[]=$header['filename'];
}
return $files;
}
/**
* get the content of a file
* @param string path
* @return string
*/
function getFile($path){
return $this->tar->extractInString($path);
}
/**
* extract a single file from the archive
* @param string path
* @param string dest
* @return bool
*/
function extractFile($path,$dest){
$tmp=OC_Helper::tmpFolder();
if(!$this->fileExists($path)){
return false;
}
$success=$this->tar->extractList(array($path),$tmp);
if($success){
rename($tmp.$path,$dest);
}
OC_Helper::rmdirr($tmp);
return $success;
}
/**
* extract the archive
* @param string path
* @param string dest
* @return bool
*/
function extract($dest){
return $this->tar->extract($dest);
}
/**
* check if a file or folder exists in the archive
* @param string path
* @return bool
*/
function fileExists($path){
return $this->getHeader($path)!==null;
}
/**
* remove a file or folder from the archive
* @param string path
* @return bool
*/
function remove($path){
if(!$this->fileExists($path)){
return false;
}
//no proper way to delete, extract entire archive, delete file and remake archive
$tmp=OC_Helper::tmpFolder();
$this->tar->extract($tmp);
OC_Helper::rmdirr($tmp.$path);
$this->tar=null;
unlink($this->path);
$this->reopen();
$this->tar->createModify(array($tmp),'',$tmp);
return true;
}
/**
* get a file handler
* @param string path
* @param string mode
* @return resource
*/
function getStream($path,$mode){
if(strrpos($path,'.')!==false){
$ext=substr($path,strrpos($path,'.'));
}else{
$ext='';
}
$tmpFile=OC_Helper::tmpFile($ext);
if($this->fileExists($path)){
$this->extractFile($path,$tmpFile);
}elseif($mode=='r' or $mode=='rb'){
return false;
}
if($mode=='r' or $mode=='rb'){
return fopen($tmpFile,$mode);
}else{
OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
self::$tempFiles[$tmpFile]=$path;
return fopen('close://'.$tmpFile,$mode);
}
}
private static $tempFiles=array();
/**
* write back temporary files
*/
function writeBack($tmpFile){
if(isset(self::$tempFiles[$tmpFile])){
$this->addFile(self::$tempFiles[$tmpFile],$tmpFile);
unlink($tmpFile);
}
}
/**
* reopen the archive to ensure everything is written
*/
private function reopen(){
if($this->tar){
$this->tar->_close();
$this->tar=null;
}
$types=array(null,'gz','bz');
$this->tar=new Archive_Tar($this->path,$types[self::getTarType($this->path)]);
}
}

View file

@ -11,7 +11,6 @@ class OC_Archive_ZIP extends OC_Archive{
* @var ZipArchive zip
*/
private $zip=null;
private $contents=array();
private $success=false;
private $path;
@ -56,7 +55,9 @@ class OC_Archive_ZIP extends OC_Archive{
* @return bool
*/
function rename($source,$dest){
return $this->zip->renameName($source,$dest);
$source=$this->stripPath($source);
$dest=$this->stripPath($dest);
$this->zip->renameName($source,$dest);
}
/**
* get the uncompressed size of a file in the archive
@ -99,15 +100,11 @@ class OC_Archive_ZIP extends OC_Archive{
* @return array
*/
function getFiles(){
if(count($this->contents)){
return $this->contents;
}
$fileCount=$this->zip->numFiles;
$files=array();
for($i=0;$i<$fileCount;$i++){
$files[]=$this->zip->getNameIndex($i);
}
$this->contents=$files;
return $files;
}
/**
@ -128,13 +125,22 @@ class OC_Archive_ZIP extends OC_Archive{
$fp = $this->zip->getStream($path);
file_put_contents($dest,$fp);
}
/**
* extract the archive
* @param string path
* @param string dest
* @return bool
*/
function extract($dest){
return $this->zip->extractTo($dest);
}
/**
* check if a file or folder exists in the archive
* @param string path
* @return bool
*/
function fileExists($path){
return $this->zip->locateName($path)!==false;
return ($this->zip->locateName($path)!==false) or ($this->zip->locateName($path.'/')!==false);
}
/**
* remove a file or folder from the archive
@ -142,7 +148,11 @@ class OC_Archive_ZIP extends OC_Archive{
* @return bool
*/
function remove($path){
return $this->zip->deleteName($path);
if($this->fileExists($path.'/')){
return $this->zip->deleteName($path.'/');
}else{
return $this->zip->deleteName($path);
}
}
/**
* get a file handler
@ -179,4 +189,12 @@ class OC_Archive_ZIP extends OC_Archive{
unlink($tmpFile);
}
}
private function stripPath($path){
if(substr($path,0,1)=='/'){
return substr($path,1);
}else{
return $path;
}
}
}

View file

@ -27,10 +27,10 @@ abstract class Test_Archive extends UnitTestCase {
$this->instance=$this->getExisting();
$allFiles=$this->instance->getFiles();
$expected=array('lorem.txt','logo-wide.png','dir/','dir/lorem.txt');
$this->assertEqual(4,count($allFiles));
$this->assertEqual(4,count($allFiles),'only found '.count($allFiles).' out of 4 expected files');
foreach($expected as $file){
$this->assertNotIdentical(false,array_search($file,$allFiles),'cant find '.$file.' in archive');
$this->assertTrue($this->instance->fileExists($file));
$this->assertTrue($this->instance->fileExists($file),'file '.$file.' does not exist in archive');
}
$this->assertFalse($this->instance->fileExists('non/existing/file'));
@ -68,6 +68,7 @@ abstract class Test_Archive extends UnitTestCase {
$this->instance->addFile('lorem.txt',$textFile);
$this->assertEqual(1,count($this->instance->getFiles()));
$this->assertTrue($this->instance->fileExists('lorem.txt'));
$this->assertFalse($this->instance->fileExists('lorem.txt/'));
$this->assertEqual(file_get_contents($textFile),$this->instance->getFile('lorem.txt'));
$this->instance->addFile('lorem.txt','foobar');
@ -94,4 +95,39 @@ abstract class Test_Archive extends UnitTestCase {
$this->assertTrue($this->instance->fileExists('lorem.txt'));
$this->assertEqual(file_get_contents($dir.'/lorem.txt'),$this->instance->getFile('lorem.txt'));
}
public function testFolder(){
$this->instance=$this->getNew();
$this->assertFalse($this->instance->fileExists('/test'));
$this->assertFalse($this->instance->fileExists('/test/'));
$this->instance->addFolder('/test');
$this->assertTrue($this->instance->fileExists('/test'));
$this->assertTrue($this->instance->fileExists('/test/'));
$this->instance->remove('/test');
$this->assertFalse($this->instance->fileExists('/test'));
$this->assertFalse($this->instance->fileExists('/test/'));
}
public function testExtract(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$this->instance=$this->getExisting();
$tmpDir=OC_Helper::tmpFolder();
$this->instance->extract($tmpDir);
$this->assertEqual(true,file_exists($tmpDir.'lorem.txt'));
$this->assertEqual(true,file_exists($tmpDir.'dir/lorem.txt'));
$this->assertEqual(true,file_exists($tmpDir.'logo-wide.png'));
$this->assertEqual(file_get_contents($dir.'/lorem.txt'),file_get_contents($tmpDir.'lorem.txt'));
OC_Helper::rmdirr($tmpDir);
}
public function testMoveRemove(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$textFile=$dir.'/lorem.txt';
$this->instance=$this->getNew();
$this->instance->addFile('lorem.txt',$textFile);
$this->assertFalse($this->instance->fileExists('target.txt'));
$this->instance->rename('lorem.txt','target.txt');
$this->assertTrue($this->instance->fileExists('target.txt'));
$this->assertFalse($this->instance->fileExists('lorem.txt'));
$this->assertEqual(file_get_contents($textFile),$this->instance->getFile('target.txt'));
$this->instance->remove('target.txt');
$this->assertFalse($this->instance->fileExists('target.txt'));
}
}

View file

@ -0,0 +1,20 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('archive.php');
class Test_Archive_TAR extends Test_Archive{
protected function getExisting(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
return new OC_Archive_TAR($dir.'/data.tar.gz');
}
protected function getNew(){
return new OC_Archive_TAR(OC_Helper::tmpFile('.tar.gz'));
}
}

View file

@ -7,4 +7,7 @@
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
<types>
<filesystem/>
</types>
</info>

View file

@ -0,0 +1,11 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php';
OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_external/lib/webdav.php';
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php';

View file

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<info>
<id>files_external</id>
<name>External storage support</name>
<description>Mount external storage sources</description>
<version>0.1</version>
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
<types>
<filesystem/>
</types>
</info>

View file

@ -12,7 +12,7 @@ class Test_Filestorage_FTP extends Test_FileStorage {
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config=include('apps/files_external/tests/config.php');
$this->config['ftp']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_FTP($this->config['ftp']);
}

View file

@ -27,7 +27,7 @@ class Test_Filestorage_Google extends Test_FileStorage {
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config=include('apps/files_external/tests/config.php');
$this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_Google($this->config['google']);
}
@ -35,4 +35,4 @@ class Test_Filestorage_Google extends Test_FileStorage {
public function tearDown(){
$this->instance->rmdir('/');
}
}
}

View file

@ -12,7 +12,7 @@ class Test_Filestorage_DAV extends Test_FileStorage {
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config=include('apps/files_external/tests/config.php');
$this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_DAV($this->config['webdav']);
}

View file

@ -1,11 +0,0 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_remote/lib/ftp.php';
OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_remote/lib/webdav.php';
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_remote/lib/google.php';

View file

@ -1,10 +0,0 @@
<?xml version="1.0"?>
<info>
<id>files_remote</id>
<name>Remote storage support</name>
<description>Mount remote storage sources</description>
<version>0.1</version>
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
</info>

View file

@ -7,21 +7,23 @@ OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('files_sharing');
$users = array();
$ocusers = OC_User::getUsers();
$groups = array();
$self = OC_User::getUser();
$groups = OC_Group::getUserGroups($self);
$userGroups = OC_Group::getUserGroups($self);
$users[] = "<optgroup label='Users'>";
foreach ($ocusers as $user) {
if ($user != $self) {
$users[] = "<option value='".$user."'>".$user."</option>";
$groups[] = "<optgroup label='Groups'>";
foreach ($userGroups as $group) {
$groupUsers = OC_Group::usersInGroup($group);
foreach ($groupUsers as $user) {
if ($user != $self) {
$users[] = "<option value='".$user."'>".$user."</option>";
}
}
$groups[] = "<option value='".$group."'>".$group."</option>";
}
$users[] = "</optgroup>";
$users[] = "<optgroup label='Groups'>";
foreach ($groups as $group) {
$users[] = "<option value='".$group."'>".$group."</option>";
}
$users[] = "</optgroup>";
$groups[] = "</optgroup>";
$users = array_merge($users, $groups);
OC_JSON::encodedPrint($users);
?>

View file

@ -8,4 +8,7 @@
<author>Michael Gapczynski</author>
<require>2</require>
<default_enable/>
<types>
<filesystem/>
</types>
</info>

View file

@ -52,8 +52,18 @@ class OC_Share {
// Remove the owner from the list of users in the group
$uid_shared_with = array_diff($uid_shared_with, array($uid_owner));
} else if (OC_User::userExists($uid_shared_with)) {
$gid = null;
$uid_shared_with = array($uid_shared_with);
$userGroups = OC_Group::getUserGroups($uid_owner);
// Check if the user is in one of the owner's groups
foreach ($userGroups as $group) {
if ($inGroup = OC_Group::inGroup($uid_shared_with, $group)) {
$gid = null;
$uid_shared_with = array($uid_shared_with);
break;
}
}
if (!$inGroup) {
throw new Exception("You can't share with ".$uid_shared_with);
}
} else {
throw new Exception($uid_shared_with." is not a user");
}

View file

@ -127,6 +127,9 @@ function handleGetGallery($path) {
function handleShare($path, $share, $recursive) {
$recursive = $recursive == 'true' ? 1 : 0;
$owner = OC_User::getUser();
$root = OC_Preferences::getValue(OC_User::getUser(),'gallery', 'root', '/');
$path = utf8_decode(rtrim($root.$path,'/'));
if($path == '') $path = '/';
$r = OC_Gallery_Album::find($owner, null, $path);
if ($row = $r->fetchRow()) {
$albumId = $row['album_id'];

View file

@ -32,14 +32,14 @@ $l = new OC_L10N('gallery');
OC_App::register(array(
'order' => 20,
'id' => 'gallery',
'name' => 'Gallery'));
'name' => 'Pictures'));
OC_App::addNavigationEntry( array(
'id' => 'gallery_index',
'order' => 20,
'href' => OC_Helper::linkTo('gallery', 'index.php'),
'icon' => OC_Helper::imagePath('core', 'places/picture.svg'),
'name' => $l->t('Gallery')));
'name' => $l->t('Pictures')));
class OC_GallerySearchProvider implements OC_Search_Provider{
static function search($query){

View file

@ -1,11 +1,11 @@
<?xml version="1.0"?>
<info>
<id>gallery</id>
<name>Gallery</name>
<name>Pictures</name>
<version>0.4</version>
<licence>AGPL</licence>
<author>Bartek Przybylski</author>
<require>2</require>
<description>Gallery application for ownCloud</description>
<description>Dedicated pictures application</description>
<default_enable/>
</info>

View file

@ -43,8 +43,9 @@ function shareGallery() {
{text: 'Shared gallery address', name: 'address', type: 'text', value: existing_token}];
OC.dialogs.form(form_fields, t('gallery', 'Share gallery'), function(values){
var p = '';
for (var i in paths) p += '/'+paths[i];
for (var i in paths) p += paths[i]+'/';
if (p == '') p = '/';
alert(p);
$.getJSON(OC.filePath('gallery', 'ajax', 'galleryOp.php'), {operation: 'share', path: p, share: values[0].value, recursive: values[1].value}, function(r) {
if (r.status == 'success') {
Albums.shared = r.sharing;
@ -112,42 +113,28 @@ function scanForAlbums(cleanup) {
}
function settings() {
$( '#g-dialog-settings' ).dialog({
height: 180,
width: 350,
modal: false,
buttons: [
{
text: t('gallery', 'Apply'),
click: function() {
var scanning_root = $('#g-scanning-root').val();
var disp_order = $('#g-display-order option:selected').val();
OC.dialogs.form([{text: t('gallery', 'Scanning root'), name: 'root', type:'text', value:gallery_scanning_root},
{text: t('gallery', 'Default order'), name: 'order', type:'select', value:gallery_default_order, options:[
{text:t('gallery', 'Ascending'), value:'ASC'}, {text: t('gallery', 'Descending'), value:'DESC'} ]}],
t('gallery', 'Settings'),
function(values) {
var scanning_root = values[0].value;
var disp_order = values[1].value;
if (scanning_root == '') {
alert('Scanning root cannot be empty');
OC.dialogs.alert(t('gallery', 'Scanning root cannot be empty'), t('gallery', 'Error'));
return;
}
$.getJSON(OC.filePath('gallery','ajax','galleryOp.php'), {operation: 'store_settings', root: scanning_root, order: disp_order}, function(r) {
if (r.status == 'success') {
if (r.rescan == 'yes') {
$('#g-dialog-settings').dialog('close');
Albums.clear(document.getElementById('gallery_list'));
scanForAlbums(true);
return;
}
if (r.rescan == 'yes') {
Albums.clear(document.getElementById('gallery_list'));
scanForAlbums(true);
}
gallery_scanning_root = scanning_root;
} else {
alert('Error: ' + r.cause);
return;
OC.dialogs.alert(t('gallery', 'Error: ') + r.cause, t('gallery', 'Error'));
return;
}
$('#g-dialog-settings').dialog('close');
});
}
},
{
text: t('gallery', 'Cancel'),
click: function() {
$(this).dialog('close');
}
}
],
});
});
}

View file

@ -9,7 +9,7 @@ OC_Util::addScript('files_imageviewer', 'jquery.fancybox-1.3.4.pack');
OC_Util::addStyle( 'files_imageviewer', 'jquery.fancybox-1.3.4' );
$l = new OC_L10N('gallery');
?>
<script type="text/javascript">var gallery_scanning_root='<? echo OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'root', '/'); ?>'; var gallery_default_order = '<? echo OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'order', 'ASC'); ?>';</script>
<div id="controls">
<div id="scan">
<div id="scanprogressbar"></div>
@ -29,40 +29,3 @@ $l = new OC_L10N('gallery');
</div>
<div id="gallery_list">
</div>
<div id="dialog-confirm" title="<?php echo $l->t('Remove confirmation');?>" style="display: none">
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span><?php echo $l->t('Do you want to remove album');?> <span id="albumName"></span>?</p>
</div>
<div id="dialog-form" title="<?php echo $l->t('Change album name');?>" style="display:none">
<form>
<fieldset>
<label for="name"><?php echo $l->t('New album name');?></label>
<input type="text" name="name" id="name" class="text ui-widget-content ui-corner-all" />
</fieldset>
</form>
</div>
<div id="g-dialog-settings" title="<?php echo $l->t('Settings');?>" style="display:none">
<form>
<fieldset><?php $root = OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'root', '/'); $order = OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'order', 'ASC');?>
<label for="name"><?php echo $l->t('Scanning root');?></label>
<input type="text" name="g-scanning-root" id="g-scanning-root" class="text ui-widget-content ui-corner-all" value="<?php echo $root;?>" /><br/>
<label for="sort"><?php echo $l->t('Default sorting'); ?></label>
<select id="g-display-order">
<option value="ASC"<?php echo $order=='ASC'?'selected':'';?>><?php echo $l->t('Ascending'); ?></option>
<option value="DESC"<?php echo $order=='DESC'?'selected':'';?>><?php echo $l->t('Descending'); ?></option>
</select><br/>
<!--
<label for="sort"><?php echo $l->t('Thumbnails size'); ?></label>
<select>
<option value="100">100px</option>
<option value="150">150px</option>
<option value="200">200px</option>
</select>
-->
</fieldset>
</form>
</div>

View file

@ -22,6 +22,7 @@ div.jp-volume-bar-value { background:#ccc; width:0; height:0.4em; }
#leftcontent img.remove { display:none; float:right; cursor:pointer; opacity: 0; }
#leftcontent li:hover img.remove { display:inline; opacity: .3; }
#leftcontent li div.label { float: left; width: 200px; overflow: hidden; text-overflow: ellipsis; }
#rightcontent { overflow: auto; }
#playlist li { list-style-type:none; }
.template { display:none; }
.collection_playing { background:#eee; font-weight: bold; }

View file

@ -2,7 +2,7 @@
<info>
<id>remoteStorage</id>
<name>remoteStorage compatibility</name>
<description>Enables your users to use ownCloud as their remote storage for unhosted applications.</description>
<description>Enables you to use ownCloud as their remote storage for unhosted applications. This app requires the Webfinger app to be enabled as well. More info on <a href="http://unhosted.org">the website of the unhosted movement</a>.</description>
<version>0.5</version>
<licence>AGPL or MIT</licence>
<author>Michiel de Jong</author>

View file

@ -33,8 +33,12 @@
*/
OC.EventSource=function(src,data){
var dataStr='';
for(name in data){
dataStr+=name+'='+encodeURIComponent(data[name])+'&';
this.typelessListeners=[];
this.listeners={};
if(data){
for(name in data){
dataStr+=name+'='+encodeURIComponent(data[name])+'&';
}
}
if(!this.useFallBack && typeof EventSource !='undefined'){
this.source=new EventSource(src+'?'+dataStr);
@ -42,7 +46,7 @@ OC.EventSource=function(src,data){
for(var i=0;i<this.typelessListeners.length;i++){
this.typelessListeners[i](JSON.parse(e.data));
}
}
}.bind(this);
}else{
iframeId='oc_eventsource_iframe_'+OC.EventSource.iframeCount;
OC.EventSource.fallBackSources[OC.EventSource.iframeCount]=this;
@ -64,7 +68,7 @@ OC.EventSource=function(src,data){
OC.EventSource.fallBackSources=[];
OC.EventSource.iframeCount=0;//number of fallback iframes
OC.EventSource.fallBackCallBack=function(id,type,data){
OC.EventSource.fallBackSources[id].fallBackCallBack(type,JSON.parse(data));
OC.EventSource.fallBackSources[id].fallBackCallBack(type,data);
}
OC.EventSource.prototype={
typelessListeners:[],

View file

@ -84,10 +84,18 @@ OCdialogs = {
} else content += '>';
} else if (type == 'text' || type == 'password' && fields[a].value)
content += ' value="'+fields[a].value+'">';
} else if (type == 'select') {
content += '<select name="'+fields[a].name+'"';
if (fields[a].value != undefined)
content += ' value="'+fields[a].value+'"';
content += '>';
for (var o in fields[a].options)
content += '<option value="'+fields[a].options[o].value+'">'+fields[a].options[o].text+'</option>';
content += '</select>';
}
content += "</td></tr>"
content += '</td></tr>';
}
content += "</table>";
content += '</table>';
OCdialogs.message(content, title, OCdialogs.FORM_DIALOG, OCdialogs.OK_CANCEL_BUTTONS, callback);
},
message:function(content, title, dialog_type, buttons, callback) {
@ -107,7 +115,7 @@ OCdialogs = {
var f;
switch(dialog_type) {
case OCdialogs.ALERT_DIALOG:
f = function(){$(c_id).dialog('close'); };
f = function(){$(c_id).dialog('close'); callback();};
break;
case OCdialogs.PROMPT_DIALOG:
f = function(){OCdialogs.prompt_ok_handler(callback, c_id)};
@ -144,7 +152,7 @@ OCdialogs = {
if (callback != undefined) {
var r = [];
var c = 0;
$(c_id + ' input').each(function(i, elem) {
$(c_id + ' input, '+c_id+' select').each(function(i, elem) {
r[c] = {name: $(elem).attr('name'), value: OCdialogs.determineValue(elem)};
c++;
});

View file

@ -1,3 +1,4 @@
<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}</style><![endif]-->
<form action="index.php" method="post">
<fieldset>
<?php if(!empty($_['redirect'])) { echo '<input type="hidden" name="redirect_url" value="'.$_['redirect'].'" />'; } ?>

View file

@ -64,6 +64,14 @@
<length>512</length>
</field>
<field>
<name>path_hash</name>
<type>text</type>
<default></default>
<notnull>true</notnull>
<length>32</length>
</field>
<field>
<name>parent</name>
<type>integer</type>
@ -79,7 +87,7 @@
<default>
</default>
<notnull>true</notnull>
<length>512</length>
<length>300</length>
</field>
<field>
@ -159,14 +167,13 @@
<length>1</length>
</field>
<!--<index>
<name>fscache_path_index</name>
<unique>true</unique>
<index>
<name>fscache_path_hash_index</name>
<field>
<name>path</name>
<name>path_hash</name>
<sorting>ascending</sorting>
</field>
</index>-->
</index>
<index>
<name>parent_index</name>
@ -176,6 +183,14 @@
</field>
</index>
<index>
<name>name_index</name>
<field>
<name>name</name>
<sorting>ascending</sorting>
</field>
</index>
<index>
<name>parent_name_index</name>
<field>

View file

@ -21,6 +21,9 @@
*
*/
// only need filesystem apps
$RUNTIME_APPTYPES=array('filesystem');
// Init owncloud
require_once('../../lib/base.php');

View file

@ -1,5 +1,8 @@
<?php
// only need filesystem apps
$RUNTIME_APPTYPES=array('filesystem');
// Init owncloud
require_once('../../lib/base.php');

View file

@ -1,5 +1,8 @@
<?php
// no need for apps
$RUNTIME_NOAPPS=false;
// Init owncloud
require_once('../../lib/base.php');

View file

@ -17,6 +17,7 @@ if($force or !OC_FileCache::inCache('')){
if(!$checkOnly){
OC_DB::beginTransaction();
OC_FileCache::scan('',$eventSource);
OC_FileCache::clean();
OC_DB::commit();
$eventSource->send('success',true);
}else{

View file

@ -64,8 +64,8 @@ table td.filename .nametext { width:60%; }
table td.filename form { float:left; font-size:.85em; }
table thead.fixed tr{ position:fixed; top:6.5em; z-index:49; -moz-box-shadow:0 -3px 7px #ddd; -webkit-box-shadow:0 -3px 7px #ddd; box-shadow:0 -3px 7px #ddd; }
table thead.fixed { height:2em; }
#fileList tr td.filename>input[type=checkbox]:first-child { opacity:0; float:left; margin:.7em 0 0 1em; /* bigger clickable area doesnt work in FF width:2.8em; height:2.4em;*/ -webkit-transition:opacity 500ms; -moz-transition:opacity 500ms; -o-transition:opacity 500ms; transition:opacity 500ms; }
#fileList tr td.filename>input[type="checkbox"]:hover:first-child { opacity:.8; }
#fileList tr td.filename>input[type=checkbox]:first-child { opacity:0; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; float:left; margin:.7em 0 0 1em; /* bigger clickable area doesnt work in FF width:2.8em; height:2.4em;*/ -webkit-transition:opacity 500ms; -moz-transition:opacity 500ms; -o-transition:opacity 500ms; transition:opacity 500ms; }
#fileList tr td.filename>input[type="checkbox"]:hover:first-child { opacity:.8; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; }
#fileList tr td.filename>input[type="checkbox"]:checked:first-child { opacity:1; }
#fileList tr td.filename { -webkit-transition:background-image 500ms; -moz-transition:background-image 500ms; -o-transition:background-image 500ms; transition:background-image 500ms; }
#select_all { float:left; margin:.3em 0.6em 0 .5em; }

View file

@ -98,7 +98,7 @@ $(document).ready(function() {
procesSelection();
});
$('td.filename input:checkbox').live('click',function(event) {
$('td.filename input:checkbox').live('change',function(event) {
if (event.shiftKey) {
var last = $(lastChecked).parent().parent().prevAll().length;
var first = $(this).parent().parent().prevAll().length;

View file

@ -1,3 +1,4 @@
<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}table td{position:static !important;}</style><![endif]-->
<div id="controls">
<?php echo($_['breadcrumb']); ?>
<?php if (!isset($_['readonly']) || !$_['readonly']):?>
@ -62,12 +63,12 @@
</div>
<div id="scanning-message">
<h3>
<?php echo $l->t('Files are being scanned, please wait.');?> <span id='scan-count'></spann>
<?php echo $l->t('Files are being scanned, please wait.');?> <span id='scan-count'></span>
</h3>
<p>
<?php echo $l->t('Current scanning');?> <span id='scan-current'></spann>
<?php echo $l->t('Current scanning');?> <span id='scan-current'></span>
</p>
</div>
<!-- config hints for javascript -->
<input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php echo $_['allowZipDownload']; ?>" />
<input type="hidden" name="allowZipDownload" id="allowZipDownload" value="<?php echo $_['allowZipDownload']; ?>" />

View file

@ -26,6 +26,9 @@
// Do not load FS ...
$RUNTIME_NOSETUPFS = true;
// only need filesystem apps
$RUNTIME_APPTYPES=array('filesystem');
require_once('../lib/base.php');
// Backends

View file

@ -34,16 +34,20 @@ class OC_App{
static private $settingsForms = array();
static private $adminForms = array();
static private $personalForms = array();
static private $appInfo = array();
/**
* @brief loads all apps
* @param array $types
* @returns true/false
*
* This function walks through the owncloud directory and loads all apps
* it can find. A directory contains an app if the file /appinfo/app.php
* exists.
*
* if $types is set, only apps of those types will be loaded
*/
public static function loadApps(){
public static function loadApps($types=null){
// Did we allready load everything?
if( self::$init ){
return true;
@ -51,13 +55,15 @@ class OC_App{
// Our very own core apps are hardcoded
foreach( array('files', 'settings') as $app ){
require( $app.'/appinfo/app.php' );
if(is_null($types) or self::isType($app,$types)){
require( $app.'/appinfo/app.php' );
}
}
// The rest comes here
$apps = OC_Appconfig::getApps();
$apps = self::getEnabledApps();
foreach( $apps as $app ){
if( self::isEnabled( $app )){
if(is_null($types) or self::isType($app,$types)){
if(is_file(OC::$APPSROOT.'/apps/'.$app.'/appinfo/app.php')){
require( $app.'/appinfo/app.php' );
}
@ -70,6 +76,41 @@ class OC_App{
return true;
}
/**
* check if an app is of a sepcific type
* @param string $app
* @param string/array $types
*/
public static function isType($app,$types){
if(is_string($types)){
$types=array($types);
}
$appData=self::getAppInfo($app);
if(!isset($appData['types'])){
return false;
}
$appTypes=$appData['types'];
foreach($types as $type){
if(array_search($type,$appTypes)!==false){
return true;
}
}
return false;
}
/**
* get all enabled apps
*/
public static function getEnabledApps(){
$apps=array();
$query = OC_DB::prepare( 'SELECT appid FROM *PREFIX*appconfig WHERE configkey = "enabled" AND configvalue="yes"' );
$query->execute();
while($row=$query->fetchRow()){
$apps[]=$row['appid'];
}
return $apps;
}
/**
* @brief checks whether or not an app is enabled
* @param $app app
@ -265,24 +306,36 @@ class OC_App{
/**
* @brief Read app metadata from the info.xml file
* @param string $appid id of the app or the path of the info.xml file
* @param boolean path (optional)
* @returns array
*/
public static function getAppInfo($appid){
if(is_file($appid)){
public static function getAppInfo($appid,$path=false){
if($path){
$file=$appid;
}else{
$file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/info.xml';
if(!is_file($file)){
return array();
if(isset(self::$appInfo[$appid])){
return self::$appInfo[$appid];
}
$file=OC::$APPSROOT.'/apps/'.$appid.'/appinfo/info.xml';
}
$data=array();
$content=file_get_contents($file);
if(!$content){
return;
}
$xml = new SimpleXMLElement($content);
$data['info']=array();
foreach($xml->children() as $child){
$data[$child->getName()]=(string)$child;
if($child->getName()=='types'){
$data['types']=array();
foreach($child->children() as $type){
$data['types'][]=$type->getName();
}
}else{
$data[$child->getName()]=(string)$child;
}
}
self::$appInfo[$appid]=$data;
return $data;
}
@ -381,9 +434,8 @@ class OC_App{
*/
public static function updateApps(){
// The rest comes here
$apps = OC_Appconfig::getApps();
foreach( $apps as $app ){
$installedVersion=OC_Appconfig::getValue($app,'installed_version');
$versions = self::getAppVersions();
foreach( $versions as $app=>$installedVersion ){
$appInfo=OC_App::getAppInfo($app);
if (isset($appInfo['version'])) {
$currentVersion=$appInfo['version'];
@ -395,6 +447,19 @@ class OC_App{
}
}
/**
* get the installed version of all papps
*/
public static function getAppVersions(){
$versions=array();
$query = OC_DB::prepare( 'SELECT appid, configvalue FROM *PREFIX*appconfig WHERE configkey = "installed_version"' );
$result = $query->execute();
while($row = $result->fetchRow()){
$versions[$row['appid']]=$row['configvalue'];
}
return $versions;
}
/**
* update the database for the app and call the update script
* @param string appid

View file

@ -229,6 +229,39 @@ class OC{
}
}
public static function initTemplateEngine() {
// if the formfactor is not yet autodetected do the autodetection now. For possible forfactors check the detectFormfactor documentation
if(!isset($_SESSION['formfactor'])){
$_SESSION['formfactor']=OC::detectFormfactor();
}
// allow manual override via GET parameter
if(isset($_GET['formfactor'])){
$_SESSION['formfactor']=$_GET['formfactor'];
}
// Add the stuff we need always
OC_Util::addScript( "jquery-1.6.4.min" );
OC_Util::addScript( "jquery-ui-1.8.16.custom.min" );
OC_Util::addScript( "jquery-showpassword" );
OC_Util::addScript( "jquery.infieldlabel.min" );
OC_Util::addScript( "jquery-tipsy" );
OC_Util::addScript( "oc-dialogs" );
OC_Util::addScript( "js" );
OC_Util::addScript( "eventsource" );
OC_Util::addScript( "config" );
//OC_Util::addScript( "multiselect" );
OC_Util::addScript('search','result');
OC_Util::addStyle( "styles" );
OC_Util::addStyle( "multiselect" );
OC_Util::addStyle( "jquery-ui-1.8.16.custom" );
OC_Util::addStyle( "jquery-tipsy" );
}
public static function initSession() {
ini_set('session.cookie_httponly','1;');
session_start();
}
public static function init(){
// register autoloader
spl_autoload_register(array('OC','autoload'));
@ -270,38 +303,11 @@ class OC{
self::checkInstalled();
self::checkSSL();
self::initSession();
self::initTemplateEngine();
self::checkUpgrade();
ini_set('session.cookie_httponly','1;');
session_start();
// if the formfactor is not yet autodetected do the autodetection now. For possible forfactors check the detectFormfactor documentation
if(!isset($_SESSION['formfactor'])){
$_SESSION['formfactor']=OC::detectFormfactor();
}
// allow manual override via GET parameter
if(isset($_GET['formfactor'])){
$_SESSION['formfactor']=$_GET['formfactor'];
}
// Add the stuff we need always
OC_Util::addScript( "jquery-1.6.4.min" );
OC_Util::addScript( "jquery-ui-1.8.16.custom.min" );
OC_Util::addScript( "jquery-showpassword" );
OC_Util::addScript( "jquery.infieldlabel.min" );
OC_Util::addScript( "jquery-tipsy" );
OC_Util::addScript( "oc-dialogs" );
OC_Util::addScript( "js" );
OC_Util::addScript( "eventsource" );
OC_Util::addScript( "config" );
//OC_Util::addScript( "multiselect" );
OC_Util::addScript('search','result');
OC_Util::addStyle( "styles" );
OC_Util::addStyle( "multiselect" );
OC_Util::addStyle( "jquery-ui-1.8.16.custom" );
OC_Util::addStyle( "jquery-tipsy" );
$errors=OC_Util::checkServer();
if(count($errors)>0) {
OC_Template::printGuestPage('', 'error', array('errors' => $errors));
@ -333,8 +339,13 @@ class OC{
// Load Apps
// This includes plugins for users and filesystems as well
global $RUNTIME_NOAPPS;
global $RUNTIME_APPTYPES;
if(!$RUNTIME_NOAPPS ){
OC_App::loadApps();
if($RUNTIME_APPTYPES){
OC_App::loadApps($RUNTIME_APPTYPES);
}else{
OC_App::loadApps();
}
}
//make sure temporary files are cleaned up

View file

@ -318,9 +318,6 @@ class OC_DB {
// Make changes and save them to an in-memory file
$file2 = 'static://db_scheme';
if($file2 == ''){
die('could not create tempfile in get_temp_dir() - aborting');
}
$content = str_replace( '*dbname*', $CONFIG_DBNAME, $content );
$content = str_replace( '*dbprefix*', $CONFIG_DBTABLEPREFIX, $content );
if( $CONFIG_DBTYPE == 'pgsql' ){ //mysql support it too but sqlite doesn't

View file

@ -32,6 +32,7 @@ class OC_EventSource{
private $fallBackId=0;
public function __construct(){
@ob_end_clean();
header('Cache-Control: no-cache');
$this->fallback=isset($_GET['fallback']) and $_GET['fallback']=='true';
if($this->fallback){
@ -58,7 +59,7 @@ class OC_EventSource{
$type=null;
}
if($this->fallback){
$response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('.$this->fallBackId.',"'.$type.'","'.json_encode($data).'")</script>'.PHP_EOL;
$response='<script type="text/javascript">window.parent.OC.EventSource.fallBackCallBack('.$this->fallBackId.',"'.$type.'",'.json_encode($data).')</script>'.PHP_EOL;
echo $response;
}else{
if($type){

View file

@ -59,8 +59,8 @@ class OC_FileCache{
$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();
$query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path_hash=?');
$result=$query->execute(array(md5($path)))->fetchRow();
if(is_array($result)){
return $result;
}else{
@ -111,8 +111,8 @@ class OC_FileCache{
}
$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,encrypted,versioned) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)');
$result=$query->execute(array($parent,basename($path),$path,$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned']));
$query=OC_DB::prepare('INSERT INTO *PREFIX*fscache(parent, name, path, path_hash, size, mtime, ctime, mimetype, mimepart,user,writable,encrypted,versioned) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)');
$result=$query->execute(array($parent,basename($path),$path,md5($path),$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned']));
if(OC_DB::isError($result)){
OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR);
}
@ -162,8 +162,8 @@ class OC_FileCache{
$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));
$query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=?, path_hash=? WHERE path_hash=?');
$query->execute(array($newParent,basename($newPath),$newPath,md5($newPath),md5($oldPath)));
}
/**
@ -285,12 +285,12 @@ class OC_FileCache{
* @return int
*/
private static function getFileId($path){
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path=?');
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path_hash=?');
if(OC_DB::isError($query)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
}
$result=$query->execute(array($path));
$result=$query->execute(array(md5($path)));
if(OC_DB::isError($result)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
@ -367,8 +367,8 @@ class OC_FileCache{
}
}
$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();
$query=OC_DB::prepare('SELECT ctime,mtime,mimetype,size,encrypted,versioned,writable FROM *PREFIX*fscache WHERE path_hash=?');
$result=$query->execute(array(md5($path)))->fetchRow();
if(is_array($result)){
if(isset(self::$savedData[$path])){
$result=array_merge($result,self::$savedData[$path]);
@ -389,8 +389,8 @@ class OC_FileCache{
}
}
$path=$root.$path;
$query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path=?');
$result=$query->execute(array($path));
$query=OC_DB::prepare('SELECT size FROM *PREFIX*fscache WHERE path_hash=?');
$result=$query->execute(array(md5($path)));
if($row=$result->fetchRow()){
return $row['size'];
}else{//file not in cache
@ -469,6 +469,10 @@ class OC_FileCache{
* @param string root (optionak)
*/
public static function scan($path,$eventSource=false,&$count=0,$root=''){
if($eventSource){
$eventSource->send('scanning',array('file'=>$path,'count'=>$count));
}
$lastSend=$count;
if(!$root){
$view=OC_Filesystem::getView();
}else{
@ -482,13 +486,14 @@ class OC_FileCache{
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++;
if($count>$lastSend+25 and $eventSource){
$lastSend=$count;
$eventSource->send('scanning',array('file'=>$path,'count'=>$count));
}
}
}
}
@ -579,8 +584,8 @@ class OC_FileCache{
$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));
$query=OC_DB::prepare('SELECT mtime FROM *PREFIX*fscache WHERE path_hash=?');
$result=$query->execute(array(md5($path)));
if($row=$result->fetchRow()){
$cachedMTime=$row['mtime'];
return ($mtime>$cachedMTime);
@ -637,6 +642,14 @@ class OC_FileCache{
self::fileSystemWatcherWrite(array('path'=>$path),$root);
}
}
/**
* clean old pre-path_hash entries
*/
public static function clean(){
$query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE LENGTH(path_hash)<30');
$query->execute();
}
}
//watch for changes and try to keep the cache up to date

View file

@ -432,6 +432,19 @@ class OC_Helper {
self::$tmpFiles[]=$file;
return $file;
}
/**
* create a temporary folder with an unique filename
* @return string
*
* temporary files are automatically cleaned up after the script is finished
*/
public static function tmpFolder(){
$path=get_temp_dir().'/'.md5(time().rand());
mkdir($path);
self::$tmpFiles[]=$path;
return $path.'/';
}
/**
* remove all files created by self::tmpFile
@ -439,7 +452,7 @@ class OC_Helper {
public static function cleanTmp(){
foreach(self::$tmpFiles as $file){
if(file_exists($file)){
unlink($file);
self::rmdirr($file);
}
}
}

View file

@ -62,7 +62,7 @@ class OC_Installer{
//download the file if necesary
if($data['source']=='http'){
$path=OC_Helper::tmpFile('.zip');
$path=OC_Helper::tmpFile();
if(!isset($data['href'])){
OC_Log::write('core','No href specified when installing app from http',OC_Log::ERROR);
return false;
@ -76,14 +76,24 @@ class OC_Installer{
$path=$data['path'];
}
//detect the archive type
$mime=OC_Helper::getMimeType($path);
if($mime=='application/zip'){
rename($path,$path.'.zip');
$path.='.zip';
}elseif($mime=='application/x-gzip'){
rename($path,$path.'.tgz');
$path.='.tgz';
}else{
OC_Log::write('core','Archives of type '.$mime.' are not supported',OC_Log::ERROR);
return false;
}
//extract the archive in a temporary folder
$extractDir=tempnam(get_temp_dir(),'oc_installer_uncompressed_');
unlink($extractDir);
$extractDir=OC_Helper::tmpFolder();
mkdir($extractDir);
$zip = new ZipArchive;
if($zip->open($path)===true){
$zip->extractTo($extractDir);
$zip->close();
if($archive=OC_Archive::open($path)){
$archive->extract($extractDir);
} else {
OC_Log::write('core','Failed to open archive when installing app',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
@ -94,6 +104,17 @@ class OC_Installer{
}
//load the info.xml file of the app
if(!is_file($extractDir.'/appinfo/info.xml')){
//try to find it in a subdir
$dh=opendir($extractDir);
while($folder=readdir($dh)){
if(substr($folder,0,1)!='.' and is_dir($extractDir.'/'.$folder)){
if(is_file($extractDir.'/'.$folder.'/appinfo/info.xml')){
$extractDir.='/'.$folder;
}
}
}
}
if(!is_file($extractDir.'/appinfo/info.xml')){
OC_Log::write('core','App does not provide an info.xml file',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
@ -102,7 +123,7 @@ class OC_Installer{
}
return false;
}
$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml');
$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true);
$basedir=OC::$APPSROOT.'/apps/'.$info['id'];
//check if an app with the same id is already installed
@ -275,7 +296,7 @@ class OC_Installer{
if(is_file(OC::$APPSROOT."/apps/$app/appinfo/install.php")){
include(OC::$APPSROOT."/apps/$app/appinfo/install.php");
}
$info=OC_App::getAppInfo(OC::$APPSROOT."/apps/$app/appinfo/info.xml");
$info=OC_App::getAppInfo($app);
OC_Appconfig::setValue($app,'installed_version',$info['version']);
return $info;
}

View file

@ -1,78 +1,39 @@
<?php
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2012 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/>.
*
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
/**
*logging utilities
* logging utilities
*
* Log is saved at data/owncloud.log (on default)
* Log is saved by default at data/owncloud.log using OC_Log_Owncloud.
* Selecting other backend is done with a config option 'log_type'.
*/
class OC_Log{
class OC_Log {
const DEBUG=0;
const INFO=1;
const WARN=2;
const ERROR=3;
const FATAL=4;
static protected $class = null;
/**
* write a message in the log
* @param string $app
* @param string $message
* @param int level
*/
public static function write($app,$message,$level){
$minLevel=OC_Config::getValue( "loglevel", 2 );
if($level>=$minLevel){
$datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
$logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
$entry=array('app'=>$app,'message'=>$message,'level'=>$level,'time'=>time());
$fh=fopen($logFile,'a');
fwrite($fh,json_encode($entry)."\n");
fclose($fh);
public static function write($app, $message, $level) {
if (!self::$class) {
self::$class = 'OC_Log_'.ucfirst(OC_Config::getValue('log_type', 'owncloud'));
call_user_func(array(self::$class, 'init'));
}
}
/**
* get entries from the log in reverse chronological order
* @param int limit
* @param int offset
* @return array
*/
public static function getEntries($limit=50,$offset=0){
$datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
$logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
$entries=array();
if(!file_exists($logFile)){
return array();
}
$contents=file($logFile);
if(!$contents){//error while reading log
return array();
}
$end=max(count($contents)-$offset-1,0);
$start=max($end-$limit,0);
for($i=$end;$i>$start;$i--){
$entries[]=json_decode($contents[$i]);
}
return $entries;
$log_class=self::$class;
$log_class::write($app, $message, $level);
}
}

79
lib/log/owncloud.php Normal file
View file

@ -0,0 +1,79 @@
<?php
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2012 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/>.
*
*/
/**
* logging utilities
*
* Log is saved at data/owncloud.log (on default)
*/
class OC_Log_Owncloud {
static protected $logFile;
/**
* Init class data
*/
public static function init() {
$datadir=OC_Config::getValue( "datadirectory", OC::$SERVERROOT.'/data' );
self::$logFile=OC_Config::getValue( "logfile", $datadir.'/owncloud.log' );
}
/**
* write a message in the log
* @param string $app
* @param string $message
* @param int level
*/
public static function write($app, $message, $level) {
$minLevel=OC_Config::getValue( "loglevel", 2 );
if($level>=$minLevel){
$entry=array('app'=>$app, 'message'=>$message, 'level'=>$level,'time'=>time());
$fh=fopen(self::$logFile, 'a');
fwrite($fh, json_encode($entry)."\n");
fclose($fh);
}
}
/**
* get entries from the log in reverse chronological order
* @param int limit
* @param int offset
* @return array
*/
public static function getEntries($limit=50, $offset=0){
self::init();
$entries=array();
if(!file_exists(self::$logFile)) {
return array();
}
$contents=file($logFile);
if(!$contents) {//error while reading log
return array();
}
$end=max(count($contents)-$offset-1, 0);
$start=max($end-$limit,0);
for($i=$end;$i>$start;$i--) {
$entries[]=json_decode($contents[$i]);
}
return $entries;
}
}

37
lib/log/syslog.php Normal file
View file

@ -0,0 +1,37 @@
<?php
/**
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Log_Syslog {
static protected $levels = array(
OC_Log::DEBUG => LOG_DEBUG,
OC_Log::INFO => LOG_INFO,
OC_Log::WARN => LOG_WARNING,
OC_Log::ERROR => LOG_ERR,
OC_Log::FATAL => LOG_CRIT,
);
/**
* Init class data
*/
public static function init() {
openlog('ownCloud', LOG_PID | LOG_CONS, LOG_USER);
// Close at shutdown
register_shutdown_function('closelog');
}
/**
* write a message in the log
* @param string $app
* @param string $message
* @param int level
*/
public static function write($app, $message, $level) {
$syslog_level = self::$levels[$level];
syslog($syslog_level, '{'.$app.'} '.$message);
}
}

View file

@ -66,7 +66,7 @@ class OC_Util {
* @return array
*/
public static function getVersion(){
return array(3,00,3);
return array(3,00,4);
}
/**

View file

@ -13,5 +13,5 @@ OC_JSON::checkAdminUser();
$count=(isset($_GET['count']))?$_GET['count']:50;
$offset=(isset($_GET['offset']))?$_GET['offset']:0;
$entries=OC_Log::getEntries($count,$offset);
$entries=OC_Log_Owncloud::getEntries($count,$offset);
OC_JSON::success(array("data" => $entries));

View file

@ -28,7 +28,7 @@ OC_Util::addStyle( "settings", "settings" );
OC_Util::addScript( "settings", "apps" );
OC_App::setActiveNavigationEntry( "core_log" );
$entries=OC_Log::getEntries();
$entries=OC_Log_Owncloud::getEntries();
OC_Util::addScript('settings','log');
OC_Util::addStyle('settings','settings');

View file

@ -38,6 +38,7 @@ foreach($apps as $app){
}
function loadTests($dir=''){
$test=isset($_GET['test'])?$_GET['test']:false;
if($dh=opendir($dir)){
while($name=readdir($dh)){
if(substr($name,0,1)!='.'){//no hidden files, '.' or '..'
@ -45,10 +46,13 @@ function loadTests($dir=''){
if(is_dir($file)){
loadTests($file);
}elseif(substr($file,-4)=='.php' and $file!=__FILE__){
$testCase=new TestSuite(getTestName($file));
$testCase->addFile($file);
if($testCase->getSize()>0){
$testCase->run(new HtmlReporter());
$name=getTestName($file);
if($test===false or $test==$name or substr($name,0,strlen($test))==$test){
$testCase=new TestSuite($name);
$testCase->addFile($file);
if($testCase->getSize()>0){
$testCase->run(new HtmlReporter());
}
}
}
}