diff --git a/livesupport/modules/storageServer/var/BasicStor.php b/livesupport/modules/storageServer/var/BasicStor.php
new file mode 100644
index 000000000..5d887b80c
--- /dev/null
+++ b/livesupport/modules/storageServer/var/BasicStor.php
@@ -0,0 +1,1050 @@
+config = $config;
+ $this->filesTable = $config['tblNamePrefix'].'files';
+ $this->mdataTable = $config['tblNamePrefix'].'mdata';
+ $this->accessTable= $config['tblNamePrefix'].'access';
+ $this->storageDir = $config['storageDir'];
+ $this->bufferDir = $config['bufferDir'];
+ $this->transDir = $config['transDir'];
+ $this->accessDir = $config['accessDir'];
+ $this->dbc->setErrorHandling(PEAR_ERROR_RETURN);
+ $this->rootId = $this->getRootNode();
+ $this->storId = $this->wd =
+ $this->getObjId('StorageRoot', $this->rootId);
+ $this->dbc->setErrorHandling();
+ }
+
+ /**
+ * Create new folder
+ *
+ * @param parid int, parent id
+ * @param folderName string, name for new folder
+ * @return id of new folder
+ * @exception PEAR::error
+ */
+ function bsCreateFolder($parid, $folderName)
+ {
+ return $this->addObj($folderName , 'Folder', $parid);
+ }
+
+ /**
+ * Store new file in the storage
+ *
+ * @param parid int, parent id
+ * @param fileName string, name for new file
+ * @param mediaFileLP string, local path of media file
+ * @param mdataFileLP string, local path of metadata file
+ * @param gunid string, global unique id OPTIONAL
+ * @return int
+ * @exception PEAR::error
+ */
+ function bsPutFile($parid, $fileName,
+ $mediaFileLP, $mdataFileLP, $gunid=NULL)
+ {
+ $name = "$fileName";
+ $id = $this->addObj($name , 'File', $parid);
+ $ac =& StoredFile::insert(
+ &$this, $id, $name, $mediaFileLP, $mdataFileLP, 'file', $gunid
+ );
+ if(PEAR::isError($ac)) return $ac;
+ return $id;
+ }
+
+ /**
+ * Analyze media file for internal metadata information
+ *
+ * @param id int, virt.file's local id
+ * @return array
+ */
+ function bsAnalyzeFile($id)
+ {
+ $ac =& StoredFile::recall(&$this, $id);
+ if(PEAR::isError($ac)) return $ac;
+ $ia = $ac->analyzeMediaFile();
+ return $ia;
+ }
+
+ /**
+ * Rename file
+ *
+ * @param id int, virt.file's local id
+ * @param newName string
+ * @return boolean or PEAR::error
+ */
+ function bsRenameFile($id, $newName)
+ {
+ $parid = $this->getParent($id);
+ $ac =& StoredFile::recall(&$this, $id);
+ if(PEAR::isError($ac)){
+ // catch nonerror exception:
+ if($ac->getCode() != GBERR_FOBJNEX) return $ac;
+ }
+ $res = $ac->rename($newName);
+ if(PEAR::isError($res)) return $res;
+ return $this->renameObj($id, $newName);
+ }
+
+ /**
+ * Move file
+ *
+ * @param id int, virt.file's local id
+ * @param did int, destination folder local id
+ * @return boolean or PEAR::error
+ */
+ function bsMoveFile($id, $did)
+ {
+ if($this->getObjType($did) !== 'Folder')
+ return PEAR::raiseError(
+ 'BasicStor::moveFile: destination is not folder', GBERR_WRTYPE
+ );
+ $this->_relocateSubtree($id, $did);
+ }
+
+ /**
+ * Copy file
+ *
+ * @param id int, virt.file's local id
+ * @param did int, destination folder local id
+ * @return boolean or PEAR::error
+ */
+ function bsCopyFile($id, $did)
+ {
+ if($this->getObjType($did)!=='Folder')
+ return PEAR::raiseError(
+ 'GreenBox::copyFile: destination is not folder', GBERR_WRTYPE
+ );
+ return $this->_copySubtree($id, $did);
+ }
+
+ /**
+ * Delete file
+ *
+ * @param id int, virt.file's local id
+ * @return true or PEAR::error
+ */
+ function bsDeleteFile($id)
+ {
+ $parid = $this->getParent($id);
+ $res = $this->removeObj($id);
+ if(PEAR::isError($res)) return $res;
+ return TRUE;
+ }
+
+ /* ----------------------------------------------------- put, access etc. */
+ /**
+ * Check validity of asscess/put token
+ *
+ * @param token string, access/put token
+ * @param type string 'put'|'access'|'download'
+ * @return boolean
+ */
+ function bsCheckToken($token, $type='put')
+ {
+ $cnt = $this->dbc->getOne("
+ SELECT count(token) FROM {$this->accessTable}
+ WHERE token='{$token}' AND type='$type'
+ ");
+ if(PEAR::isError($cnt)){ return FALSE; }
+ return ($cnt == 1);
+ }
+
+ /**
+ * Create and return access link to media file
+ *
+ * @param realFname string, local filepath to accessed file
+ * @param ext string, useful filename extension for accessed file
+ * @param gunid int, global unique id
+ * @param sessid string, session id
+ * @param type string 'access'|'download'
+ * @return array with: seekable filehandle, access token
+ */
+ function bsAccess($realFname, $ext, $gunid, $sessid='', $type='access')
+ {
+ $token = StoredFile::_createGunid();
+ $res = $this->dbc->query("
+ INSERT INTO {$this->accessTable}
+ (gunid, sessid, token, ext, type, ts)
+ VALUES
+ ('{$gunid}', '$sessid', '$token', '$ext', '$type', now())
+ ");
+ if(PEAR::isError($res)){ return $res; }
+ $linkFname = "{$this->accessDir}/$token.$ext";
+
+ if(!file_exists($realFname)){
+ return PEAR::raiseError(
+ "BasicStor::bsAccess: symlink create failed ($accLinkName)",
+ GBERR_FILEIO);
+ }
+ if(! @symlink($realFname, $linkFname)){
+ return PEAR::raiseError(
+ "BasicStor::bsAccess: symlink create failed ($linkFname)",
+ GBERR_FILEIO);
+ }
+ return array('fname'=>$linkFname, 'token'=>$token);
+ }
+
+ /**
+ * Release access link to media file
+ *
+ * @param token string, access token
+ * @param type string 'access'|'download'
+ * @return boolean
+ */
+ function bsRelease($token, $type='access')
+ {
+ if(!$this->bsCheckToken($token, $type)){
+ return PEAR::raiseError(
+ "BasicStor::bsRelease: invalid token ($token)"
+ );
+ }
+ $ext = $this->dbc->getOne("
+ SELECT ext FROM {$this->accessTable}
+ WHERE token='{$token}' AND type='$type'
+ ");
+ if(PEAR::isError($ext)){ return $ext; }
+ $linkFname = "{$this->accessDir}/$token.$ext";
+ $res = $this->dbc->query("
+ DELETE FROM {$this->accessTable} WHERE token='$token'
+ ");
+ if(PEAR::isError($res)){ return $res; }
+ if(! @unlink($linkFname)){
+ return PEAR::raiseError(
+ "BasicStor::bsRelease: unlink failed ($linkFname)",
+ GBERR_FILEIO);
+ }
+ return TRUE;
+ }
+
+ /**
+ * Create and return downloadable URL for file
+ *
+ * @param id int, virt.file's local id
+ * @param part string, 'media'|'metadata'
+ * @return array with: downloadable URL, download token
+ */
+ function bsOpenDownload($id, $part='media')
+ {
+ $ac =& StoredFile::recall(&$this, $id);
+ if(PEAR::isError($ac)) return $ac;
+ $gunid = $ac->gunid;
+ switch($part){
+ case"media":
+ $fname = $ac->_getRealRADFname();
+ $ext = $ac->_getExt();
+ break;
+ case"metadata":
+ $md = $this->bsGetMdata($id);
+ $fname = "{$this->bufferDir}/$gunid";
+ $e = FALSE;
+ if(!$fh = fopen($fname, "w")){ $e = TRUE; }
+ elseif(fwrite($fh, $md) === FALSE){ $e = TRUE; }
+ if($e){
+ return PEAR::raiseError(
+ "BasicStor::bsOpenDownload: can't write ($fname)",
+ GBERR_FILEIO);
+ }
+ fclose($fh);
+ $ext = "xml";
+ break;
+ }
+ $sessid = '';
+ $acc = $this->bsAccess($fname, $ext, $gunid, $sessid, 'download');
+ $url = $this->getUrlPart()."access/".basename($acc['fname']);
+ return array('url'=>$url, 'token'=>$acc['token']);
+ }
+
+ /**
+ * Discard downloadable URL
+ *
+ * @param token string, download token
+ * @param part string, 'media'|'metadata'
+ * @return boolean
+ */
+ function bsCloseDownload($token, $part='media')
+ {
+ if($part == 'metadata'){
+ $gunid = $this->dbc->getOne("
+ SELECT gunid FROM {$this->accessTable}
+ WHERE token='{$token}' AND type='download'
+ ");
+ if(PEAR::isError($gunid)){ return $gunid; }
+ $fname = "{$this->bufferDir}/$gunid";
+ @unlink($fname);
+ }
+ return $this->bsRelease($token, 'download');
+ }
+
+ /**
+ * Create writable URL for HTTP PUT method file insert
+ *
+ * @param chsum string, md5sum of the file having been put
+ * @param gunid string, global unique id
+ * @return array with: writable URL, PUT token
+ */
+ function bsOpenPut($chsum, $gunid)
+ {
+ $sessid = '';
+ $ext = '';
+ $token = StoredFile::_createGunid();
+ $res = $this->dbc->query("
+ INSERT INTO {$this->accessTable}
+ (gunid, sessid, token, ext, chsum, type, ts)
+ VALUES
+ ('{$gunid}', '$sessid', '$token',
+ '$ext', '$chsum', 'put', now())
+ ");
+ if(PEAR::isError($res)){ return $res; }
+ $fname = "{$this->accessDir}/$token";
+ touch($fname); // is it needed?
+ $url = $this->getUrlPart()."xmlrpc/put.php?token=$token";
+ return array('url'=>$url, 'token'=>$token);
+ }
+
+ /**
+ * Get file from writable URL and insert it to the storage
+ *
+ * @param token string, PUT token
+ * @return string, local path of the file having been put
+ */
+ function bsClosePut($token)
+ {
+ if(!$this->bsCheckToken($token, 'put')){
+ return PEAR::raiseError(
+ 'BasicStor::bsClosePut: invalid token ($token)'
+ );
+ }
+ $chsum = $this->dbc->getOne("
+ SELECT chsum FROM {$this->accessTable}
+ WHERE token='{$token}'
+ ");
+ $fname = "{$this->accessDir}/$token";
+ $md5sum = md5_file($fname);
+ if($chsum != $md5sum){
+ return PEAR::raiseError(
+ 'BasicStor::bsClosePut: md5sum does not match (token=$token)'
+ );
+ }
+ $res = $this->dbc->query("
+ DELETE FROM {$this->accessTable} WHERE token='$token'
+ ");
+ if(PEAR::isError($res)){ return $res; }
+ return $fname;
+ }
+
+ /**
+ * Return starting part of storageServer URL
+ *
+ * @return string, url
+ */
+ function getUrlPart()
+ {
+ $host = $this->config['storageUrlHost'];
+ $port = $this->config['storageUrlPort'];
+ $path = $this->config['storageUrlPath'];
+ return "http://$host:$port$path/";
+ }
+
+ /* ---------------------------------------------- replicas, versions etc. */
+ /**
+ * Create replica.
+ * TODO: NOT FINISHED
+ *
+ * @param id int, virt.file's local id
+ * @param did int, destination folder local id
+ * @param replicaName string, name of new replica
+ * @return int, local id of new object
+ */
+ function bsCreateReplica($id, $did, $replicaName)
+ {
+ return PEAR::raiseError(
+ 'GreenBox::createVersion: not implemented', GBERR_NOTIMPL
+ );
+ // ---
+ if($this->getObjType($did)!=='Folder')
+ return PEAR::raiseError(
+ 'GreenBox::createReplica: dest is not folder', GBERR_WRTYPE
+ );
+ if($replicaName=='') $replicaName = $this->getObjName($id);
+ while(($exid = $this->getObjId($replicaName, $did))<>'')
+ { $replicaName.='_R'; }
+ $rid = $this->addObj($replicaName , 'Replica', $did, 0, $id);
+ if(PEAR::isError($rid)) return $rid;
+# $this->addMdata($this->_pathFromId($rid), 'isReplOf', $id, $sessid);
+ return $rid;
+ }
+
+ /**
+ * Create version.
+ * TODO: NOT FINISHED
+ *
+ * @param id int, virt.file's local id
+ * @param did int, destination folder local id
+ * @param versionLabel string, name of new version
+ * @return int, local id of new object
+ */
+ function bsCreateVersion($id, $did, $versionLabel)
+ {
+ return PEAR::raiseError(
+ 'GreenBox::createVersion: not implemented', GBERR_NOTIMPL
+ );
+ }
+
+ /* ------------------------------------------------------------- metadata */
+
+ /**
+ * Update metadata tree
+ *
+ * @param id int, virt.file's local id
+ * @param mdataFile string, local path of metadata XML file
+ * @return boolean or PEAR::error
+ */
+ function bsUpdateMetadata($id, $mdataFile)
+ {
+ $ac =& StoredFile::recall(&$this, $id);
+ if(PEAR::isError($ac)) return $ac;
+ return $ac->updateMetaData($mdataFile);
+ }
+
+ /**
+ * Update object namespace and value of one metadata record
+ *
+ * @param id int, virt.file's local id
+ * @param mdid int, metadata record id
+ * @param object string, object value, e.g. title string
+ * @param objns string, object namespace prefix, have to be defined
+ * in file's metadata (or reserved prefix)
+ * @return boolean or PEAR::error
+ * @see MetaData
+ */
+ function bsUpdateMetadataRecord($id, $mdid, $object, $objns='_L')
+ {
+ $ac =& StoredFile::recall(&$this, $id);
+ if(PEAR::isError($ac)) return $ac;
+ return $ac->updateMetaDataRecord($mdid, $object, $objns);
+ }
+
+ /**
+ * Add single metadata record.
+ * TODO: NOT FINISHED
+ * Params could be changed!
+ *
+ * @param id int, virt.file's local id
+ * @param propertyName string
+ * @param propertyValue string
+ * @return boolean or PEAR::error
+ * @see MetaData
+ */
+ function bsAddMetaDataRecord($id, $propertyName, $propertyValue)
+ {
+ return PEAR::raiseError(
+ 'GreenBox::addMetaDataRecord: not implemented', GBERR_NOTIMPL
+ );
+ }
+
+ /**
+ * Get metadata XML tree as string
+ *
+ * @param id int, virt.file's local id
+ * @return string or PEAR::error
+ */
+ function bsGetMdata($id)
+ {
+ $ac =& StoredFile::recall(&$this, $id);
+ if(PEAR::isError($ac)) return $ac;
+ return $ac->getMetaData();
+ }
+
+ /**
+ * Search in local metadata database.
+ * TODO: NOT FINISHED
+ * It will support structured queries - array of mode and query parts.
+ * Mode is "match all" or "match any".
+ * Query parts is array of [fieldname, operator, value] entities.
+ *
+ * @param searchData string, search query -
+ * only one SQL LIKE term supported now.
+ * It will be searched in all literal object values
+ * in metadata database
+ * @return array of gunid strings
+ */
+ function bsLocalSearch($searchData)
+ {
+ $ftsrch = $searchData;
+ $res = $this->dbc->getCol("SELECT md.gunid as gunid
+ FROM {$this->filesTable} f, {$this->mdataTable} md
+ WHERE f.gunid=md.gunid AND md.objns='_L' AND
+ md.object like '%$ftsrch%'
+ GROUP BY md.gunid
+ ");
+ if(!is_array($res)) $res = array();
+ return $res;
+ }
+
+ /* --------------------------------------------------------- info methods */
+
+ /**
+ * List files in folder
+ *
+ * @param id int, local id of folder
+ * @return array
+ */
+ function bsListFolder($id)
+ {
+ if($this->getObjType($id)!=='Folder')
+ return PEAR::raiseError(
+ 'GreenBox::listFolder: not a folder', GBERR_NOTF
+ );
+ $a = $this->getDir($id, 'id, name, type, param as target', 'name');
+ return $a;
+ }
+
+ /**
+ * List files in folder
+ *
+ * @param id int, local id of object
+ * @param relPath string, relative path
+ * @return array
+ */
+ function getObjIdFromRelPath($id, $relPath='.')
+ {
+ $a = split('/', $relPath);
+ if($this->getObjType($id)!=='Folder') $nid = $this->getparent($id);
+ else $nid = $id;
+ foreach($a as $i=>$item){
+ switch($item){
+ case".":
+ break;
+ case"..":
+ $nid = $this->getparent($nid);
+ break;
+ case"":
+ break;
+ default:
+ $nid = $this->getObjId($item, $nid);
+ }
+ }
+ return $nid;
+ }
+
+
+
+
+ /* -------------------------------------------- remote repository methods */
+
+ /**
+ * Upload file to remote repository
+ *
+ * @param id int, virt.file's local id
+ * @param gunid string, global id
+ * @param sessid string, session id
+ * @return string - transfer id or PEAR::error
+ */
+ function uploadFile($id, $gunid, $sessid='')
+ {
+ $res = $this->prepareForTransport($id, $gunid, $sessid);
+ if(PEAR::isError($res)) return $res;
+ list($mediaFile, $mdataFile, $gunid) = $res;
+ $tr =& new Transport(&$this->dbc, $this->config);
+ $res = $tr->uploadOpen($mediaFile, 'media', $sessid, $gunid);
+ if(PEAR::isError($res)) return $res;
+ $res2 = $tr->uploadOpen($mdataFile, 'metadata', $sessid, $gunid);
+ if(PEAR::isError($res2)) return $res2;
+ $res3 = $tr->getTransportStatus($res);
+ $res4 = $tr->getTransportStatus($res2);
+# return $res;
+ return array($res, $res2, $res3, $res4);
+ }
+
+ /**
+ * Download file from remote repository
+ *
+ * @param gunid int, global unique id
+ * @param sessid string, session id
+ * @return string - transfer id or PEAR::error
+ */
+ function downloadFile($gunid, $sessid='')
+ {
+ $tr =& new Transport(&$this->dbc, $this->config);
+ // get home dir if needed
+ $res = $tr->downloadOpen($sessid, 'media', $gunid,
+ $this->getSessUserId($sessid)
+ );
+ if(PEAR::isError($res)) return $res;
+ $res2 = $tr->downloadOpen($sessid, 'metadata', $gunid,
+ $this->getSessUserId($sessid)
+ );
+ if(PEAR::isError($res)) return $res;
+ $res3 = $tr->getTransportStatus($res);
+ $res4 = $tr->getTransportStatus($res2);
+# return $res;
+ return array($res, $res2, $res3, $res4);
+ }
+
+
+
+ /**
+ * Method for handling interupted transports via cron
+ *
+ */
+ function cronJob()
+ {
+ $tr =& new Transport(&$this->dbc, $this->config);
+ $ru = $tr->uploadCron();
+ $rd = $tr->downloadCron(&$this);
+ return array($ru, $rd);
+ }
+
+ /**
+ * Get status of asynchronous transfer
+ *
+ * @param transferId int, id of asynchronous transfer
+ * returned by uploadFile or downloadFile methods
+ * @param sessid string, session id
+ * @return string or PEAR::error
+ */
+ function getTransferStatus($transferId, $sessid='')
+ {
+ return PEAR::raiseError(
+ 'GreenBox::getTransferStatus: not implemented', GBERR_NOTIMPL
+ );
+ }
+
+ /**
+ * Prepare symlink to media file and create metadata file for transport
+ *
+ * @param id
+ * @param gunid
+ * @param sessid
+ * @return array
+ */
+ function prepareForTransport($id, $gunid, $sessid='')
+ {
+ if(!$gunid) $gunid = $this->_gunidFromId($id);
+ else $id = $this->_idFromGunid($gunid);
+ $ac =& StoredFile::recallByGunid(&$this, $gunid);
+ if(PEAR::isError($ac)) return $ac;
+ $mediaTarget = $ac->_getRealRADFname();
+ $mediaFile = "$gunid";
+ $mdataFile = "$gunid.xml";
+ @symlink($mediaTarget, $this->transDir."/$mediaFile");
+ $mdata = $this->getMdata($id, $sessid);
+ if(PEAR::isError($mdata)) return $mdata;
+ if(!($fh = fopen($this->transDir."/$mdataFile", 'w'))) $res=FALSE;
+ else{
+ $res = fwrite($fh, $mdata);
+ fclose($fh);
+ }
+ if($res === FALSE) return PEAR::raiseError(
+ "GreenBox::prepareForTransport:".
+ " can't write metadata tmp file ($mdataFile)"
+ );
+ return array($mediaFile, $mdataFile, $gunid);
+ }
+
+ /**
+ * Insert transported file and metadata into storage.
+ * TODO: cals methods from LocStor - it's not good
+ *
+ * @param sessid string - session id
+ * @param file string - local path to filr
+ * @param type string - media|metadata|search
+ * @param gunid string - global unique id
+ */
+ function processTransported($sessid, $file, $type, $gunid='X')
+ {
+ switch($type){
+ case 'media':
+ if(!file_exists($file)) break;
+ $res = $this->storeAudioClip($sessid, $gunid,
+ $file, '');
+ if(PEAR::isError($res)) return $res;
+ @unlink($file);
+ break;
+ case 'metadata':
+ case 'mdata':
+ if(!file_exists($file)) break;
+ $res = $this->updateAudioClipMetadata($sessid, $gunid,
+ $file);
+ if(PEAR::isError($res)){
+ // catch valid exception
+ if($res->getCode() == GBERR_FOBJNEX){
+ $res2 = $this->storeAudioClip($sessid, $gunid,
+ '', $file);
+ if(PEAR::isError($res2)) return $res2;
+ }else return $res;
+ }
+ @unlink($file);
+ break;
+ case 'search':
+ //$this->localSearch($criteria);
+ return PEAR::raiseError("processTranferred: search not implemented");
+ break;
+ default:
+ return PEAR::raiseError("processTranferred: unknown type ($type)");
+ break;
+ }
+ }
+
+ /**
+ * Search in central metadata database
+ *
+ * @param searchData string, search query - see localSearch method
+ * @param sessid string, session id
+ * @return string - job id or PEAR::error
+ */
+ function globalSearch($searchData, $sessid='')
+ {
+ return PEAR::raiseError(
+ 'GreenBox::globalSearch: not implemented', GBERR_NOTIMPL
+ );
+ /*
+ $srchid = md5($sessid.mtime());
+ $fh = fopen($this->transDir."/$srchid", "w");
+ fwrite($fh, serialize($searchData));
+ fclose($fh);
+ $res = $tr->uploadOpen($srchid, 'search', $sessid, $gunid);
+ if(PEAR::isError($res)) return $res;
+ return $res;
+ */
+ }
+
+ /**
+ * Get results from asynchronous search
+ *
+ * @param transferId int, transfer id returned by
+ * @param sessid string, session id
+ * @return array with results or PEAR::error
+ */
+ function getSearchResults($transferId, $sessid='')
+ {
+ return PEAR::raiseError(
+ 'GreenBox::getSearchResults: not implemented', GBERR_NOTIMPL
+ );
+ }
+
+ /* =============================================== test and debug methods */
+ /**
+ * dump
+ *
+ */
+ function dump($id='', $indch=' ', $ind='', $format='{name}')
+ {
+ if($id=='') $id = $this->storId;
+ return parent::dump($id, $indch, $ind, $format);
+ }
+
+ /**
+ *
+ *
+ */
+ function dumpDir($id='', $format='$o["name"]')
+ {
+ if($id=='') $id = $this->storId;
+ $arr = $this->getDir($id, 'id,name');
+// if($this->doDebug){ $this->debug($arr); exit; }
+ $arr = array_map(create_function('$o', 'return "'.$format.'";'), $arr);
+ return join('', $arr);
+ }
+
+ /**
+ *
+ *
+ */
+ function debug($va)
+ {
+ echo"
\n"; print_r($va); #exit;
+ }
+
+ /**
+ * deleteData
+ *
+ * @return void
+ */
+ function deleteData()
+ {
+// $this->dbc->query("DELETE FROM {$this->filesTable}");
+ $ids = $this->dbc->getAll("SELECT id FROM {$this->filesTable}");
+ if(is_array($ids)) foreach($ids as $i=>$item){
+ $this->removeObj($item['id']);
+ }
+ parent::deleteData();
+ $this->initData();
+ }
+ /**
+ * testData
+ *
+ */
+ function testData($d='')
+ {
+ $exdir = '../../../storageServer/var/tests';
+ $o[] = $this->addSubj('test1', 'a');
+ $o[] = $this->addSubj('test2', 'a');
+ $o[] = $this->addSubj('test3', 'a');
+ $o[] = $this->addSubj('test4', 'a');
+
+ $o[] = $t1hd = $this->getObjId('test1', $this->storId);
+ $o[] = $t1d1 = $this->bsCreateFolder($t1hd, 'test1_folder1');
+ $o[] = $this->bsCreateFolder($t1hd, 'test1_folder2');
+ $o[] = $this->bsCreateFolder($t1d1, 'test1_folder1_1');
+ $o[] = $t1d12 = $this->bsCreateFolder($t1d1, 'test1_folder1_2');
+
+ $o[] = $t2hd = $this->getObjId('test2', $this->storId);
+ $o[] = $this->bsCreateFolder($t2hd, 'test2_folder1');
+
+ $o[] = $this->bsPutFile($t1hd, 'file1.mp3', "$exdir/ex1.mp3", '');
+ $o[] = $this->bsPutFile($t1d12, 'file2.wav', "$exdir/ex2.wav", '');
+/*
+*/
+ $this->tdata['storage'] = $o;
+ }
+
+ /**
+ * test
+ *
+ */
+ function test()
+ {
+// if(PEAR::isError($p = parent::test())) return $p;
+ $this->deleteData();
+ $this->testData();
+ $this->test_correct = " StorageRoot
+ root
+ test1
+ test1_folder1
+ test1_folder1_1
+ test1_folder1_2
+ file2.wav
+ test1_folder2
+ file1.mp3
+ test2
+ test2_folder1
+ test3
+ test4
+";
+ $this->test_dump = $this->dumpTree($this->storId);
+ if($this->test_dump==$this->test_correct)
+ { $this->test_log.="storageServer: OK\n"; return true; }
+ else PEAR::raiseError('GreenBox::test:', 1, PEAR_ERROR_DIE, '%s'.
+ "\ncorrect:\n.{$this->test_correct}.\n".
+ "dump:\n.{$this->test_dump}.\n\n");
+ }
+
+ /**
+ * initData - initialize
+ *
+ */
+ function initData()
+ {
+ $this->rootId = $this->getRootNode();
+ $this->storId = $this->wd =
+ $this->addObj('StorageRoot', 'Folder', $this->rootId);
+ $rootUid = parent::addSubj('root', $this->config['tmpRootPass']);
+ $res = $this->addPerm($rootUid, '_all', $this->rootId, 'A');
+ $fid = $this->bsCreateFolder($this->storId, 'root');
+ }
+ /**
+ * install - create tables
+ *
+ * file states:
+ * \n"; print_r($ac); exit;
- $ia = $ac->analyzeMediaFile();
- return $ia;
- }
+ if(($res = $this->_authorize('read', $id, $sessid)) !== TRUE)
+ return $res;
+ return $this->bsAnalyzeFile($id);
}
- /**
- * Create and return access link to media file
- *
- * @param id int, virt.file's local id
- * @param sessid string, session id
- * @return filename as string or PEAR::error
- */
- function access($id, $sessid='')
- {
- if(($res = $this->_authorize('read', $id, $sessid)) !== TRUE)
- return $res;
- $ac =& StoredFile::recall(&$this, $id);
- if(PEAR::isError($ac)) return $ac;
- else{
- $fname = $ac->accessRawMediaData($sessid);
- return $fname;
- }
- }
-
- /**
- * Release access link to media file
- *
- * @param id int, virt.file's local id
- * @param sessid string, session id
- * @return boolean or PEAR::error
- */
- function release($id, $sessid='')
- {
- if(($res = $this->_authorize('read', $id, $sessid)) !== TRUE)
- return $res;
- $ac =& StoredFile::recall(&$this, $id);
- if(PEAR::isError($ac)) return $ac;
- else{
- $res = $ac->releaseRawMediaData($sessid);
- return $res;
- }
- }
-
/**
* Rename file
*
@@ -225,15 +107,7 @@ class GreenBox extends Alib{
$parid = $this->getParent($id);
if(($res = $this->_authorize('write', $parid, $sessid)) !== TRUE)
return $res;
- $ac =& StoredFile::recall(&$this, $id);
- if(PEAR::isError($ac)){
- // catch nonerror exception:
- if($ac->getCode() != GBERR_FOBJNEX) return $ac;
- }else{
- $res = $ac->rename($newName);
- if(PEAR::isError($res)) return $res;
- }
- return $this->renameObj($id, $newName);
+ return $this->bsRenameFile($id, $newName);
}
/**
@@ -246,14 +120,10 @@ class GreenBox extends Alib{
*/
function moveFile($id, $did, $sessid='')
{
- if($this->getObjType($did) !== 'Folder')
- return PEAR::raiseError(
- 'GreenBox::moveFile: destination is not folder', GBERR_WRTYPE
- );
if(($res = $this->_authorize(
array('read', 'write'), array($id, $did), $sessid
)) !== TRUE) return $res;
- $this->_relocateSubtree($id, $did);
+ return $this->bsMoveFile($id, $did);
}
/**
@@ -266,14 +136,10 @@ class GreenBox extends Alib{
*/
function copyFile($id, $did, $sessid='')
{
- if($this->getObjType($did)!=='Folder')
- return PEAR::raiseError(
- 'GreenBox::copyFile: destination is not folder', GBERR_WRTYPE
- );
if(($res = $this->_authorize(
array('read', 'write'), array($id, $did), $sessid
)) !== TRUE) return $res;
- return $this->_copySubtree($id, $did);
+ return $this->bsCopyFile($id, $did);
}
/**
@@ -288,13 +154,41 @@ class GreenBox extends Alib{
$parid = $this->getParent($id);
if(($res = $this->_authorize('write', $parid, $sessid)) !== TRUE)
return $res;
- $res = $this->removeObj($id);
- if(PEAR::isError($res)) return $res;
- return TRUE;
+ return $this->bsDeleteFile($id);
+ }
+
+ /* ----------------------------------------------------- put, access etc. */
+ /**
+ * Create and return access link to media file
+ *
+ * @param id int, virt.file's local id
+ * @param sessid string, session id
+ * @return array with: seekable filehandle, access token
+ */
+ function access($id, $sessid='')
+ {
+ $ac =& StoredFile::recall(&$this, $id);
+ if(PEAR::isError($ac)) return $ac;
+ if(($res = $this->_authorize('read', $id, $sessid)) !== TRUE)
+ return $res;
+ return $ac->accessRawMediaData($sessid);
+ }
+
+ /**
+ * Release access link to media file
+ *
+ * @param sessid string, session id
+ * @param token string, access token
+ * @return boolean or PEAR::error
+ */
+ function release($token, $sessid='')
+ {
+ $ac =& StoredFile::recallByToken(&$this, $token);
+ if(PEAR::isError($ac)) return $ac;
+ return $ac->releaseRawMediaData($sessid, $token);
}
/* ---------------------------------------------- replicas, versions etc. */
-
/**
* Create replica.
* TODO: NOT FINISHED
@@ -307,24 +201,10 @@ class GreenBox extends Alib{
*/
function createReplica($id, $did, $replicaName='', $sessid='')
{
- return PEAR::raiseError(
- 'GreenBox::createVersion: not implemented', GBERR_NOTIMPL
- );
- // ---
- if($this->getObjType($did)!=='Folder')
- return PEAR::raiseError(
- 'GreenBox::createReplica: dest is not folder', GBERR_WRTYPE
- );
if(($res = $this->_authorize(
array('read', 'write'), array($id, $did), $sessid
)) !== TRUE) return $res;
- if($replicaName=='') $replicaName = $this->getObjName($id);
- while(($exid = $this->getObjId($replicaName, $did))<>'')
- { $replicaName.='_R'; }
- $rid = $this->addObj($replicaName , 'Replica', $did, 0, $id);
- if(PEAR::isError($rid)) return $rid;
-# $this->addMdata($this->_pathFromId($rid), 'isReplOf', $id, $sessid);
- return $rid;
+ return $this->bsCreateReplica($id, $did, $replicaName);
}
/**
@@ -339,9 +219,7 @@ class GreenBox extends Alib{
*/
function createVersion($id, $did, $versionLabel, $sessid='')
{
- return PEAR::raiseError(
- 'GreenBox::createVersion: not implemented', GBERR_NOTIMPL
- );
+ return $this->bsCreateVersion($id, $did, $versionLabel);
}
@@ -359,11 +237,7 @@ class GreenBox extends Alib{
{
if(($res = $this->_authorize('write', $id, $sessid)) !== TRUE)
return $res;
- $ac =& StoredFile::recall(&$this, $id);
- if(PEAR::isError($ac)) return $ac;
- else{
- return $ac->updateMetaData($mdataFile);
- }
+ return $this->bsUpdateMetadata($id, $mdataFile);
}
/**
@@ -382,11 +256,7 @@ class GreenBox extends Alib{
{
if(($res = $this->_authorize('write', $id, $sessid)) !== TRUE)
return $res;
- $ac =& StoredFile::recall(&$this, $id);
- if(PEAR::isError($ac)) return $ac;
- else{
- return $ac->updateMetaDataRecord($mdid, $object, $objns);
- }
+ return $this->bsUpdateMetadataRecord($id, $mdid, $object, $objns);
}
/**
@@ -401,14 +271,11 @@ class GreenBox extends Alib{
* @return boolean or PEAR::error
* @see MetaData
*/
- function addMetaDataRecord($id, $propertyName,
- $propertyValue, $sessid='')
+ function addMetaDataRecord($id, $propertyName, $propertyValue, $sessid='')
{
- //if(($res = $this->_authorize('write', $id, $sessid)) !== TRUE)
- // return $res;
- return PEAR::raiseError(
- 'GreenBox::addMetaDataRecord: not implemented', GBERR_NOTIMPL
- );
+ if(($res = $this->_authorize('write', $id, $sessid)) !== TRUE)
+ return $res;
+ return $this->bsAddMetaDataRecord($id, $propertyName, $propertyValue);
}
/**
@@ -422,21 +289,16 @@ class GreenBox extends Alib{
{
if(($res = $this->_authorize('read', $id, $sessid)) !== TRUE)
return $res;
- $ac =& StoredFile::recall(&$this, $id);
- if(PEAR::isError($ac)) return $ac;
- else{
- return $ac->getMetaData();
- }
+ return $this->bsGetMdata($id);
}
/**
* Search in local metadata database.
* TODO: NOT FINISHED
- * Should support structured queries, e.g.:
- * XML file with the structure as metadata, but
- * with SQL LIKE terms instead of metadata values.
- * Some standard query format would be better,
- * but I've not found it yet.
+ * It will support structured queries - array of mode and query parts.
+ * Mode is "match all" or "match any".
+ * Query parts is array of [fieldname, operator, value] entities.
+ *
*
* @param searchData string, search query -
* only one SQL LIKE term supported now.
@@ -447,211 +309,9 @@ class GreenBox extends Alib{
*/
function localSearch($searchData, $sessid='')
{
- $ftsrch = $searchData;
- $res = $this->dbc->getCol("SELECT md.gunid as gunid
- FROM {$this->filesTable} f, {$this->mdataTable} md
- WHERE f.gunid=md.gunid AND md.objns='_L' AND
- md.object like '%$ftsrch%'
- GROUP BY md.gunid
- ");
- if(!is_array($res)) $res = array();
- return $res;
+ return $this->bsLocalSearch($searchData);
}
- /* -------------------------------------------- remote repository methods */
-
- /**
- * Upload file to remote repository
- *
- * @param id int, virt.file's local id
- * @param gunid string, global id
- * @param sessid string, session id
- * @return string - transfer id or PEAR::error
- */
- function uploadFile($id, $gunid, $sessid='')
- {
- $res = $this->prepareForTransport($id, $gunid, $sessid);
- if(PEAR::isError($res)) return $res;
- list($mediaFile, $mdataFile, $gunid) = $res;
- $tr =& new Transport(&$this->dbc, $this->config);
- $res = $tr->uploadOpen($mediaFile, 'media', $sessid, $gunid);
- if(PEAR::isError($res)) return $res;
- $res2 = $tr->uploadOpen($mdataFile, 'metadata', $sessid, $gunid);
- if(PEAR::isError($res2)) return $res2;
- $res3 = $tr->getTransportStatus($res);
- $res4 = $tr->getTransportStatus($res2);
-# return $res;
- return array($res, $res2, $res3, $res4);
- }
-
- /**
- * Download file from remote repository
- *
- * @param gunid int, global unique id
- * @param sessid string, session id
- * @return string - transfer id or PEAR::error
- */
- function downloadFile($gunid, $sessid='')
- {
- $tr =& new Transport(&$this->dbc, $this->config);
- // get home dir if needed
- $res = $tr->downloadOpen($sessid, 'media', $gunid,
- $this->getSessUserId($sessid)
- );
- if(PEAR::isError($res)) return $res;
- $res2 = $tr->downloadOpen($sessid, 'metadata', $gunid,
- $this->getSessUserId($sessid)
- );
- if(PEAR::isError($res)) return $res;
- $res3 = $tr->getTransportStatus($res);
- $res4 = $tr->getTransportStatus($res2);
-# return $res;
- return array($res, $res2, $res3, $res4);
- }
-
-
-
- /**
- * Method for handling interupted transports via cron
- *
- */
- function cronJob()
- {
- $tr =& new Transport(&$this->dbc, $this->config);
- $ru = $tr->uploadCron();
- $rd = $tr->downloadCron(&$this);
- return array($ru, $rd);
- }
-
- /**
- * Get status of asynchronous transfer
- *
- * @param transferId int, id of asynchronous transfer
- * returned by uploadFile or downloadFile methods
- * @param sessid string, session id
- * @return string or PEAR::error
- */
- function getTransferStatus($transferId, $sessid='')
- {
- return PEAR::raiseError(
- 'GreenBox::getTransferStatus: not implemented', GBERR_NOTIMPL
- );
- }
-
- /**
- * Prepare symlink to media file and create metadata file for transport
- *
- * @param id
- * @param gunid
- * @param sessid
- * @return array
- */
- function prepareForTransport($id, $gunid, $sessid='')
- {
- if(!$gunid) $gunid = $this->_gunidFromId($id);
- else $id = $this->_idFromGunid($gunid);
- $ac =& StoredFile::recallByGunid(&$this, $gunid);
- if(PEAR::isError($ac)) return $ac;
- $mediaTarget = $ac->_getRealRADFname();
- $mediaFile = "$gunid";
- $mdataFile = "$gunid.xml";
- @symlink($mediaTarget, $this->transDir."/$mediaFile");
- $mdata = $this->getMdata($id, $sessid);
- if(PEAR::isError($mdata)) return $mdata;
- if(!($fh = fopen($this->transDir."/$mdataFile", 'w'))) $res=FALSE;
- else{
- $res = fwrite($fh, $mdata);
- fclose($fh);
- }
- if($res === FALSE) return PEAR::raiseError(
- "GreenBox::prepareForTransport:".
- " can't write metadata tmp file ($mdataFile)"
- );
- return array($mediaFile, $mdataFile, $gunid);
- }
-
- /**
- * Insert transported file and metadata into storage.
- * TODO: cals methods from LocStor - it's not good
- *
- * @param sessid string - session id
- * @param file string - local path to filr
- * @param type string - media|metadata|search
- * @param gunid string - global unique id
- */
- function processTransported($sessid, $file, $type, $gunid='X')
- {
- switch($type){
- case 'media':
- if(!file_exists($file)) break;
- $res = $this->storeAudioClip($sessid, $gunid,
- $file, '');
- if(PEAR::isError($res)) return $res;
- @unlink($file);
- break;
- case 'metadata':
- case 'mdata':
- if(!file_exists($file)) break;
- $res = $this->updateAudioClipMetadata($sessid, $gunid,
- $file);
- if(PEAR::isError($res)){
- // catch valid exception
- if($res->getCode() == GBERR_FOBJNEX){
- $res2 = $this->storeAudioClip($sessid, $gunid,
- '', $file);
- if(PEAR::isError($res2)) return $res2;
- }else return $res;
- }
- @unlink($file);
- break;
- case 'search':
- //$this->localSearch($criteria);
- return PEAR::raiseError("processTranferred: search not implemented");
- break;
- default:
- return PEAR::raiseError("processTranferred: unknown type ($type)");
- break;
- }
- }
-
- /**
- * Search in central metadata database
- *
- * @param searchData string, search query - see localSearch method
- * @param sessid string, session id
- * @return string - job id or PEAR::error
- */
- function globalSearch($searchData, $sessid='')
- {
- return PEAR::raiseError(
- 'GreenBox::globalSearch: not implemented', GBERR_NOTIMPL
- );
- /*
- $srchid = md5($sessid.mtime());
- $fh = fopen($this->transDir."/$srchid", "w");
- fwrite($fh, serialize($searchData));
- fclose($fh);
- $res = $tr->uploadOpen($srchid, 'search', $sessid, $gunid);
- if(PEAR::isError($res)) return $res;
- return $res;
- */
- }
-
- /**
- * Get results from asynchronous search
- *
- * @param transferId int, transfer id returned by
- * @param sessid string, session id
- * @return array with results or PEAR::error
- */
- function getSearchResults($transferId, $sessid='')
- {
- return PEAR::raiseError(
- 'GreenBox::getSearchResults: not implemented', GBERR_NOTIMPL
- );
- }
-
-
/* --------------------------------------------------------- info methods */
/**
@@ -665,43 +325,9 @@ class GreenBox extends Alib{
{
if(($res = $this->_authorize('read', $id, $sessid)) !== TRUE)
return $res;
- if($this->getObjType($id)!=='Folder')
- return PEAR::raiseError(
- 'GreenBox::listFolder: not a folder', GBERR_NOTF
- );
- $a = $this->getDir($id, 'id, name, type, param as target', 'name');
- return $a;
+ return $this->bsListFolder($id);
}
- /**
- * List files in folder
- *
- * @param id int, local id of object
- * @param relPath string, relative path
- * @return array
- */
- function getObjIdFromRelPath($id, $relPath='.')
- {
- $a = split('/', $relPath);
- if($this->getObjType($id)!=='Folder') $nid = $this->getparent($id);
- else $nid = $id;
- foreach($a as $i=>$item){
- switch($item){
- case".":
- break;
- case"..":
- $nid = $this->getparent($nid);
- break;
- case"":
- break;
- default:
- $nid = $this->getObjId($item, $nid);
- }
- }
- return $nid;
- }
-
-
/* ---------------------------------------------------- redefined methods */
/**
@@ -712,13 +338,15 @@ class GreenBox extends Alib{
*/
function logout($sessid)
{
+ /* release all accessed files on logout - probably not useful
$acfa = $this->dbc->getAll("SELECT * FROM {$this->accessTable}
WHERE sessid='$sessid'");
if(PEAR::isError($acfa)) return $acfa;
foreach($acfa as $i=>$acf){
- $ac =& StoredFile::recallFromLink(&$this, $acf['tmplink'], $sessid);
- $ac->releaseRawMediaData($sessid);
+ $ac =& StoredFile::recallByToken(&$this, $acf['token']);
+ $ac->releaseRawMediaData($sessid, $acf['token']);
}
+ */
return parent::logout($sessid);
}
@@ -898,248 +526,5 @@ class GreenBox extends Alib{
);
}
- /* =============================================== test and debug methods */
- /**
- * dump
- *
- */
- function dump($id='', $indch=' ', $ind='', $format='{name}')
- {
- if($id=='') $id = $this->storId;
- return parent::dump($id, $indch, $ind, $format);
- }
-
- /**
- *
- *
- */
- function dumpDir($id='', $format='$o["name"]')
- {
- if($id=='') $id = $this->storId;
- $arr = $this->getDir($id, 'id,name');
-// if($this->doDebug){ $this->debug($arr); exit; }
- $arr = array_map(create_function('$o', 'return "'.$format.'";'), $arr);
- return join('', $arr);
- }
-
- /**
- *
- *
- */
- function debug($va)
- {
- echo"\n"; print_r($va); #exit;
- }
-
- /**
- * deleteData
- *
- * @return void
- */
- function deleteData()
- {
-// $this->dbc->query("DELETE FROM {$this->filesTable}");
- $ids = $this->dbc->getAll("SELECT id FROM {$this->filesTable}");
- if(is_array($ids)) foreach($ids as $i=>$item){
- $this->removeObj($item['id']);
- }
- parent::deleteData();
- $this->initData();
- }
- /**
- * testData
- *
- */
- function testData($d='')
- {
- $exdir = '../../../storageServer/var/tests';
- $s = $this->sessid;
- $o[] = $this->addSubj('test1', 'a');
- $o[] = $this->addSubj('test2', 'a');
- $o[] = $this->addSubj('test3', 'a');
- $o[] = $this->addSubj('test4', 'a');
-
- $o[] = $t1hd = $this->getObjId('test1', $this->storId);
- $o[] = $t1d1 = $this->createFolder($t1hd, 'test1_folder1', $s);
- $o[] = $this->createFolder($t1hd, 'test1_folder2', $s);
- $o[] = $this->createFolder($t1d1, 'test1_folder1_1', $s);
- $o[] = $t1d12 = $this->createFolder($t1d1, 'test1_folder1_2', $s);
-
- $o[] = $t2hd = $this->getObjId('test2', $this->storId);
- $o[] = $this->createFolder($t2hd, 'test2_folder1', $s);
-
- $o[] = $this->putFile($t1hd, 'file1.mp3', "$exdir/ex1.mp3", '', $s);
- $o[] = $this->putFile($t1d12 , 'file2.wav', "$exdir/ex2.wav", '', $s);
-/*
-*/
- $this->tdata['storage'] = $o;
- }
-
- /**
- * test
- *
- */
- function test()
- {
-// if(PEAR::isError($p = parent::test())) return $p;
- $this->deleteData();
- $this->login('root', $this->config['tmpRootPass']);
- $this->testData();
- $this->logout($this->sessid);
- $this->test_correct = " StorageRoot
- root
- test1
- test1_folder1
- test1_folder1_1
- test1_folder1_2
- file2.wav
- test1_folder2
- file1.mp3
- test2
- test2_folder1
- test3
- test4
-";
- $this->test_dump = $this->dumpTree($this->storId);
- if($this->test_dump==$this->test_correct)
- { $this->test_log.="storageServer: OK\n"; return true; }
- else PEAR::raiseError('GreenBox::test:', 1, PEAR_ERROR_DIE, '%s'.
- "\ncorrect:\n.{$this->test_correct}.\n".
- "dump:\n.{$this->test_dump}.\n\n");
- }
-
- /**
- * initData - initialize
- *
- */
- function initData()
- {
- $this->rootId = $this->getRootNode();
- $this->storId = $this->wd =
- $this->addObj('StorageRoot', 'Folder', $this->rootId);
- $rootUid = parent::addSubj('root', $this->config['tmpRootPass']);
- $this->login('root', $this->config['tmpRootPass']);
- $res = $this->addPerm($rootUid, '_all', $this->rootId, 'A');
- $fid = $this->createFolder($this->storId, 'root', $this->sessid);
-# $id = $this->dbc->nextId("{$this->mdataTable}_id_seq");
- $this->logout($this->sessid);
- }
- /**
- * install - create tables
- *
- */
- function install()
- {
- parent::install();
- $this->dbc->query("CREATE TABLE {$this->filesTable} (
- id int not null,
- gunid char(32) not null,
- name varchar(255) not null default'',
- type varchar(255) not null default'',
- currentlyAccessing int not null default 0
- )");
- $this->dbc->query("CREATE UNIQUE INDEX {$this->filesTable}_id_idx
- ON {$this->filesTable} (id)");
- $this->dbc->query("CREATE UNIQUE INDEX {$this->filesTable}_gunid_idx
- ON {$this->filesTable} (gunid)");
- $this->dbc->query("CREATE INDEX {$this->filesTable}_name_idx
- ON {$this->filesTable} (name)");
-
- $this->dbc->createSequence("{$this->mdataTable}_id_seq");
- $this->dbc->query("CREATE TABLE {$this->mdataTable} (
- id int not null,
- gunid char(32),
- subjns varchar(255), -- subject namespace shortcut/uri
- subject varchar(255) not null default '',
- predns varchar(255), -- predicate namespace shortcut/uri
- predicate varchar(255) not null,
- predxml char(1) not null default 'T', -- Tag or Attribute
- objns varchar(255), -- object namespace shortcut/uri
- object text
- )");
- $this->dbc->query("CREATE UNIQUE INDEX {$this->mdataTable}_id_idx
- ON {$this->mdataTable} (id)");
- $this->dbc->query("CREATE INDEX {$this->mdataTable}_gunid_idx
- ON {$this->mdataTable} (gunid)");
- $this->dbc->query("CREATE INDEX {$this->mdataTable}_subj_idx
- ON {$this->mdataTable} (subjns, subject)");
- $this->dbc->query("CREATE INDEX {$this->mdataTable}_pred_idx
- ON {$this->mdataTable} (predns, predicate)");
-
- $this->dbc->query("CREATE TABLE {$this->accessTable} (
- gunid char(32) not null,
- sessid char(32) not null,
- tmpLink varchar(255) not null default'',
- ts timestamp
- )");
- $this->dbc->query("CREATE INDEX {$this->accessTable}_acc_idx
- ON {$this->accessTable} (tmpLink, sessid)");
- if(!file_exists($this->bufferDir)){
- mkdir($this->bufferDir, 02775);
- chmod($this->bufferDir, 02775); // may be obsolete
- }
- $this->initData();
- }
- /**
- * id subjns subject predns predicate objns object
- * y1 literal xmbf NULL namespace literal http://www.sotf.org/xbmf
- * x1 gunid xbmf contributor NULL NULL
- * x2 mdid x1 xbmf role literal Editor
- *
- * predefined shortcuts:
- * _L = literal
- * _G = gunid (global id of media file)
- * _I = mdid (local id of metadata record)
- * _nssshortcut = namespace shortcut definition
- * _blank = blank node
- */
-
- /**
- * uninstall
- *
- * @return void
- */
- function uninstall()
- {
- $this->dbc->query("DROP TABLE {$this->mdataTable}");
- $this->dbc->dropSequence("{$this->mdataTable}_id_seq");
- $this->dbc->query("DROP TABLE {$this->filesTable}");
- $this->dbc->query("DROP TABLE {$this->accessTable}");
- $d = dir($this->storageDir);
- while (is_object($d) && (false !== ($entry = $d->read()))){
- if(filetype("{$this->storageDir}/$entry")=='dir' &&
- $entry!='CVS' && strlen($entry)==3)
- {
- $dd = dir("{$this->storageDir}/$entry");
- while (false !== ($ee = $dd->read())){
- if(substr($ee, 0, 1)!=='.')
- unlink("{$this->storageDir}/$entry/$ee");
- }
- $dd->close();
- rmdir("{$this->storageDir}/$entry");
- }
- }
- if(is_object($d)) $d->close();
- if(file_exists($this->bufferDir)){
- $d = dir($this->bufferDir);
- while (false !== ($entry = $d->read())) if(substr($entry,0,1)!='.')
- { unlink("{$this->bufferDir}/$entry"); }
- $d->close();
- rmdir($this->bufferDir);
- }
- parent::uninstall();
- }
-
- /**
- * Aux logging for debug
- *
- * @param msg string - log message
- */
- function debugLog($msg)
- {
- $fp=fopen("{$this->storageDir}/log", "a") or die("Can't write to log\n");
- fputs($fp, date("H:i:s").">$msg<\n");
- fclose($fp);
- }
}
?>
\ No newline at end of file
diff --git a/livesupport/modules/storageServer/var/LocStor.php b/livesupport/modules/storageServer/var/LocStor.php
index 0e13fba15..ca09dafcd 100644
--- a/livesupport/modules/storageServer/var/LocStor.php
+++ b/livesupport/modules/storageServer/var/LocStor.php
@@ -23,7 +23,7 @@
Author : $Author: tomas $
- Version : $Revision: 1.8 $
+ Version : $Revision: 1.9 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/LocStor.php,v $
------------------------------------------------------------------------------*/
@@ -36,6 +36,212 @@ require_once "GreenBox.php";
* Livesupport local storage interface
*/
class LocStor extends GreenBox{
+ /* ---------------------------------------------------------------- store */
+ /**
+ * Store or replace existing audio clip
+ *
+ * @param sessid string
+ * @param gunid string
+ * @param metadata string with metadata XML
+ * @param chsum string, md5 checksum of media file
+ * @return struct {url:writable URL for HTTP PUT, token:access token
+ */
+ function storeAudioClipOpen($sessid, $gunid, $metadata, $chsum)
+ {
+ // test if specified gunid exists:
+ $ac =& StoredFile::recallByGunid(&$this, $gunid);
+ if(!PEAR::isError($ac)){
+ // gunid exists - do replace
+ if(($res = $this->_authorize(
+ 'write', $ac->getId(), $sessid
+ )) !== TRUE) return $res;
+ if($ac->isAccessed()){
+ return PEAR::raiseError(
+ 'LocStor.php: storeAudioClip: is accessed'
+ );
+ }
+ $res = $ac->replace(
+ $ac->getId(), $ac->name, '', $metadata, 'string'
+ );
+ if(PEAR::isError($res)) return $res;
+ }else{
+ // gunid doesn't exists - do insert
+ $tmpid = uniqid('');
+ $parid = $this->getObjId(
+ $this->getSessLogin($sessid), $this->storId
+ );
+ if(PEAR::isError($parid)) return $parid;
+ if(($res = $this->_authorize('write', $parid, $sessid)) !== TRUE)
+ return $res;
+ $oid = $this->addObj($tmpid , 'File', $parid);
+ if(PEAR::isError($oid)) return $oid;
+ $ac =& StoredFile::insert(
+ &$this, $oid, '', '', $metadata, 'string', $gunid
+ );
+ if(PEAR::isError($ac)){
+ $res = $this->removeObj($oid);
+ return $ac;
+ }
+ $res = $this->renameFile($oid, $ac->gunid, $sessid);
+ if(PEAR::isError($res)) return $res;
+ }
+ $res = $ac->setState('incomplete');
+ if(PEAR::isError($res)) return $res;
+ return $this->bsOpenPut($chsum, $ac->gunid);
+ }
+
+ /**
+ * Store or replace existing audio clip
+ *
+ * @param sessid string
+ * @param token string
+ * @return string gunid or PEAR::error
+ */
+ function storeAudioClipClose($sessid, $token)
+ {
+ $ac =& StoredFile::recallByToken(&$this, $token);
+ $fname = $this->bsClosePut($token);
+ if(PEAR::isError($ac)){ return $ac; }
+ $res = $ac->replaceRawMediaData($fname);
+ if(PEAR::isError($res)){ return $res; }
+ @unlink($fname);
+ $res = $ac->setState('ready');
+ if(PEAR::isError($res)) return $res;
+ return $ac->gunid;
+ }
+
+ /* --------------------------------------------------------------- access */
+ /**
+ * Make access to audio clip
+ *
+ * @param sessid string
+ * @param gunid string
+ * @return array with: seekable filehandle, access token
+ */
+ function accessRawAudioData($sessid, $gunid)
+ {
+ $ac =& StoredFile::recallByGunid(&$this, $gunid);
+ if(PEAR::isError($ac)) return $ac;
+ if(($res = $this->_authorize('read', $ac->getId(), $sessid)) !== TRUE)
+ return $res;
+ return $ac->accessRawMediaData($sessid);
+ }
+
+ /**
+ * Release access to audio clip
+ *
+ * @param sessid string
+ * @param token string, access token
+ * @return boolean or PEAR::error
+ */
+ function releaseRawAudioData($sessid, $token)
+ {
+ $ac =& StoredFile::recallByToken(&$this, $token);
+ if(PEAR::isError($ac)) return $ac;
+ return $ac->releaseRawMediaData($token);
+ }
+
+ /* ------------------------------------------------------------- download */
+ /**
+ * Create and return downloadable URL for audio file
+ *
+ * @param sessid string, session id
+ * @param gunid string, global unique id
+ * @return array with: downloadable URL, download token
+ */
+ function downloadRawAudioDataOpen($sessid, $gunid)
+ {
+ $res = $this->existsAudioClip($sessid, $gunid);
+ if(PEAR::isError($res)) return $res;
+ $id = $this->_idFromGunid($gunid);
+ if(is_null($id)){
+ return PEAR::raiseError(
+ "LocStor::downloadRawAudioDataOpen: gunid not found ($gunid)"
+ );
+ }
+ if(($res = $this->_authorize('read', $id, $sessid)) !== TRUE)
+ return $res;
+ return $this->bsOpenDownload($id);
+ }
+
+ /**
+ * Discard downloadable URL for audio file
+ *
+ * @param token string, download token
+ * @return boolean
+ */
+ function downloadRawAudioDataClose($token)
+ {
+ return $this->bsCloseDownload($token);
+ }
+
+ /**
+ * Create and return downloadable URL for metadata
+ *
+ * @param sessid string, session id
+ * @param gunid string, global unique id
+ * @return array with: downloadable URL, download token
+ */
+ function downloadMetadataOpen($sessid, $gunid)
+ {
+ $res = $this->existsAudioClip($sessid, $gunid);
+ if(PEAR::isError($res)) return $res;
+ $id = $this->_idFromGunid($gunid);
+ if(is_null($id)){
+ return PEAR::raiseError(
+ "LocStor::downloadMetadataOpen: gunid not found ($gunid)"
+ );
+ }
+ if(($res = $this->_authorize('read', $id, $sessid)) !== TRUE)
+ return $res;
+ return $this->bsOpenDownload($id, 'metadata');
+ }
+
+ /**
+ * Discard downloadable URL for metadata
+ *
+ * @param token string, download token
+ * @return boolean
+ */
+ function downloadMetadataClose($token)
+ {
+ return $this->bsCloseDownload($token, 'metadata');
+ }
+
+ /**
+ * Return metadata as XML
+ *
+ * @param sessid string
+ * @param gunid string
+ * @return string or PEAR::error
+ */
+ function getAudioClip($sessid, $gunid)
+ {
+ $ac =& StoredFile::recallByGunid(&$this, $gunid);
+ if(PEAR::isError($ac)) return $ac;
+ if(($res = $this->_authorize('read', $ac->getId(), $sessid)) !== TRUE)
+ return $res;
+ $md = $this->getMdata($ac->getId(), $sessid);
+ if(PEAR::isError($md)) return $md;
+ return $md;
+ }
+
+ /* --------------------------------------------------------------- search */
+ /**
+ * Search in metadata database
+ *
+ * @param sessid string
+ * @param criteria string
+ * @return array or PEAR::error
+ * @see GreenBox::localSearch
+ */
+ function searchMetadata($sessid, $criteria)
+ {
+ $res = $this->localSearch($criteria, $sessid);
+ return $res;
+ }
+
+ /* ----------------------------------------------------------------- etc. */
/**
* Check if audio clip exists
*
@@ -61,56 +267,7 @@ class LocStor extends GreenBox{
return $res;
return $ac->exists();
}
- /**
- * Store or replace existing audio clip
- *
- * @param sessid string
- * @param gunid string
- * @param mediaFileLP string, local path to media file
- * @param mdataFileLP string, local path to metadata XML file
- * @return string gunid or PEAR::error
- */
- function storeAudioClip($sessid, $gunid, $mediaFileLP, $mdataFileLP)
- {
- // test if specified gunid exists:
- $ac =& StoredFile::recallByGunid(&$this, $gunid);
- if(!PEAR::isError($ac)){
- // gunid exists - do replace
- if(($res = $this->_authorize(
- 'write', $ac->getId(), $sessid
- )) !== TRUE) return $res;
- if($ac->isAccessed()){
- return PEAR::raiseError(
- 'LocStor.php: storeAudioClip: is accessed'
- );
- }
- $res = $ac->replace(
- $ac->getId(), $ac->name,$mediaFileLP, $mdataFileLP
- );
- if(PEAR::isError($res)) return $res;
- }else{
- // gunid doesn't exists - do insert
- $tmpid = uniqid('');
- $parid = $this->getObjId(
- $this->getSessLogin($sessid), $this->storId
- );
- if(PEAR::isError($parid)) return $parid;
- if(($res = $this->_authorize('write', $parid, $sessid)) !== TRUE)
- return $res;
- $oid = $this->addObj($tmpid , 'File', $parid);
- if(PEAR::isError($oid)) return $oid;
- $ac =& StoredFile::insert(
- &$this, $oid, '', $mediaFileLP, $mdataFileLP, $gunid
- );
- if(PEAR::isError($ac)){
- $res = $this->removeObj($oid);
- return $ac;
- }
- $res = $this->renameFile($oid, $ac->gunid, $sessid);
- if(PEAR::isError($res)) return $res;
- }
- return $ac->gunid;
- }
+
/**
* Delete existing audio clip
*
@@ -133,82 +290,24 @@ class LocStor extends GreenBox{
if(PEAR::isError($res)) return $res;
return TRUE;
}
+
/**
* Update existing audio clip metadata
*
* @param sessid string
* @param gunid string
- * @param mdataFileLP string, local path to metadata XML file
+ * @param metadata string, metadata XML string
* @return boolean or PEAR::error
*/
- function updateAudioClipMetadata($sessid, $gunid, $mdataFileLP)
+ function updateAudioClipMetadata($sessid, $gunid, $metadata)
{
$ac =& StoredFile::recallByGunid(&$this, $gunid);
if(PEAR::isError($ac)) return $ac;
if(($res = $this->_authorize('write', $ac->getId(), $sessid)) !== TRUE)
return $res;
- return $ac->replaceMetaData($mdataFileLP);
- }
- /**
- * Make access to audio clip
- *
- * @param sessid string
- * @param gunid string
- * @return string - access symlink path or PEAR::error
- */
- function accessRawAudioData($sessid, $gunid)
- {
- $ac =& StoredFile::recallByGunid(&$this, $gunid);
- if(PEAR::isError($ac)) return $ac;
- if(($res = $this->_authorize('read', $ac->getId(), $sessid)) !== TRUE)
- return $res;
- return $ac->accessRawMediaData($sessid);
- }
- /**
- * Release access to audio clip
- *
- * @param sessid string
- * @param tmpLink string
- * @return boolean or PEAR::error
- */
- function releaseRawAudioData($sessid, $tmpLink)
- {
- $ac =& StoredFile::recallFromLink(&$this, $tmpLink, $sessid);
- if(PEAR::isError($ac)) return $ac;
- if(($res = $this->_authorize('read', $ac->getId(), $sessid)) !== TRUE)
- return $res;
- return $ac->releaseRawMediaData($sessid);
- }
- /**
- * Search in metadata database
- *
- * @param sessid string
- * @param criteria string
- * @return array or PEAR::error
- * @see GreenBox::localSearch
- */
- function searchMetadata($sessid, $criteria)
- {
- $res = $this->localSearch($criteria, $sessid);
- return $res;
- }
- /**
- * Return metadata as XML
- *
- * @param sessid string
- * @param gunid string
- * @return string or PEAR::error
- */
- function getAudioClip($sessid, $gunid)
- {
- $ac =& StoredFile::recallByGunid(&$this, $gunid);
- if(PEAR::isError($ac)) return $ac;
- if(($res = $this->_authorize('read', $ac->getId(), $sessid)) !== TRUE)
- return $res;
- $md = $this->getMdata($ac->getId(), $sessid);
- if(PEAR::isError($md)) return $md;
- return $md;
+ return $ac->replaceMetaData($metadata, 'string');
}
+
/**
* Reset storageServer for debugging.
*
diff --git a/livesupport/modules/storageServer/var/RawMediaData.php b/livesupport/modules/storageServer/var/RawMediaData.php
index f10592816..a5e08bf3d 100644
--- a/livesupport/modules/storageServer/var/RawMediaData.php
+++ b/livesupport/modules/storageServer/var/RawMediaData.php
@@ -23,7 +23,7 @@
Author : $Author: tomas $
- Version : $Revision: 1.3 $
+ Version : $Revision: 1.4 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/RawMediaData.php,v $
------------------------------------------------------------------------------*/
@@ -39,6 +39,7 @@
/* ================== RawMediaData ================== */
class RawMediaData{
+
/**
* Constructor
*
@@ -53,6 +54,7 @@ class RawMediaData{
$this->fname = $this->makeFname();
$this->exists = file_exists($this->fname);
}
+
/**
* Insert media file to filesystem
*
@@ -69,11 +71,10 @@ class RawMediaData{
}
umask(0002);
if(@copy($mediaFileLP, $this->fname)){
-// @chmod($this->fname, 0775);
$this->exists = TRUE;
return TRUE;
}else{
-// @unlink($this->fname);
+ //@unlink($this->fname); // maybe useless
$this->exists = FALSE;
return PEAR::raiseError(
"RawMediaData::insert: file save failed".
@@ -81,6 +82,7 @@ class RawMediaData{
);
}
}
+
/**
* Delete and insert media file
*
@@ -93,6 +95,7 @@ class RawMediaData{
if(PEAR::isError($r)) return $r;
return $this->insert($mediaFileLP);
}
+
/**
* Return true if file corresponding to the object exists
*
@@ -102,6 +105,7 @@ class RawMediaData{
{
return $this->exists;
}
+
/**
* Return filename
*
@@ -111,38 +115,42 @@ class RawMediaData{
{
return $this->fname;
}
+
+/*
/**
* Make access symlink to the media file
*
* @param accLinkName string, access symlink name
* @return string, access symlink name
- */
+ * /
function access($accLinkName)
{
if(!$this->exists) return FALSE;
if(file_exists($accLinkName)) return $accLinkName;
if(@symlink($this->fname, $accLinkName)){
-// @chmod($accLinkName, 0775);
return $accLinkName;
}else return PEAR::raiseError(
"RawMediaData::access: symlink create failed ($accLinkName)",
GBERR_FILEIO
);
}
+
/**
* Delete access symlink
*
* @param accLinkName string, access symlink name
* @return boolean or PEAR::error
- */
+ * /
function release($accLinkName)
{
if(!$this->exists) return FALSE;
if(@unlink($accLinkName)) return TRUE;
else return PEAR::raiseError(
- "RawMediaData::release: symlink unlink failed", GBERR_FILEIO
+ "RawMediaData::release: unlink failed ($accLinkName)", GBERR_FILEIO
);
}
+*/
+
/**
* Delete media file from filesystem
*
@@ -196,6 +204,7 @@ class RawMediaData{
{
return "{$this->resDir}/{$this->gunid}";
}
+
/**
* Test method
*
diff --git a/livesupport/modules/storageServer/var/StoredFile.php b/livesupport/modules/storageServer/var/StoredFile.php
index 50f56dad1..b8d59f457 100644
--- a/livesupport/modules/storageServer/var/StoredFile.php
+++ b/livesupport/modules/storageServer/var/StoredFile.php
@@ -23,7 +23,7 @@
Author : $Author: tomas $
- Version : $Revision: 1.6 $
+ Version : $Revision: 1.7 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/StoredFile.php,v $
------------------------------------------------------------------------------*/
@@ -59,7 +59,7 @@ class StoredFile{
$this->gb =& $gb;
$this->dbc =& $gb->dbc;
$this->filesTable = $gb->filesTable;
- $this->accessTable= $gb->accessTable;
+ $this->accessTable= $gb->accessTable;
$this->gunid = $gunid;
if(is_null($this->gunid)) $this->gunid = $this->_createGunid();
$this->resDir = $this->_getResDir($this->gunid);
@@ -68,6 +68,7 @@ class StoredFile{
$this->md =& new MetaData(&$gb, $this->gunid);
return $this->gunid;
}
+
/* ========= 'factory' methods - should be called to construct StoredFile */
/**
* Create instace of StoreFile object and insert new file
@@ -76,36 +77,41 @@ class StoredFile{
* @param oid int, local object id in the tree
* @param name string, name of new file
* @param mediaFileLP string, local path to media file
- * @param mdataFileLP string, local path to metadata XML file
+ * @param metadata string, local path to metadata XML file or XML string
+ * @param mdataLoc string 'file'|'string' (optional)
* @param gunid global unique id (optional) - for insert file with gunid
* @return instace of StoredFile object
*/
function insert(&$gb, $oid, $name,
- $mediaFileLP='', $mdataFileLP='', $gunid=NULL)
+ $mediaFileLP='', $metadata='', $mdataLoc='file', $gunid=NULL)
{
$ac =& new StoredFile(&$gb, ($gunid ? $gunid : NULL));
$ac->name = $name;
$ac->id = $oid;
$ac->type = "unKnown";
+ $emptyState = TRUE;
if($ac->name=='') $ac->name=$ac->gunid;
$this->dbc->query("BEGIN");
- $res = $ac->dbc->query("INSERT INTO {$ac->filesTable}
- (id, name, gunid, type)
+ $res = $ac->dbc->query("
+ INSERT INTO {$ac->filesTable}
+ (id, name, gunid, type, state)
VALUES
- ('$oid', '{$ac->name}', '{$ac->gunid}', '{$ac->type}')"
- );
+ ('$oid', '{$ac->name}', '{$ac->gunid}', '{$ac->type}',
+ 'incomplete')
+ ");
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
// --- metadata insert:
- if($mdataFileLP != ''){
- if(!file_exists($mdataFileLP))
+ if($metadata != ''){
+ if($mdataLoc=='file' && !file_exists($metadata))
{
return PEAR::raiseError("StoredFile::insert: ".
- "metadata file doesn't exists ($mdataFileLP)");
+ "metadata file doesn't exists ($metadata)");
}
- $res = $ac->md->insert($mdataFileLP);
+ $res = $ac->md->insert($metadata, $mdataLoc);
if(PEAR::isError($res)){
$this->dbc->query("ROLLBACK"); return $res;
}
+ $emptyState = FALSE;
}
// --- media file insert:
if($mediaFileLP != ''){
@@ -121,17 +127,22 @@ class StoredFile{
$mime = $ac->rmd->getMime();
//$gb->debugLog("gunid={$ac->gunid}, mime=$mime");
if($mime !== FALSE){
- $res = $ac->dbc->query("UPDATE {$ac->filesTable}
- SET type='$mime' WHERE id='$oid'");
+ $res = $ac->setType($mime);
if(PEAR::isError($res)){
$ac->dbc->query("ROLLBACK"); return $res;
}
}
+ $emptyState = FALSE;
+ }
+ if(!$emptyState){
+ $res = $ac->setState('ready');
+ if(PEAR::isError($res)){ $ac->dbc->query("ROLLBACK"); return $res; }
}
$res = $this->dbc->query("COMMIT");
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
return $ac;
}
+
/**
* Create instace of StoreFile object and recall existing file.
* Should be supplied oid XOR gunid - not both ;)
@@ -144,8 +155,10 @@ class StoredFile{
function recall(&$gb, $oid='', $gunid='')
{
$cond = ($oid != '' ? "id='".intval($oid)."'" : "gunid='$gunid'" );
- $row = $gb->dbc->getRow("SELECT id, gunid, type, name
- FROM {$gb->filesTable} WHERE $cond");
+ $row = $gb->dbc->getRow("
+ SELECT id, gunid, type, name
+ FROM {$gb->filesTable} WHERE $cond
+ ");
if(PEAR::isError($row)) return $row;
if(is_null($row)){
return PEAR::raiseError(
@@ -159,9 +172,10 @@ class StoredFile{
$ac->id = $row['id'];
return $ac;
}
+
/**
* Create instace of StoreFile object and recall existing file
- * by gunid.
+ * by gunid.
*
* @param gb reference to GreenBox object
* @param gunid string, optional, global unique id of file
@@ -171,24 +185,27 @@ class StoredFile{
{
return StoredFile::recall(&$gb, '', $gunid);
}
+
/**
- * Create instace of StoreFile object and recall existing file from tmpLink
+ * Create instace of StoreFile object and recall existing file
+ * by access token.
*
* @param gb reference to GreenBox object
- * @param tmpLink string
- * @param sessid string
+ * @param token string, access token
+ * @return instace of StoredFile object
*/
- function recallFromLink(&$gb, $tmpLink, $sessid)
+ function recallByToken(&$gb, $token)
{
$gunid = $gb->dbc->getOne("SELECT gunid FROM {$gb->accessTable}
- WHERE tmpLink='$tmpLink' AND sessid='$sessid'");
+ WHERE token='$token'");
if(PEAR::isError($gunid)) return $gunid;
if(is_null($gunid)) return PEAR::raiseError(
- "StoredFile::recallFromLink: accessobj not exist ($tmpLink)", GBERR_AOBJNEX);
+ "StoredFile::recallByToken: invalid token ($token)", GBERR_AOBJNEX);
return StoredFile::recall(&$gb, '', $gunid);
}
+
/**
- * Create instace of StoreFile object and make copy of existing file
+ * Create instace of StoredFile object and make copy of existing file
*
* @param src reference to source object
* @param nid int, new local id
@@ -208,35 +225,30 @@ class StoredFile{
* @param oid int, local id
* @param name string, name of file
* @param mediaFileLP string, local path to media file
- * @param mdataFileLP string, local path to metadata XML file or XML string
+ * @param metadata string, local path to metadata XML file or XML string
* @param mdataLoc string 'file'|'string'
*/
- function replace($oid, $name, $mediaFileLP='', $mdataFileLP='',
+ function replace($oid, $name, $mediaFileLP='', $metadata='',
$mdataLoc='file')
{
$this->dbc->query("BEGIN");
- $res = $this->dbc->query("UPDATE {$this->filesTable}
- SET name='$name', type='{$this->type}' WHERE id='$oid'");
+ $res = $this->rename($name);
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
- if($mediaFileLP != ''){
- $res = $this->rmd->replace($mediaFileLP, $this->type);
- if(PEAR::isError($res)){
- $this->dbc->query("ROLLBACK"); return $res;
- }
- $mime = $this->rmd->getMime();
- if($mime !== FALSE){
- $res = $this->dbc->query("UPDATE {$this->filesTable}
- SET type='$mime' WHERE id='$oid'");
- if(PEAR::isError($res)){
- $this->dbc->query("ROLLBACK"); return $res;
- }
- }
+ if($mediaFileLP != ''){ // media
+ $res = $this->replaceRawMediaData($mediaFileLP);
+ }else{
+ $res = $this->rmd->delete();
}
- if($mdataFileLP != ''){
- $res = $this->md->replace($mdataFileLP, $mdataLoc);
- if(PEAR::isError($res)){
- $this->dbc->query("ROLLBACK"); return $res;
- }
+ if(PEAR::isError($res)){
+ $this->dbc->query("ROLLBACK"); return $res;
+ }
+ if($metadata != ''){ // metadata
+ $res = $this->md->replace($metadata, $mdataLoc);
+ }else{
+ $res = $this->md->delete();
+ }
+ if(PEAR::isError($res)){
+ $this->dbc->query("ROLLBACK"); return $res;
}
$res = $this->dbc->query("COMMIT");
if(PEAR::isError($res)){
@@ -244,97 +256,107 @@ class StoredFile{
}
return TRUE;
}
+
/**
- * Increase access counter, create access record,
+ * Increase access counter, create access token, insert access record,
* call access method of RawMediaData
*
* @param sessid string
+ * @return array with: access URL, access token
*/
function accessRawMediaData($sessid)
{
$this->dbc->query("BEGIN");
- $res = $this->dbc->query("UPDATE {$this->filesTable}
+ $res = $this->dbc->query("
+ UPDATE {$this->filesTable}
SET currentlyAccessing=currentlyAccessing+1
- WHERE gunid='{$this->gunid}'");
+ WHERE gunid='{$this->gunid}'
+ ");
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
- $accLinkName = $this->_getAccessFname($sessid, $this->_getExt());
- $res = $this->dbc->query("INSERT INTO {$this->accessTable}
- (gunid, sessid, tmplink, ts)
- VALUES
- ('{$this->gunid}', '$sessid', '$accLinkName', now())");
+# $token = $this->_createGunid();
+ $realFname = $this->_getRealRADFname();
+ $ext = $this->_getExt();
+
+ $res = $this->gb->bsAccess($realFname, $ext, $this->gunid, $sessid);
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
- $acc = $this->rmd->access($accLinkName);
- if(PEAR::isError($acc)){ $this->dbc->query("ROLLBACK"); return $acc; }
- if($acc === FALSE){
- $this->dbc->query("ROLLBACK");
- return PEAR::raiseError(
- 'StoredFile::accessRawMediaData: not exists'
- );
- }
+ $resultArray =
+ array('url'=>"file://{$res['fname']}", 'token'=>$res['token']);
$res = $this->dbc->query("COMMIT");
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
- return $acc;
+ return $resultArray;
}
+
/**
* Decrease access couter, delete access record,
* call release method of RawMediaData
*
- * @param sessid string
+ * @param token string, access token
+ * @return boolean
*/
- function releaseRawMediaData($sessid)
+ function releaseRawMediaData($token)
{
$this->dbc->query("BEGIN");
$res = $this->dbc->query("UPDATE {$this->filesTable}
SET currentlyAccessing=currentlyAccessing-1
- WHERE gunid='{$this->gunid}' AND currentlyAccessing>0"
- );
+ WHERE gunid='{$this->gunid}' AND currentlyAccessing>0
+ ");
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
- $ca = $this->dbc->getOne("SELECT currentlyAccessing
- FROM {$this->filesTable}
- WHERE gunid='{$this->gunid}'"
- );
- if(PEAR::isError($ca)){ $this->dbc->query("ROLLBACK"); return $ca; }
- $accLinkName = $this->_getAccessFname($sessid, $this->_getExt());
- $res = $this->dbc->query("DELETE FROM {$this->accessTable}
- WHERE gunid='{$this->gunid}' AND sessid='$sessid'
- AND tmplink='$accLinkName'");
+ $res = $this->gb->bsRelease($token);
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
$res = $this->dbc->query("COMMIT");
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
- if(intval($ca)==0) return $this->rmd->release($accLinkName);
return TRUE;
}
+
+ /**
+ * Replace media file only with new binary file
+ *
+ * @param mediaFileLP string, local path to media file
+ */
+ function replaceRawMediaData($mediaFileLP)
+ {
+ $res = $this->rmd->replace($mediaFileLP);
+ if(PEAR::isError($res)){ return $res; }
+ $mime = $this->rmd->getMime();
+ if($mime !== FALSE){
+ $res = $this->setType($mime);
+ if(PEAR::isError($res)){ return $res; }
+ }
+ }
+
/**
* Replace metadata with new XML file
*
- * @param mdataFileLP string, local path to metadata XML file or XML string
+ * @param metadata string, local path to metadata XML file or XML string
* @param mdataLoc string 'file'|'string'
*/
- function replaceMetaData($mdataFileLP, $mdataLoc='file')
+ function replaceMetaData($metadata, $mdataLoc='file')
{
$this->dbc->query("BEGIN");
- $res = $this->md->replace($mdataFileLP, $mdataLoc);
+ $res = $this->md->replace($metadata, $mdataLoc);
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
$res = $this->dbc->query("COMMIT");
if(PEAR::isError($res)) return $res;
return TRUE;
}
+
/**
* Update metadata with new XML file
*
- * @param mdataFileLP string, local path to metadata XML file or XML string
+ * @param metadata string, local path to metadata XML file or XML string
* @param mdataLoc string 'file'|'string'
* @return boolean or PEAR::error
*/
- function updateMetaData($mdataFileLP, $mdataLoc='file')
+ function updateMetaData($metadata, $mdataLoc='file')
{
$this->dbc->query("BEGIN");
- $res = $this->md->update($mdataFileLP, $mdataLoc);
+ $res = $this->md->update($metadata, $mdataLoc);
if(PEAR::isError($res)){ $this->dbc->query("ROLLBACK"); return $res; }
$res = $this->dbc->query("COMMIT");
if(PEAR::isError($res)) return $res;
return TRUE;
}
+
/**
* Update object namespace and value of one metadata record
*
@@ -349,6 +371,7 @@ class StoredFile{
{
return $this->md->updateRecord($mdid, $object, $objns='_L');
}
+
/**
* Get metadata as XML string
*
@@ -359,6 +382,7 @@ class StoredFile{
{
return $this->md->getMetaData();
}
+
/**
* Analyze file with getid3 module.
* Obtain some metadata stored in media file.
@@ -372,6 +396,7 @@ class StoredFile{
$ia = $this->rmd->analyze();
return $ia;
}
+
/**
* Rename stored virtual file
*
@@ -380,11 +405,46 @@ class StoredFile{
*/
function rename($newname)
{
- $res = $this->dbc->query("UPDATE {$this->filesTable} SET name='$newname'
- WHERE gunid='{$this->gunid}'");
+ $res = $this->dbc->query("
+ UPDATE {$this->filesTable} SET name='$newname'
+ WHERE gunid='{$this->gunid}'
+ ");
if(PEAR::isError($res)) return $res;
return TRUE;
}
+
+ /**
+ * Set state of virtual file
+ *
+ * @param state string, 'empty'|'incomplete'|'ready'|'edited'
+ * @return boolean or error
+ */
+ function setState($state)
+ {
+ $res = $this->dbc->query("
+ UPDATE {$this->filesTable} SET state='$state'
+ WHERE gunid='{$this->gunid}'
+ ");
+ if(PEAR::isError($res)){ return $res; }
+ return TRUE;
+ }
+
+ /**
+ * Set mime-type of virtual file
+ *
+ * @param type string, mime-type
+ * @return boolean or error
+ */
+ function setType($type)
+ {
+ $res = $this->dbc->query("
+ UPDATE {$this->filesTable} SET type='$type'
+ WHERE gunid='{$this->gunid}'
+ ");
+ if(PEAR::isError($res)){ return $res; }
+ return TRUE;
+ }
+
/**
* Delete stored virtual file
*
@@ -397,10 +457,11 @@ class StoredFile{
if(PEAR::isError($res)) return $res;
$res = $this->md->delete();
if(PEAR::isError($res)) return $res;
- $links = $this->dbc->getAll("SELECT tmplink FROM {$this->accessTable}
+ $tokens = $this->dbc->getAll("SELECT token FROM {$this->accessTable}
WHERE gunid='{$this->gunid}'");
- if(is_array($links)) foreach($links as $i=>$item){
- @unlink($item['tmplink']);
+ if(is_array($tokens)) foreach($tokens as $i=>$item){
+ $file = _getAccessFname($item['token'], $item['ext']);
+ @unlink($file);
}
$res = $this->dbc->query("DELETE FROM {$this->accessTable}
WHERE gunid='{$this->gunid}'");
@@ -425,6 +486,7 @@ class StoredFile{
WHERE gunid='$gunid'
"));
}
+
/**
* Returns local id of virtual file
*
@@ -433,14 +495,17 @@ class StoredFile{
{
return $this->id;
}
+
/**
* Returns true if raw media file exists
*
*/
function exists()
{
- $indb = $this->dbc->getRow("SELECT gunid FROM {$this->filesTable}
- WHERE gunid='{$this->gunid}'");
+ $indb = $this->dbc->getRow("
+ SELECT gunid FROM {$this->filesTable}
+ WHERE gunid='{$this->gunid}'
+ ");
return (!is_null($indb) && $this->rmd->exists());
}
@@ -451,9 +516,11 @@ class StoredFile{
*/
function _createGunid()
{
- return md5(microtime().$_SERVER['SERVER_ADDR'].rand().
- "org.mdlf.livesupport");
+ return md5(
+ microtime().$_SERVER['SERVER_ADDR'].rand()."org.mdlf.livesupport"
+ );
}
+
/**
* Get local id from global id.
* Static or dynamic call is possible.
@@ -471,6 +538,7 @@ class StoredFile{
);
return $id;
}
+
/**
* Return suitable extension.
* TODO: make it general - is any tool for it?
@@ -487,6 +555,7 @@ class StoredFile{
}
return $ext;
}
+
/**
* Get filetype from global id
*
@@ -494,9 +563,12 @@ class StoredFile{
*/
function _getType($gunid)
{
- return $this->dbc->getOne("SELECT type FROM {$this->filesTable}
- WHERE gunid='$gunid'");
+ return $this->dbc->getOne("
+ SELECT type FROM {$this->filesTable}
+ WHERE gunid='$gunid'
+ ");
}
+
/**
* Get and optionaly create subdirectory in real filesystem for storing
* raw media data
@@ -509,6 +581,7 @@ class StoredFile{
if(!file_exists($resDir)){ mkdir($resDir, 02775); chmod($resDir, 02775); }
return $resDir;
}
+
/**
* Get real filename of raw media data
*
@@ -518,14 +591,15 @@ class StoredFile{
{
return $this->rmd->getFname();
}
+
/**
* Create and return name for temporary symlink.
* TODO: Should be more unique
*
*/
- function _getAccessFname($sessid, $ext='EXT')
+ function _getAccessFname($token, $ext='EXT')
{
- $spart = md5("{$sessid}_{$this->gunid}");
+ $spart = md5($token);
return "{$this->accessDir}/$spart.$ext";
}
}
diff --git a/livesupport/modules/storageServer/var/html/gbHttp.php b/livesupport/modules/storageServer/var/html/gbHttp.php
index 9d5f6e82f..17e5f091e 100644
--- a/livesupport/modules/storageServer/var/html/gbHttp.php
+++ b/livesupport/modules/storageServer/var/html/gbHttp.php
@@ -23,7 +23,7 @@
Author : $Author: tomas $
- Version : $Revision: 1.6 $
+ Version : $Revision: 1.7 $
Location : $ $
------------------------------------------------------------------------------*/
@@ -33,7 +33,7 @@ require_once"gbHtml_h.php";
* storageServer WWW-form interface
*
* @author $Author: tomas $
- * @version $Revision: 1.6 $
+ * @version $Revision: 1.7 $
* @see Alib
* @see GreenBox
*/
@@ -147,7 +147,7 @@ switch($_REQUEST['act']){
* @param id int, destination folder id
*/
case"rename":
- $parid = $gb->getparent($id);
+ $parid = $gb->getParent($id);
$r = $gb->renameFile($id, $_REQUEST['newname'], $sessid);
if(PEAR::isError($r)) $_SESSION['alertMsg'] = $r->getMessage();
$redirUrl = BROWSER."?id=$parid";
@@ -164,7 +164,7 @@ switch($_REQUEST['act']){
case"move":
$newPath = urlencode($_REQUEST['newPath']);
$did = $gb->getObjIdFromRelPath($id, $newPath);
- $parid = $gb->getparent($id);
+ $parid = $gb->getParent($id);
$r = $gb->moveFile($id, $did, $sessid);
if(PEAR::isError($r)){
$_SESSION['alertMsg'] = $r->getMessage();
@@ -184,7 +184,7 @@ switch($_REQUEST['act']){
case"copy":
$newPath = urldecode($_REQUEST['newPath']);
$did = $gb->getObjIdFromRelPath($id, $newPath);
- $parid = $gb->getparent($id);
+ $parid = $gb->getParent($id);
$r = $gb->copyFile($id, $did, $sessid);
if(PEAR::isError($r)){
$_SESSION['alertMsg'] = $r->getMessage();
@@ -200,7 +200,7 @@ switch($_REQUEST['act']){
* @param id int, local id of deleted file or folder
*/
case"delete":
- $parid = $gb->getparent($id);
+ $parid = $gb->getParent($id);
$r = $gb->deleteFile($id, $sessid);
if(PEAR::isError($r)) $_SESSION['alertMsg'] = $r->getMessage();
$redirUrl = BROWSER."?id=$parid";
diff --git a/livesupport/modules/storageServer/var/xmlrpc/put.php b/livesupport/modules/storageServer/var/xmlrpc/put.php
new file mode 100644
index 000000000..cfdc58979
--- /dev/null
+++ b/livesupport/modules/storageServer/var/xmlrpc/put.php
@@ -0,0 +1,77 @@
+setFetchMode(DB_FETCHMODE_ASSOC);
+$gb = &new GreenBox(&$dbc, $config);
+
+$token = $_REQUEST['token'];
+
+function http_error($code, $err){
+ header("HTTP/1.1 $code");
+ header("Content-type: text/plain; charset=UTF-8");
+ echo "$err\r\n";
+ exit;
+}
+
+$tc = $gb->bsCheckToken($token, 'put');
+if(PEAR::isError($tc)){ echo "ERR".$tc->getMessage()."\n"; exit; }
+if(!$tc){ http_error(410, "Token not valid."); }
+#var_dump($tc); exit;
+
+header("Content-type: text/plain");
+#var_dump($_SERVER); var_dump($_REQUEST); exit;
+
+#$destfile = $_SERVER['PATH_TRANSLATED'];
+$destfile = "{$config['accessDir']}/{$token}";
+
+/* PUT data comes in on the input stream */
+$putdata = @fopen("php://input", "r") or
+ http_error(500, "put.php: Can't read input");
+
+/* Open a file for writing */
+$fp = @fopen($destfile, "ab") or
+ http_error(500, "put.php: Can't write to destination file (token=$token)");
+
+/* Read the data 1 KB at a time and write to the file */
+while ($data = fread($putdata, 1024)){
+ fwrite($fp, $data);
+}
+
+/* Close the streams */
+fclose($fp);
+fclose($putdata);
+
+header("HTTP/1.1 200");
+?>
\ No newline at end of file
diff --git a/livesupport/modules/storageServer/var/xmlrpc/simpleGet.php b/livesupport/modules/storageServer/var/xmlrpc/simpleGet.php
new file mode 100644
index 000000000..0ce6be2ed
--- /dev/null
+++ b/livesupport/modules/storageServer/var/xmlrpc/simpleGet.php
@@ -0,0 +1,59 @@
+setFetchMode(DB_FETCHMODE_ASSOC);
+
+$locStor = &new LocStor(&$dbc, $config);
+
+function http_error($code, $err){
+ header("HTTP/1.1 $code");
+ header("Content-type: text/plain; charset=UTF-8");
+ echo "$err\r\n";
+ exit;
+}
+
+$sessid = $_REQUEST['sessid'];
+$gunid = $_REQUEST['id'];
+
+$res = $locStor->existsAudioClip($sessid, $gunid);
+if(PEAR::isError($res)){ http_error(500, $res->getMessage()); }
+$ac =& StoredFile::recallByGunid(&$locStor, $gunid);
+if(PEAR::isError($ac)){ http_error(500, $ac->getMessage()); }
+$realFname = $ac->_getRealRADFname();
+$mime = $ac->rmd->getMime();
+header("Content-type: $mime");
+readfile($realFname);
+?>
diff --git a/livesupport/modules/storageServer/var/xmlrpc/testRunner.sh b/livesupport/modules/storageServer/var/xmlrpc/testRunner.sh
index 022b98146..95485fe6b 100755
--- a/livesupport/modules/storageServer/var/xmlrpc/testRunner.sh
+++ b/livesupport/modules/storageServer/var/xmlrpc/testRunner.sh
@@ -23,10 +23,12 @@
#
#
# Author : $Author: tomas $
-# Version : $Revision: 1.6 $
+# Version : $Revision: 1.7 $
# Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/xmlrpc/testRunner.sh,v $
#-------------------------------------------------------------------------------
+#DEBUG=yes
+
COMM=$1
shift
GUNID=$1
@@ -54,27 +56,79 @@ existsAudioClip() {
$XR_CLI existsAudioClip $SESSID $GUNID || exit $?
}
-accessRawAudioData() {
- echo "# accessRawAudioData: "
- FPATH=`$XR_CLI accessRawAudioData $SESSID $GUNID` || exit $?
- FPATH=""
- FPATH=`echo "$FPATH" | php -q`
- echo $FPATH
-# ls -l $FPATH
- echo -n "# releaseRawAudioData: "
- $XR_CLI releaseRawAudioData $SESSID $FPATH || exit $?
-#$XR_CLI getAudioClip $SESSID $GUNID
-}
-
storeAudioClip() {
- echo -n "# storeAudioClip: "
- MEDIA=../tests/ex1.mp3
+# echo -n "# storeAudioClip: "
+# MEDIA=../tests/ex1.mp3
+ MEDIA=var/tests/ex1.mp3
METADATA=../tests/testStorage.xml
- RGUNID=`$XR_CLI storeAudioClip "$SESSID" '' "$MEDIA" "$METADATA"` || \
+# RGUNID=`$XR_CLI storeAudioClip "$SESSID" '' "$MEDIA" "$METADATA"` || \
+# { ERN=$?; echo $RGUNID; exit $ERN; }
+ MD5=`md5sum $MEDIA`; for i in $MD5; do MD5=$i; break; done
+ echo -n "# storeAudioClipOpen: "
+ RES=`$XR_CLI storeAudioClipOpen "$SESSID" '' 'Title XY ' "$MD5"` || \
+ { ERN=$?; echo $RES; exit $ERN; }
+ unset URL
+ for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
+ echo $TOKEN
+ echo $URL
+ if [ $DEBUG ]; then echo -n "Pres a key ..."; read KEY; fi
+ echo -n "# curl (PUT): "
+ curl -C 0 -T $MEDIA $URL || { ERN=$?; echo $RGUNID; exit $ERN; }
+ echo "status: $?"
+ if [ $DEBUG ]; then echo -n "Pres a key ..."; read KEY; fi
+ echo -n "# storeAudioClipClose: "
+ RGUNID=`$XR_CLI storeAudioClipClose "$SESSID" "$TOKEN"` || \
{ ERN=$?; echo $RGUNID; exit $ERN; }
echo $RGUNID
}
+accessRawAudioData() {
+ echo "# accessRawAudioData: "
+ RES=`$XR_CLI accessRawAudioData $SESSID $GUNID` || \
+ { ERN=$?; echo $RES; exit $ERN; }
+ unset URL
+ for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
+ echo $TOKEN
+ echo $URL
+ if [ $DEBUG ]; then echo -n "Pres a key ..."; read KEY; fi
+ echo -n "# releaseRawAudioData: "
+ $XR_CLI releaseRawAudioData $SESSID $TOKEN || exit $?
+}
+
+downloadRAD() {
+ echo "# downloadRawAudioDataOpen: "
+ RES=`$XR_CLI downloadRawAudioDataOpen $SESSID $GUNID` || \
+ { ERN=$?; echo $RES; exit $ERN; }
+ unset URL
+ for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
+ echo $TOKEN
+ echo $URL
+ if [ $DEBUG ]; then echo -n "Pres a key ..."; read KEY; fi
+ echo -n "# curl: "
+ curl -Ifs $URL > /dev/null || { ERN=$?; echo $RES; exit $ERN; }
+ echo "status: $?"
+ echo -n "# downloadRawAudioDataClose: "
+ $XR_CLI downloadRawAudioDataClose $SESSID $TOKEN || exit $?
+}
+
+downloadMeta() {
+ echo "# downloadMetadataOpen: "
+ RES=`$XR_CLI downloadMetadataOpen $SESSID $GUNID` || \
+ { ERN=$?; echo $RES; exit $ERN; }
+ unset URL
+ for i in $RES; do if [ -z $URL ] ; then URL=$i; else TOKEN=$i; fi; done
+ echo $TOKEN
+ echo $URL
+ if [ $DEBUG ]; then echo -n "Pres a key ..."; read KEY; fi
+ echo -n "# curl: "
+ if [ $DEBUG ]; then lynx -source $URL; else
+ curl -Ifs $URL > /dev/null || { ERN=$?; echo $RES; exit $ERN; }
+ fi
+ echo "status: $?"
+ echo -n "# downloadMetadataClose: "
+ $XR_CLI downloadMetadataClose $SESSID $TOKEN || exit $?
+}
+
deleteAudioClip() {
echo -n "# deleteAudioClip: "
$XR_CLI deleteAudioClip $SESSID $GUNID || exit $?
@@ -145,6 +199,8 @@ elif [ "x$COMM" == "x" ]; then
storeAudioClip
GUNID=$RGUNID
accessRawAudioData
+ downloadRAD
+ downloadMeta
deleteAudioClip
logout
echo "#XMLRPC tests: OK."
diff --git a/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php b/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php
index dad35e7b7..515d6c0f0 100644
--- a/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php
+++ b/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php
@@ -23,11 +23,13 @@
Author : $Author: tomas $
- Version : $Revision: 1.8 $
+ Version : $Revision: 1.9 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/xmlrpc/xrLocStor.php,v $
------------------------------------------------------------------------------*/
-#error_reporting(0);
+
+/* ====================================================== specific PHP config */
+//error_reporting(0);
ini_set("error_prepend_string", "
@@ -48,11 +50,13 @@ ini_set("error_append_string", "
");
header("Content-type: text/xml");
+/* ================================================================= includes */
require_once 'DB.php';
require_once "XML/RPC/Server.php";
require_once '../conf.php';
require_once '../LocStor.php';
+/* ============================================ setting default error handler */
function errHndl($errno, $errmsg, $filename, $linenum, $vars){
if($errno == 8 /*E_NOTICE*/) return;
$xr =& new XML_RPC_Response(0, 805,
@@ -63,74 +67,14 @@ function errHndl($errno, $errmsg, $filename, $linenum, $vars){
}
$old_error_handler = set_error_handler("errHndl");
-PEAR::setErrorHandling(PEAR_ERROR_RETURN);
-$dbc = DB::connect($config['dsn'], TRUE);
-$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
-
-
+/* ====================================== XML-RPC interface class for LocStor */
+/**
+ * XML-RPC interface for LocStor class
+ *
+ */
class XR_LocStor extends LocStor{
- /**
- * Convert PHP variables to XMLRPC objects
- *
- * @param var mixed - PHP variable
- * @param struct boolean - flag for using XMLRPC struct instead of array
- * @return XMLRPC object
- */
- function _v2xr($var, $struct=true){
- if(is_array($var)){
- $r = array();
- foreach($var as $k=>$v){
- if($struct) $r[$k]=$this->_v2xr($v);
- else $r[]=$this->_v2xr($v);
- }
- return new XML_RPC_Value($r, ($struct ? "struct" : "array"));
- }else if(is_int($var)){
- return new XML_RPC_Value($var, "int");
- }else if(is_bool($var)){
- return new XML_RPC_Value($var, "boolean");
- }else{
- return new XML_RPC_Value($var, "string");
- }
- }
- /**
- * Convert XMLRPC struct to PHP array
- *
- * @param input XMLRPC struct
- * @return array
- */
- function _xr_getPars($input)
- {
- $p = $input->getParam(0);
- if(isset($p) && $p->scalartyp()=="struct"){
- $p->structreset(); $r = array();
- while(list($k,$v) = $p->structeach()){ $r[$k] = $v->scalarval(); }
- return array(TRUE, $r);
- }
- else return array(FALSE, new XML_RPC_Response(0, 801,
- "wrong 1st parameter, struct expected."
- ));
- }
-
- /**
- * Test XMLRPC - strupper and return given string,
- * also return loginname of logged user
- *
- * @param input XMLRPC struct
- * @return XMLRPC struct
- */
- function xr_test($input)
- {
- list($ok, $r) = $this->_xr_getPars($input);
- if(!$ok) return $r;
- return new XML_RPC_Response($this->_v2xr(array(
- 'str'=>strtoupper($r['teststring']),
- 'login'=>$this->getSessLogin($r['sessid']),
- 'sessid'=>$r['sessid']
- ), true));
- }
-
-
+ /* ------------------------------------------------------- authentication */
/**
* Checks the login name and password of the user and return
* true if login data are correct, othervise return false.
@@ -142,9 +86,9 @@ class XR_LocStor extends LocStor{
* login : string - login name
* pass : string - password
*
- * On success, returns a single XML-RPC value:
+ * On success, returns a XML-RPC struct with single field:
*
- * - boolean
+ * - authenticate : boolean
*
*
* On errors, returns an XML-RPC error response.
@@ -157,7 +101,7 @@ class XR_LocStor extends LocStor{
*
*
* @param input XMLRPC struct
- * @return boolean
+ * @return XMLRPC struct
* @see Subjects::authenticate
*/
function xr_authenticate($input)
@@ -169,7 +113,9 @@ class XR_LocStor extends LocStor{
return new XML_RPC_Response(0, 804,"xr_authenticate: database error");
}
$retval = ($res !== FALSE);
- return new XML_RPC_Response(new XML_RPC_Value($retval, "boolean"));
+ return new XML_RPC_Response(
+ XML_RPC_encode(array('authenticate'=>$retval))
+ );
}
/**
@@ -187,9 +133,9 @@ class XR_LocStor extends LocStor{
* pass : string - password
*
*
- * On success, returns a single XML-RPC value:
+ * On success, returns a XML-RPC struct with single field:
*
- * - string - the newly generated session ID
+ * - sessid : string - the newly generated session ID
*
*
* On errors, returns an XML-RPC error response.
@@ -204,7 +150,7 @@ class XR_LocStor extends LocStor{
*
*
* @param input XMLRPC struct
- * @return string
+ * @return XMLRPC struct
* @see Alib::login
*/
function xr_login($input)
@@ -220,11 +166,11 @@ class XR_LocStor extends LocStor{
"xr_login: login failed - incorrect username or password."
);
else
- return new XML_RPC_Response($this->_v2xr($res, false));
+ return new XML_RPC_Response(XML_RPC_encode(array('sessid'=>$res)));
}
/**
- * Logout, destroy session and return 'Bye'.
+ * Logout, destroy session and return status.
* If session is not valid error message is returned.
*
* The XML-RPC name of this method is "locstor.logout".
@@ -235,9 +181,9 @@ class XR_LocStor extends LocStor{
* sessid : string - session id
*
*
- * On success, returns a single XML-RPC value:
+ * On success, returns a XML-RPC struct with single field:
*
- * - boolean - TRUE
+ * - status : boolean - TRUE
*
*
* On errors, returns an XML-RPC error response.
@@ -250,7 +196,7 @@ class XR_LocStor extends LocStor{
*
*
* @param input XMLRPC struct
- * @return string
+ * @return XMLRPC struct
* @see GreenBox::logout
*/
function xr_logout($input)
@@ -258,14 +204,438 @@ class XR_LocStor extends LocStor{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->logout($r['sessid']);
- if(!PEAR::isError($res))
- return new XML_RPC_Response($this->_v2xr('Bye', false));
- else
+ if(PEAR::isError($res)){
return new XML_RPC_Response(0, 803,
"xr_logout: logout failed - not logged."
);
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res)));
}
+ /* ---------------------------------------------------------------- store */
+ /**
+ * Open writable URL for store new AudioClip or replace existing one.
+ * Writing to returned URL is possible using HTTP PUT method
+ * (as e.g. curl -T <filename> command does)
+ *
+ * The XML-RPC name of this method is "locstor.storeAudioClipOpen".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - gunid : string - global unique id of AudioCLip
+ * - metadata : metadata XML string
+ * - chsum : md5 checksum of media file
+ *
+ *
+ * On success, returns a XML-RPC struct:
+ *
+ * - url : string - writable URL for HTTP PUT
+ * - token : string - access token
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_storeAudioClipOpen:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::storeAudioClipOpen
+ */
+ function xr_storeAudioClipOpen($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->storeAudioClipOpen(
+ $r['sessid'], $r['gunid'], $r['metadata'], $r['chsum']
+ );
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_storeAudioClipOpen: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode($res));
+ }
+
+ /**
+ * Close writable URL for store new AudioClip or replace existing one.
+ *
+ * The XML-RPC name of this method is "locstor.storeAudioClip".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - token : string - access token
+ *
+ *
+ * On success, returns a XML-RPC struct with single field:
+ *
+ * - gunid : string - gunid of stored file
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_storeAudioClipClose:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::storeAudioClipClose
+ */
+ function xr_storeAudioClipClose($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->storeAudioClipClose($r['sessid'], $r['token']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_storeAudioClipClose: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('gunid'=>$res)));
+ }
+
+ /* ------------------------------------------------ access raw audio data */
+ /**
+ * Make access to audio clip.
+ *
+ * The XML-RPC name of this method is "locstor.accessRawAudioData".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - gunid : string - global unique id of AudioClip
+ *
+ *
+ * On success, returns a XML-RPC struct:
+ *
+ * - url : string - local access url
+ * - token : string - access token
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_accessRawAudioData:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::accessRawAudioData
+ */
+ function xr_accessRawAudioData($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->accessRawAudioData($r['sessid'], $r['gunid']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_accessRawAudioData: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode($res));
+ }
+
+ /**
+ * Release access to audio clip
+ *
+ * The XML-RPC name of this method is "locstor.releaseRawAudioData".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - token : string - access token
+ * returned by locstor.accessRawAudioData
+ *
+ *
+ * On success, returns a XML-RPC struct with single field:
+ *
+ * - status : boolean
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_releaseRawAudioData:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::releaseRawAudioData
+ */
+ function xr_releaseRawAudioData($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->releaseRawAudioData($r['sessid'], $r['token']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_releaseRawAudioData: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res)));
+ }
+
+ /* ---------------------------------------------- download raw audio data */
+ /**
+ * Create downlodable URL for stored file
+ *
+ * The XML-RPC name of this method is "locstor.downloadRawAudioDataOpen".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - gunid : string - global unique id of AudioClip
+ *
+ *
+ * On success, returns a XML-RPC struct:
+ *
+ * - url : string - downloadable url
+ * - token : string - download token
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_accessRawAudioDataOpen:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::downloadRawAudioDataOpen
+ */
+ function xr_downloadRawAudioDataOpen($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->downloadRawAudioDataOpen($r['sessid'], $r['gunid']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_downloadRawAudioDataOpen: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode($res));
+ }
+
+ /**
+ * Delete downlodable URL with media file.
+ *
+ * The XML-RPC name of this method is "locstor.downloadRawAudioDataClose".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - token : string - download token
+ * returned by locstor.downloadRawAudioDataOpen
+ *
+ *
+ * On success, returns a XML-RPC struct with single field:
+ *
+ * - status : boolean
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_releaseRawAudioDataClose:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::downloadRawAudioDataClose
+ */
+ function xr_downloadRawAudioDataClose($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->downloadRawAudioDataClose($r['token']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_downloadRawAudioDataClose: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res)));
+ }
+
+ /* ---------------------------------------------------- download metadata */
+ /**
+ * Create downlodable URL for metadata part of stored file
+ *
+ * The XML-RPC name of this method is "locstor.downloadMetadataOpen".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - gunid : string - global unique id of AudioClip
+ *
+ *
+ * On success, returns a XML-RPC struct:
+ *
+ * - url : string - downloadable url
+ * - token : string - download token
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_downloadMetadataOpen:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::downloadRawAudioDataOpen
+ */
+ function xr_downloadMetadataOpen($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->downloadMetadataOpen($r['sessid'], $r['gunid']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_downloadMetadataOpen: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode($res));
+ }
+
+ /**
+ * Delete downlodable URL with metadata.
+ *
+ * The XML-RPC name of this method is "locstor.downloadMetadataClose".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - token : string - download token
+ * returned by locstor.downloadRawAudioDataOpen
+ *
+ *
+ * On success, returns a XML-RPC struct with single field:
+ *
+ * - status : boolean
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_downloadMetadataClose:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::downloadRawAudioDataClose
+ */
+ function xr_downloadMetadataClose($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->downloadMetadataClose($r['token']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_downloadMetadataClose: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res)));
+ }
+
+ /* --------------------------------------------------------------- delete */
+ /**
+ * Delete existing audio clip
+ *
+ * The XML-RPC name of this method is "locstor.deleteAudioClip".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - gunid : string - global unique id of AudioCLip
+ *
+ *
+ * On success, returns a XML-RPC struct with single field:
+ *
+ * - status : boolean - TRUE
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_deleteAudioClip:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::deleteAudioClip
+ */
+ function xr_deleteAudioClip($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->deleteAudioClip($r['sessid'], $r['gunid']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_deleteAudioClip: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res)));
+ }
+
+ /* ----------------------------------------------------------------- etc. */
/**
* Check if audio clip exists and return TRUE/FALSE
*
@@ -278,9 +648,9 @@ class XR_LocStor extends LocStor{
* gunid : string - global unique id of AudioCLip
*
*
- * On success, returns a single XML-RPC value:
+ * On success, returns a XML-RPC struct with single field:
*
- * - boolean
+ * - exists : boolean
*
*
* On errors, returns an XML-RPC error response.
@@ -294,7 +664,7 @@ class XR_LocStor extends LocStor{
*
*
* @param input XMLRPC struct
- * @return boolean
+ * @return XMLRPC struct
* @see LocStor::existsAudioClip
*/
function xr_existsAudioClip($input)
@@ -309,289 +679,7 @@ class XR_LocStor extends LocStor{
"xr_existsAudioClip: ".$res->getMessage().
" ".$res->getUserInfo()
);
- return new XML_RPC_Response(new XML_RPC_Value($res, "boolean"));
- }
-
- /**
- * Store new AudioClip or replace existing one.
- *
- * The XML-RPC name of this method is "locstor.storeAudioClip".
- *
- * The input parameters are an XML-RPC struct with the following
- * fields:
- *
- * - sessid : string - session id
- * - gunid : string - global unique id of AudioCLip
- * - mediaFileLP : local path of raw audio file
- * - mdataFileLP : local path of metadata XML file
- *
- *
- * On success, returns a single XML-RPC value:
- *
- * - string - gunid of stored file
- *
- *
- * On errors, returns an XML-RPC error response.
- * The possible error codes and error message are:
- *
- * - 3 - Incorrect parameters passed to method:
- * Wanted ... , got ... at param
- * - 801 - wrong 1st parameter, struct expected.
- * - 805 - xr_storeAudioClip:
- * <message from lower layer>
- *
- *
- * @param input XMLRPC struct
- * @return string
- * @see LocStor::storeAudioClip
- */
- function xr_storeAudioClip($input)
- {
- list($ok, $r) = $this->_xr_getPars($input);
- if(!$ok) return $r;
- $res = $this->storeAudioClip(
- $r['sessid'], $r['gunid'], $r['mediaFileLP'], $r['mdataFileLP']
- );
- if(!PEAR::isError($res))
- return new XML_RPC_Response(new XML_RPC_Value($res, "string"));
- else
- return new XML_RPC_Response(0, 805,
- "xr_storeAudioClip: ".$res->getMessage().
- " ".$res->getUserInfo()
- );
- }
-
- /**
- * Delete existing audio clip
- *
- * The XML-RPC name of this method is "locstor.deleteAudioClip".
- *
- * The input parameters are an XML-RPC struct with the following
- * fields:
- *
- * - sessid : string - session id
- * - gunid : string - global unique id of AudioCLip
- *
- *
- * On success, returns a single XML-RPC value:
- *
- * - boolean - TRUE
- *
- *
- * On errors, returns an XML-RPC error response.
- * The possible error codes and error message are:
- *
- * - 3 - Incorrect parameters passed to method:
- * Wanted ... , got ... at param
- * - 801 - wrong 1st parameter, struct expected.
- * - 805 - xr_deleteAudioClip:
- * <message from lower layer>
- *
- *
- * @param input XMLRPC struct
- * @return boolean
- * @see LocStor::deleteAudioClip
- */
- function xr_deleteAudioClip($input)
- {
- list($ok, $r) = $this->_xr_getPars($input);
- if(!$ok) return $r;
- $res = $this->deleteAudioClip($r['sessid'], $r['gunid']);
- if(!PEAR::isError($res))
- return new XML_RPC_Response(new XML_RPC_Value($res, "boolean"));
- else
- return new XML_RPC_Response(0, 805,
- "xr_deleteAudioClip: ".$res->getMessage().
- " ".$res->getUserInfo()
- );
- }
-
- /**
- * Update existing audio clip metadata
- *
- * The XML-RPC name of this method is "locstor.updateAudioClipMetadata".
- *
- * The input parameters are an XML-RPC struct with the following
- * fields:
- *
- * - sessid : string - session id
- * - gunid : string - global unique id of AudioCLip
- * - mdataFileLP : local path of metadata XML file
- *
- *
- * On success, returns a single XML-RPC value:
- *
- * - boolean - TRUE
- *
- *
- * On errors, returns an XML-RPC error response.
- * The possible error codes and error message are:
- *
- * - 3 - Incorrect parameters passed to method:
- * Wanted ... , got ... at param
- * - 801 - wrong 1st parameter, struct expected.
- * - 805 - xr_updateAudioClipMetadata:
- * <message from lower layer>
- *
- *
- * @param input XMLRPC struct
- * @return boolean
- * @see LocStor::updateAudioClipMetadata
- */
- function xr_updateAudioClipMetadata($input)
- {
- list($ok, $r) = $this->_xr_getPars($input);
- if(!$ok) return $r;
- $res = $this->updateAudioClipMetadata(
- $r['sessid'], $r['gunid'], $r['mdataFileLP']
- );
- if(!PEAR::isError($res))
- return new XML_RPC_Response(new XML_RPC_Value($res, "boolean"));
- else
- return new XML_RPC_Response(0, 805,
- "xr_updateAudioClip: ".$res->getMessage().
- " ".$res->getUserInfo()
- );
- }
-
- /**
- * Search in local metadata database
- *
- * The XML-RPC name of this method is "locstor.searchMetadata".
- *
- * The input parameters are an XML-RPC struct with the following
- * fields:
- *
- * - sessid : string - session id
- * - criteria : search string
- * - will be searched in object part of RDF tripples
- * - this parameter may be changed structured
- * queries will be supported in the future
- *
- *
- * On success, returns a single XML-RPC value:
- *
- * - boolean - TRUE
- *
- *
- * On errors, returns an XML-RPC error response.
- * The possible error codes and error message are:
- *
- * - 3 - Incorrect parameters passed to method:
- * Wanted ... , got ... at param
- * - 801 - wrong 1st parameter, struct expected.
- * - 805 - xr_searchMetadata:
- * <message from lower layer>
- *
- *
- * @param input XMLRPC struct
- * @return boolean
- * @see LocStor::searchMetadata
- * @see GreenBox::localSearch
- */
- function xr_searchMetadata($input)
- {
- list($ok, $r) = $this->_xr_getPars($input);
- if(!$ok) return $r;
- $res = $this->searchMetadata($r['sessid'], $r['criteria']);
- if(!PEAR::isError($res))
- return new XML_RPC_Response(XML_RPC_encode($res));
- else
- return new XML_RPC_Response(0, 803,
- "xr_searchAudioClip: ".$res->getMessage().
- " ".$res->getUserInfo()
- );
- }
-
- /**
- * Make access to audio clip.
- *
- * The XML-RPC name of this method is "locstor.accessRawAudioData".
- *
- * The input parameters are an XML-RPC struct with the following
- * fields:
- *
- * - sessid : string - session id
- * - gunid : string - global unique id of AudioClip
- *
- *
- * On success, returns a single XML-RPC value:
- *
- * - string - access symlink filename
- *
- *
- * On errors, returns an XML-RPC error response.
- * The possible error codes and error message are:
- *
- * - 3 - Incorrect parameters passed to method:
- * Wanted ... , got ... at param
- * - 801 - wrong 1st parameter, struct expected.
- * - 805 - xr_accessRawAudioData:
- * <message from lower layer>
- *
- *
- * @param input XMLRPC struct
- * @return string
- * @see LocStor::accessRawAudioData
- */
- function xr_accessRawAudioData($input)
- {
- list($ok, $r) = $this->_xr_getPars($input);
- if(!$ok) return $r;
- $res = $this->accessRawAudioData($r['sessid'], $r['gunid']);
- if(!PEAR::isError($res))
- return new XML_RPC_Response(new XML_RPC_Value($res, "string"));
- else
- return new XML_RPC_Response(0, 805,
- "xr_accessRawAudioData: ".$res->getMessage().
- " ".$res->getUserInfo()
- );
- }
-
- /**
- * Release access to audio clip
- *
- * The XML-RPC name of this method is "locstor.releaseRawAudioData".
- *
- * The input parameters are an XML-RPC struct with the following
- * fields:
- *
- * - sessid : string - session id
- * - tmpLink : string - temporary access symlink
- * returned by locstor.accessRawAudioData
- *
- *
- * On success, returns a single XML-RPC value:
- *
- * - boolean
- *
- *
- * On errors, returns an XML-RPC error response.
- * The possible error codes and error message are:
- *
- * - 3 - Incorrect parameters passed to method:
- * Wanted ... , got ... at param
- * - 801 - wrong 1st parameter, struct expected.
- * - 805 - xr_releaseRawAudioData:
- * <message from lower layer>
- *
- *
- * @param input XMLRPC struct
- * @return boolean
- * @see LocStor::releaseRawAudioData
- */
- function xr_releaseRawAudioData($input)
- {
- list($ok, $r) = $this->_xr_getPars($input);
- if(!$ok) return $r;
- $res = $this->releaseRawAudioData($r['sessid'], $r['tmpLink']);
- if(!PEAR::isError($res))
- return new XML_RPC_Response(new XML_RPC_Value($res, "boolean"));
- else
- return new XML_RPC_Response(0, 805,
- "xr_releaseRawAudioData: ".$res->getMessage().
- " ".$res->getUserInfo()
- );
+ return new XML_RPC_Response(XML_RPC_encode(array('exists'=>$res)));
}
/**
@@ -606,9 +694,9 @@ class XR_LocStor extends LocStor{
* gunid : string - global unique id of AudioCLip
*
*
- * On success, returns a single XML-RPC value:
+ * On success, returns a XML-RPC struct with single field:
*
- * - string - metadata as XML
+ * - metadata : string - metadata as XML
*
*
* On errors, returns an XML-RPC error response.
@@ -622,7 +710,7 @@ class XR_LocStor extends LocStor{
*
*
* @param input XMLRPC struct
- * @return string
+ * @return XMLRPC struct
* @see LocStor::getAudioClip
*/
function xr_getAudioClip($input)
@@ -630,24 +718,30 @@ class XR_LocStor extends LocStor{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->getAudioClip($r['sessid'], $r['gunid']);
- if(!PEAR::isError($res))
- return new XML_RPC_Response(new XML_RPC_Value($res, "string"));
- else
+ if(PEAR::isError($res)){
return new XML_RPC_Response(0, 805,
"xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo()
);
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('metadata'=>$res)));
}
/**
- * Reset storageServer for debugging.
+ * Update existing audio clip metadata
*
- * The XML-RPC name of this method is "locstor.resetStorage".
+ * The XML-RPC name of this method is "locstor.updateAudioClipMetadata".
*
- * There are no input parameters
- *
- * On success, returns a single XML-RPC value:
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
*
- * - array - array with gunids of inserted files
+ * - sessid : string - session id
+ * - gunid : string - global unique id of AudioCLip
+ * - metadata : metadata XML string
+ *
+ *
+ * On success, returns a XML-RPC struct with single field:
+ *
+ * - status : boolean - TRUE
*
*
* On errors, returns an XML-RPC error response.
@@ -656,12 +750,103 @@ class XR_LocStor extends LocStor{
* 3 - Incorrect parameters passed to method:
* Wanted ... , got ... at param
* 801 - wrong 1st parameter, struct expected.
- * 805 - xr_getAudioClip:
+ * 805 - xr_updateAudioClipMetadata:
* <message from lower layer>
*
*
* @param input XMLRPC struct
- * @return string
+ * @return XMLRPC struct
+ * @see LocStor::updateAudioClipMetadata
+ */
+ function xr_updateAudioClipMetadata($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->updateAudioClipMetadata(
+ $r['sessid'], $r['gunid'], $r['metadata']
+ );
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_updateAudioClip: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('status'=>$res)));
+ }
+
+ /**
+ * Search in local metadata database
+ *
+ * The XML-RPC name of this method is "locstor.searchMetadata".
+ *
+ * The input parameters are an XML-RPC struct with the following
+ * fields:
+ *
+ * - sessid : string - session id
+ * - criteria : search string
+ * - will be searched in object part of RDF tripples
+ * - this parameter may be changed structured
+ * queries will be supported in the near future
+ *
+ *
+ * On success, returns a XML-RPC struct with single field:
+ *
+ * - results: array - array of gunids have founded
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_searchMetadata:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ * @see LocStor::searchMetadata
+ * @see GreenBox::localSearch
+ */
+ function xr_searchMetadata($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->searchMetadata($r['sessid'], $r['criteria']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 803,
+ "xr_searchAudioClip: ".$res->getMessage().
+ " ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('results'=>$res)));
+ }
+
+ /**
+ * Reset storageServer for debugging.
+ *
+ * The XML-RPC name of this method is "locstor.resetStorage".
+ *
+ * The input parameters are an empty XML-RPC struct.
+ *
+ * On success, returns a XML-RPC struct with single field:
+ *
+ * - gunids : array - array with gunids of inserted files
+ *
+ *
+ * On errors, returns an XML-RPC error response.
+ * The possible error codes and error message are:
+ *
+ * - 3 - Incorrect parameters passed to method:
+ * Wanted ... , got ... at param
+ * - 801 - wrong 1st parameter, struct expected.
+ * - 805 - xr_resetStorage:
+ * <message from lower layer>
+ *
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
* @see LocStor::getAudioClip
*/
function xr_resetStorage($input)
@@ -669,14 +854,98 @@ class XR_LocStor extends LocStor{
list($ok, $r) = $this->_xr_getPars($input);
if(!$ok) return $r;
$res = $this->resetStorage();
- if(!PEAR::isError($res))
- return new XML_RPC_Response(XML_RPC_encode($res));
- else
+ if(PEAR::isError($res)){
return new XML_RPC_Response(0, 805,
"xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo()
);
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('gunids'=>$res)));
}
-}
+
+
+ /* ------------------------------------------- test methods for debugging */
+ /**
+ * Test XMLRPC - strupper and return given string,
+ * also return loginname of logged user
+ * - debug method only
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ */
+ function xr_test($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ return new XML_RPC_Response(XML_RPC_encode(array(
+ 'str'=>strtoupper($r['teststring']),
+ 'login'=>$this->getSessLogin($r['sessid']),
+ 'sessid'=>$r['sessid']
+ )));
+ }
+
+ /**
+ * Open writable URL for put method - debug method only
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ */
+ function xr_openPut($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->bsOpenPut();
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode($res));
+ }
+
+ /**
+ * Close writable URL - debug method only
+ *
+ * @param input XMLRPC struct
+ * @return XMLRPC struct
+ */
+ function xr_closePut($input)
+ {
+ list($ok, $r) = $this->_xr_getPars($input);
+ if(!$ok) return $r;
+ $res = $this->bsClosePut($r['token'], $r['chsum']);
+ if(PEAR::isError($res)){
+ return new XML_RPC_Response(0, 805,
+ "xr_getAudioClip: ".$res->getMessage()." ".$res->getUserInfo()
+ );
+ }
+ return new XML_RPC_Response(XML_RPC_encode(array('fname'=>$res)));
+ }
+
+ /* ---------------------------------------------------- "private" methods */
+ /**
+ * Check and convert struct of parameters
+ *
+ * @param input XMLRPC parameters
+ * @return array
+ */
+ function _xr_getPars($input)
+ {
+ $p = $input->getParam(0);
+ if(isset($p) && $p->scalartyp()=="struct"){
+ $r = XML_RPC_decode($p);
+ return array(TRUE, $r);
+ }
+ else return array(FALSE, new XML_RPC_Response(0, 801,
+ "wrong 1st parameter, struct expected."
+ ));
+ }
+
+} // end of class definition
+
+/* ============================================================= runable code */
+PEAR::setErrorHandling(PEAR_ERROR_RETURN);
+$dbc = DB::connect($config['dsn'], TRUE);
+$dbc->setFetchMode(DB_FETCHMODE_ASSOC);
$locStor = &new XR_LocStor(&$dbc, $config);
@@ -688,8 +957,18 @@ $methods = array(
'logout' => 'Logout from storage.',
'existsAudioClip' => 'Checks if an Audio clip with the specified '.
'id is stored in local storage.',
- 'storeAudioClip' => 'Store a new audio clip or replace '.
- 'an existing one.',
+ 'storeAudioClipOpen' => 'Open channel for store a new audio clip '.
+ 'or replace an existing one.',
+ 'storeAudioClipClose' => 'Close channel for store a new audio clip'.
+ ' or replace an existing one.',
+ 'downloadRawAudioDataOpen'=> 'Create and return downloadable URL'.
+ 'for audio file',
+ 'downloadRawAudioDataClose'=>'Discard downloadable URL for audio file',
+ 'downloadMetadataOpen' => 'Create and return downloadable URL'.
+ 'for metadata',
+ 'downloadMetadataClose' => 'Discard downloadable URL for metadata',
+ 'openPut' => 'openPut',
+ 'closePut' => 'closePut',
'deleteAudioClip' => 'Delete an existing Audio clip.',
'updateAudioClipMetadata' => 'Update the metadata of an Audio clip '.
'stored in Local storage.',
@@ -714,13 +993,4 @@ foreach($methods as $method=>$description){
}
$s=new XML_RPC_Server( $defs );
-#$s=new XML_RPC_Server( $defs , 0 );
-##var_dump($s);
-#$r = $s->parseRequest();
-#$r = $r[0];
-#var_dump($r);
-#echo ($cn = get_class($r))."\n";
-#$a = get_class_methods($cn);
-#var_dump($a);
-#echo $r->serialize();
?>
diff --git a/livesupport/modules/storageServer/var/xmlrpc/xr_cli_test.py b/livesupport/modules/storageServer/var/xmlrpc/xr_cli_test.py
index 7d686ecdb..20b4bd30e 100755
--- a/livesupport/modules/storageServer/var/xmlrpc/xr_cli_test.py
+++ b/livesupport/modules/storageServer/var/xmlrpc/xr_cli_test.py
@@ -24,7 +24,7 @@
#
#
# Author : $Author: tomas $
-# Version : $Revision: 1.3 $
+# Version : $Revision: 1.4 $
# Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/xmlrpc/Attic/xr_cli_test.py,v $
#
#------------------------------------------------------------------------------
@@ -84,29 +84,47 @@ try:
elif method=="test":
print server.locstor.test({'sessid':pars[0], 'teststring':pars[1]})
elif method=="authenticate":
- print server.locstor.authenticate({'login':pars[0], 'pass':pars[1]})
+ print server.locstor.authenticate({'login':pars[0], 'pass':pars[1]})['authenticate']
elif method=="login":
- print server.locstor.login({'login':pars[0], 'pass':pars[1]})
+ print server.locstor.login({'login':pars[0], 'pass':pars[1]})['sessid']
elif method=="logout":
print server.locstor.logout({'sessid':pars[0]})
- elif method=="existsAudioClip":
- print server.locstor.existsAudioClip({'sessid':pars[0], 'gunid':pars[1]} )
- elif method=="storeAudioClip":
- print server.locstor.storeAudioClip({'sessid':pars[0], 'gunid':pars[1], 'mediaFileLP':pars[2], 'mdataFileLP':pars[3]})
+ elif method=="storeAudioClipOpen":
+ r = server.locstor.storeAudioClipOpen({'sessid':pars[0], 'gunid':pars[1], 'metadata':pars[2], 'chsum':pars[3]})
+ print r['url']+'\n'+r['token']
+ elif method=="storeAudioClipClose":
+ print server.locstor.storeAudioClipClose({'sessid':pars[0], 'token':pars[1]})['gunid']
+ elif method=="accessRawAudioData":
+ r = server.locstor.accessRawAudioData({'sessid':pars[0], 'gunid':pars[1]})
+ print r['url']+'\n'+r['token']
+ elif method=="releaseRawAudioData":
+ print server.locstor.releaseRawAudioData({'sessid':pars[0], 'token':pars[1]})
+ elif method=="downloadRawAudioDataOpen":
+ r = server.locstor.downloadRawAudioDataOpen({'sessid':pars[0], 'gunid':pars[1]})
+ print r['url']+'\n'+r['token']
+ elif method=="downloadRawAudioDataClose":
+ print server.locstor.downloadRawAudioDataClose({'sessid':pars[0], 'token':pars[1]})
+ elif method=="downloadMetadataOpen":
+ r = server.locstor.downloadMetadataOpen({'sessid':pars[0], 'gunid':pars[1]})
+ print r['url']+'\n'+r['token']
+ elif method=="downloadMetadataClose":
+ print server.locstor.downloadMetadataClose({'sessid':pars[0], 'token':pars[1]})
elif method=="deleteAudioClip":
print server.locstor.deleteAudioClip({'sessid':pars[0], 'gunid':pars[1]})
+ elif method=="existsAudioClip":
+ print server.locstor.existsAudioClip({'sessid':pars[0], 'gunid':pars[1]} )['exists']
elif method=="updateAudioClipMetadata":
print server.locstor.updateAudioClipMetadata({'sessid':pars[0], 'gunid':pars[1], 'mdataFileLP':pars[2]})
elif method=="searchMetadata":
print server.locstor.searchMetadata({'sessid':pars[0], 'criteria':pars[1]})
- elif method=="accessRawAudioData":
- print server.locstor.accessRawAudioData({'sessid':pars[0], 'gunid':pars[1]})
- elif method=="releaseRawAudioData":
- print server.locstor.releaseRawAudioData({'sessid':pars[0], 'tmpLink':pars[1]})
elif method=="getAudioClip":
print server.locstor.getAudioClip({'sessid':pars[0], 'gunid':pars[1]})
elif method=="resetStorage":
print server.locstor.resetStorage({})
+ elif method=="openPut":
+ r = server.locstor.openPut({}); print r['url']+'\n'+r['token']
+ elif method=="closePut":
+ print server.locstor.closePut({'token':pars[0], 'chsum':pars[1]})
else:
print "Unknown command: "+method
sys.exit(1)