Copied over the /backend/tests directory and modified the paths to their new locations. Moved the liquidsoap directory to be under the pypo directory.
419 lines
No EOL
11 KiB
PHP
419 lines
No EOL
11 KiB
PHP
<?php
|
|
|
|
define('TR_LEAVE_CLOSED', TRUE);
|
|
|
|
/**
|
|
* Auxiliary class for transport records
|
|
*
|
|
* @package Campcaster
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class TransportRecord
|
|
{
|
|
/**
|
|
* @var DB
|
|
*/
|
|
//public $dbc;
|
|
|
|
/**
|
|
* @var GreenBox
|
|
*/
|
|
private $gb;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
//private $config;
|
|
|
|
/**
|
|
* @var Transport
|
|
*/
|
|
private $tr;
|
|
|
|
/**
|
|
* @var boolean
|
|
*/
|
|
private $recalled = FALSE;
|
|
|
|
/**
|
|
* @var boolean
|
|
*/
|
|
private $dropped = FALSE;
|
|
|
|
|
|
/**
|
|
* @param Transport $tr
|
|
* @return TransportRecord
|
|
*/
|
|
public function __construct(&$tr)
|
|
{
|
|
$this->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
|
|
?>
|