Changes to how the playlist works, from files to database.

This commit is contained in:
naomiaro 2010-09-21 15:52:35 -04:00
parent 1d20c0bc27
commit 5a84cee98d
11 changed files with 576 additions and 621 deletions

View File

@ -322,7 +322,7 @@ if ($uiBrowser->userid) {
break; break;
case "editItem": case "editItem":
$uiBrowser->SCRATCHPAD->addItem($_REQUEST['id']); //$uiBrowser->SCRATCHPAD->addItem($_REQUEST['id']);
$Smarty->assign('editItem', array('type' => $uiBrowser->type, 'id' => $_REQUEST['id'], 'folderId' => $uiBrowser->fid, 'curr_langid' => $_REQUEST['curr_langid'])); $Smarty->assign('editItem', array('type' => $uiBrowser->type, 'id' => $_REQUEST['id'], 'folderId' => $uiBrowser->fid, 'curr_langid' => $_REQUEST['curr_langid']));
break; break;

View File

@ -301,12 +301,12 @@ switch ($_REQUEST['act']) {
break; break;
case "PL.create": case "PL.create":
$ids = (isset($_REQUEST['id']) ? $_REQUEST['id'] : null); //$ids = (isset($_REQUEST['id']) ? $_REQUEST['id'] : null);
if (($ui_tmpid = $uiHandler->PLAYLIST->create($ids)) !== FALSE) { if (($ui_tmpid = $uiHandler->PLAYLIST->create()) !== FALSE) {
if ($ids) { if ($ids) {
$uiHandler->SCRATCHPAD->addItem($ids); //$uiHandler->SCRATCHPAD->addItem($ids);
} }
$uiHandler->SCRATCHPAD->addItem($ui_tmpid); //$uiHandler->SCRATCHPAD->addItem($ui_tmpid);
} }
$uiHandler->PLAYLIST->setRedirect('_2PL.editMetaData'); $uiHandler->PLAYLIST->setRedirect('_2PL.editMetaData');
break; break;
@ -366,7 +366,7 @@ switch ($_REQUEST['act']) {
break; break;
case "PL.moveItem": case "PL.moveItem":
$uiHandler->PLAYLIST->moveItem($_REQUEST['id'], $_REQUEST['pos']); $uiHandler->PLAYLIST->moveItem($_REQUEST['oldPos'], $_REQUEST['newPos']);
$uiHandler->PLAYLIST->setReload(); $uiHandler->PLAYLIST->setReload();
break; break;
@ -382,12 +382,12 @@ switch ($_REQUEST['act']) {
case "PL.editMetaData": case "PL.editMetaData":
$uiHandler->PLAYLIST->editMetaData($_REQUEST); $uiHandler->PLAYLIST->editMetaData($_REQUEST);
$uiHandler->SCRATCHPAD->addItem($_REQUEST['id']); //$uiHandler->SCRATCHPAD->addItem($_REQUEST['id']);
break; break;
case "PL.deleteActive": case "PL.deleteActive":
if (($ui_tmpid = $uiHandler->PLAYLIST->deleteActive()) !== FALSE) { if (($ui_tmpid = $uiHandler->PLAYLIST->deleteActive()) !== FALSE) {
$uiHandler->SCRATCHPAD->removeItems($ui_tmpid); //$uiHandler->SCRATCHPAD->removeItems($ui_tmpid);
} }
$uiHandler->PLAYLIST->setReload(); $uiHandler->PLAYLIST->setReload();
break; break;

View File

@ -19,50 +19,56 @@
<td style="width: 30px"><input type="checkbox" name="all" onClick="collector_switchAll('PL')"></td> <td style="width: 30px"><input type="checkbox" name="all" onClick="collector_switchAll('PL')"></td>
<td style="width: 200px">##Title##</td> <td style="width: 200px">##Title##</td>
<td style="white-space: nowrap">##Clip length##</td> <td style="white-space: nowrap">##Clip length##</td>
<td> ##Original##</td> <td>##Cue In##</td>
<td>##Cue Out##</td>
<td style="width: 200px">##Artist##</td> <td style="width: 200px">##Artist##</td>
<td style="width: 30px;">##Type##</td> <td style="width: 30px;">##Type##</td>
<td style="width: 30px; border: 0">##Move##</td> <td style="width: 30px; border: 0">##Move##</td>
</tr> </tr>
<!-- end repeat after 14 columns --> <!-- end repeat after 14 columns -->
<!-- start item --> <!-- start item -->
{foreach from=$PL->getFlat($PL->activeId) key='pos' item='i'} {foreach from=$PL->getActiveArr($PL->activeId) key='pos' item='i'}
{*
<!-- fade information --> <!-- fade information -->
<tr onClick="return contextmenu('{$i.attrs.id}', {if $i.firstInList == 1}'PL.changeFadeIn'{else}'PL.changeTransition'{/if})" style="background-color: #bbb"> <tr onClick="return contextmenu('{$i.attrs.id}', {if $i.firstInList == 1}'PL.changeFadeIn'{else}'PL.changeTransition'{/if})" style="background-color: #bbb">
<td></td> <td></td>
<td colspan="5" style="border: 0; cursor: pointer">##Fade## {$i.fadein_ms|string_format:"%d"} ms</td> <td colspan="7" style="border: 0; cursor: pointer">##Fade In## {$i.fadein|string_format:"%d"} ms</td>
</tr> </tr>
<!-- /fade information --> <!-- /fade information -->
*}
<tr class="{cycle values='blue1, blue2'}"> <tr class="{cycle values='blue1, blue2'}">
<td><input type="checkbox" class="checkbox" name="{$i.attrs.id}"/></td> <td><input type="checkbox" class="checkbox" name="{$pos}"/></td>
<td {include file="playlist/actionhandler.tpl"}>{$i.title}</td> <td {include file="playlist/actionhandler.tpl"}>{$i.track_title}</td>
<td {include file="playlist/actionhandler.tpl"} style="text-align: right"> <td {include file="playlist/actionhandler.tpl"} style="text-align: right">
{assign var="_playlength" value=$i.attrs.clipLength}{niceTime in=$_playlength} {assign var="_playlength" value=$i.cliplength}{niceTime in=$_playlength}
</td> </td>
<td {include file="playlist/actionhandler.tpl"} style="text-align: right"> <td {include file="playlist/actionhandler.tpl"} style="text-align: right">
{assign var="_duration" value=$i.playlength}{niceTime in=$_duration} {assign var="_duration" value=$i.cuein}{niceTime in=$_duration}
</td> </td>
<td {include file="playlist/actionhandler.tpl"}>{$i.creator}</td> <td {include file="playlist/actionhandler.tpl"} style="text-align: right">
{assign var="_duration" value=$i.cueout}{niceTime in=$_duration}
</td>
<td {include file="playlist/actionhandler.tpl"}>{$i.artist_name}</td>
<td {include file="playlist/actionhandler.tpl"}> <td {include file="playlist/actionhandler.tpl"}>
<img src="img/{$i.type}.png" border="0" alt="{$i.type|capitalize}" {* include file="sub/alttext.tpl" *} /> <img src="img/{$i.type}.png" border="0" alt="{$i.ftype|capitalize}" {* include file="sub/alttext.tpl" *} />
</td> </td>
<td style="border: 0"> <td style="border: 0">
<a href="#" onClick="hpopup('{$UI_HANDLER}?act=PL.moveItem&id={$i.attrs.id}&pos={$pos-1}')"><img src="img/bt_top_xsm.png" alt="##move up##" vspace=1 hspace=1/></a> <a href="#" onClick="hpopup('{$UI_HANDLER}?act=PL.moveItem&id=&oldPos={$pos}&newPos={$pos-1}')"><img src="img/bt_top_xsm.png" alt="##move up##" vspace=1 hspace=1/></a>
<a href="#" onClick="hpopup('{$UI_HANDLER}?act=PL.moveItem&id={$i.attrs.id}&pos={$pos+1}')"><img src="img/bt_bottom_xsm.png" alt="##move down##" vspace=1 hspace=1/></a> <a href="#" onClick="hpopup('{$UI_HANDLER}?act=PL.moveItem&oldPos={$pos}&newPos={$pos+1}')"><img src="img/bt_bottom_xsm.png" alt="##move down##" vspace=1 hspace=1/></a>
</td> </td>
</tr> </tr>
{/foreach}
{if isset($pos)} <!-- fade information -->
{*
<!-- fade information -->
<tr onClick="return contextmenu('{$i.attrs.id}', 'PL.changeFadeOut')" style="background-color: #bbb"> <tr onClick="return contextmenu('{$i.attrs.id}', 'PL.changeFadeOut')" style="background-color: #bbb">
<td></td> <td></td>
<td colspan="5" style="border: 0; cursor: pointer">##Fade## {$i.fadeout_ms|string_format:"%d"} ms</td> <td colspan="7" style="border: 0; cursor: pointer">##Fade Out## {$i.fadeout|string_format:"%d"} ms</td>
</tr> </tr>
<!-- /fade information --> <!-- /fade information -->
*} {/foreach}
{if isset($pos)}
{else} {else}
<tr class="{cycle values='blue1, blue2'}"> <tr class="{cycle values='blue1, blue2'}">
<td style="border: 0" colspan="7" align="center">##Empty playlist##</td> <td style="border: 0" colspan="7" align="center">##Empty playlist##</td>
@ -78,8 +84,6 @@
<input type="button" class="button_large" onClick="collector_clearAll('PL', 'PL.removeItem')" value="##Clear Playlist##" /> <input type="button" class="button_large" onClick="collector_clearAll('PL', 'PL.removeItem')" value="##Clear Playlist##" />
</div> </div>
<div class="container_button"> <div class="container_button">
<input type="button" class="button_large" value="##Save Playlist##" onClick="hpopup('{$UI_HANDLER}?act=PL.save')">
<input type="button" class="button_large" value="##Revert to Saved##" onClick="popup('{$UI_BROWSER}?popup[]=PL.confirmRevert', 'PL.revertChanges', 400, 50)">
<input type="button" class="button_large" value="##Delete Playlist##" onClick="popup('{$UI_BROWSER}?popup[]=PL.confirmDelete', 'PL.deleteActive', 400, 50)"> <input type="button" class="button_large" value="##Delete Playlist##" onClick="popup('{$UI_BROWSER}?popup[]=PL.confirmDelete', 'PL.deleteActive', 400, 50)">
</div> </div>
<div class="container_button"> <div class="container_button">

View File

@ -92,140 +92,120 @@ class uiHandler extends uiBase {
// --- files --- // --- files ---
function processFile($audio_file, $caller){ function processFile($audio_file, $caller){
global $CC_CONFIG; global $CC_CONFIG;
if ($this->testForAudioType($audio_file) === FALSE) { if ($this->testForAudioType($audio_file) === FALSE) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "uses an unsupported file type."}}'); die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "uses an unsupported file type."}}');
}
$md5 = md5_file($audio_file);
$duplicate = StoredFile::RecallByMd5($md5);
if ($duplicate) {
$_SESSION['plupload'] = "is duplicate";
if (PEAR::isError($duplicate)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}');
}
else {
$duplicateName = $this->gb->getMetadataValue($duplicate->getId(), UI_MDATA_KEY_TITLE, $this->sessid);
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}');
}
}
$metadata = camp_get_audio_metadata($audio_file);
if (PEAR::isError($metadata)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $metadata->getMessage() + '}}');
}
// #2196 no id tag -> use the original filename
if (basename($audio_file) == $metadata['dc:title']) {
$metadata['dc:title'] = basename($audio_file);
$metadata['ls:filename'] = basename($audio_file);
}
// bsSetMetadataBatch doesnt like these values
unset($metadata['audio']);
unset($metadata['playtime_seconds']);
$values = array(
"filename" => basename($audio_file),
"filepath" => $audio_file,
"filetype" => "audioclip",
"mime" => $metadata["dc:format"],
"md5" => $md5
);
$storedFile = $this->gb->putFile($values, $this->sessid);
if (PEAR::isError($storedFile)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $storedFile->getMessage() + '}}');
}
$result = $this->gb->bsSetMetadataBatch($storedFile->getId(), $metadata);
return $storedFile->getId();
} }
function pluploadFile($data) $md5 = md5_file($audio_file);
{ $duplicate = StoredFile::RecallByMd5($md5);
header('Content-type: text/plain; charset=UTF-8'); if ($duplicate) {
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); if (PEAR::isError($duplicate)) {
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' . $duplicate->getMessage() .'}}');
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
// Settings
$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
$cleanupTargetDir = false; // Remove old files
$maxFileAge = 60 * 60; // Temp file age in seconds
// 5 minutes execution time
@set_time_limit(5 * 60);
// Get parameters
$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
// Clean the fileName for security reasons
//$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
// Create target dir
if (!file_exists($targetDir)) {
@mkdir($targetDir);
}
// Remove old temp files
if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
while (($file = readdir($dir)) !== false) {
$filePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// Remove temp files if they are older than the max age
if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
@unlink($filePath);
}
closedir($dir);
} }
else { else {
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}'); $duplicateName = $this->gb->getMetadataValue($duplicate->getId(), UI_MDATA_KEY_TITLE, $this->sessid);
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "An identical audioclip named ' . $duplicateName . ' already exists in the storage server."}}');
}
}
$metadata = camp_get_audio_metadata($audio_file);
if (PEAR::isError($metadata)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $metadata->getMessage() + '}}');
}
// #2196 no id tag -> use the original filename
if (basename($audio_file) == $metadata['dc:title']) {
$metadata['dc:title'] = basename($audio_file);
$metadata['ls:filename'] = basename($audio_file);
}
// bsSetMetadataBatch doesnt like these values
unset($metadata['audio']);
unset($metadata['playtime_seconds']);
$values = array(
"filename" => basename($audio_file),
"filepath" => $audio_file,
"filetype" => "audioclip",
"mime" => $metadata["dc:format"],
"md5" => $md5
);
$storedFile = $this->gb->putFile($values, $this->sessid);
if (PEAR::isError($storedFile)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": ' + $storedFile->getMessage() + '}}');
}
$result = $this->gb->bsSetMetadataBatch($storedFile->getId(), $metadata);
return $storedFile->getId();
}
function pluploadFile($data)
{
header('Content-type: text/plain; charset=UTF-8');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
// Settings
$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
$cleanupTargetDir = false; // Remove old files
$maxFileAge = 60 * 60; // Temp file age in seconds
// 5 minutes execution time
@set_time_limit(5 * 60);
// Get parameters
$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
// Clean the fileName for security reasons
//$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
// Create target dir
if (!file_exists($targetDir)) {
@mkdir($targetDir);
}
// Remove old temp files
if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
while (($file = readdir($dir)) !== false) {
$filePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// Remove temp files if they are older than the max age
if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
@unlink($filePath);
} }
// Look for the content type header closedir($dir);
if (isset($_SERVER["HTTP_CONTENT_TYPE"])) }
$contentType = $_SERVER["HTTP_CONTENT_TYPE"]; else {
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
}
if (isset($_SERVER["CONTENT_TYPE"])) // Look for the content type header
$contentType = $_SERVER["CONTENT_TYPE"]; if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
if (strpos($contentType, "multipart") !== false) { if (isset($_SERVER["CONTENT_TYPE"]))
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) { $contentType = $_SERVER["CONTENT_TYPE"];
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen($_FILES['file']['tmp_name'], "rb");
if ($in) { if (strpos($contentType, "multipart") !== false) {
while ($buff = fread($in, 4096)) if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
fwrite($out, $buff);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($out);
unlink($_FILES['file']['tmp_name']);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
} else {
// Open temp file // Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab"); $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out) { if ($out) {
// Read binary input stream and append it to temp file // Read binary input stream and append it to temp file
$in = fopen("php://input", "rb"); $in = fopen($_FILES['file']['tmp_name'], "rb");
if ($in) { if ($in) {
while ($buff = fread($in, 4096)) while ($buff = fread($in, 4096))
@ -234,16 +214,35 @@ class uiHandler extends uiBase {
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($out); fclose($out);
return $this->processFile($targetDir . DIRECTORY_SEPARATOR . $fileName); unlink($_FILES['file']['tmp_name']);
} else } else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
} } else
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
} else {
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen("php://input", "rb");
// Return JSON-RPC response if ($in) {
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); while ($buff = fread($in, 4096))
fwrite($out, $buff);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($out);
return $this->processFile($targetDir . DIRECTORY_SEPARATOR . $fileName);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
} }
// Return JSON-RPC response
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
}
/** /**
* Provides file upload and store it to the storage * Provides file upload and store it to the storage
* *

View File

@ -11,23 +11,19 @@ class uiPlaylist
public $activeId; public $activeId;
public $title; public $title;
public $duration; public $duration;
public $changed;
public $token;
private $Base; private $Base;
private $reloadUrl; private $reloadUrl;
private $redirectUrl; private $redirectUrl;
private $returnUrl; private $returnUrl;
private $flat; private $flat;
public function __construct(&$uiBase) public function __construct($uiBase)
{ {
$this->Base =& $uiBase; $this->Base = $uiBase;
$this->activeId =& $_SESSION[UI_PLAYLIST_SESSNAME]['activeId']; $this->activeId =& $_SESSION[UI_PLAYLIST_SESSNAME]['activeId'];
$this->changed =& $_SESSION[UI_PLAYLIST_SESSNAME]['changed']; $this->title = $this->Base->gb->getPLMetadataValue($this->activeId, UI_MDATA_KEY_TITLE);
$this->title = $this->Base->getMetadataValue($this->activeId, UI_MDATA_KEY_TITLE); $this->duration = $this->Base->gb->getPLMetadataValue($this->activeId, UI_MDATA_KEY_DURATION);
$this->duration = $this->Base->getMetadataValue($this->activeId, UI_MDATA_KEY_DURATION);
$this->token =& $_SESSION[UI_PLAYLIST_SESSNAME]['token'];
$this->reloadUrl = UI_BROWSER.'?popup[]=_reload_parent&popup[]=_close'; $this->reloadUrl = UI_BROWSER.'?popup[]=_reload_parent&popup[]=_close';
$this->redirectUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close'; $this->redirectUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close';
$this->returnUrl = UI_BROWSER.'?act=PL.simpleManagement'; $this->returnUrl = UI_BROWSER.'?act=PL.simpleManagement';
@ -58,12 +54,13 @@ class uiPlaylist
private function getPLArray($id) private function getPLArray($id)
{ {
return $this->Base->gb->getPlaylistArray($id, $this->Base->sessid); $res = $this->Base->gb->getPlaylistArray($id);
return $res;
} // fn getPLArray } // fn getPLArray
public function getActiveArr() public function getActiveArr()
{ {
if (!$this->activeId) { if (!$this->activeId) {
return FALSE; return FALSE;
} }
@ -86,7 +83,7 @@ class uiPlaylist
// look PL // look PL
// store access token to ls_pref abd session // store access token to ls_pref abd session
// load PL into session // load PL into session
if ($this->token) { if ($this->activeId) {
if (UI_WARNING) { if (UI_WARNING) {
$this->Base->_retMsg('You already have an open playlist. Close it first.'); $this->Base->_retMsg('You already have an open playlist. Close it first.');
} }
@ -99,17 +96,19 @@ class uiPlaylist
} }
return FALSE; return FALSE;
} }
$token = $this->Base->gb->lockPlaylistForEdit($plid, $this->Base->sessid); $res = $this->Base->gb->lockPlaylistForEdit($plid, $this->Base->sessid);
if (PEAR::isError($token)) { if (PEAR::isError($res)) {
if (UI_VERBOSE === TRUE) { if (UI_VERBOSE === TRUE) {
print_r($token); print_r($res);
} }
$this->Base->_retMsg('Unable to open playlist "$1".', $this->Base->getMetadataValue($plid, UI_MDATA_KEY_TITLE)); $this->Base->_retMsg('Unable to open playlist "$1".', $this->Base->getMetadataValue($plid, UI_MDATA_KEY_TITLE));
return FALSE; return FALSE;
} }
$this->token = $token;
$this->Base->gb->savePref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY, $plid.':'.$this->token); $this->Base->gb->savePref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY, $plid);
$this->activeId = $plid; $this->activeId = $plid;
$_SESSION['pl'] = "Activating playlist with id: " . $this->activeId;
if ($msg && UI_VERBOSE) { if ($msg && UI_VERBOSE) {
$this->Base->_retMsg('Playlist "$1" opened.', $this->Base->getMetadataValue($plid, UI_MDATA_KEY_TITLE)); $this->Base->_retMsg('Playlist "$1" opened.', $this->Base->getMetadataValue($plid, UI_MDATA_KEY_TITLE));
} }
@ -119,21 +118,19 @@ class uiPlaylist
public function release($msg=TRUE) public function release($msg=TRUE)
{ {
// get token from ls_pref
// release PL // release PL
// delete PL from session // delete PL from session
// remove token from ls_pref if (!$this->activeId) {
if (!$this->token) {
if (UI_WARNING) { if (UI_WARNING) {
$this->Base->_retMsg('There is no playlist available to unlock.'); $this->Base->_retMsg('There is no playlist available to unlock.');
} }
return FALSE; return FALSE;
} }
$plgunid = $this->Base->gb->releaseLockedPlaylist($this->token, $this->Base->sessid); $res = $this->Base->gb->releaseLockedPlaylist($this->activeId, $this->Base->sessid);
if (PEAR::isError($plgunid)) { if (PEAR::isError($res)) {
if (UI_VERBOSE === TRUE) { if (UI_VERBOSE === TRUE) {
print_r($plgunid); print_r($res);
} }
if (UI_WARNING) { if (UI_WARNING) {
$this->Base->_retMsg('Unable to release playlist.'); $this->Base->_retMsg('Unable to release playlist.');
@ -144,64 +141,12 @@ class uiPlaylist
$this->Base->_retMsg('Playlist "$1" released.', $this->Base->getMetadataValue(BasicStor::IdFromGunid($plgunid), UI_MDATA_KEY_TITLE)); $this->Base->_retMsg('Playlist "$1" released.', $this->Base->getMetadataValue(BasicStor::IdFromGunid($plgunid), UI_MDATA_KEY_TITLE));
} }
$this->activeId = NULL; $this->activeId = NULL;
$this->token = NULL;
$this->Base->gb->delPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY); $this->Base->gb->delPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY);
$this->changed = FALSE;
return TRUE; return TRUE;
} // fn release } // fn release
public function save()
{
$tmpid = $this->activeId;
$this->release(FALSE);
$this->activate($tmpid, FALSE);
$this->changed = FALSE;
if (UI_VERBOSE) {
$this->Base->_retMsg('Playlist "$1" saved.', $this->Base->getMetadataValue($tmpid, UI_MDATA_KEY_TITLE));
}
$this->Base->SCRATCHPAD->reloadMetadata();
return $this->activeId;
} // fn save
public function revert()
{
if (!$this->token) {
if (UI_WARNING) {
$this->Base->_retMsg('No playlists have been locked by you.');
}
return FALSE;
}
$plgunid = $this->Base->gb->revertEditedPlaylist($this->token, $this->Base->sessid);
if (PEAR::isError($plgunid)) {
if (UI_VERBOSE === TRUE) {
print_r($plgunid);
}
if (UI_WARNING) {
$this->Base->_retMsg('Unable to revert to locked state.');
}
return FALSE;
}
if (UI_VERBOSE) {
$this->Base->_retMsg('Playlist "$1" reverted.', $this->Base->getMetadataValue(BasicStor::IdFromGunid($plgunid), UI_MDATA_KEY_TITLE));
}
$this->activeId = NULL;
$this->token = NULL;
$this->Base->gb->delPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY);
if ($this->activate(BasicStor::IdFromGunid($plgunid), FALSE) !== TRUE) {
return FALSE;
}
$this->changed = FALSE;
return $this->activeId;
} // fn revert
public function reportLookedPL($setMsg=FALSE) public function reportLookedPL($setMsg=FALSE)
{ {
if (is_string($this->Base->gb->loadPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY))) { if (is_string($this->Base->gb->loadPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY))) {
@ -216,20 +161,17 @@ class uiPlaylist
public function loadLookedFromPref() public function loadLookedFromPref()
{ {
$this->changed = TRUE; if (is_string($plid = $this->Base->gb->loadPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY))) {
if (is_string($saved = $this->Base->gb->loadPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY))) { if (!$this->Base->gb->existsPlaylist($plid)) {
list ($plid, $token) = explode (':', $saved);
if (!$this->Base->gb->existsPlaylist($plid, $this->Base->sessid)) {
$this->Base->gb->delPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY); $this->Base->gb->delPref($this->Base->sessid, UI_PL_ACCESSTOKEN_KEY);
$this->Base->_retMsg('Playlist not found in database.'); $this->Base->_retMsg('Playlist not found in database.');
$this->Base->redirUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close'; $this->Base->redirUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close';
return FALSE; return FALSE;
} }
$this->activeId = $plid; $this->activeId = $plid;
$this->token = $token;
$this->Base->redirUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close'; $this->Base->redirUrl = UI_BROWSER.'?popup[]=_2PL.simpleManagement&popup[]=_close';
return TRUE; return TRUE;
} }
@ -244,14 +186,14 @@ class uiPlaylist
* @param array $duration * @param array $duration
* @return unknown * @return unknown
*/ */
public function addItem($elemIds, $duration=NULL) public function addItem($elemIds, $pos=NULL, $duration=NULL)
{ {
$this->changed = TRUE;
$fadeIn = NULL; $fadeIn = NULL;
$fadeOut = NULL; $fadeOut = NULL;
$length = NULL; $cliplength = NULL;
$clipstart = NULL; $cueIn = NULL;
$cueIn = NULL;
/* /*
gstreamer bug: gstreamer bug:
Warning: The clipEnd can't be bigger than ninety nine percent (99%) of the clipLength, Warning: The clipEnd can't be bigger than ninety nine percent (99%) of the clipLength,
@ -264,15 +206,16 @@ class uiPlaylist
$this->Base->_retMsg('No item(s) selected.'); $this->Base->_retMsg('No item(s) selected.');
} }
return FALSE; return FALSE;
} }
if (!is_array($elemIds)) { if (!is_array($elemIds)) {
$elemIds = array($elemIds); $elemIds = array($elemIds);
} }
if (isset($duration)) { if (isset($duration)) {
$length = sprintf('%02d', $duration['H']).':'.sprintf('%02d', $duration['i']).':'.sprintf('%02d', $duration['s']).'.000000'; $length = sprintf('%02d', $duration['H']).':'.sprintf('%02d', $duration['i']).':'.sprintf('%02d', $duration['s']).'.000000';
} }
foreach ($elemIds as $elemId) { foreach ($elemIds as $elemId) {
$r = $this->Base->gb->addAudioClipToPlaylist($this->token, $elemId, $this->Base->sessid, $fadeIn, $fadeOut, $length, $clipstart, $clipend); $r = $this->Base->gb->addAudioClipToPlaylist($this->activeId, $elemId, $pos, $fadeIn, $fadeOut, $cliplength, $cueIn, $cueOut);
if (PEAR::isError($r)) { if (PEAR::isError($r)) {
if (UI_VERBOSE === TRUE) { if (UI_VERBOSE === TRUE) {
print_r($r); print_r($r);
@ -285,21 +228,23 @@ class uiPlaylist
} // fn addItem } // fn addItem
public function removeItem($elemIds) public function removeItem($positions)
{ {
$this->changed = TRUE; if (!$positions) {
if (!$elemIds) {
if (UI_WARNING) { if (UI_WARNING) {
$this->Base->_retMsg('No item(s) selected.'); $this->Base->_retMsg('No item(s) selected.');
} }
return FALSE; return FALSE;
} }
if (!is_array($elemIds)) if (!is_array($positions))
$elemIds = array($elemIds); $positions = array($positions);
foreach ($elemIds as $elemId) { //so the automatic updating of playlist positioning doesn't affect removal.
if ($this->Base->gb->delAudioClipFromPlaylist($this->token, $elemId, $this->Base->sessid) !== TRUE) { sort($positions);
$positions = array_reverse($positions);
foreach ($positions as $pos) {
if ($this->Base->gb->delAudioClipFromPlaylist($this->activeId, $pos) !== TRUE) {
$this->Base->_retMsg('Cannot remove item from playlist.'); $this->Base->_retMsg('Cannot remove item from playlist.');
return FALSE; return FALSE;
} }
@ -321,23 +266,25 @@ class uiPlaylist
// create PL // create PL
// activate // activate
// add clip if $id is set // add clip if $id is set
$this->changed = TRUE;
if ($this->activeId) {
if (is_array($this->activeId)) {
$this->Base->_retMsg('A playlist is already opened.'); $this->Base->_retMsg('A playlist is already opened.');
return FALSE; return FALSE;
} }
$datetime = strftime('%Y-%m-%d %H:%M:%S'); $datetime = strftime('%Y-%m-%d %H:%M:%S');
$plid = $this->Base->gb->createPlaylist($datetime, $this->Base->sessid); $plid = $this->Base->gb->createPlaylist($datetime, $this->Base->sessid);
if (!$plid) { if (!$plid) {
$this->Base->_retMsg('Cannot create playlist.'); $this->Base->_retMsg('Cannot create playlist.');
return FALSE; return FALSE;
} }
$this->Base->setMetadataValue($plid, UI_MDATA_KEY_CREATOR, $this->Base->login); $this->Base->gb->setPLMetadataValue($plid, UI_MDATA_KEY_CREATOR, $this->Base->login);
$this->Base->setMetadataValue($plid, UI_MDATA_KEY_DESCRIPTION, tra('created at $1', $datetime)); $this->Base->gb->setPLMetadataValue($plid, UI_MDATA_KEY_DESCRIPTION, tra('created at $1', $datetime));
if ($this->activate($plid)===FALSE) { if ($this->activate($plid)===FALSE) {
$this->Base->_retMsg('Cannot activate playlist.');
return FALSE; return FALSE;
} }
if ($ids) { if ($ids) {
@ -345,6 +292,7 @@ class uiPlaylist
return FALSE; return FALSE;
} }
} }
return $plid; return $plid;
} // fn create } // fn create
@ -400,7 +348,6 @@ class uiPlaylist
public function changeTransition($id, $type, $duration) public function changeTransition($id, $type, $duration)
{ {
$this->changed = TRUE;
$pause = $pause; $pause = $pause;
$xfade = Playlist::secondsToPlaylistTime($duration/1000); $xfade = Playlist::secondsToPlaylistTime($duration/1000);
@ -467,12 +414,10 @@ class uiPlaylist
} // fn changeTransition } // fn changeTransition
public function moveItem($id, $pos) public function moveItem($oldPos, $newPos)
{ {
$this->changed = TRUE; $r = $this->Base->gb->moveAudioClipInPlaylist($this->activeId, $oldPos, $newPos);
if (PEAR::isError($r) || $r === FALSE) {
$r = $this->Base->gb->moveAudioClipInPlaylist($this->token, $id, $pos, $this->Base->sessid);
if (PEAR::isError($r)) {
if (UI_VERBOSE === TRUE) { if (UI_VERBOSE === TRUE) {
print_r($r); print_r($r);
} }
@ -485,8 +430,6 @@ class uiPlaylist
public function reorder($items) public function reorder($items)
{ {
$this->changed = TRUE;
// just to be sure items are in right order // just to be sure items are in right order
asort($items); asort($items);
$pos = 0; $pos = 0;
@ -647,7 +590,9 @@ class uiPlaylist
foreach ($mask['playlist'] as $k=>$v) { foreach ($mask['playlist'] as $k=>$v) {
$mask['playlist'][$k]['element'] = uiBase::formElementEncode($v['element']); $mask['playlist'][$k]['element'] = uiBase::formElementEncode($v['element']);
if ($getval = $this->Base->getMetadataValue($id, $v['element'], $langid)) {
$getval = $this->Base->gb->getPLMetadataValue($id, $v['element'], $langid);
if ($getval) {
$mask['playlist'][$k]['default'] = $getval; $mask['playlist'][$k]['default'] = $getval;
$mask['playlist'][$k]['attributes']['onFocus'] = 'MData_confirmChange(this)'; $mask['playlist'][$k]['attributes']['onFocus'] = 'MData_confirmChange(this)';
}; };
@ -679,8 +624,6 @@ class uiPlaylist
public function editMetaData($formdata) public function editMetaData($formdata)
{ {
$this->changed = TRUE;
include(dirname(__FILE__).'/formmask/metadata.inc.php'); include(dirname(__FILE__).'/formmask/metadata.inc.php');
$id = $this->activeId; $id = $this->activeId;
@ -692,8 +635,9 @@ class uiPlaylist
} else { } else {
$this->Base->redirUrl = UI_BROWSER."?act=PL.editMetaData&id=$id&curr_langid=".$formdata['target_langid']; $this->Base->redirUrl = UI_BROWSER."?act=PL.editMetaData&id=$id&curr_langid=".$formdata['target_langid'];
} }
foreach ($mask['playlist'] as $k=>$v) { foreach ($mask['playlist'] as $k=>$v) {
$formdata[uiBase::formElementEncode($v['element'])] ? $mData[uiBase::formElementDecode($v['element'])] = $formdata[uiBase::formElementEncode($v['element'])] : NULL; $formdata[uiBase::formElementEncode($v['element'])] ? $mData[uiBase::formElementDecode($v['element'])] = $formdata[uiBase::formElementEncode($v['element'])] : NULL;
} }
@ -702,7 +646,7 @@ class uiPlaylist
} }
foreach ($mData as $key => $val) { foreach ($mData as $key => $val) {
$r = $this->Base->gb->setMetadataValue($id, $key, $this->Base->sessid, $val, $curr_langid); $r = $this->Base->gb->setPLMetadataValue($id, $key, $val, $curr_langid);
if (PEAR::isError($r)) { if (PEAR::isError($r)) {
if (UI_VERBOSE === TRUE) { if (UI_VERBOSE === TRUE) {
print_r($r); print_r($r);
@ -712,7 +656,7 @@ class uiPlaylist
} }
if (UI_VERBOSE) { if (UI_VERBOSE) {
$this->Base->_retMsg('Metadata saved.'); $this->Base->_retMsg('Metadata saved.');
} }
} // fn editMetadata } // fn editMetadata
@ -720,9 +664,12 @@ class uiPlaylist
{ {
$id = $this->activeId; $id = $this->activeId;
$this->release(FALSE); $this->release(FALSE);
if ($this->Base->delete($id)) {
$res = $this->Base->gb->deletePlaylist($id);
if ($res === TRUE) {
return $id; return $id;
} }
$this->Base->_retMsg('Cannot delete this playlist.'); $this->Base->_retMsg('Cannot delete this playlist.');
return FALSE; return FALSE;
} // fn deleteActive } // fn deleteActive

View File

@ -1432,7 +1432,7 @@ class BasicStor {
*/ */
public static function GetObjType($oid) public static function GetObjType($oid)
{ {
$type = "unknown"; $type = "unknown";
$gunid = BasicStor::GunidFromId($oid); $gunid = BasicStor::GunidFromId($oid);
if (PEAR::isError($gunid)) { if (PEAR::isError($gunid)) {
return $gunid; return $gunid;
@ -1662,13 +1662,12 @@ class BasicStor {
$res = preg_match("|^([0-9a-fA-F]{16})?$|", $p_gunid); $res = preg_match("|^([0-9a-fA-F]{16})?$|", $p_gunid);
return $res; return $res;
} }
/** /**
* Set playlist edit flag * Set playlist edit flag
* *
* @param string $p_playlistId * @param string $p_playlistId
* Playlist global unique ID * Playlist unique ID
* @param boolean $p_val * @param boolean $p_val
* Set/clear of edit flag * Set/clear of edit flag
* @param string $p_sessid * @param string $p_sessid
@ -1686,15 +1685,15 @@ class BasicStor {
return $p_subjid; return $p_subjid;
} }
} }
$storedFile = StoredFile::RecallByGunid($p_playlistId); $pl = Playlist::Recall($p_playlistId);
if (is_null($storedFile) || PEAR::isError($storedFile)) { if (is_null($pl) || PEAR::isError($pl)) {
return $storedFile; return $pl;
} }
$state = $storedFile->getState(); $state = $pl->getState();
if ($p_val) { if ($p_val) {
$r = $storedFile->setState('edited', $p_subjid); $r = $pl->setState('edited', $p_subjid);
} else { } else {
$r = $storedFile->setState('ready', 'NULL'); $r = $pl->setState('ready', 'NULL');
} }
if (PEAR::isError($r)) { if (PEAR::isError($r)) {
return $r; return $r;
@ -1713,14 +1712,14 @@ class BasicStor {
*/ */
public function isEdited($p_playlistId) public function isEdited($p_playlistId)
{ {
$storedFile = StoredFile::RecallByGunid($p_playlistId); $pl = Playlist::Recall($p_playlistId);
if (is_null($storedFile) || PEAR::isError($storedFile)) { if (is_null($pl) || PEAR::isError($pl)) {
return $storedFile; return $pl;
} }
if (!$storedFile->isEdited($p_playlistId)) { if (!$pl->isEdited($p_playlistId)) {
return FALSE; return FALSE;
} }
return $storedFile->isEditedBy($p_playlistId); return $pl->isEditedBy($p_playlistId);
} }

View File

@ -472,21 +472,35 @@ class GreenBox extends BasicStor {
*/ */
public function createPlaylist($fname, $sessid='') public function createPlaylist($fname, $sessid='')
{ {
global $CC_CONFIG, $CC_DBC; $pl = new Playlist();
$gunid = StoredFile::CreateGunid(); $pl = $pl->create($fname);
$lc = new LocStor($CC_DBC, $CC_CONFIG);
$gunid2 = $lc->createPlaylist($sessid, $gunid, $fname); return $pl;
if (PEAR::isError($gunid2)) {
return $gunid2;
}
// get local id:
$id = BasicStor::IdFromGunid($gunid2);
if (PEAR::isError($id)) {
return $id;
}
return $id;
} // fn createPlaylist } // fn createPlaylist
public function setPLMetadataValue($id, $category, $value, $lang=NULL, $mid=NULL)
{
$pl = Playlist::Recall($id);
if($pl === FALSE)
return FALSE;
$res = $pl->setMetaData($category, $value, $lang);
return $res;
}
public function getPLMetadataValue($id, $category, $langId=NULL)
{
$pl = Playlist::Recall($id);
if($pl === FALSE)
return FALSE;
$res = $pl->getPLMetaData($category);
return $res;
}
/** /**
* Return playlist as XML string * Return playlist as XML string
@ -513,15 +527,19 @@ class GreenBox extends BasicStor {
* session ID * session ID
* @return array * @return array
*/ */
public function getPlaylistArray($id, $sessid) public function getPlaylistArray($id)
{ {
$gunid = BasicStor::GunidFromId($id); $pl = Playlist::Recall($id);
$pl = StoredFile::Recall($id); if ($pl === FALSE) {
if (is_null($pl) || PEAR::isError($pl)) { return FALSE;
return $pl;
} }
$gunid = $pl->gunid;
return $pl->md->genPhpArray(); $res = $pl->getContents();
if(is_null($res))
return array();
return $res;
} // fn getPlaylistArray } // fn getPlaylistArray
@ -535,45 +553,32 @@ class GreenBox extends BasicStor {
* @return string * @return string
* playlist access token * playlist access token
*/ */
public function lockPlaylistForEdit($id, $sessid) public function lockPlaylistForEdit($id, $sessid) {
{ $pl = Playlist::Recall($id);
global $CC_CONFIG, $CC_DBC;
$gunid = BasicStor::GunidFromId($id); if($pl === FALSE)
$lc = new LocStor($CC_DBC, $CC_CONFIG); return;
$res = $lc->editPlaylist($sessid, $gunid);
if (PEAR::isError($res)) { $res = $pl->lock($sessid);
return $res; }
}
return $res['token'];
} // fn lockPlaylistForEdit
/** /**
* Release token, regenerate XML from DB and clear edit flag. * clear edit flag.
* *
* @param string $token
* playlist access token
* @param string $sessid * @param string $sessid
* session ID * session ID
* @return string gunid * @return string gunid
*/ */
public function releaseLockedPlaylist($token, $sessid) public function releaseLockedPlaylist($id, $sessid) {
{ $pl = Playlist::Recall($id);
$gunid = $this->bsCloseDownload($token, 'metadata');
if (PEAR::isError($gunid)) { if($pl === FALSE)
return $gunid; return FALSE;
}
$storedFile = StoredFile::RecallByGunid($gunid); $res = $pl->unlock($sessid);
if (is_null($storedFile) || PEAR::isError($storedFile)) { return $res;
return $storedFile; }
}
// $r = $storedFile->md->regenerateXmlFile();
// if (PEAR::isError($r)) {
// return $r;
// }
$this->setEditFlag($gunid, FALSE, $sessid);
return $gunid;
} // fn releaseLockedPlaylist
/** /**
@ -596,32 +601,17 @@ class GreenBox extends BasicStor {
* optional clipstart time format hh:mm:ss.ssssss - relative to begin * optional clipstart time format hh:mm:ss.ssssss - relative to begin
* @param string $clipend * @param string $clipend
* optional $clipend time format hh:mm:ss.ssssss - relative to begin * optional $clipend time format hh:mm:ss.ssssss - relative to begin
* @return string, generated playlistElement gunid * @return boolean, true if added.
*/ */
public function addAudioClipToPlaylist($token, $acId, $sessid, public function addAudioClipToPlaylist($id, $acId, $pos=NULL, $fadeIn=NULL, $fadeOut=NULL, $cliplength=NULL, $cueIn=NULL, $cueOut=NULL)
$fadeIn=NULL, $fadeOut=NULL, $length=NULL, $clipstart=NULL, $clipend=NULL)
{ {
require_once("Playlist.php"); $pl = Playlist::Recall($id);
$pl = StoredFile::RecallByToken($token); if ($pl === FALSE) {
if (is_null($pl) || PEAR::isError($pl)) { return FALSE;
return $pl;
}
$acGunid = BasicStor::GunidFromId($acId);
if ($pl->cyclicRecursion($acGunid)){
return PEAR::raiseError(
"GreenBox::addAudioClipToPlaylist: cyclic-recursion detected".
" ($type)"
);
}
$res = $pl->addAudioClip($acId, $fadeIn, $fadeOut, NULL, $length, $clipstart, $clipend);
if (PEAR::isError($res)) {
return $res;
}
// recalculate offsets and total length:
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
} }
$res = $pl->addAudioClip($acId, $pos, $fadeIn, $fadeOut, $cliplength, $cueIn, $cueOut);
return $res; return $res;
} // fn addAudioClipToPlaylist } // fn addAudioClipToPlaylist
@ -629,159 +619,100 @@ class GreenBox extends BasicStor {
/** /**
* Remove audioclip from playlist * Remove audioclip from playlist
* *
* @param string $token * @param string $id
* playlist access token * playlist id
* @param string $plElGunid * @param int $pos
* global id of deleted playlistElement * position of element in playlist to delete.
* @param string $sessid * @return boolean, true if deleted.
* session ID
* @return boolean
* @todo rename this function to "deleteAudioClipFromPlaylist" * @todo rename this function to "deleteAudioClipFromPlaylist"
*/ */
public function delAudioClipFromPlaylist($token, $plElGunid, $sessid) public function delAudioClipFromPlaylist($id, $pos)
{ {
require_once("Playlist.php"); $pl = Playlist::Recall($id);
$pl = StoredFile::RecallByToken($token); if ($pl === FALSE) {
if (is_null($pl) || PEAR::isError($pl)) { return FALSE;
return $pl;
}
$res = $pl->delAudioClip($plElGunid);
if (PEAR::isError($res)) {
return $res;
}
// recalculate offsets and total length:
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
} }
$res = $pl->delAudioClip($pos);
return $res; return $res;
} // fn delAudioClipFromPlaylist }
/**
* Move audioClip to the new position in the playlist.
*
* This method may change id attributes of playlistElements and/or
* fadeInfo.
*
* @param string $id
* playlist id
* @param id $oldPos
* old position in playlist
* @param int $newPos
* new position in playlist
* @return boolean
*/
public function moveAudioClipInPlaylist($id, $oldPos, $newPos)
{
$pl = Playlist::Recall($id);
if ($pl === FALSE) {
return FALSE;
}
$res = $pl->moveAudioClip($oldPos, $newPos);
return $res;
}
/** /**
* Change fadeInfo values * Change fadeInfo values
* *
* @param string $token * @param string $id
* playlist access token * playlist id
* @param string $plElGunid
* global id of deleted playlistElement
* @param string $fadeIn * @param string $fadeIn
* in time format hh:mm:ss.ssssss * in time format hh:mm:ss.ssssss
* @param string $fadeOut * @param string $fadeOut
* in time format hh:mm:ss.ssssss * in time format hh:mm:ss.ssssss
* @param sessid $string
* session ID
* @return boolean * @return boolean
*/ */
public function changeFadeInfo($token, $plElGunid, $fadeIn, $fadeOut, $sessid) public function changeFadeInfo($id, $pos, $fadeIn, $fadeOut)
{ {
require_once("Playlist.php"); $pl = Playlist::Recall($id);
$pl = StoredFile::RecallByToken($token); if ($pl === FALSE) {
if (is_null($pl) || PEAR::isError($pl)) { return FALSE;
return $pl;
} }
$res = $pl->changeFadeInfo($plElGunid, $fadeIn, $fadeOut);
if (PEAR::isError($res)) { $res = $pl->changeFadeInfo($pos, $fadeIn, $fadeOut);
return $res;
} return $res;
// recalculate offsets and total length: }
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
} // fn changeFadeInfo
/** /**
* Change cueIn/curOut values for playlist element * Change cueIn/cueOut values for playlist element
* *
* @param string $token * @param string $id
* playlist access token * playlist id
* @param string $plElGunid * @param string $cueIn
* global id of deleted playlistElement
* @param string $clipStart
* in time format hh:mm:ss.ssssss * in time format hh:mm:ss.ssssss
* @param string $clipEnd * @param string $cueOut
* in time format hh:mm:ss.ssssss * in time format hh:mm:ss.ssssss
* relative to begin * relative to begin
* @param sessid $string * @param sessid $string
* session ID * session ID
* @return boolean or pear error object * @return boolean or pear error object
*/ */
public function changeClipLength($token, $plElGunid, $clipStart, $clipEnd, $sessid) public function changeClipLength($id, $cueIn, $cueOut)
{ {
require_once("Playlist.php"); $pl = Playlist::Recall($id);
$pl = StoredFile::RecallByToken($token); if ($pl === FALSE) {
if (is_null($pl) || PEAR::isError($pl)) { return FALSE;
return $pl;
} }
$res = $pl->changeClipLength($plElGunid, $clipStart, $clipEnd);
if (PEAR::isError($res)) { $res = $pl->changeClipLength($pos, $cueIn, $cueOut);
return $res;
} return $res;
// recalculate offsets and total length: }
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
} // fn changeFadeInfo
/**
* Move audioClip to the new position in the playlist.
*
* This method may change id attributes of playlistElements and/or
* fadeInfo.
*
* @param string $token
* playlist access token
* @param string $plElGunid
* global id of deleted playlistElement
* @param int $newPos
* new position in playlist
* @param string $sessid
* session ID
* @return boolean
*/
public function moveAudioClipInPlaylist($token, $plElGunid, $newPos, $sessid)
{
require_once("Playlist.php");
$pl = StoredFile::RecallByToken($token);
if (is_null($pl) || PEAR::isError($pl)) {
return $pl;
}
$res = $pl->moveAudioClip($plElGunid, $newPos);
if (PEAR::isError($res)) {
return $res;
}
// recalculate offsets and total length:
$r = $pl->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
}
return TRUE;
} // fn moveAudioClipInPlaylist
/**
* RollBack playlist changes to the locked state
*
* @param string $token
* playlist access token
* @param string $sessid
* session ID
* @return string
* gunid of playlist
*/
public function revertEditedPlaylist($token, $sessid='')
{
global $CC_CONFIG, $CC_DBC;
$lc = new LocStor($CC_DBC, $CC_CONFIG);
return $lc->revertEditedPlaylist($token, $sessid);
} // fn revertEditedPlaylist
/** /**
* Delete a Playlist metafile. * Delete a Playlist metafile.
* *
@ -791,14 +722,11 @@ class GreenBox extends BasicStor {
* session ID * session ID
* @return boolean * @return boolean
*/ */
public function deletePlaylist($id, $sessid) public function deletePlaylist($id)
{ {
global $CC_CONFIG, $CC_DBC; return Playlist::Delete($id);
$gunid = BasicStor::GunidFromId($id);
$lc = new LocStor($CC_DBC, $CC_CONFIG); }
return $lc->deletePlaylist($sessid, $gunid);
} // fn deletePlaylist
/** /**
* Find info about clip at specified offset in playlist. * Find info about clip at specified offset in playlist.
@ -951,12 +879,14 @@ class GreenBox extends BasicStor {
* session ID * session ID
* @return boolean * @return boolean
*/ */
public function existsPlaylist($id, $sessid) public function existsPlaylist($id)
{ {
global $CC_CONFIG, $CC_DBC; $pl = Playlist::Recall($id);
$gunid = BasicStor::GunidFromId($id); if ($pl === FALSE) {
$lc = new LocStor($CC_DBC, $CC_CONFIG); return FALSE;
return $lc->existsPlaylist($sessid, $gunid); }
return TRUE;
} // fn existsPlaylist } // fn existsPlaylist
@ -974,10 +904,17 @@ class GreenBox extends BasicStor {
*/ */
public function playlistIsAvailable($id, $sessid) public function playlistIsAvailable($id, $sessid)
{ {
global $CC_CONFIG, $CC_DBC; $pl = Playlist::Recall($id);
$gunid = BasicStor::GunidFromId($id); if ($pl === FALSE) {
$lc = new LocStor($CC_DBC, $CC_CONFIG); return FALSE;
return $lc->playlistIsAvailable($sessid, $gunid, TRUE); }
$res = $pl->isEdited();
if($res !== FALSE)
return $res;
return TRUE;
} // fn playlistIsAvailable } // fn playlistIsAvailable

View File

@ -988,15 +988,15 @@ class LocStor extends BasicStor {
*/ */
public function playlistIsAvailable($sessid, $playlistId, $getUid=FALSE) public function playlistIsAvailable($sessid, $playlistId, $getUid=FALSE)
{ {
// $ex = $this->existsPlaylist($sessid, $playlistId); $ex = $this->existsPlaylist($sessid, $playlistId);
// if (PEAR::isError($ex)) { if (PEAR::isError($ex)) {
// return $ex; return $ex;
// } }
// if (!$ex) { if (!$ex) {
// return PEAR::raiseError( return PEAR::raiseError(
// 'LocStor::playlistIsAvailable: playlist not exists' 'LocStor::playlistIsAvailable: playlist not exists'
// ); );
// } }
$ie = $this->isEdited($playlistId); $ie = $this->isEdited($playlistId);
if ($ie === FALSE) { if ($ie === FALSE) {
return TRUE; return TRUE;

View File

@ -53,6 +53,8 @@ class Playlist {
*/ */
public $md; public $md;
private $categories = array("dc:title" => "name", "dc:creator" => "creator", "dc:description" => "description", "dcterms:extent" => "length");
public function __construct($p_gunid=NULL) public function __construct($p_gunid=NULL)
{ {
@ -102,8 +104,30 @@ class Playlist {
} }
// Recall the object to get all the proper values // Recall the object to get all the proper values
$storedPlaylist = Playlist::Recall($storedPlaylist->id); //$storedPlaylist = Playlist::Recall($storedPlaylist->id);
return $storedPlaylist; return $storedPlaylist->id;
}
public static function Delete($id) {
global $CC_CONFIG, $CC_DBC;
$CC_DBC->query("BEGIN");
$sql = "DELETE FROM ".$CC_CONFIG['playListTable']. " WHERE id='{$id}'";
$res = $CC_DBC->query($sql);
if (PEAR::isError($res)) {
$CC_DBC->query("ROLLBACK");
return $res;
}
// Commit changes
$res = $CC_DBC->query("COMMIT");
if (PEAR::isError($res)) {
$CC_DBC->query("ROLLBACK");
return $res;
}
return TRUE;
} }
/** /**
@ -113,25 +137,24 @@ class Playlist {
* @return StoredFile|Playlist|NULL * @return StoredFile|Playlist|NULL
* Return NULL if the object doesnt exist in the DB. * Return NULL if the object doesnt exist in the DB.
*/ */
public static function Recall($id) public static function Recall($id) {
{
global $CC_DBC; global $CC_DBC, $CC_CONFIG;
global $CC_CONFIG;
$cond = "id='$id'";
$escapedID = pg_escape_string($id);
$sql = "SELECT id," $sql = "SELECT id,"
." name, state, currentlyaccessing, editedby, " ." name, state, currentlyaccessing, editedby, "
." mtime" ." mtime"
." FROM ".$CC_CONFIG['playListTable'] ." FROM ".$CC_CONFIG['playListTable']
." WHERE $cond"; ." WHERE id ='{$escapedID}'";
$row = $CC_DBC->getRow($sql); $row = $CC_DBC->getRow($sql);
if (PEAR::isError($row)) { if (PEAR::isError($row)) {
return $row; return FALSE;
} }
if (is_null($row)) { if (is_null($row)) {
return null; return FALSE;
} }
$storedPlaylist = new Playlist($id); $storedPlaylist = new Playlist($id);
@ -272,53 +295,58 @@ class Playlist {
} }
return ($ca > 0); return ($ca > 0);
} }
/**
* Returns true if virtual file is edited
*
* @param string $p_playlistId
* playlist global unique ID
* @return boolean
*/
public function isEdited($p_playlistId=NULL)
{
if (is_null($p_playlistId)) {
return ($this->state == 'edited');
}
$state = $this->getState($p_playlistId);
if ($state != 'edited') {
return FALSE;
}
return TRUE;
}
/** /**
* Returns id of user editing playlist * Returns id of user editing playlist
* *
* @param string $p_playlistId * @param string $p_playlistId
* playlist global unique ID * playlist global unique ID
* @return int|null|PEAR_Error * @return int id of user editing playlist
* id of user editing it
*/ */
public function isEditedBy($p_playlistId=NULL) public function isEdited() {
{
global $CC_CONFIG, $CC_DBC; if($this->state === 'edited') {
if (is_null($p_playlistId)) { return $this->editedby;
$p_playlistId = $this->id; }
} return FALSE;
$sql = "SELECT editedBy FROM ".$CC_CONFIG['playListTable']
." WHERE id='$p_playlistId'";
$ca = $CC_DBC->getOne($sql);
if (PEAR::isError($ca)) {
return $ca;
}
if (is_null($ca)) {
return $ca;
}
return intval($ca);
} }
/**
* Set playlist edit flag
*
* @param string $p_playlistId
* Playlist unique ID
* @param boolean $p_val
* Set/clear of edit flag
* @param string $p_sessid
* Session id
* @param int $p_subjid
* Subject id (if sessid is not specified)
* @return boolean
* previous state
*/
public function setEditFlag($p_val=TRUE, $p_sessid=NULL, $p_subjid=NULL) {
if (!is_null($p_sessid)) {
$p_subjid = Alib::GetSessUserId($p_sessid);
if (PEAR::isError($p_subjid)) {
return $p_subjid;
}
}
$state = $this->state;
if ($p_val) {
$r = $this->setState('edited', $p_subjid);
} else {
$r = $this->setState('ready', 'NULL');
}
if (PEAR::isError($r)) {
return $r;
}
return ($state == 'edited');
}
/** /**
* Return local ID of virtual file. * Return local ID of virtual file.
* *
@ -328,12 +356,33 @@ class Playlist {
return $this->id; return $this->id;
} }
private function getNextPos() {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT MAX(position) AS nextPos
FROM cc_playlistcontents
WHERE playlist_id='{$this->getId()}'";
$res = $CC_DBC->getOne($sql);
if(is_null($res))
return 0;
if(PEAR::isError($res)){
return $res;
}
return $res + 1;
}
public function getContents() { public function getContents() {
global $CC_CONFIG, $CC_DBC; global $CC_CONFIG, $CC_DBC;
$sql = "SELECT * FROM ".$CC_CONFIG['playListContentsTable'] $sql = "SELECT *
." WHERE playlist_id ='{$this->getId()}' ORDER BY position"; FROM cc_playlistcontents C JOIN cc_files F ON C.file_id = F.id
WHERE C.playlist_id='{$this->getId()}' ORDER BY C.position";
return $CC_DBC->getAll($sql); return $CC_DBC->getAll($sql);
} }
@ -350,6 +399,9 @@ class Playlist {
return $res; return $res;
} }
if(is_null($res))
return '00:00:00.000000';
return $res['length']; return $res['length'];
} }
@ -363,29 +415,19 @@ class Playlist {
public function create($fname=NULL) public function create($fname=NULL)
{ {
$values = array("filename" => $fname); $values = array("filename" => $fname);
$pl = Playlist::Insert($values); $pl_id = Playlist::Insert($values);
if (PEAR::isError($pl)) { if (PEAR::isError($pl_id)) {
return $pl; return $pl_id;
} }
/** return $pl_id;
* TODO deal with metadata.
*/
/*
$res = $pl->setAuxMetadata();
if (PEAR::isError($res)) {
return $res;
}
*/
return $pl;
} }
/** /**
* Lock playlist for edit * Lock playlist for edit
* *
* @param GreenBox $gb * @param string $sessid
* reference to GreenBox object * session id
* @param int $subjid * @param int $subjid
* local subject (user) id * local subject (user) id
* @param boolean $val * @param boolean $val
@ -393,39 +435,29 @@ class Playlist {
* @return boolean * @return boolean
* previous state or error object * previous state or error object
*/ */
public function lock($gb, $subjid=NULL, $val=TRUE) public function lock($sessid, $subjid=NULL, $val=TRUE)
{ {
if ($val && $gb->isEdited($this->id) !== FALSE) { if ($val && $this->isEdited() !== FALSE) {
return PEAR::raiseError( return PEAR::raiseError(
'Playlist::lock: playlist already locked' 'Playlist::lock: playlist already locked'
); );
} }
$r = $gb->setEditFlag($this->id, $val, NULL, $subjid); $r = $this->setEditFlag($val, $sessid, $subjid);
return $r; return $r;
} }
/** /**
* Unlock playlist (+recalculate and pregenerate XML) * Unlock playlist
* *
* @param GreenBox $gb * @param sessId
* reference to GreenBox object * reference to GreenBox object
* @return boolean * @return boolean
* previous state or error object * previous state or error object
*/ */
public function unlock($gb) public function unlock($sessid)
{ {
/** $r = $this->lock($sessid, NULL, FALSE);
* TODO deal with playlist length.
*/
/*
$r = $this->recalculateTimes();
if (PEAR::isError($r)) {
return $r;
}
*/
$r = $this->lock($gb, $this->id, NULL, FALSE);
return $r; return $r;
} }
@ -451,7 +483,7 @@ class Playlist {
* @return string * @return string
* generated playlistElement gunid * generated playlistElement gunid
*/ */
public function addAudioClip($acId, $pos, $fadeIn=NULL, $fadeOut=NULL, $cliplength=NULL, $cuein=NULL, $cueout=NULL) public function addAudioClip($acId, $pos=NULL, $fadeIn=NULL, $fadeOut=NULL, $cliplength=NULL, $cuein=NULL, $cueout=NULL)
{ {
//get audio clip. //get audio clip.
$ac = StoredFile::Recall($acId); $ac = StoredFile::Recall($acId);
@ -467,7 +499,14 @@ class Playlist {
if (!is_null($cliplength)) { if (!is_null($cliplength)) {
$acLen = $cliplength; $acLen = $cliplength;
} }
//insert at end of playlist.
if(is_null($pos))
$pos = $this->getNextPos();
if (PEAR::isError($pos)) {
return $pos;
}
// insert default values if parameter was empty // insert default values if parameter was empty
$cuein = !is_null($cuein) ? $cuein : '00:00:00.000000'; $cuein = !is_null($cuein) ? $cuein : '00:00:00.000000';
$cueout = !is_null($cueout) ? $cueout : $acLen; $cueout = !is_null($cueout) ? $cueout : $acLen;
@ -641,7 +680,43 @@ class Playlist {
{ {
} }
public function getPLMetaData($category)
{
global $CC_CONFIG, $CC_DBC;
$cat = $this->categories[$category];
if($cat === 'length') {
return $this->getLength();
}
$sql = "SELECT {$cat} AS mdata FROM ".$CC_CONFIG['playListTable'].
" WHERE id='{$this->getId()}'";
$res = $CC_DBC->getOne($sql);
if (PEAR::isError($res)) {
return FALSE;
}
return $res;
}
public function setMetaData($category, $value)
{
global $CC_CONFIG, $CC_DBC;
$cat = $this->categories[$category];
$sql = "UPDATE ".$CC_CONFIG['playListTable']. " SET {$cat}='{$value}'" .
" WHERE id='{$this->getId()}'";
$res = $CC_DBC->query($sql);
if (PEAR::isError($res)) {
return $res;
}
return TRUE;
}
/** /**
* Return array with gunids of all sub-playlists and clips used in * Return array with gunids of all sub-playlists and clips used in

View File

@ -459,6 +459,7 @@ class StoredFile {
} }
} }
} }
/* ========= 'factory' methods - should be called to construct StoredFile */ /* ========= 'factory' methods - should be called to construct StoredFile */
/** /**
@ -586,7 +587,6 @@ class StoredFile {
return $storedFile; return $storedFile;
} }
/** /**
* Fetch instance of StoreFile object.<br> * Fetch instance of StoreFile object.<br>
* Should be supplied with only ONE parameter, all the rest should * Should be supplied with only ONE parameter, all the rest should
@ -1063,7 +1063,6 @@ class StoredFile {
return TRUE; return TRUE;
} }
/** /**
* Set mime-type of virtual file * Set mime-type of virtual file
* *
@ -1161,7 +1160,10 @@ class StoredFile {
/** /**
* Returns gunIds of the playlists the stored file is in. * Returns gunIds of the playlists the stored file is in.
* TODO update this to work with new tables.
*/ */
/*
public function getPlaylists() { public function getPlaylists() {
global $CC_CONFIG, $CC_DBC; global $CC_CONFIG, $CC_DBC;
@ -1176,17 +1178,7 @@ class StoredFile {
return $playlists; return $playlists;
} }
*/
public function isScheduled() {
global $CC_CONFIG, $CC_DBC;
$sql = "SELECT * "
." FROM ".$CC_CONFIG['scheduleTable']
." WHERE ends > now() and playlist=x'{$this->gunid}'::bigint";
$scheduled = $CC_DBC->getAll($sql);
return $scheduled;
}
/** /**

View File

@ -171,7 +171,7 @@ if (!camp_db_table_exists($CC_CONFIG['filesTable'])) {
bit_rate character varying(32), bit_rate character varying(32),
sample_rate character varying(32), sample_rate character varying(32),
format character varying(128), format character varying(128),
length character(16), length time without time zone,
album_title character varying(512), album_title character varying(512),
genre character varying(64), genre character varying(64),
comments text, comments text,
@ -220,6 +220,8 @@ if (!camp_db_table_exists($CC_CONFIG['playListTable'])) {
currentlyaccessing integer NOT NULL DEFAULT 0, currentlyaccessing integer NOT NULL DEFAULT 0,
editedby integer, editedby integer,
mtime timestamp(6) with time zone, mtime timestamp(6) with time zone,
creator character varying(32),
description character varying(512),
CONSTRAINT cc_playlist_pkey PRIMARY KEY (id), CONSTRAINT cc_playlist_pkey PRIMARY KEY (id),
CONSTRAINT cc_playlist_editedby_fkey FOREIGN KEY (editedby) CONSTRAINT cc_playlist_editedby_fkey FOREIGN KEY (editedby)
REFERENCES cc_subjs (id) MATCH SIMPLE REFERENCES cc_subjs (id) MATCH SIMPLE
@ -249,10 +251,10 @@ if (!camp_db_table_exists($CC_CONFIG['playListContentsTable'])) {
CONSTRAINT cc_playlistcontents_pkey PRIMARY KEY (id), CONSTRAINT cc_playlistcontents_pkey PRIMARY KEY (id),
CONSTRAINT cc_playlistcontents_playlist_id_fkey FOREIGN KEY (playlist_id) CONSTRAINT cc_playlistcontents_playlist_id_fkey FOREIGN KEY (playlist_id)
REFERENCES ".$CC_CONFIG['playListTable']." (id) MATCH SIMPLE REFERENCES ".$CC_CONFIG['playListTable']." (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION, ON UPDATE NO ACTION ON DELETE CASCADE,
CONSTRAINT cc_playlistcontents_file_id_fkey FOREIGN KEY (file_id) CONSTRAINT cc_playlistcontents_file_id_fkey FOREIGN KEY (file_id)
REFERENCES ".$CC_CONFIG['filesTable']." (id) MATCH SIMPLE REFERENCES ".$CC_CONFIG['filesTable']." (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION ON UPDATE NO ACTION ON DELETE CASCADE
); );
CREATE OR REPLACE FUNCTION calculate_position() RETURNS trigger AS CREATE OR REPLACE FUNCTION calculate_position() RETURNS trigger AS