diff --git a/application/models/AccessRecur.php b/application/models/AccessRecur.php
deleted file mode 100644
index ff18f11f7..000000000
--- a/application/models/AccessRecur.php
+++ /dev/null
@@ -1,183 +0,0 @@
-
-/**
- * AccessRecur class
- *
- * Handles recursive accessPlaylist/releasePlaylist.
- * Should be 'required_once' from LocStor.php only.
- *
- * @package Airtime
- * @subpackage StorageServer
- * @copyright 2010 Sourcefabric O.P.S.
- * @license http://www.gnu.org/licenses/gpl.txt
- */
-class AccessRecur {
- public $ls;
- public $sessid;
-
- public function __construct(&$ls, $sessid)
- {
- $this->ls =& $ls;
- $this->sessid = $sessid;
- }
-
-
- public static function accessPlaylist(&$ls, $sessid, $plid, $parent='0')
- {
- $ppa = new AccessRecur($ls, $sessid);
- $r = $ls->accessPlaylist($sessid, $plid, FALSE, $parent);
- if (PEAR::isError($r)) {
- return $r;
- }
- $plRes = $r;
- $r = StoredFile::RecallByGunid($plid);
- if (is_null($r) || PEAR::isError($r)) {
- return $r;
- }
- $ac = $r;
- $r = $ac->md->genPhpArray();
- if (PEAR::isError($r)) {
- return $r;
- }
- $pla = $r;
- $r = $ppa->processPlaylist($pla, $plRes['token']);
- if (PEAR::isError($r)) {
- return $r;
- }
- $plRes['content'] = $r;
- return $plRes;
- }
-
-
- public static function releasePlaylist(&$ls, $sessid, $token)
- {
- global $CC_CONFIG, $CC_DBC;
- $ppa = new AccessRecur($ls, $sessid);
- $r = $CC_DBC->getAll("
- SELECT to_hex(token)as token2, to_hex(gunid)as gunid
- FROM ".$CC_CONFIG['accessTable']."
- WHERE parent=x'{$token}'::bigint
- ");
- if (PEAR::isError($r)) {
- return $r;
- }
- $arr = $r;
- foreach ($arr as $i => $item) {
- extract($item); // token2, gunid
- $r = BasicStor::GetType($gunid);
- if (PEAR::isError($r)) {
- return $r;
- }
- $ftype = $r;
- # echo "$ftype/$token2\n";
- switch (strtolower($ftype)) {
- case "audioclip":
- $r = $ppa->ls->releaseRawAudioData($ppa->sessid, $token2);
- if (PEAR::isError($r)) {
- return $r;
- }
- # var_dump($r);
- break;
- case "playlist":
- $r = $ppa->releasePlaylist($ppa->ls, $ppa->sessid, $token2);
- if (PEAR::isError($r)) {
- return $r;
- }
- # var_dump($r);
- break;
- default:
- }
- }
- $r = $ppa->ls->releasePlaylist($ppa->sessid, $token, FALSE);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $r;
- }
-
-
- private function processPlaylist($pla, $parent)
- {
- $res = array();
- foreach ($pla['children'] as $ple) {
- switch ($ple['elementname']) {
- case "playlistElement":
- $r = $this->processPlaylistElement($ple, $parent);
- if (PEAR::isError($r)) {
- return $r;
- }
- // $res = array_merge($res, $r);
- $res[] = $r;
- break;
- default:
- }
- }
- return $res;
- }
-
-
- private function processAudioClip($gunid, $parent)
- {
- $r = $this->ls->accessRawAudioData($this->sessid, $gunid, $parent);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $r;
- }
-
-
- private function processPlaylistElement($ple, $parent='0')
- {
- foreach ($ple['children'] as $ac) {
- switch ($ac['elementname']) {
- case "audioClip":
- $r = $this->processAudioClip($ac['attrs']['id'], $parent);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $r;
- case "playlist":
- // if(empty($ac['children'])){
- $r = $this->accessPlaylist($this->ls, $this->sessid,
- $ac['attrs']['id'], $parent);
- if (PEAR::isError($r)) {
- if ($r->getCode() != GBERR_NOTF) {
- return $r;
- } else {
- $r = $this->processPlaylist($ac, $parent);
- if (PEAR::isError($r)) {
- return $r;
- }
- $r = array(
- 'content' => $r,
- 'url' => NULL,
- 'token' => NULL,
- 'chsum' => NULL,
- 'size' => NULL,
- 'warning' => 'inline playlist?',
- );
- }
- }
- return $r;
- /*
- }else{
- $r = $this->processPlaylist($ac, $parent);
- if(PEAR::isError($r)) return $r;
- $res = array(
- 'content' => $r,
- 'url' => NULL,
- 'token' => NULL,
- 'chsum' => NULL,
- 'size' => NULL,
- 'warning' => 'inline playlist',
- );
- return $res;
- }
- */
- break;
- default:
- }
- }
- return array();
- }
-
-} // class AccessRecur
diff --git a/application/models/BasicStor.php b/application/models/BasicStor.php
index dc31970e1..e9a93ca04 100644
--- a/application/models/BasicStor.php
+++ b/application/models/BasicStor.php
@@ -56,7 +56,6 @@ define('GBERR_NOTIMPL', 69);
require_once(dirname(__FILE__)."/Alib.php");
require_once(dirname(__FILE__)."/StoredFile.php");
-require_once(dirname(__FILE__)."/Transport.php");
require_once(dirname(__FILE__)."/Playlist.php");
/**
diff --git a/application/models/GreenBox.php b/application/models/GreenBox.php
deleted file mode 100644
index 0cffb4f89..000000000
--- a/application/models/GreenBox.php
+++ /dev/null
@@ -1,156 +0,0 @@
-";
-}
-require_once("BasicStor.php");
-if (isset($WHITE_SCREEN_OF_DEATH) && $WHITE_SCREEN_OF_DEATH) {
- echo __FILE__.':line '.__LINE__.": Loaded BasicStor
";
-}
-require_once("Playlist.php");
-require_once('Prefs.php');
-require_once("Transport.php");
-
-/**
- * GreenBox class
- *
- * File storage module.
- *
- * @package Airtime
- * @subpackage StorageServer
- * @copyright 2010 Sourcefabric O.P.S.
- * @license http://www.gnu.org/licenses/gpl.txt
- */
-class GreenBox extends BasicStor {
-
- /* ====================================================== storage methods */
- /* ------------------------------------------------------------- metadata */
-
- /**
- * Search in local metadata database.
- *
- * @param array $criteria
- * with following structure:
- *
- * - filetype - string, type of searched files,
- * meaningful values: 'audioclip', 'webstream', 'playlist', 'all'
- * - operator - string, type of conditions join
- * (any condition matches / all conditions match),
- * meaningful values: 'and', 'or', ''
- * (may be empty or ommited only with less then 2 items in
- * "conditions" field)
- *
- * - limit : int - limit for result arrays (0 means unlimited)
- * - offset : int - starting point (0 means without offset)
- * - orderby : string - metadata category for sorting (optional)
- * or array of strings for multicolumn orderby
- * [default: dc:creator, dc:source, dc:title]
- *
- * - desc : boolean - flag for descending order (optional)
- * or array of boolean for multicolumn orderby
- * (it corresponds to elements of orderby field)
- * [default: all ascending]
- *
- * - conditions - array of hashes with structure:
- *
- * - cat - string, metadata category name
- * - op - string, operator - meaningful values:
- * 'full', 'partial', 'prefix', '=', '<',
- * '<=', '>', '>='
- * - val - string, search value
- *
- *
- *
- * @param string $sessid
- * session id
- * @return array of hashes, fields:
- *
- * - cnt : integer - number of matching gunids
- * of files have been found
- * - results : array of hashes:
- *
- * - gunid: string
- * - type: string - audioclip | playlist | webstream
- * - title: string - dc:title from metadata
- * - creator: string - dc:creator from metadata
- * - length: string - dcterms:extent in extent format
- *
- *
- *
- * @see BasicStor::bsLocalSearch
- */
- public function localSearch($criteria, $sessid='')
- {
- $limit = intval(isset($criteria['limit']) ? $criteria['limit'] : 0);
- $offset = intval(isset($criteria['offset']) ? $criteria['offset'] : 0);
- return $this->bsLocalSearch($criteria, $limit, $offset);
- } // fn localSearch
-
-
- /*====================================================== playlist methods */
- /**
- * Close import-handle and import playlist
- *
- * @param string $token
- * import token obtained by importPlaylistOpen method
- * @return int
- * result file local id (or error object)
- */
- public function importPlaylistClose($token)
- {
- $arr = $this->bsClosePut($token);
- if (PEAR::isError($arr)) {
- return $arr;
- }
- $fname = $arr['fname'];
- $owner = $arr['owner'];
- $res = $this->bsImportPlaylist($fname, $owner);
- if (file_exists($fname)) {
- @unlink($fname);
- }
- return $res;
- } // fn importPlaylistClose
-
-
- /* ========================================================= info methods */
- /* ==================================================== redefined methods */
-
- /**
- * Change user password.
- *
- * ('superuser mode'= superuser is changing some password without
- * knowledge of the old password)
- *
- * @param string $login
- * @param string $oldpass
- * old password
- * (should be null or empty for 'superuser mode')
- * @param string $pass
- * @param string $sessid
- * session id, required for 'superuser mode'
- * @return boolean/err
- */
- public function passwd($login, $oldpass=null, $pass='', $sessid='')
- {
- if (is_null($oldpass) || ($oldpass == '') ) {
- if (($res = BasicStor::Authorize('subjects', $this->rootId, $sessid)) !== TRUE) {
- sleep(2);
- return $res;
- } else {
- $oldpass = null;
- }
- } else {
- if (FALSE === Subjects::Authenticate($login, $oldpass)) {
- sleep(2);
- return PEAR::raiseError(
- "GreenBox::passwd: access denied (oldpass)", GBERR_DENY);
- }
- }
- $res = Subjects::Passwd($login, $oldpass, $pass);
- if (PEAR::isError($res)) {
- return $res;
- }
- return TRUE;
- } // fn passwd
-
-
-} // class GreenBox
diff --git a/application/models/LocStor.php b/application/models/LocStor.php
deleted file mode 100644
index 6bdd4d02c..000000000
--- a/application/models/LocStor.php
+++ /dev/null
@@ -1,1384 +0,0 @@
-";
-}
-require_once("BasicStor.php");
-if (isset($WHITE_SCREEN_OF_DEATH) && $WHITE_SCREEN_OF_DEATH) {
- echo __FILE__.':line '.__LINE__.": Loaded BasicStor
";
-}
-require_once("Transport.php");
-if (isset($WHITE_SCREEN_OF_DEATH) && $WHITE_SCREEN_OF_DEATH) {
- echo __FILE__.':line '.__LINE__.": Loaded Transport
";
-}
-
-/**
- * LocStor class
- *
- * Local storage interface
- *
- * @package Airtime
- * @subpackage StorageServer
- * @copyright 2010 Sourcefabric O.P.S.
- * @license http://www.gnu.org/licenses/gpl.txt
- */
-class LocStor extends BasicStor {
-
- /* ---------------------------------------------------------------- store */
-
- /**
- * Store or replace existing audio clip.
- *
- * Sending a file to the storage server is a 3 step process:
- * 1) Call storeAudioClipOpen
- * 2) Upload the file to the URL specified
- * 3) Call storeAudioClipClose
- *
- * @param string $sessid
- * session id
- * @param string $gunid
- * global unique id
- * @param string $metadata
- * metadata XML string
- * @param string $fname
- * human readable menmonic file name
- * with extension corresponding to filetype
- * @param string $chsum
- * md5 checksum of media file
- * @param string $ftype
- * audioclip | playlist | webstream
- * @return array
- * {url:writable URL for HTTP PUT, token:access token}
- */
- protected function storeAudioClipOpen($sessid, $gunid, $metadata,
- $fname, $chsum, $ftype='audioclip')
- {
- // Check the gunid format
- if (!BasicStor::CheckGunid($gunid)) {
- return PEAR::raiseError(
- "LocStor::storeAudioClipOpen: Wrong gunid ($gunid)"
- );
- }
-
- // Check if we already have this file.
- $duplicate = StoredFile::RecallByMd5($chsum);
- if (!empty($chsum) && $duplicate) {
- return PEAR::raiseError(
- "LocStor::storeAudioClipOpen: Duplicate file"
- ." - Matched MD5 ($chsum) against '".$duplicate->getName()."'",
- 888);
- }
-
- // Check if specified gunid exists.
- $storedFile =& StoredFile::RecallByGunid($gunid);
- if (!is_null($storedFile) && !PEAR::isError($storedFile)) {
- // gunid exists - do replace
- $oid = $storedFile->getId();
- if (($res = BasicStor::Authorize('write', $oid, $sessid)) !== TRUE) {
- return $res;
- }
- if ($storedFile->isAccessed()) {
- return PEAR::raiseError(
- 'LocStor::storeAudioClipOpen: is accessed'
- );
- }
- $res = $storedFile->replace($oid, $storedFile->getName(), '', $metadata, 'string');
- if (PEAR::isError($res)) {
- return $res;
- }
- } else {
- // gunid doesn't exist - do insert:
- $tmpFname = uniqid();
- if (($res = BasicStor::Authorize('write', null, $sessid)) !== TRUE) {
- return $res;
- }
- $values = array(
- "metadata" => $metadata,
- "gunid" => $gunid,
- "filetype" => $ftype);
- $storedFile =& StoredFile::Insert($values);
- if (PEAR::isError($storedFile)) {
- return $storedFile;
- }
- if (PEAR::isError($res)) {
- return $res;
- }
- }
- $res = $storedFile->setState('incomplete');
- if (PEAR::isError($res)) {
- return $res;
- }
- if ($fname == '') {
- $fname = "newFile";
- }
- $storedFile->setName($fname);
- return $this->bsOpenPut($chsum, $storedFile->gunid);
- }
-
-
- /**
- * Store or replace existing audio clip
- *
- * @param string $sessid
- * @param string $token
- * @return string gunid|PEAR_Error
- */
- protected function storeAudioClipClose($sessid, $token)
- {
- $storedFile =& StoredFile::RecallByToken($token);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- $arr = $this->bsClosePut($token);
- if (PEAR::isError($arr)) {
- $storedFile->delete();
- return $arr;
- }
- $fname = $arr['fname'];
- $res = $storedFile->setRawMediaData($fname);
- if (PEAR::isError($res)) {
- return $res;
- }
- if (file_exists($fname)) {
- @unlink($fname);
- }
- $res = $storedFile->setState('ready');
- if (PEAR::isError($res)) {
- return $res;
- }
- return $storedFile->gunid;
- }
-
-
- /**
- * Check uploaded file
- *
- * @param string $token
- * "put" token
- * @return array
- * hash, (status: boolean, size: int - filesize)
- */
- protected function uploadCheck($token)
- {
- return $this->bsCheckPut($token);
- }
-
-
- /**
- * Store webstream
- *
- * @param string $sessid
- * session id
- * @param string $gunid
- * global unique id
- * @param string $metadata
- * metadata XML string
- * @param string $fname
- * human readable menmonic file name with extension corresponding to filetype
- * @param string $url
- * webstream url
- * @return string
- * gunid
- */
- protected function storeWebstream($sessid, $gunid, $metadata, $fname, $url)
- {
- $a = $this->storeAudioClipOpen(
- $sessid, $gunid, $metadata, $fname, md5(''), 'webstream');
- if (PEAR::isError($a)) {
- return $a;
- }
- $gunid = $this->storeAudioClipClose($sessid, $a['token']);
- if (PEAR::isError($gunid)) {
- return $gunid;
- }
- $storedFile =& StoredFile::RecallByGunid($gunid);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- $r = $storedFile->setMetadataValue('ls:url', $url);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $gunid;
- }
-
-
- /* --------------------------------------------------------------- access */
- /**
- * Make access to audio clip
- *
- * @param string $sessid
- * @param string $gunid
- * @param int $parent
- * parent token
- * @return array
- * with: seekable filehandle, access token
- */
- public function accessRawAudioData($sessid, $gunid, $parent='0')
- {
- $storedFile =& StoredFile::RecallByGunid($gunid);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- if (($res = BasicStor::Authorize('read', $storedFile->getId(), $sessid)) !== TRUE) {
- return $res;
- }
- return $storedFile->accessRawMediaData($parent);
- }
-
-
- /**
- * Release access to audio clip
- *
- * @param string $sessid
- * @param string $token
- * access token
- * @return boolean|PEAR_Error
- */
- public function releaseRawAudioData($sessid, $token)
- {
- $storedFile =& StoredFile::RecallByToken($token);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- return $storedFile->releaseRawMediaData($token);
- }
-
-
- /* ------------------------------------------------------------- download */
- /**
- * Create and return downloadable URL for audio file
- *
- * @param string $sessid
- * session id
- * @param string $gunid
- * global unique id
- * @return array
- * array with strings:
- * downloadable URL, download token, chsum, size, filename
- */
- protected function downloadRawAudioDataOpen($sessid, $gunid)
- {
- $ex = $this->existsAudioClip($sessid, $gunid);
- if (PEAR::isError($ex)) {
- return $ex;
- }
- $media = StoredFile::RecallByGunid($gunid);
- $id = $media->getId();
- if (is_null($id) || !$ex) {
- return PEAR::raiseError(
- "LocStor::downloadRawAudioDataOpen: gunid not found ($gunid)",
- GBERR_NOTF
- );
- }
- if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) {
- return $res;
- }
- return $this->bsOpenDownload($id);
- }
-
-
- /**
- * Discard downloadable URL for audio file
- *
- * @param string $token
- * download token
- * @return string
- * gunid
- */
- protected function downloadRawAudioDataClose($token)
- {
- return $this->bsCloseDownload($token);
- }
-
-
- /**
- * Create and return downloadable URL for metadata
- *
- * @param string $sessid
- * session id
- * @param string $gunid
- * global unique id
- * @return array
- * array with strings:
- * downloadable URL, download token, chsum, filename
- */
- protected function downloadMetadataOpen($sessid, $gunid)
- {
- // $res = $this->existsAudioClip($sessid, $gunid);
- // if(PEAR::isError($res)) return $res;
- $media = StoredFile::RecallByGunid($gunid);
- $id = $media->getGunid();
- if (is_null($id)) {
- return PEAR::raiseError(
- "LocStor::downloadMetadataOpen: gunid not found ($gunid)"
- );
- }
- if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) {
- return $res;
- }
- $res = $this->bsOpenDownload($id, 'metadata');
- #unset($res['filename']);
- return $res;
- }
-
-
- /**
- * Discard downloadable URL for metadata
- *
- * @param string $token
- * download token
- * @return string
- * gunid
- */
- protected function downloadMetadataClose($token)
- {
- return $this->bsCloseDownload($token, 'metadata');
- }
-
-
- /**
- * Return metadata as XML
- *
- * @param string $sessid
- * @param string $gunid
- * @return string|PEAR_Error
- */
- protected function getAudioClip($sessid, $gunid)
- {
- $storedFile =& StoredFile::RecallByGunid($gunid);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- if (($res = BasicStor::Authorize('read', $storedFile->getId(), $sessid)) !== TRUE) {
- return $res;
- }
- $md = $storedFile->getMetadata();
- if (PEAR::isError($md)) {
- return $md;
- }
- return $md;
- }
-
-
- /* ------------------------------------------------------- search, browse */
-
- /**
- * Search in metadata database
- *
- * @param string $sessid
- * @param array $criteria
- * with following structure:
- *
- * - filetype - string, type of searched files,
- * meaningful values: 'audioclip', 'webstream', 'playlist', 'all'
- * - operator - string, type of conditions join
- * (any condition matches / all conditions match),
- * meaningful values: 'and', 'or', ''
- * (may be empty or ommited only with less then 2 items in
- * "conditions" field)
- *
- * - limit : int - limit for result arrays (0 means unlimited)
- * - offset : int - starting point (0 means without offset)
- * - orderby : string - metadata category for sorting (optional)
- * or array of strings for multicolumn orderby
- * [default: dc:creator, dc:source, dc:title]
- *
- * - desc : boolean - flag for descending order (optional)
- * or array of boolean for multicolumn orderby
- * (it corresponds to elements of orderby field)
- * [default: all ascending]
- *
- * - conditions - array of hashes with structure:
- *
- * - cat - string, metadata category name
- * - op - string, operator - meaningful values:
- * 'full', 'partial', 'prefix', '=', '<',
- * '<=', '>', '>='
- * - val - string, search value
- *
- *
- *
- * @return array of hashes, fields:
- *
- * - cnt : integer - number of matching gunids
- * of files have been found
- * - results : array of hashes:
- *
- * - gunid: string
- * - type: string - audioclip | playlist | webstream
- * - title: string - dc:title from metadata
- * - creator: string - dc:creator from metadata
- * - source: string - dc:source from metadata
- * - length: string - dcterms:extent in extent format
- *
- *
- *
- * @see BasicStor::localSearch
- */
- public function searchMetadata($sessid, $criteria)
- {
- if (($res = BasicStor::Authorize('read', $this->storId, $sessid)) !== TRUE) {
- return $res;
- }
- $criteria['resultMode'] = 'xmlrpc';
- $res = $this->localSearch($criteria, $sessid);
- return $res;
- }
-
-
- /**
- * @param array $criteria
- * @param mixed $sessid
- * This variable isnt used.
- * @return unknown
- */
- public function localSearch($criteria, $sessid='')
- {
- $limit = intval(isset($criteria['limit']) ? $criteria['limit'] : 0);
- $offset = intval(isset($criteria['offset']) ? $criteria['offset'] : 0);
- $res = $this->bsLocalSearch($criteria, $limit, $offset);
- return $res;
- }
-
-
- /**
- * Return values of specified metadata category
- *
- * @param string $category
- * metadata category name
- * with or without namespace prefix (dc:title, author)
- * @param hash $criteria
- * see searchMetadata method
- * @param string $sessid
- * @return array
- * hash, fields:
- * results : array with found values
- * cnt : integer - number of matching values
- * @see BasicStor::bsBrowseCategory
- */
- protected function browseCategory($category, $criteria=NULL, $sessid='')
- {
- $limit = intval(isset($criteria['limit']) ? $criteria['limit'] : 0);
- $offset = intval(isset($criteria['offset']) ? $criteria['offset'] : 0);
- $res = $this->bsBrowseCategory($category, $limit, $offset, $criteria);
- return $res;
- }
-
-
- /* ----------------------------------------------------------------- etc. */
- /**
- * Check if audio clip exists
- *
- * @param string $sessid
- * @param string $gunid
- * @return boolean
- */
- protected function existsAudioClip($sessid, $gunid)
- {
- $ex = $this->existsFile($sessid, $gunid, 'audioclip');
- // webstreams are subset of audioclips - moved to BasicStor
- // if($ex === FALSE ){
- // $ex = $this->existsFile($sessid, $gunid, 'webstream');
- // }
- if ($ex === FALSE ) {
- return FALSE;
- }
- if (PEAR::isError($ex)) {
- return $ex;
- }
- $storedFile =& StoredFile::RecallByGunid($gunid);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- return $storedFile->exists();
- }
-
-
- /**
- * Check if file exists in the storage
- *
- * @param string $sessid
- * @param string $gunid
- * @param string $ftype
- * internal file type
- * @return boolean
- */
- protected function existsFile($sessid, $gunid, $ftype=NULL)
- {
- if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) {
- return $res;
- }
- $f = StoredFile::RecallByGunid($gunid);
- if (PEAR::isError($f)) {
- return FALSE;
- }
- return $f->existsFile();
- }
-
-
- /**
- * Delete existing audio clip
- *
- * @param string $sessid
- * @param string $gunid
- * @param boolean $forced
- * if true, don't use trash
- * @return boolean|PEAR_Error
- */
- protected function deleteAudioClip($sessid, $gunid, $forced=FALSE)
- {
- $storedFile =& StoredFile::RecallByGunid($gunid);
- if (is_null($storedFile)) {
- return TRUE;
- }
- if (PEAR::isError($storedFile)) {
- if ($storedFile->getCode()==GBERR_FOBJNEX && $forced) {
- return TRUE;
- }
- return $storedFile;
- }
- if (($res = BasicStor::Authorize('write', $storedFile->getId(), $sessid)) !== TRUE) {
- return $res;
- }
- $res = $storedFile->delete();
- if (PEAR::isError($res)) {
- return $res;
- }
- return TRUE;
- }
-
-
- /**
- * Update existing audio clip metadata
- *
- * @param string $sessid
- * @param string $gunid
- * @param string $metadata
- * metadata XML string
- * @return boolean|PEAR_Error
- */
- protected function updateAudioClipMetadata($sessid, $gunid, $metadata)
- {
- $storedFile =& StoredFile::RecallByGunid($gunid);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- if (($res = BasicStor::Authorize('write', $storedFile->getId(), $sessid)) !== TRUE) {
- return $res;
- }
- return $storedFile->setMetadata($metadata, 'string');
- }
-
-
- /*====================================================== playlist methods */
- /**
- * Create a new empty playlist.
- *
- * @param string $sessid
- * session ID
- * @param string $playlistId
- * playlist global unique ID
- * @param string $fname
- * human readable mnemonic file name
- * @return string
- * playlist global unique ID
- */
- public function createPlaylist($sessid, $playlistId, $fname)
- {
- $ex = $this->existsPlaylist($sessid, $playlistId);
- if (PEAR::isError($ex)) {
- return $ex;
- }
- if ($ex) {
- return PEAR::raiseError(
- 'LocStor::createPlaylist: already exists'
- );
- }
- $tmpFname = uniqid('');
- if (($res = BasicStor::Authorize('write', null, $sessid)) !== TRUE) {
- return $res;
- }
- $values = array(
- "metadata" => dirname(__FILE__).'/emptyPlaylist.xml',
- "gunid" => $playlistId,
- "filetype" => "playlist");
- // This is all wrong now.
- $storedFile = StoredFile::Insert($values);
- if ($fname == '') {
- $fname = "newFile.xml";
- }
- $storedFile->setName($fname);
- $storedFile->setState('ready');
- $storedFile->setMime('application/smil');
- return $storedFile->gunid;
- }
-
-
- /**
- * Open a Playlist metafile for editing.
- * Open readable URL and mark file as beeing edited.
- *
- * @param string $sessid
- * session ID
- * @param string $playlistId
- * playlist global unique ID
- * @return struct
- * {url:readable URL for HTTP GET, token:access token, chsum:checksum}
- */
- public function editPlaylist($sessid, $playlistId)
- {
- $ex = $this->existsPlaylist($sessid, $playlistId);
- if (PEAR::isError($ex)) {
- return $ex;
- }
- if (!$ex) {
- return PEAR::raiseError(
- 'LocStor::editPlaylist: playlist not exists'
- );
- }
- if ($this->isEdited($playlistId) !== FALSE) {
- return PEAR::raiseError(
- 'LocStor::editPlaylist: playlist already edited'
- );
- }
- $storedFile =& StoredFile::RecallByGunid($playlistId);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- $id = $storedFile->getId();
- if (($res = BasicStor::Authorize('write', $id, $sessid)) !== TRUE) {
- return $res;
- }
- $res = $this->bsOpenDownload($id, 'metadata');
- if (PEAR::isError($res)) {
- return $res;
- }
- $r = $this->setEditFlag($playlistId, TRUE, $sessid);
- if (PEAR::isError($r)) {
- return $r;
- }
- unset($res['filename']);
- return $res;
- }
-
-
- /**
- * Store a new Playlist metafile in place of the old one.
- *
- * @param string $sessid
- * session ID
- * @param string $playlistToken
- * playlist access token
- * @param string $newPlaylist
- * new playlist as XML string
- * @return string
- * playlistId
- */
- protected function savePlaylist($sessid, $playlistToken, $newPlaylist)
- {
- $playlistId = $this->bsCloseDownload($playlistToken, 'metadata');
- if (PEAR::isError($playlistId)) {
- return $playlistId;
- }
- $storedFile =& StoredFile::RecallByGunid($playlistId);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- $res = $storedFile->setMetadata($newPlaylist, 'string', 'playlist');
- if (PEAR::isError($res)) {
- return $res;
- }
- $r = $this->setEditFlag($playlistId, FALSE, $sessid);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $playlistId;
- }
-
-
- /**
- * RollBack playlist changes to the locked state
- *
- * @param string $playlistToken
- * playlist access token
- * @param string $sessid
- * session ID
- * @return string
- * gunid of playlist
- */
- public function revertEditedPlaylist($playlistToken, $sessid='')
- {
- $gunid = $this->bsCloseDownload($playlistToken, 'metadata');
- if (PEAR::isError($gunid)) {
- return $gunid;
- }
- $storedFile =& StoredFile::RecallByGunid($gunid);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- $id = $storedFile->getId();
- $mdata = $storedFile->getMetadata();
- if (PEAR::isError($mdata)) {
- return $mdata;
- }
- $res = $storedFile->setMetadata($mdata, 'string');
- if (PEAR::isError($res)) {
- return $res;
- }
- $this->setEditFlag($gunid, FALSE, $sessid);
- return $gunid;
- }
-
-
- /**
- * Delete a Playlist metafile.
- *
- * @param string $sessid
- * session ID
- * @param string $playlistId
- * playlist global unique ID
- * @param boolean $forced
- * if true don't use trash
- * @return boolean
- */
- public function deletePlaylist($sessid, $playlistId, $forced=FALSE)
- {
- $ex = $this->existsPlaylist($sessid, $playlistId);
- if (PEAR::isError($ex)) {
- return $ex;
- }
- if (!$ex) {
- if ($forced) {
- return TRUE;
- }
- return PEAR::raiseError(
- 'LocStor::deletePlaylist: playlist not exists',
- GBERR_FILENEX
- );
- }
- $storedFile =& StoredFile::RecallByGunid($playlistId);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- if (($res = BasicStor::Authorize('write', $storedFile->getId(), $sessid)) !== TRUE) {
- return $res;
- }
- $res = $storedFile->delete();
- if (PEAR::isError($res)) {
- return $res;
- }
- return TRUE;
- }
-
-
- /**
- * Access (read) a Playlist metafile.
- *
- * @param string $sessid
- * session ID
- * @param string $playlistId
- * playlist global unique ID
- * @param boolean $recursive
- * flag for recursive access content inside playlist
- * @param int $parent
- * parent token
- * @return struct {
- * url: readable URL for HTTP GET,
- * token: access token,
- * chsum: checksum,
- * content: array of structs - recursive access (optional)
- * filename: string mnemonic filename
- * }
- */
- public function accessPlaylist($sessid, $playlistId, $recursive=FALSE, $parent='0')
- // {
- // if ($recursive) {
- // require_once("AccessRecur.php");
- // $r = AccessRecur::accessPlaylist($this, $sessid, $playlistId);
- // if (PEAR::isError($r)) {
- // return $r;
- // }
- // return $r;
- // }
- // $ex = $this->existsPlaylist($sessid, $playlistId);
- // if (PEAR::isError($ex)) {
- // return $ex;
- // }
- // if (!$ex) {
- // return PEAR::raiseError(
- // "LocStor::accessPlaylist: playlist not found ($playlistId)",
- // GBERR_NOTF
- // );
- // }
- // $id = BasicStor::IdFromGunid($playlistId);
- // if (($res = BasicStor::Authorize('read', $id, $sessid)) !== TRUE) {
- // return $res;
- // }
- // $res = $this->bsOpenDownload($id, 'metadata', $parent);
- // #unset($res['filename']);
- // return $res;
- }
-
-
- /**
- * Release the resources obtained earlier by accessPlaylist().
- *
- * @param string $sessid
- * session ID
- * @param string $playlistToken
- * playlist access token
- * @param boolean $recursive
- * flag for recursive access content inside playlist
- * @return string
- * playlist ID
- */
- public function releasePlaylist($sessid, $playlistToken, $recursive=FALSE)
- {
- if ($recursive) {
- require_once"AccessRecur.php";
- $r = AccessRecur::releasePlaylist($this, $sessid, $playlistToken);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $r;
- }
- return $this->bsCloseDownload($playlistToken, 'metadata');
- }
-
-
- /**
- * Create a tarfile with playlist export - playlist and all matching
- * sub-playlists and media files (if desired)
- *
- * @param string $sessid
- * session ID
- * @param array $plids
- * array of strings, playlist global unique IDs (one gunid is accepted too)
- * @param string $type
- * playlist format, values: lspl | smil | m3u
- * @param boolean $standalone
- * if only playlist should be exported or with all related files
- * @return hasharray with fields:
- * url string: readable url,
- * token string: access token
- * chsum string: md5 checksum,
- */
- protected function exportPlaylistOpen($sessid, $plids, $type='lspl', $standalone=FALSE)
- {
- $res = $this->bsExportPlaylistOpen($plids, $type, !$standalone);
- if (PEAR::isError($res)) {
- return $res;
- }
- $url = BasicStor::GetUrlPart()."access/".basename($res['fname']);
- $chsum = md5_file($res['fname']);
- $size = filesize($res['fname']);
- return array(
- 'url' => $url,
- 'token' => $res['token'],
- 'chsum' => $chsum,
- );
- }
-
-
- /**
- * Close playlist export previously opened by the exportPlaylistOpen method
- *
- * @param string $token
- * access token obtained from exportPlaylistOpen method call
- * @return boolean|PEAR_Error
- */
- protected function exportPlaylistClose($token)
- {
- return $this->bsExportPlaylistClose($token);
- }
-
-
- /**
- * Open writable handle for import playlist in LS Archive format
- *
- * @param string $sessid
- * session id
- * @param string $chsum
- * md5 checksum of imported file
- * @return hasharray with:
- * url string: writable URL
- * token string: PUT token
- */
- protected function importPlaylistOpen($sessid, $chsum)
- {
- $userid = Alib::GetSessUserId($sessid);
- if (PEAR::isError($userid)) {
- return $userid;
- }
- $r = $this->bsOpenPut($chsum, NULL, $userid);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $r;
- }
-
-
- /**
- * Close import-handle and import playlist
- *
- * @param string $token
- * import token obtained by importPlaylistOpen method
- * @return string
- * result file global id (or error object)
- */
- protected function importPlaylistClose($token)
- {
- $arr = $this->bsClosePut($token);
- if (PEAR::isError($arr)) {
- return $arr;
- }
- $fname = $arr['fname'];
- $owner = $arr['owner'];
- $res = $this->bsImportPlaylist($fname);
- if (file_exists($fname)) {
- @unlink($fname);
- }
- if (PEAR::isError($res)) {
- return $res;
- }
- $media = StoredFile::Recall($id);
- return $media->getGunId();
- }
-
-
- /**
- * Check whether a Playlist metafile with the given playlist ID exists.
- *
- * @param string $sessid
- * session ID
- * @param string $playlistId
- * playlist global unique ID
- * @return boolean
- */
- public function existsPlaylist($sessid, $playlistId)
- {
- return $this->existsFile($sessid, $playlistId, 'playlist');
- }
-
-
- /**
- * Check whether a Playlist metafile with the given playlist ID
- * is available for editing, i.e., exists and is not marked as
- * being edited.
- *
- * @param string $sessid
- * session ID
- * @param string $playlistId
- * playlist global unique ID
- * @param boolean $getUid
- * flag for returning editedby uid
- * @return boolean
- */
- public function playlistIsAvailable($sessid, $playlistId, $getUid=FALSE)
- {
- $ex = $this->existsPlaylist($sessid, $playlistId);
- if (PEAR::isError($ex)) {
- return $ex;
- }
- if (!$ex) {
- return PEAR::raiseError(
- 'LocStor::playlistIsAvailable: playlist not exists'
- );
- }
- $ie = $this->isEdited($playlistId);
- if ($ie === FALSE) {
- return TRUE;
- }
- if ($getUid) {
- return $ie;
- }
- return FALSE;
- }
-
-
- /*===================================================== auxiliary methods */
- /**
- * Dummy method - only returns Airtime version
- *
- * @return string
- */
- public static function getVersion()
- {
- return AIRTIME_VERSION;
- }
-
- /**
- * Open upload transport (from station to hub)
- *
- * @param string $sessid
- * session id
- * @param string $chsum
- * checksum
- * @return array
- * hasharray with:
- * url string: writable URL
- * token string: PUT token
- */
- function uploadOpen($sessid, $chsum)
- {
- $owner = Alib::GetSessUserId($sessid);
- if (PEAR::isError($owner)) {
- return $owner;
- }
- $res = $this->bsOpenPut($chsum, NULL, $owner);
- if (PEAR::isError($res)) {
- return $res;
- }
- return array('url'=>$res['url'], 'token'=>$res['token']);
- }
-
-
- /**
- * Close upload transport
- *
- * @param string $token
- * transport token
- * @param string $trtype
- * transport type
- * @param array $pars
- * transport parameters
- * @return mixed
- */
- function uploadClose($token, $trtype, $pars=array())
- {
- $res = $this->bsClosePut($token);
- if (PEAR::isError($res)) {
- return $res;
- }
- extract($res); // fname, owner
- switch ($trtype) {
- case "audioclip":
- $mdtoken = $pars['mdpdtoken'];
- $res = $this->bsClosePut($mdtoken);
- if (PEAR::isError($res)) {
- return $res;
- }
- $mdfname = $res['fname'];
- if ($gunid == '') {
- $gunid = NULL;
- }
- $values = array(
- "filename" => $pars['name'],
- "filepath" => $fname,
- "metadata" => $mdfname,
- "gunid" => $pars['gunid'],
- "filetype" => "audioclip"
- );
- $storedFile = StoredFile::Insert($values);
- if (PEAR::isError($storedFile)) {
- return $storedFile;
- }
- $res = $storedFile->getId();
- @unlink($fname);
- @unlink($mdfname);
- break;
- case "playlist":
- if ($gunid == '') {
- $gunid = NULL;
- }
- $values = array(
- "filename" => $pars['name'],
- "metadata" => $fname,
- "gunid" => $pars['gunid'],
- "filetype" => "playlist"
- );
- $storedFile = StoredFile::Insert($values);
- if (PEAR::isError($storedFile)) {
- return $storedFile;
- }
- $res = $storedFile->getId();
- @unlink($fname);
- break;
- case "playlistPkg":
- $chsum = md5_file($fname);
- // importPlaylistOpen:
- $res = $this->bsOpenPut($chsum, NULL, $owner);
- if (PEAR::isError($res)) {
- return $res;
- }
- $dest = $res['fname'];
- $token = $res['token'];
- copy($fname, $dest);
- $r = $this->importPlaylistClose($token);
- if (PEAR::isError($r)) {
- return $r;
- }
- @unlink($fname);
- return $r;
- break;
- case "searchjob":
- $crits = file_get_contents($fname);
- $criteria = unserialize($crits);
- @unlink($fname);
- $results = $this->localSearch($criteria);
- if (PEAR::isError($results)) {
- return $results;
- }
- $realfile = tempnam($this->accessDir, 'searchjob_');
- @chmod($realfile, 0660);
- $len = file_put_contents($realfile, serialize($results));
- $acc = BasicStor::bsAccess($realfile, '', NULL, 'download');
- if (PEAR::isError($acc)) {
- return $acc;
- }
- $url = BasicStor::GetUrlPart()."access/".basename($acc['fname']);
- $chsum = md5_file($realfile);
- $size = filesize($realfile);
- $res = array(
- 'url'=>$url, 'token'=>$acc['token'],
- 'chsum'=>$chsum, 'size'=>$size,
- 'filename'=>$filename
- );
- return $res;
- break;
- case "metadata":
- break;
- default:
- }
- return $res;
- }
-
-
- /**
- * Open download transport
- *
- * @param string $sessid
- * session id
- * @param string $trtype
- * transport type
- * @param array $pars
- * transport parameters
- * @return hasharray with:
- * url string: writable URL
- * token string: PUT token
- */
- function downloadOpen($sessid, $trtype, $pars=array())
- {
- // global $CC_CONFIG;
- // switch ($trtype) {
- // case "unknown":
- // case "audioclip":
- // case "metadata":
- // case "playlist":
- // case "playlistPkg":
- // if (!isset($pars['gunid'])) {
- // return PEAR::raiseError("Archive::downloadOpen: gunid not set");
- // }
- // break;
- // }
- // $gunid = $pars['gunid'];
- // // resolve trtype by object type:
- // if ( ($trtype == 'unknown') || ($trtype == 'playlistPkg') ) {
- // $media = StoredFile::RecallByGunid($gunid);
- // $trtype2 = $media->getType();
- // if (PEAR::isError($trtype2)) {
- // return $trtype2;
- // }
- // // required with content:
- // $trtype = ( ($trtype2 == 'playlist') && ($trtype == 'playlistPkg') ?
- // 'playlistPkg' : $trtype2);
- // //return PEAR::raiseError("Archive::downloadOpen: TT=$trtype TT2=$trtype2 G=$gunid");
- // }
- // switch ($trtype) {
- // case "audioclip":
- // $res = $this->downloadRawAudioDataOpen($sessid, $gunid);
- // break;
- // case "metadata":
- // $res = $this->downloadMetadataOpen($sessid, $gunid);
- // break;
- // case "playlist":
- // $res = $this->accessPlaylist($sessid, $gunid);
- // break;
- // case "playlistPkg":
- // $res = $this->bsExportPlaylistOpen($gunid);
- // if (PEAR::isError($res)) {
- // return $res;
- // }
- // $tmpn = tempnam($CC_CONFIG['transDir'], 'plExport_');
- // $plfpath = "$tmpn.lspl";
- // copy($res['fname'], $plfpath);
- // $res = $this->bsExportPlaylistClose($res['token']);
- // if (PEAR::isError($res)) {
- // return $res;
- // }
- // $fname = "transported_playlist.lspl";
- // $id = BasicStor::IdFromGunid($gunid);
- // $acc = BasicStor::bsAccess($plfpath, 'lspl', NULL, 'download');
- // if (PEAR::isError($acc)) {
- // return $acc;
- // }
- // $url = BasicStor::GetUrlPart()."access/".basename($acc['fname']);
- // $chsum = md5_file($plfpath);
- // $size = filesize($plfpath);
- // $res = array(
- // 'url'=>$url, 'token'=>$acc['token'],
- // 'chsum'=>$chsum, 'size'=>$size,
- // 'filename'=>$fname
- // );
- // break;
- // case "searchjob":
- // $res = $pars;
- // break;
- // case "file":
- // $res = array();
- // break;
- // default:
- // return PEAR::raiseError("Archive::downloadOpen: NotImpl ($trtype)");
- // }
- // if (PEAR::isError($res)) {
- // return $res;
- // }
- // switch ($trtype) {
- // case "audioclip":
- // case "metadata":
- // case "playlist":
- // case "playlistPkg":
- // $f = StoredFile::RecallByGunid($gunid);
- // $title = $f->getTitle();
- // break;
- // case "searchjob":
- // $title = 'searchjob';
- // break;
- // case "file":
- // $title = 'regular file';
- // break;
- // default:
- // }
- // $res['title'] = $title;
- // $res['trtype'] = $trtype;
- // return $res;
- }
-
-
- /**
- * Close download transport
- *
- * @param string $token
- * transport token
- * @param string $trtype
- * transport type
- * @return array
- * hasharray with:
- * url string: writable URL
- * token string: PUT token
- */
- function downloadClose($token, $trtype)
- {
- switch ($trtype) {
- case "audioclip":
- $res = $this->downloadRawAudioDataClose($token);
- if (PEAR::isError($res)) {
- return $res;
- }
- return $res;
- case "metadata":
- $res = $this->downloadMetadataClose($token);
- return $res;
- case "playlist":
- $res = $this->releasePlaylist(NULL/*$sessid*/, $token);
- return $res;
- case "playlistPkg":
- $res = BasicStor::bsRelease($token, 'download');
- if (PEAR::isError($res)) {
- return $res;
- }
- $realFname = $r['realFname'];
- @unlink($realFname);
- if (preg_match("|(plExport_[^\.]+)\.lspl$|", $realFname, $va)) {
- list(,$tmpn) = $va;
- $tmpn = $CC_CONFIG['transDir']."/$tmpn";
- if (file_exists($tmpn)) {
- @unlink($tmpn);
- }
- }
- return $res;
- case "searchjob":
- $res = BasicStor::bsRelease($token, 'download');
- return $res;
- case "file":
- return array();
- default:
- return PEAR::raiseError("Archive::downloadClose: NotImpl ($trtype)");
- }
- }
-
-
- /**
- * Prepare hub initiated transport
- *
- * @param string $target
- * hostname of transport target
- * @param string $trtype
- * transport type
- * @param string $direction
- * 'up' | 'down'
- * @param array $pars
- * transport parameters
- * @return mixed
- */
- function prepareHubInitiatedTransfer(
- $target, $trtype='file', $direction='up',$pars=array())
- {
- $tr = new Transport($this);
- $trec = TransportRecord::create($tr, $trtype, $direction,
- array_merge($pars, array('target'=>$target)));
- if (PEAR::isError($trec)) {
- return $trec;
- }
- return TRUE;
- }
-
-
- /**
- * List hub initiated transports
- *
- * @param string $target
- * hostname of transport target
- * @param string $direction
- * 'up' | 'down'
- * @param string $trtok
- * transport token
- * @return mixed
- */
- function listHubInitiatedTransfers(
- $target=NULL, $direction=NULL, $trtok=NULL)
- {
- $tr = new Transport($this);
- $res = $tr->getTransports($direction, $target, $trtok);
- return $res;
- }
-
-
- /**
- * Set state of hub initiated transport
- *
- * @param string $target
- * hostname of transport target
- * @param string $trtok
- * transport token
- * @param string $state
- * transport state
- * @return TransportRecord|PEAR_Error
- */
- function setHubInitiatedTransfer($target, $trtok, $state)
- {
- $tr = new Transport($this);
- $trec = TransportRecord::recall($tr, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $r = $trec->setState($state);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $trec;
- }
-
- /* ==================================================== auxiliary methods */
-
-} // class LocStor
diff --git a/application/models/Playlist.php b/application/models/Playlist.php
index 9d9905e7b..732a142e9 100644
--- a/application/models/Playlist.php
+++ b/application/models/Playlist.php
@@ -1,10 +1,7 @@
gb =& $gb;
}
diff --git a/application/models/Transport.php b/application/models/Transport.php
deleted file mode 100644
index 5478618ce..000000000
--- a/application/models/Transport.php
+++ /dev/null
@@ -1,1833 +0,0 @@
-
- * over unreliable network and from behind firewall
- *
- * Transport states:
- *
- * - init: transport is prepared, but not started
- * (e.g. no network connection is present)
- * - pending: transport is in progress, file is not fully transported to
- * target system
- * - waiting: transport is in progress, but not running now
- * - finished: transport is finished, but file processing on target side
- * is not completed
- * - closed: processing on target side is completed without errors
- * - failed: error - error message stored in errmsg field
- * - paused: transport have been paused
- *
- *
- * Transport types:
- *
- * - audioclip
- * - playlist
- * - metadata
- * - file
- *
- *
- * @package Airtime
- * @subpackage StorageServer
- * @copyright 2010 Sourcefabric O.P.S.
- * @license http://www.gnu.org/licenses/gpl.txt
- */
-class Transport
-{
- /**
- * @var GreenBox
- */
- public $gb;
-
- /**
- * File name
- * @var string
- */
- private $cronJobScript;
-
- /**
- * wget --read-timeout parameter [s]
- * @var int
- */
- private $downTimeout = 900;
-
- /**
- * wget --waitretry parameter [s]
- * @var int
- */
- private $downWaitretry = 10;
-
- /**
- * wget --limit-rate parameter
- */
- private $downLimitRate = NULL;
-# private $downLimitRate = 500;
-
- /**
- * wget -t parameter
- * @var int
- */
- private $downRetries = 6;
-
- /**
- * curl --max-time parameter
- * @var int
- */
- private $upTrMaxTime = 1800;
-
- /**
- * curl --speed-time parameter
- * @var int
- */
- private $upTrSpeedTime = 30;
-
- /**
- * curl --speed-limit parameter
- * @var int
- */
- private $upTrSpeedLimit = 30;
-
- /**
- * curl --connect-timeout parameter
- * @var int
- */
- private $upTrConnectTimeout = 20;
-
- /**
- * curl --limit-rate parameter
- * @var int
- */
- private $upLimitRate = NULL;
-# private $upLimitRate = 500;
-
-
- /**
- * Constructor
- *
- * @param LocStor $gb
- * @return Transport
- */
- public function __construct(&$gb)
- {
- $this->gb =& $gb;
- $this->cronJobScript = realpath(
- dirname(__FILE__).
- '/../../storageServer/var/cron/transportCronJob.php'
- );
- }
-
-
- /* ==================================================== transport methods */
- /* ------------------------------------------------------- common methods */
- /**
- * Common "check" method for transports
- *
- * @param string $trtok
- * transport token
- * @return array
- * struct/hasharray with fields:
- * trtype: string -
- * audioclip | playlist | playlistPkg | metadata | file
- * state: string - transport state
- * init | pending | waiting | finished | closed | failed
- * direction: string - up | down
- * expectedsize: int - file size in bytes
- * realsize: int - currently transported bytes
- * expectedsum: string - orginal file checksum
- * realsum: string - transported file checksum
- * title: string - dc:title or filename etc.
- * errmsg: string - error message for failed transports
- * ... ?
- */
- function getTransportInfo($trtok)
- {
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $res = array();
- foreach (array(
- 'trtype', 'state', 'direction', 'expectedsize', 'realsize',
- 'expectedsum', 'realsum', 'title', 'errmsg'
- ) as $k) {
- $res[$k] = ( isset($trec->row[$k]) ? $trec->row[$k] : NULL );
- }
- if ( ($trec->row['direction'] == 'down') && file_exists($trec->row['localfile']) ){
- $res['realsize'] = filesize($trec->row['localfile']);
- $res['realsum'] = $this->_chsum($trec->row['localfile']);
- }
- if ( ($trec->row['direction'] == 'up') ){
- $check = $this->uploadCheck($trec->row['pdtoken']);
- if (!PEAR::isError($check)) {
- $res['realsize'] = $check['size'];
- $res['realsum'] = $check['realsum'];
- }
- }
- return $res;
- }
-
-
- /**
- * Turn transports on/off, optionaly return current state.
- * (true=On / false=off)
- *
- * @param string $sessid
- * session id
- * @param boolean $onOff
- * optional (if not used, current state is returned)
- * @return boolea
- * previous state
- */
- function turnOnOffTransports($sessid, $onOff=NULL)
- {
- require_once('Prefs.php');
- $pr = new Prefs($this->gb);
- $group = $CC_CONFIG['StationPrefsGr'];
- $key = 'TransportsDenied';
- $res = $pr->loadGroupPref($group, $key);
- if (PEAR::isError($res)) {
- if ($res->getCode() !== GBERR_PREF) {
- return $res;
- } else {
- $res = FALSE; // default
- }
- }
- $state = !$res;
- if (is_null($onOff)) {
- return $state;
- }
- $res = $pr->saveGroupPref($sessid, $group, $key, !$onOff);
- if (PEAR::isError($res)) {
- return $res;
- }
- return $state;
- }
-
-
- /**
- * Pause, resume or cancel transport
- *
- * @param string $trtok
- * transport token
- * @param string $action
- * pause | resume | cancel
- * @return string
- * resulting transport state
- */
- function doTransportAction($trtok, $action)
- {
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- if ($trec->getState() == 'closed') {
- return PEAR::raiseError(
- "Transport::doTransportAction:".
- " closed transport token ($trtok)", TRERR_TOK
- );
- }
- switch ($action) {
- case 'pause';
- $newState = 'paused';
- break;
- case 'resume';
- $newState = 'waiting';
- break;
- case 'cancel';
- $newState = 'closed';
- break;
- default:
- return PEAR::raiseError(
- "Transport::doTransportAction:".
- " unknown action ($action)"
- );
- }
- $res = $trec->setState($newState);
- switch ($action) {
- case 'pause';
- case 'cancel';
- $trec->killJob();
- }
- return $res;
- }
-
- /* ------------- special methods for audioClip/webstream object transport */
-
- /**
- * Start upload of audioClip/webstream/playlist from local storageServer
- * to hub.
- *
- * @param string $gunid
- * global unique id of object being transported
- * @param boolean $withContent
- * if true, transport playlist content too (optional)
- * @param array $pars
- * default parameters (optional, internal use)
- * @return string
- * transport token
- */
- function upload2Hub($gunid, $withContent=TRUE, $pars=array())
- {
- global $CC_CONFIG, $CC_DBC;
- $this->trLog("upload2Hub start: ".strftime("%H:%M:%S"));
- switch ($ftype = BasicStor::GetType($gunid)) {
- case "audioclip":
- case "webstream":
- $storedFile = StoredFile::RecallByGunid($gunid);
- if (is_null($storedFile) || PEAR::isError($storedFile)) {
- return $storedFile;
- }
- // handle metadata:
- $mdfpath = $storedFile->getRealMetadataFileName();
- if (PEAR::isError($mdfpath)) {
- return $mdfpath;
- }
- $mdtrec = $this->_uploadGeneralFileToHub($mdfpath, 'metadata',
- array_merge(array('gunid'=>$gunid, 'fname'=>'metadata',), $pars)
- );
- if (PEAR::isError($mdtrec)) {
- return $mdtrec;
- }
- // handle raw media file:
- $fpath = $storedFile->getRealFileName();
- if (PEAR::isError($fpath)) {
- return $fpath;
- }
- $fname = $storedFile->getName();
- if (PEAR::isError($fname)) {
- return $fname;
- }
- $trec = $this->_uploadGeneralFileToHub($fpath, 'audioclip',
- array_merge(array(
- 'gunid'=>$gunid, 'fname'=>$fname, 'mdtrtok'=>$mdtrec->trtok,
- ), $pars)
- );
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $this->startCronJobProcess($mdtrec->trtok);
- break;
-
- case "playlist":
- $plid = $gunid;
- require_once("Playlist.php");
- $pl = StoredFile::RecallByGunid($plid);
- if (is_null($pl) || PEAR::isError($pl)) {
- return $pl;
- }
- $fname = $pl->getName();
- if (PEAR::isError($fname)) {
- return $fname;
- }
- if ($withContent) {
- $this->trLog("upload2Hub exportPlaylistOpen BEGIN: ".strftime("%H:%M:%S"));
- $res = $this->gb->bsExportPlaylistOpen($plid);
- $this->trLog("upload2Hub exportPlaylistOpen END: ".strftime("%H:%M:%S"));
- if (PEAR::isError($res)) {
- return $res;
- }
- $tmpn = tempnam($CC_CONFIG['transDir'], 'plExport_');
- $plfpath = "$tmpn.lspl";
- $this->trLog("upload2Hub begin copy: ".strftime("%H:%M:%S"));
- copy($res['fname'], $plfpath);
- $this->trLog("upload2Hub end copy: ".strftime("%H:%M:%S"));
- $res = $this->gb->bsExportPlaylistClose($res['token']);
- if (PEAR::isError($res)) {
- return $res;
- }
- $fname = $fname.".lspl";
- $trtype = 'playlistPkg';
- } else {
- $plfpath = $pl->getRealMetadataFileName();
- if (PEAR::isError($plfpath)) {
- return $plfpath;
- }
- $trtype = 'playlist';
- }
- $trec = $this->_uploadGeneralFileToHub($plfpath, $trtype,
- array_merge(array('gunid'=>$plid,'fname'=>$fname,), $pars));
- if (PEAR::isError($trec)) {
- return $trec;
- }
- break;
- default:
- return PEAR::raiseError("Transport::upload2Hub: ftype not supported ($ftype)");
- }
- $this->startCronJobProcess($trec->trtok);
- $this->trLog("upload2Hub end: ".strftime("%H:%M:%S"));
- return $trec->trtok;
- }
-
-
- /**
- * Start download of audioClip/webstream/playlist from hub to local
- * storageServer
- *
- * @param int $uid
- * local user id of transport owner
- * (for downloading file to homedir in storage)
- * @param string $gunid
- * global unique id of object being transported
- * @param boolean $withContent
- * if true, transport playlist content too (optional)
- * @param array $pars
- * default parameters (optional, internal use)
- * @return string
- * transport token
- */
- function downloadFromHub($uid, $gunid, $withContent=TRUE, $pars=array())
- {
- $trtype = ($withContent ? 'playlistPkg' : 'unknown' );
- $trec = TransportRecord::create($this, $trtype, 'down',
- array_merge(array('gunid'=>$gunid, 'uid'=>$uid), $pars));
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $this->startCronJobProcess($trec->trtok);
- return $trec->trtok;
- }
-
-
- /* ------------------------------------------------ remote-search methods */
- /**
- * Start search job on remote Airtime instance.
- *
- * @param array $criteria
- * LS criteria format (see localSearch)
- * @param string $resultMode
- * 'php' | 'xmlrpc'
- * @param array $pars
- * default parameters (optional, internal use)
- * @return string
- * transport token
- */
- function remoteSearch($criteria, $resultMode='php')
- {
- global $CC_CONFIG, $CC_DBC;
- $criteria['resultMode'] = $resultMode;
-
- // testing of hub availability and hub account configuration.
- $sessid = $this->loginToArchive();
- if (PEAR::isError($sessid)) {
- switch(intval($sessid->getCode())) {
- case 802:
- return PEAR::raiseError("Can't login to Hub ({$sessid->getMessage()})", TRERR_XR_FAIL);
- case TRERR_XR_FAIL:
- return PEAR::raiseError("Can't connect to Hub ({$sessid->getMessage()})", TRERR_XR_FAIL);
- }
- return $sessid;
- }
- $params = array("sessid" => $sessid, "criteria" => $criteria);
- $result = $this->xmlrpcCall("locstor.searchMetadata", $params);
- //$result = $this->xmlrpcCall("locstor.ping", array("par" => "foo"));
- $this->logoutFromArchive($sessid);
- return $result;
- }
-
- /**
- * Start search job on network hub
- *
- * @param array $criteria
- * LS criteria format (see localSearch)
- * @param string $resultMode
- * 'php' | 'xmlrpc'
- * @param array $pars
- * default parameters (optional, internal use)
- * @return string
- * transport token
- */
-// function globalSearch($criteria, $resultMode='php', $pars=array())
-// {
-// global $CC_CONFIG, $CC_DBC;
-// // testing of hub availability and hub account configuration.
-// // it makes searchjob not async - should be removed for real async
-// $r = $this->loginToArchive();
-// if (PEAR::isError($r)) {
-// switch(intval($r->getCode())) {
-// case 802:
-// return PEAR::raiseError("Can't login to Hub ({$r->getMessage()})", TRERR_XR_FAIL);
-// case TRERR_XR_FAIL:
-// return PEAR::raiseError("Can't connect to Hub ({$r->getMessage()})", TRERR_XR_FAIL);
-// }
-// return $r;
-// }
-// $this->logoutFromArchive($r);
-// $criteria['resultMode'] = $resultMode;
-// $localfile = tempnam($CC_CONFIG['transDir'], 'searchjob_');
-// @chmod($localfile, 0660);
-// $len = file_put_contents($localfile, serialize($criteria));
-// $trec = $this->_uploadGeneralFileToHub($localfile, 'searchjob', $pars);
-// if (PEAR::isError($trec)) {
-// return $trec;
-// }
-// $this->startCronJobProcess($trec->trtok);
-// return $trec->trtok;
-// }
-
-
- /**
- * Get results from search job on network hub
- *
- * @param string $trtok
- * transport token
- * @param boolean $andClose
- * if TRUE, close transport token
- * @return array
- * LS search result format (see localSearch)
- */
-// function getSearchResults($trtok, $andClose=TRUE)
-// {
-// $trec = TransportRecord::recall($this, $trtok);
-// if (PEAR::isError($trec)) {
-// return $trec;
-// }
-// $row = $trec->row;
-// switch ($st = $trec->getState()) {
-// case "failed":
-// return PEAR::raiseError(
-// "Transport::getSearchResults:".
-// " global search or results transport failed".
-// " ({$trec->row['errmsg']})"
-// );
-// case "closed":
-///*
-// $res = file_get_contents($row['localfile']);
-// $results = unserialize($res);
-// return $results;
-//*/
-// return PEAR::raiseError(
-// "Transport::getSearchResults:".
-// " closed transport token ($trtok)", TRERR_TOK
-// );
-// case "finished":
-// if ($row['direction'] == 'down') {
-// // really finished
-// $res = file_get_contents($row['localfile']);
-// $results = unserialize($res);
-// if ($andClose) {
-// $ret = $this->xmlrpcCall('archive.downloadClose',
-// array(
-// 'token' => $row['pdtoken'] ,
-// 'trtype' => $row['trtype'] ,
-// ));
-// if (PEAR::isError($ret)) {
-// return $ret;
-// }
-// @unlink($row['localfile']);
-// $r = $trec->close();
-// if (PEAR::isError($r)) {
-// return $r;
-// }
-// }
-// return $results;
-// }
-// // otherwise not really finished - only request upload finished
-// default:
-// return PEAR::raiseError(
-// "Transport::getSearchResults: not finished ($st)",
-// TRERR_NOTFIN
-// );
-// }
-// }
-
-
- /* ------------------------ methods for ls-archive-format file transports */
- /**
- * Open async file transfer from local storageServer to network hub,
- * file should be ls-archive-format file.
- *
- * @param string $filePath
- * local path to uploaded file
- * @param array $pars
- * default parameters (optional, internal use)
- * @return string
- * transport token
- */
- function uploadFile2Hub($filePath, $pars=array())
- {
- if (!file_exists($filePath)) {
- return PEAR::raiseError(
- "Transport::uploadFile2Hub: file not found ($filePath)"
- );
- }
- $trec = $this->_uploadGeneralFileToHub($filePath, 'file', $pars);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $this->startCronJobProcess($trec->trtok);
- return $trec->trtok;
- }
-
-
- /**
- * Open async file transfer from network hub to local storageServer,
- * file should be ls-archive-format file.
- *
- * @param string $url
- * readable url
- * @param string $chsum
- * checksum from remote side
- * @param int $size
- * filesize from remote side
- * @param array $pars
- * default parameters (internal use)
- * @return array
- * trtok: string - transport token
- * localfile: string - filepath of downloaded file
- */
- function downloadFileFromHub($url, $chsum=NULL, $size=NULL, $pars=array())
- {
- global $CC_CONFIG, $CC_DBC;
- $tmpn = tempnam($CC_CONFIG['transDir'], 'HITrans_');
- $trec = TransportRecord::create($this, 'file', 'down',
- array_merge(array(
- 'url' => $url,
- 'localfile' => $tmpn,
- 'expectedsum' => $chsum,
- 'expectedsize' => $size,
- ), $pars)
- );
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $this->startCronJobProcess($trec->trtok);
- return array('trtok'=>$trec->trtok, 'localfile'=>$tmpn);
- }
-
-
- /**
- * Get list of prepared transfers initiated by hub
- *
- * @return array
- * array of structs/hasharrays with fields:
- * trtok: string transport token
- */
- function getHubInitiatedTransfers()
- {
- $ret = $this->xmlrpcCall('archive.listHubInitiatedTransfers',
- array('target' => HOSTNAME));
- if (PEAR::isError($ret)) {
- return $ret;
- }
- $res = array();
- foreach ($ret as $it) {
- $res[] = array('trtok'=>$it['trtok']);
- }
- return $res;
- }
-
-
- /**
- * Start of download initiated by hub
- *
- * @param int $uid
- * local user id of transport owner
- * (for downloading file to homedir in storage)
- * @param string $rtrtok
- * transport token obtained from the getHubInitiatedTransfers method
- * @return string
- * transport token
- */
- function startHubInitiatedTransfer($uid, $rtrtok)
- {
- $ret = $this->xmlrpcCall('archive.listHubInitiatedTransfers',
- array(
- 'target' => HOSTNAME,
- 'trtok' => $rtrtok,
- ));
- if (PEAR::isError($ret)) {
- return $ret;
- }
- if (count($ret) != 1) {
- return PEAR::raiseError(
- "Transport::startHubInitiatedTransfer:".
- " wrong number of transports (".count($ret).")"
- );
- }
- $ta = $ret[0];
- // direction invertation to locstor point of view:
- $direction = ( $ta['direction']=='up' ? 'down' : 'up' );
- $gunid = $ta['gunid'];
- switch ($direction) {
- case "up":
- switch ($ta['trtype']) {
- case "audioclip":
- case "playlist":
- case "playlistPkg":
- $trtok = $this->upload2Hub($gunid, TRUE,
- array('rtrtok'=>$rtrtok));
- if (PEAR::isError($trtok)) {
- return $trtok;
- }
- break;
- //case "searchjob": break; // not supported yet
- //case "file": break; // probably unusable
- default:
- return PEAR::raiseError(
- "Transport::startHubInitiatedTransfer:".
- " wrong direction / transport type combination".
- " ({$ta['direction']}/{$ta['trtype']})"
- );
- }
- break;
- case "down":
- switch ($ta['trtype']) {
- case "audioclip":
- case "playlist":
- case "playlistPkg":
- $trtok = $this->downloadFromHub($uid, $gunid, TRUE,
- array('rtrtok'=>$rtrtok));
- if (PEAR::isError($trtok)) {
- return $trtok;
- }
- break;
- //case "searchjob": break; // probably unusable
- case "file":
- $r = $this->downloadFileFromHub(
- $ta['url'], $ta['expectedsum'], $ta['expectedsize'],
- array('rtrtok'=>$rtrtok));
- if (PEAR::isError($r)) {
- return $r;
- }
- extract($r); // trtok, localfile
- break;
- default:
- return PEAR::raiseError(
- "Transport::startHubInitiatedTransfer:".
- " wrong direction / transport type combination".
- " ({$ta['direction']}/{$ta['trtype']})"
- );
- }
- break;
- default:
- return PEAR::raiseError(
- "Transport::startHubInitiatedTransfer: ???"
- );
- }
- $ret = $this->xmlrpcCall('archive.setHubInitiatedTransfer',
- array(
- 'target' => HOSTNAME,
- 'trtok' => $rtrtok,
- 'state' => 'waiting',
- ));
- if (PEAR::isError($ret)) {
- return $ret;
- }
- $this->startCronJobProcess($trtok);
- return $trtok;
- }
-
-
- /* =============================================== authentication methods */
-
- /**
- * Login to archive server
- * (account info is taken from storageServer's config)
- *
- * @return string
- * sessid or error
- */
- function loginToArchive()
- {
- global $CC_CONFIG;
- $res = $this->xmlrpcCall('locstor.login',
- array(
- 'login' => $CC_CONFIG['archiveAccountLogin'],
- 'pass' => $CC_CONFIG['archiveAccountPass']
- ));
- if (PEAR::isError($res)) {
- return $res;
- }
- return $res['sessid'];
- }
-
-
- /**
- * Logout from archive server
- *
- * @param unknown $sessid
- * session id
- * @return string
- * Bye or error
- */
- function logoutFromArchive($sessid)
- {
- $res = $this->xmlrpcCall('locstor.logout',
- array('sessid'=>$sessid));
- return $res;
- }
-
-
- /* ========================================================= cron methods */
- /* -------------------------------------------------- common cron methods */
- /**
- * Main method for periodical transport tasks - called by cron
- *
- * @param string $direction
- * optional
- * @return boolean
- * TRUE
- */
- function cronMain($direction=NULL)
- {
- global $CC_CONFIG;
- if (is_null($direction)) {
- $r = $this->cronMain('up');
- if (PEAR::isError($r)) {
- return $r;
- }
- $r = $this->cronMain('down');
- if (PEAR::isError($r)) {
- return $r;
- }
- return TRUE;
- }
- // fetch all opened transports
- $transports = $this->getTransports($direction);
- if (PEAR::isError($transports)) {
- $this->trLog("cronMain: DB error");
- return FALSE;
- }
- if (count($transports) == 0) {
- if (TR_LOG_LEVEL > 1) {
- $this->trLog("cronMain: $direction - nothing to do.");
- }
- return TRUE;
- }
- // ping to archive server:
- $r = $this->ping();
- chdir($CC_CONFIG['transDir']);
- // for all opened transports:
- foreach ($transports as $i => $row) {
- $r = $this->startCronJobProcess($row['trtok']);
- } // foreach transports
- return TRUE;
- }
-
-
- /**
- * Cron job process starter
- *
- * @param string $trtok
- * transport token
- * @return boolean
- * status
- */
- function startCronJobProcess($trtok)
- {
- global $CC_CONFIG, $CC_DBC;
- if (TR_LOG_LEVEL > 2) {
- $redirect = $CC_CONFIG['transDir']."/debug.log";
- } else {
- $redirect = "/dev/null";
- }
- $redirect_escaped = escapeshellcmd($redirect);
- $command = "{$this->cronJobScript} {$trtok}";
- $command_escaped = escapeshellcmd($command);
- $command_final = "$command_escaped >> $redirect_escaped 2>&1 &";
- $res = system($command_final, $status);
- if ($res === FALSE) {
- $this->trLog(
- "cronMain: Error on execute cronJobScript with trtok {$trtok}"
- );
- return FALSE;
- }
- return TRUE;
- }
-
-
- /**
- * Dynamic method caller - wrapper
- *
- * @param string $trtok
- * transport token
- * @return mixed
- * inherited from called method
- */
- function cronCallMethod($trtok)
- {
- global $CC_CONFIG;
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $row = $trec->row;
- $state = $row['state'];
-
- $states = array('init'=>'init',
- 'pending'=>'pending',
- 'waiting'=>'waiting',
- 'finished'=>'finished',
- 'failed'=>'failed',
- 'closed'=>'closed');
- $directions = array('up'=>'upload', 'down'=>'download');
- // method name construction:
- $mname = "cron";
- if (isset($directions[$row['direction']])) {
- $mname .= ucfirst($directions[$row['direction']]);
- } else {
- return PEAR::raiseError(
- "Transport::cronCallMethod: invalid direction ({$row['direction']})"
- );
- }
- if (isset($states[$state])) {
- $mname .= ucfirst($states[$state]);
- } else {
- return PEAR::raiseError(
- "Transport::cronCallMethod: invalid state ({$state})"
- );
- }
- switch ($state) {
- // do nothing if closed, penfing or failed:
- case 'closed': // excluded in SQL query too, but let check it here
- case 'failed': // -"-
- case 'pending':
- case 'paused':
- return TRUE;
- case 'waiting':
- require_once('Prefs.php');
- $pr = new Prefs($this->gb);
- $group = $CC_CONFIG['StationPrefsGr'];
- $key = 'TransportsDenied';
- $res = $pr->loadGroupPref($group, $key);
- if (PEAR::isError($res)) {
- if ($res->getCode() !== GBERR_PREF) {
- return $res;
- } else {
- $res = FALSE; // default
- }
- }
- // transfers turned off
- // if ($res) { return TRUE; break; }
- if ($res) {
- return PEAR::raiseError(
- "Transport::cronCallMethod: transfers turned off"
- );
- }
- // NO break here!
- default:
- if (method_exists($this, $mname)) {
- // lock the job:
- $pid = getmypid();
- $r = $trec->setLock(TRUE, $pid);
- if (PEAR::isError($r)) {
- return $r;
- }
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- $trec->setLock(FALSE);
- return $trec;
- }
- $row = $trec->row;
- $state = $row['state'];
-
- // login to archive server:
- $r = $this->loginToArchive();
- if (PEAR::isError($r)) {
- $r2 = $trec->setLock(FALSE);
- return $r;
- }
- $asessid = $r;
- // method call:
- if (TR_LOG_LEVEL > 2) {
- $this->trLog("cronCallMethod($pid): $mname($trtok) >");
- }
- $ret = call_user_func(array($this, $mname), $row, $asessid);
- if (PEAR::isError($ret)) {
- $trec->setLock(FALSE);
- return $this->_failFatal($ret, $trec);
- }
- if (TR_LOG_LEVEL > 2) {
- $this->trLog("cronCallMethod($pid): $mname($trtok) <");
- }
- // unlock the job:
- $r = $trec->setLock(FALSE);
- if (PEAR::isError($r)) {
- return $r;
- }
- // logout:
- $r = $this->logoutFromArchive($asessid);
- if (PEAR::isError($r)) {
- return $r;
- }
- return $ret;
- } else {
- return PEAR::raiseError(
- "Transport::cronCallMethod: unknown method ($mname)"
- );
- }
- }
- }
-
-
- /**
- * Upload initialization
- *
- * @param array $row
- * row from getTransport results
- * @param string $asessid
- * session id (from network hub)
- * @return mixed
- * boolean TRUE or error object
- */
- function cronUploadInit($row, $asessid)
- {
- $trtok = $row['trtok'];
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $ret = $this->xmlrpcCall('archive.uploadOpen',
- array(
- 'sessid' => $asessid ,
- 'chsum' => $row['expectedsum'],
- ));
- if (PEAR::isError($ret)) {
- return $ret;
- }
- $r = $trec->setState('waiting',
- array('url'=>$ret['url'], 'pdtoken'=>$ret['token']));
- if (PEAR::isError($r)) {
- return $r;
- }
- return TRUE;
- }
-
-
- /**
- * Download initialization
- *
- * @param array $row
- * row from getTransport results
- * @param string $asessid
- * session id (from network hub)
- * @return mixed
- * boolean TRUE or error object
- */
- function cronDownloadInit($row, $asessid)
- {
- global $CC_CONFIG;
- $trtok = $row['trtok'];
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $ret = $this->xmlrpcCall('archive.downloadOpen',
- array(
- 'sessid'=> $asessid,
- 'trtype'=> $row['trtype'],
- 'pars'=>array(
- 'gunid' => $row['gunid'],
- 'token' => $row['pdtoken'],
- ),
- ));
- if (PEAR::isError($ret)) {
- return $ret;
- }
- $trtype = $ret['trtype'];
- $title = $ret['title'];
- $pars = array();
- switch ($trtype) {
-// case "searchjob":
-// $r = $trec->setState('waiting', $pars);
-// break;
- case "file":
- $r = $trec->setState('waiting',array_merge($pars, array(
- 'trtype'=>$trtype,
- 'url'=>$ret['url'], 'pdtoken'=>$ret['token'],
- 'expectedsum'=>$ret['chsum'], 'expectedsize'=>$ret['size'],
- 'fname'=>$ret['filename'],
- 'localfile'=>$CC_CONFIG['transDir']."/$trtok",
- )));
- break;
- case "audioclip":
- $mdtrec = TransportRecord::create($this, 'metadata', 'down',
- array('gunid'=>$row['gunid'], 'uid'=>$row['uid'], )
- );
- if (PEAR::isError($mdtrec)) {
- return $mdtrec;
- }
- $this->startCronJobProcess($mdtrec->trtok);
- $pars = array('mdtrtok'=>$mdtrec->trtok);
- // NO break here !
- default:
- $r = $trec->setState('waiting',array_merge($pars, array(
- 'trtype'=>$trtype,
- 'url'=>$ret['url'], 'pdtoken'=>$ret['token'],
- 'expectedsum'=>$ret['chsum'], 'expectedsize'=>$ret['size'],
- 'fname'=>$ret['filename'], 'title'=>$title,
- 'localfile'=>$CC_CONFIG['transDir']."/$trtok",
- )));
- }
- if (PEAR::isError($r)) {
- return $r;
- }
- return TRUE;
- }
-
-
- /**
- * Upload next part of transported file
- *
- * @param array $row
- * row from getTransport results
- * @param string $asessid
- * session id (from network hub)
- * @return mixed
- * boolean TRUE or error object
- */
- function cronUploadWaiting($row, $asessid)
- {
- $trtok = $row['trtok'];
- $check = $this->uploadCheck($row['pdtoken']);
- if (PEAR::isError($check)) {
- return $check;
- }
- // test filesize
- if (!file_exists($row['localfile'])) {
- return PEAR::raiseError("Transport::cronUploadWaiting:".
- " file being uploaded does not exist! ({$row['localfile']})"
- );
- }
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $size = escapeshellarg($check['size']);
- $localfile = escapeshellarg($row['localfile']);
- $url = escapeshellarg($row['url']);
- $command =
- "curl -f -s -C $size --max-time {$this->upTrMaxTime}".
- " --speed-time {$this->upTrSpeedTime}".
- " --speed-limit {$this->upTrSpeedLimit}".
- " --connect-timeout {$this->upTrConnectTimeout}".
- (!is_null($this->upLimitRate)?
- " --limit-rate {$this->upLimitRate}" : "").
- " -T $localfile $url";
- $r = $trec->setState('pending', array(), 'waiting');
- if (PEAR::isError($r)) {
- return $r;
- }
- if ($r === FALSE) {
- return TRUE;
- }
- $res = system($command, $status);
-
- // leave paused and closed transports
- $trec2 = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $state2 = $trec2->row['state'];
- if ($state2 == 'paused' || $state2 == 'closed' ) {
- return TRUE;
- }
-
-
- // status 18 - Partial file. Only a part of the file was transported.
- // status 28 - Timeout. Too long/slow upload, try to resume next time rather.
- // status 6 - Couldn't resolve host.
- // status 7 - Failed to connect to host.
- // status 56 - Failure in receiving network data. Important - this status is
- // returned if file is locked on server side
- if ($status == 0 || $status == 18 || $status == 28 || $status == 6 || $status == 7 || $status == 56) {
- $check = $this->uploadCheck($row['pdtoken']);
- if (PEAR::isError($check)) {
- return $check;
- }
- // test checksum
- if ($check['status'] == TRUE) {
- // finished
- $r = $trec->setState('finished',
- array('realsum'=>$check['realsum'], 'realsize'=>$check['size']));
- if (PEAR::isError($r)) {
- return $r;
- }
- } else {
- if (intval($check['size']) < $row['expectedsize']) {
- $r = $trec->setState('waiting',
- array('realsum'=>$check['realsum'], 'realsize'=>$check['size']));
- if (PEAR::isError($r)) {
- return $r;
- }
- } else {
- // wrong md5 at finish - TODO: start again
- // $this->xmlrpcCall('archive.uploadReset', array());
- $trec->fail('file uploaded with bad md5');
- return PEAR::raiseError("Transport::cronUploadWaiting:".
- " file uploaded with bad md5 ".
- "($trtok: {$check['realsum']}/{$check['expectedsum']})"
- );
- }
- }
- } else {
- return PEAR::raiseError("Transport::cronUploadWaiting:".
- " wrong return status from curl: $status on $url".
- "($trtok)"
- );
- }
- return TRUE;
- }
-
-
- /**
- * Download next part of transported file
- *
- * @param array $row
- * row from getTransport results
- * @param string $asessid
- * session id (from network hub)
- * @return mixed
- * boolean TRUE or error object
- */
- function cronDownloadWaiting($row, $asessid)
- {
- $trtok = $row['trtok'];
- // wget the file
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $localfile = escapeshellarg($row['localfile']);
- $url = escapeshellarg($row['url']);
- $command =
- "wget -q -c".
- " --read-timeout={$this->downTimeout}".
- " --waitretry={$this->downWaitretry}".
- " -t {$this->downRetries}".
- (!is_null($this->downLimitRate)?
- " --limit-rate={$this->downLimitRate}" : "").
- " -O $localfile $url"
- ;
- $r = $trec->setState('pending', array(), 'waiting');
- if (PEAR::isError($r)) {
- return $r;
- }
- if ($r === FALSE) {
- return TRUE;
- }
- $res = system($command, $status);
-
- // leave paused and closed transports
- $trec2 = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- $state2 = $trec2->row['state'];
- if ($state2 == 'paused' || $state2 == 'closed' ) {
- return TRUE;
- }
-
- // check consistency
- $size = filesize($row['localfile']);
- if ($size < $row['expectedsize']) {
- // not finished - return to the 'waiting' state
- $r = $trec->setState('waiting', array('realsize'=>$size));
- if (PEAR::isError($r)) {
- return $r;
- }
- } elseif ($size >= $row['expectedsize']) {
- $chsum = $this->_chsum($row['localfile']);
- if ($chsum == $row['expectedsum']) {
- // mark download as finished
- $r = $trec->setState('finished',
- array('realsum'=>$chsum, 'realsize'=>$size));
- if (PEAR::isError($r)) {
- return $r;
- }
- } else {
- // bad checksum, retry from the scratch
- @unlink($row['localfile']);
- $r = $trec->setState('waiting',
- array('realsum'=>$chsum, 'realsize'=>$size));
- if (PEAR::isError($r)) {
- return $r;
- }
- }
- }
- return TRUE;
- }
-
-
- /**
- * Finish the upload
- *
- * @param array $row
- * row from getTransport results
- * @param string $asessid
- * session id (from network hub)
- * @return mixed
- * boolean TRUE or error object
- */
- function cronUploadFinished($row, $asessid)
- {
- global $CC_CONFIG;
- $trtok = $row['trtok'];
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- // don't close metadata transport - audioclip will close it
- if ($row['trtype'] == 'metadata') {
- return TRUE;
- }
- // handle metadata transport on audioclip trtype:
- if ($row['trtype'] == 'audioclip') {
- $mdtrec = TransportRecord::recall($this, $trec->row['mdtrtok']);
- if (PEAR::isError($mdtrec)) {
- return $mdtrec;
- }
- switch ($mdtrec->row['state']) {
- case 'failed':
- case 'closed':
- return PEAR::raiseError("Transport::cronUploadFinished:".
- " metadata transport in wrong state: {$mdtrec->row['state']}".
- " ({$this->trtok})"
- );
- break;
- // don't close transport with nonfinished metadata transport:
- case 'init':
- case 'waiting':
- case 'pending':
- case 'paused':
- return TRUE;
- default: // finished - ok close parent transport
- $mdpdtoken = $mdtrec->row['pdtoken'];
- }
- } else {
- $mdpdtoken = NULL;
- }
- $ret = $this->xmlrpcCall('archive.uploadClose',
- array(
- 'token' => $row['pdtoken'] ,
- 'trtype' => $row['trtype'],
- 'pars' => array(
- 'gunid' => $row['gunid'],
- 'name' => $row['fname'],
- 'mdpdtoken' => $mdpdtoken,
- ),
- ));
- if (PEAR::isError($ret)) {
- if ($row['trtype'] == 'audioclip') {
- $r2 = $mdtrec->close();
- }
- return $ret;
- }
-
-// if ($row['trtype'] == 'searchjob') {
-// @unlink($row['localfile']);
-// $r = $trec->setState('init', array(
-// 'direction' => 'down',
-// 'pdtoken' => $ret['token'],
-// 'expectedsum' => $ret['chsum'],
-// 'expectedsize' => $ret['size'],
-// 'url' => $ret['url'],
-// 'realsize' => 0,
-// ));
-// $this->startCronJobProcess($trec->trtok);
-// } else {
- $r = $trec->close();
-// }
- if (PEAR::isError($r)) {
- return $r;
- }
- switch ($row['trtype']) {
- case 'audioclip':
- // close metadata transport:
- $r = $mdtrec->close();
- if (PEAR::isError($r)) {
- return $r;
- }
- break;
- case 'playlistPkg':
- // remove exported playlist (playlist with content)
- $ep = $row['localfile'];
- @unlink($ep);
- if (preg_match("|/(plExport_[^\.]+)\.lspl$|", $ep, $va)) {
- list(,$tmpn) = $va; $tmpn = $CC_CONFIG['transDir']."/$tmpn";
- if (file_exists($tmpn)) {
- @unlink($tmpn);
- }
- }
-
- break;
- default:
- }
-
- return TRUE;
- }
-
-
- /**
- * Finish the download
- *
- * @param array $row
- * row from getTransport results
- * @param string $asessid
- * session id (from network hub)
- * @return mixed
- * boolean TRUE or error object
- */
- function cronDownloadFinished($row, $asessid)
- {
- $trtok = $row['trtok'];
- $trec = TransportRecord::recall($this, $trtok);
- if (PEAR::isError($trec)) {
- return $trec;
- }
- switch ($row['trtype']) {
- case "audioclip":
- $mdtrtok = $trec->row['mdtrtok'];
- $mdtrec = TransportRecord::recall($this, $mdtrtok);
- if (PEAR::isError($mdtrec)) {
- return $mdtrec;
- }
- $pid = getmypid();
- $r = $mdtrec->setLock(TRUE, $pid);
- if (PEAR::isError($r)) {
- return $r;
- }
- switch ($mdtrec->row['state']) {
- // don't close transport with nonfinished metadata transport:
- case 'init':
- case 'waiting':
- case 'pending':
- case 'paused':
- $r = $mdtrec->setLock(FALSE);
- if (PEAR::isError($r)) {
- return $r;
- }
- return TRUE;
- case 'finished': // metadata finished, close main transport
- $values = array(
- "filename" => $row['fname'],
- "filepath" => $trec->row['localfile'],
- "metadata" => $mdtrec->row['localfile'],
- "gunid" => $row['gunid'],
- "filetype" => "audioclip"
- );
- $storedFile = StoredFile::Insert($values);
- if (PEAR::isError($storedFile)) {
- $mdtrec->setLock(FALSE);
- return $storedFile;
- }
- $res = $storedFile->getId();
- $ret = $this->xmlrpcCall('archive.downloadClose',
- array(
- 'token' => $mdtrec->row['pdtoken'] ,
- 'trtype' => 'metadata' ,
- ));
- if (PEAR::isError($ret)) {
- $mdtrec->setLock(FALSE);
- return $ret;
- }
- $r = $mdtrec->close();
- if (PEAR::isError($r)) {
- $r2 = $mdtrec->setLock(FALSE);
- return $r;
- }
- @unlink($trec->row['localfile']);
- @unlink($mdtrec->row['localfile']);
- break;
- default:
- $r = $mdtrec->setLock(FALSE);
- return PEAR::raiseError("Transport::cronDownloadFinished:".
- " metadata transport in wrong state: {$mdtrec->row['state']}".
- " ({$this->trtok})"
- );
- }
- $r = $mdtrec->setLock(FALSE);
- if (PEAR::isError($r)) {
- return $r;
- }
- break;
- case "metadata":
-// case "searchjob":
- return TRUE; // don't close - getSearchResults should close it
- break;
- }
- $ret = $this->xmlrpcCall('archive.downloadClose',
- array(
- 'token' => $row['pdtoken'] ,
- 'trtype' => $row['trtype'] ,
- ));
- if (PEAR::isError($ret)) {
- return $ret;
- }
- switch ($row['trtype']) {
- case "playlist":
- $values = array(
- "filename" => $row['fname'],
- "metadata" => $trec->row['localfile'],
- "gunid" => $row['gunid'],
- "filetype" => "playlist"
- );
- $storedFile = StoredFile::Insert($values);
- if (PEAR::isError($storedFile)) {
- return $storedFile;
- }
- $res = $storedFile->getId();
- @unlink($row['localfile']);
- break;
- case "playlistPkg":
- $subjid = $trec->row['uid'];
- $fname = $trec->row['localfile'];
- $res = $this->gb->bsImportPlaylist($fname, $subjid);
- if (PEAR::isError($res)) {
- return $res;
- }
- @unlink($fname);
- break;
- case "audioclip":
- case "metadata":
-// case "searchjob":
- case "file":
- break;
- default:
- return PEAR::raiseError("DEBUG: NotImpl ".var_export($row,TRUE));
- }
- if (!is_null($rtrtok = $trec->row['rtrtok'])) {
- $ret = $this->xmlrpcCall('archive.setHubInitiatedTransfer',
- array(
- 'target' => HOSTNAME,
- 'trtok' => $rtrtok,
- 'state' => 'closed',
- ));
- if (PEAR::isError($ret)) {
- return $ret;
- }
- }
- $r = $trec->close();
- if (PEAR::isError($r)) {
- return $r;
- }
- return TRUE;
- }
-
-
- /* ==================================================== auxiliary methods */
- /**
- * Prepare upload for general file
- *
- * @param string $fpath
- * local filepath of uploaded file
- * @param string $trtype
- * transport type
- * @param array $pars
- * default parameters (optional, internal use)
- * @return object - transportRecord instance
- */
- function _uploadGeneralFileToHub($fpath, $trtype, $pars=array())
- {
- $chsum = $this->_chsum($fpath);
- $size = filesize($fpath);
- $trec = TransportRecord::create($this, $trtype, 'up',
- array_merge(array(
- 'localfile'=>$fpath, 'fname'=>basename($fpath),
- 'expectedsum'=>$chsum, 'expectedsize'=>$size
- ), $pars)
- );
- if (PEAR::isError($trec)) {
- return $trec;
- }
- return $trec;
- }
-
-
- /**
- * Create new transport token
- *
- * @return string
- * transport token
- */
- function _createTransportToken()
- {
- $ip = (isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '');
- $initString = microtime().$ip.rand()."org.mdlf.campcaster";
- $hash = md5($initString);
- $res = substr($hash, 0, 16);
- return $res;
- }
-
-
- /**
- * Get all relevant transport records
- *
- * @param string $direction
- * 'up' | 'down'
- * @param string $target
- * target hostname
- * @param string $trtok
- * transport token for specific query
- * @return array
- * array of transportRecords (as hasharrays)
- */
- function getTransports($direction=NULL, $target=NULL, $trtok=NULL)
- {
- global $CC_CONFIG, $CC_DBC;
- switch ($direction) {
- case 'up':
- $dirCond = "direction='up' AND";
- break;
- case 'down':
- $dirCond = "direction='down' AND";
- break;
- default:
- $dirCond = '';
- break;
- }
- if (is_null($target)) {
- $targetCond = "";
- } else {
- $targetCond = "target='$target' AND";
- }
- if (is_null($trtok)) {
- $trtokCond = "";
- } else {
- $trtokCond = "trtok='$trtok' AND";
- }
- $rows = $CC_DBC->getAll("
- SELECT
- id, trtok, state, trtype, direction,
- to_hex(gunid)as gunid, to_hex(pdtoken)as pdtoken,
- fname, localfile, expectedsum, expectedsize, url,
- uid, target
- FROM ".$CC_CONFIG['transTable']."
- WHERE $dirCond $targetCond $trtokCond
- state not in ('closed', 'failed', 'paused')
- ORDER BY start DESC
- ");
- if (PEAR::isError($rows)) {
- return $rows;
- }
- foreach ($rows as $i => $row) {
- $rows[$i]['pdtoken'] = StoredFile::NormalizeGunid($row['pdtoken']);
- $rows[$i]['gunid'] = StoredFile::NormalizeGunid($row['gunid']);
- }
- return $rows;
- }
-
-
- /**
- * Check remote state of uploaded file
- *
- * @param string $pdtoken
- * put/download token (from network hub)
- * @return array
- * hash: chsum, size, url
- */
- function uploadCheck($pdtoken)
- {
- $ret = $this->xmlrpcCall('archive.uploadCheck',
- array('token'=>$pdtoken));
- return $ret;
- }
-
-
- /**
- * Ping to remote Airtime server
- *
- * @return string
- * network hub response or error object
- */
- function ping()
- {
- $res = $this->xmlrpcCall('ping',
- array('par'=>'ping_'.date('H:i:s')));
- return $res;
- }
-
-
- /**
- * XMLRPC call to network hub.
- *
- * @param string $method
- * method name
- * @param array $pars
- * call parameters
- * @return mixed
- * response
- */
- function xmlrpcCall($method, $pars=array())
- {
- global $CC_CONFIG;
- $xrp = XML_RPC_encode($pars);
-
- $pr = new Prefs($this->gb);
- $group = $CC_CONFIG["StationPrefsGr"];
- $key = 'archiveServerLocation';
- $archiveUrl = $pr->loadGroupPref($group, $key, false);
-
- if ($archiveUrl) {
- $archiveUrlInfo = parse_url($archiveUrl);
- if ($archiveUrlInfo['port']) {
- $port = $archiveUrlInfo['port'];
- }
- else {
- $port = 80;
- }
-
- $c = new XML_RPC_Client($archiveUrlInfo['path'], $archiveUrlInfo['host'], $port);
- }
- else {
- $c = new XML_RPC_Client(
- $CC_CONFIG['archiveUrlPath']."/".$CC_CONFIG['archiveXMLRPC'],
- $CC_CONFIG['archiveUrlHost'], $CC_CONFIG['archiveUrlPort']
- );
- }
-
- $f = new XML_RPC_Message($method, array($xrp));
- $r = $c->send($f);
- if (!$r) {
- return PEAR::raiseError("XML-RPC request failed", TRERR_XR_FAIL);
- } elseif ($r->faultCode() > 0) {
- return PEAR::raiseError($r->faultString(), $r->faultCode());
- // return PEAR::raiseError($r->faultString().
- // " (code ".$r->faultCode().")", TRERR_XR_FAIL);
- } else {
- $v = $r->value();
- return XML_RPC_decode($v);
- }
- }
-
-
- /**
- * Checksum of local file
- *
- * @param string $fpath
- * local filepath
- * @return string
- * checksum
- */
- function _chsum($fpath)
- {
- return md5_file($fpath);
- }
-
-
- /**
- * Check exception and eventually mark transport as failed
- *
- * @param mixed $res
- * result object to be checked
- * @param unknown $trec
- * transport record object
- * @return unknown
- */
- function _failFatal($res, $trec)
- {
- if (PEAR::isError($res)) {
- switch ($res->getCode()) {
- // non fatal:
- case TRERR_XR_FAIL:
- break;
- // fatal:
- default:
- $trec->fail('', $res);
- }
- }
- return $res;
- }
-
-
- /**
- * Clean up transport jobs
- *
- * @param string $interval
- * psql time interval - older closed jobs will be deleted
- * @param boolean $forced
- * if true, delete non-closed jobs too
- * @return boolean true or error
- */
- function _cleanUp($interval='1 minute'/*'1 hour'*/, $forced=FALSE)
- {
- global $CC_CONFIG, $CC_DBC;
- $cond = ($forced ? '' : " AND state='closed' AND lock = 'N'");
- $r = $CC_DBC->query("
- DELETE FROM ".$CC_CONFIG['transTable']."
- WHERE ts < now() - interval '$interval'".$cond
- );
- if (PEAR::isError($r)) {
- return $r;
- }
- return TRUE;
- }
-
-
- /**
- * Logging wrapper for PEAR error object
- *
- * @param string $txt
- * log message
- * @param PEAR_Error $eo
- * @param array $row
- * array returned from getRow
- * @return mixed
- * void or error object
- */
- function trLogPear($txt, $eo, $row=NULL)
- {
- $msg = $txt.$eo->getMessage()." ".$eo->getUserInfo().
- " [".$eo->getCode()."]";
- if (!is_null($row)) {
- $trec = TransportRecord::recall($this, $row['trtok']);
- if (!PEAR::isError($trec)) {
- $trec->setState('failed', array('errmsg'=>$msg));
- }
- $msg .= "\n ".serialize($row);
- }
- $this->trLog($msg);
- }
-
-
- /**
- * Logging for debug transports
- *
- * @param string $msg
- * log message
- * @return mixed
- * void or error object
- */
- function trLog($msg)
- {
- global $CC_CONFIG;
- $logfile = $CC_CONFIG['transDir']."/activity.log";
- if (FALSE === ($fp = fopen($logfile, "a"))) {
- return PEAR::raiseError(
- "Transport::trLog: Can't write to log ($logfile)"
- );
- }
- flock($fp,LOCK_SH);
- fputs($fp, "---".date("H:i:s")."---\n $msg\n");
- flock($fp,LOCK_UN);
- fclose($fp);
- }
-
-
- /* ====================================================== install methods */
- /**
- * Delete all transports
- *
- * @return mixed
- * void or error object
- */
- function resetData()
- {
- global $CC_CONFIG, $CC_DBC;
- return $CC_DBC->query("DELETE FROM ".$CC_CONFIG['transTable']);
- }
-
-}
-
-
diff --git a/application/models/TransportRecord.php b/application/models/TransportRecord.php
deleted file mode 100644
index 43b3a529a..000000000
--- a/application/models/TransportRecord.php
+++ /dev/null
@@ -1,419 +0,0 @@
-tr =& $tr;
- $this->gb =& $tr->gb;
- }
-
-
- /**
- * Factory method
- *
- * @param Transport $tr
- * @param string $trtype
- * transport type (see Transport::install)
- * @param string $direction
- * 'up' | 'down'
- * @param array $defaults
- * default parameters (optional, internal use)
- * @return TransportRecord
- */
- function create(&$tr, $trtype, $direction='up', $defaults=array())
- {
- global $CC_DBC, $CC_CONFIG;
- $trec = new TransportRecord($tr);
- $trec->trtok = $trtok = $tr->_createTransportToken();
- $trec->row = array_merge($defaults,
- array('trtype'=>$trtype, 'direction'=>$direction));
- $trec->recalled = TRUE;
- if (!isset($defaults['title'])) {
- $defaults['title'] = $trec->getTitle();
- if (PEAR::isError($defaults['title'])) {
- return $defaults['title'];
- }
- }
- $id = $CC_DBC->nextId($CC_CONFIG['transSequence']);
- $names = "id, trtok, direction, state, trtype, start, ts";
- $values = "$id, '$trtok', '$direction', 'init', '$trtype', now(), now()";
- foreach ($defaults as $k => $v) {
- $sqlVal = $trec->_getSqlVal($k, $v);
- $names .= ", $k";
- $values .= ", $sqlVal";
- }
- $query = "
- INSERT INTO ".$CC_CONFIG['transTable']."
- ($names)
- VALUES
- ($values)
- ";
- $res = $CC_DBC->query($query);
- if (PEAR::isError($res)) {
- return $res;
- }
- return $trec;
- }
-
-
- /**
- * Recall transport record from DB
- *
- * @param Transport $tr
- * @param string $trtok
- * transport token
- * @return TransportRecord
- */
- function recall(&$tr, $trtok)
- {
- global $CC_DBC, $CC_CONFIG;
- $trec = new TransportRecord($tr);
- $trec->trtok = $trtok;
- $row = $CC_DBC->getRow("
- SELECT
- id, trtok, state, trtype, direction,
- to_hex(gunid)as gunid, to_hex(pdtoken)as pdtoken,
- fname, localfile, url, rtrtok, mdtrtok, uid,
- expectedsize, realsize, expectedsum, realsum,
- errmsg, title, jobpid
- FROM ".$CC_CONFIG['transTable']."
- WHERE trtok='$trtok'
- ");
- if (PEAR::isError($row)) {
- return $row;
- }
- if (is_null($row)) {
- return PEAR::raiseError("TransportRecord::recall:".
- " invalid transport token ($trtok)", TRERR_TOK
- );
- }
- $row['pdtoken'] = StoredFile::NormalizeGunid($row['pdtoken']);
- $row['gunid'] = StoredFile::NormalizeGunid($row['gunid']);
- $trec->row = $row;
- $trec->recalled = TRUE;
- return $trec;
- }
-
-
- /**
- * Set state of transport record
- *
- * @param string $newState
- * @param array $data
- * other data fields to set
- * @param string $oldState
- * check old state and do nothing if differ
- * @param boolean $lock
- * check lock and do nothing if differ
- * @return boolean success
- */
- function setState($newState, $data=array(), $oldState=NULL, $lock=NULL)
- {
- global $CC_CONFIG, $CC_DBC;
- $set = " state='$newState', ts=now()";
- if (!is_null($lock)) {
- $slock = ($lock ? 'Y' : 'N');
- $nlock = (!$lock);
- $snlock = ($nlock ? 'Y' : 'N');
- $set .= ", lock='$snlock'";
- }
- foreach ($data as $k => $v) {
- $set .= ", $k=".$this->_getSqlVal($k, $v);
- }
- $r = $CC_DBC->query("
- UPDATE ".$CC_CONFIG['transTable']."
- SET $set
- WHERE trtok='{$this->trtok}'".
- (is_null($oldState) ? '' : " AND state='$oldState'").
- (is_null($lock) ? '' : " AND lock = '$slock'")
- );
- if (PEAR::isError($r)) {
- return $r;
- }
- // return TRUE;
- $affRows = $CC_DBC->affectedRows();
- if (PEAR::isError($affRows)) {
- return $affRows;
- }
- return ($affRows == 1);
- }
-
-
- /**
- * Return state of transport record
- *
- * @return string
- * state
- */
- function getState()
- {
- if (!$this->recalled) {
- return PEAR::raiseError("TransportRecord::getState:".
- " not recalled ({$this->trtok})", TRERR_TOK
- );
- }
- return $this->row['state'];
- }
-
-
- /**
- * Set lock on transport record and save/clear process id
- *
- * @param boolean $lock
- * lock if true, release lock if false
- * @param int $pid
- * process id
- * @return mixed
- * true or error
- */
- function setLock($lock, $pid=NULL)
- {
- global $CC_CONFIG, $CC_DBC;
- $pidsql = (is_null($pid) ? "NULL" : "$pid" );
- if ($this->dropped) {
- return TRUE;
- }
- $slock = ($lock ? 'Y' : 'N');
- $nlock = (!$lock);
- $snlock = ($nlock ? 'Y' : 'N');
- $r = $CC_DBC->query("
- UPDATE ".$CC_CONFIG['transTable']."
- SET lock='$slock', jobpid=$pidsql, ts=now()
- WHERE trtok='{$this->trtok}' AND lock = '$snlock'"
- );
- if (PEAR::isError($r)) {
- return $r;
- }
- $affRows = $CC_DBC->affectedRows();
- if (PEAR::isError($affRows)) {
- return $affRows;
- }
- if ($affRows === 0) {
- $ltxt = ($lock ? 'lock' : 'unlock' );
- return PEAR::raiseError(
- "TransportRecord::setLock: can't $ltxt ({$this->trtok})"
- );
- }
- return TRUE;
- }
-
-
- /**
- * Return type of transport
- *
- * @return string
- * Transport type
- */
- function getTransportType()
- {
- if (!$this->recalled) {
- return PEAR::raiseError("TransportRecord::getTransportType:".
- " not recalled ({$this->trtok})", TRERR_TOK
- );
- }
- return $this->row['trtype'];
- }
-
-
- /**
- * Kill transport job (on pause or cancel)
- *
- * @return string
- * Transport type
- */
- function killJob()
- {
- if (!$this->recalled) {
- return PEAR::raiseError("TransportRecord::getTransportType:".
- " not recalled ({$this->trtok})", TRERR_TOK
- );
- }
- $jobpid = $this->row['jobpid'];
- $res = system("pkill -P $jobpid", $status);
- }
-
-
- /**
- * Set state to failed and set error message in transport record
- *
- * @param string $txt
- * base part of error message
- * @param PEAR_Error $eo
- * (opt.) error msg can be construct from it
- * @return mixed
- * boolean true or error
- */
- function fail($txt='', $eo=NULL)
- {
- if (!$this->recalled) {
- return PEAR::raiseError("TransportRecord::fail:".
- " not recalled ({$this->trtok})", TRERR_TOK
- );
- }
- $msg = $txt;
- if (!is_null($eo)) {
- $msg .= $eo->getMessage()." ".$eo->getUserInfo().
- " [".$eo->getCode()."]";
- }
- $r = $this->setState('failed', array('errmsg'=>$msg));
- if (PEAR::isError($r)) {
- return $r;
- }
- return TRUE;
- }
-
-
- /**
- * Close transport record
- *
- * @return mixed
- * boolean true or error
- */
- function close()
- {
- global $CC_CONFIG, $CC_DBC;
- if (!$this->recalled) {
- return PEAR::raiseError("TransportRecord::close:".
- " not recalled ({$this->trtok})", TRERR_TOK
- );
- }
- if (TR_LEAVE_CLOSED) {
- $r = $this->setState('closed');
- if (PEAR::isError($r)) {
- return $r;
- }
- } else {
- $r = $CC_DBC->query("
- DELETE FROM ".$CC_CONFIG['transTable']."
- WHERE trtok='{$this->trtok}'
- ");
- if (PEAR::isError($r)) {
- return $r;
- }
- $this->recalled = FALSE;
- $this->dropped = TRUE;
- }
- return TRUE;
- }
-
-
- /**
- * Add field specific envelopes to values (e.g. ' around strings)
- *
- * @param string $fldName
- * field name
- * @param mixed $fldVal
- * field value
- * @return string
- */
- function _getSqlVal($fldName, $fldVal)
- {
- switch ($fldName) {
- case 'realsize':
- case 'expectedsize':
- case 'uid':
- return ("$fldVal"!='' ? "$fldVal" : "NULL");
- break;
- case 'gunid':
- case 'pdtoken':
- return "x'$fldVal'::bigint";
- break;
- default:
- $fldVal = pg_escape_string($fldVal);
- return "'$fldVal'";
- break;
- }
- }
-
-
- /**
- * Get title from transported object's metadata (if exists)
- *
- * @return string
- * the title or descriptive string
- */
- function getTitle()
- {
- $defStr = 'unknown';
- $trtype = $this->getTransportType(); //contains recall check
- if (PEAR::isError($trtype)) {
- return $trtype;
- }
- switch ($trtype) {
- case "audioclip":
- case "playlist":
- case "playlistPkg":
- case "metadata":
- $title = $this->gb->bsGetTitle(NULL, $this->row['gunid']);
- if (is_null($title)) {
- $title = $defStr;
- }
- if (PEAR::isError($title)) {
- if ($title->getCode() == GBERR_FOBJNEX) {
- $title = $defStr;
- } else {
- return $title;
- }
- }
- break;
- case "searchjob":
- $title = 'searchjob';
- break;
- case "file":
- $title = ( isset($this->row['localfile']) ?
- basename($this->row['localfile']) : 'regular file');
- break;
- default:
- $title = $defStr;
- }
- return $title;
- }
-
-} // class TransportRecord
-
diff --git a/application/models/cron/transportCron.php b/application/models/cron/transportCron.php
deleted file mode 100755
index caf6a24ac..000000000
--- a/application/models/cron/transportCron.php
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/php
-setErrorHandling(PEAR_ERROR_RETURN);
-$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC);
-
-$gb = new LocStor();
-$tr = new Transport($gb);
-
-$r = $tr->cronMain();
-if (!$r) {
- exit(1);
-}
-
-exit(0);
diff --git a/application/models/cron/transportCronJob.php b/application/models/cron/transportCronJob.php
deleted file mode 100755
index 0a0f66f3d..000000000
--- a/application/models/cron/transportCronJob.php
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/php
-setErrorHandling(PEAR_ERROR_RETURN);
-$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC);
-
-$gb = new LocStor();
-$tr = new Transport($gb);
-
-$pid = getmypid();
-list(, $trtok) = $_SERVER['argv'];
-if (TR_LOG_LEVEL > 1) {
- $tr->trLog("transportCronJob($pid) start ($trtok)");
-}
-
-// 4-pass on job:
-$cnt = 4;
-for ($i = 0; $i < $cnt; $i++, sleep(1)) {
- // run the action:
- $r = $tr->cronCallMethod($trtok);
- if (PEAR::isError($r)) {
- $tr->trLogPear("transportCronJob($pid): ($trtok): ", $r);
- } else {
-# $tr->trLog("X transportCronJob: ".var_export($r, TRUE));
- if ($r !== TRUE) {
- $tr->trLog("transportCronJob($pid): ($trtok): nonTRUE returned");
- }
- }
- #if(!$r) exit(1);
- #sleep(2);
-}
-
-if (TR_LOG_LEVEL>1) {
- $tr->trLog("transportCronJob($pid) end ($trtok)");
-}
-exit(0);
diff --git a/application/models/tests/PlaylistTests.php b/application/models/tests/PlaylistTests.php
deleted file mode 100644
index 08b63974f..000000000
--- a/application/models/tests/PlaylistTests.php
+++ /dev/null
@@ -1,123 +0,0 @@
-getMessage()." ".$CC_DBC->getUserInfo()."\n";
- exit(1);
-}
-$CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC);
-
-class PlaylistTests extends PHPUnit_TestCase {
-
- private $greenbox;
- private $storedFile;
- private $storedFile2;
-
- function __construct($name) {
- parent::__construct($name);
- }
-
- function setup() {
- global $CC_CONFIG, $CC_DBC;
- $this->greenbox = new GreenBox();
-
- // Add a file
- $values = array("filepath" => dirname(__FILE__)."/test10001.mp3");
- $this->storedFile = StoredFile::Insert($values, false);
-
- // Add a file
- $values = array("filepath" => dirname(__FILE__)."/test10002.mp3");
- $this->storedFile2 = StoredFile::Insert($values, false);
-
- }
-
- function testGBCreatePlaylist() {
-
- $pl = new Playlist();
- $pl_id = $pl->create("Playlist UnitTest: create ".date("g:i a"));
-
- if (!is_int($pl_id)) {
- $this->fail("problems creating playlist.");
- return;
- }
- }
-
- function testGBLock() {
- $pl = new Playlist();
- $pl_id = $pl->create("Playlist Metadata: lock ".date("g:i a"));
-
- $sessid = Alib::Login('root', 'q');
-
- $res = $this->greenbox->lockPlaylistForEdit($pl_id, $sessid);
-
- if($res !== TRUE) {
- $this->fail("problems locking playlist for editing.");
- return;
- }
- }
-
- function testGBUnLock() {
- $pl = new Playlist();
- $pl_id = $pl->create("Playlist UnitTest: unlock ".date("g:i a"));
-
- $sessid = Alib::Login('root', 'q');
-
- $this->greenbox->lockPlaylistForEdit($pl_id, $sessid);
- $res = $this->greenbox->releaseLockedPlaylist($pl_id, $sessid);
-
- if($res !== TRUE) {
- $this->fail("problems unlocking playlist.");
- return;
- }
- }
-
- function testGBSetPLMetaData() {
- $pl = new Playlist();
- $pl_id = $pl->create("Playlist UnitTest: Set Metadata ".date("g:i a"));
-
- $res = $this->greenbox->setPLMetadataValue($pl_id, "dc:title", "Playlist Unit Test: Updated Title ".date("g:i a"));
-
- if($res !== TRUE) {
- $this->fail("problems setting playlist metadata.");
- return;
- }
- }
-
- function testGBGetPLMetaData() {
- $pl = new Playlist();
- $name = "Playlist UnitTest: GetMetadata ".date("g:i a");
- $pl_id = $pl->create($name);
-
- $res = $this->greenbox->getPLMetadataValue($pl_id, "dc:title");
-
- if($res !== $name) {
- $this->fail("problems getting playlist metadata.");
- return;
- }
- }
-
-}
-
-
diff --git a/application/models/tests/analyze.php b/application/models/tests/analyze.php
deleted file mode 100755
index 7e2a9fbac..000000000
--- a/application/models/tests/analyze.php
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/php -q
-analyzeFile();
-
-echo "r=$r (".gettype($r).")\n";
-if (PEAR::isError($r)) {
- echo "ERR: ".$r->getMessage()."\n".$r->getUserInfo()."\n";
-}
-if (is_array($r)) {
- print_r($r);
-}
-echo"\n";
diff --git a/utils/airtime-import.php b/utils/airtime-import.php
index 714da2510..9e0696728 100644
--- a/utils/airtime-import.php
+++ b/utils/airtime-import.php
@@ -13,7 +13,7 @@ error_reporting(E_ALL);
set_error_handler("camp_import_error_handler", E_ALL & !E_NOTICE);
require_once(dirname(__FILE__)."/../application/configs/conf.php");
-require_once(dirname(__FILE__)."/../application/models/GreenBox.php");
+require_once(dirname(__FILE__)."/../application/models/StoredFile.php");
require_once('DB.php');
require_once('Console/Getopt.php');
@@ -104,8 +104,6 @@ function camp_import_audio_file($p_filepath, $p_importMode = null, $p_testOnly =
return;
}
- $greenbox = new GreenBox();
-
$fileCount = 0;
$duplicates = 0;
diff --git a/utils/upgrade-sql.php b/utils/upgrade-sql.php
new file mode 100644
index 000000000..5d792357a
--- /dev/null
+++ b/utils/upgrade-sql.php
@@ -0,0 +1,3 @@
+