Merge branch 'cc-84-smart-playlist' of dev.sourcefabric.org:airtime into cc-84-smart-playlist
This commit is contained in:
commit
a8f4148373
|
@ -22,6 +22,8 @@ class PlaylistController extends Zend_Controller_Action
|
|||
->addActionContext('set-playlist-description', 'json')
|
||||
->addActionContext('playlist-preview', 'json')
|
||||
->addActionContext('get-playlist', 'json')
|
||||
->addActionContext('smart-playlist-criteria-save', 'json')
|
||||
->addActionContext('smart-playlist-generate', 'json')
|
||||
->initContext();
|
||||
|
||||
$this->pl_sess = new Zend_Session_Namespace(UI_PLAYLIST_SESSNAME);
|
||||
|
@ -438,5 +440,21 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$this->playlistUnknownError($e);
|
||||
}
|
||||
}
|
||||
|
||||
public function smartPlaylistCriteriaSaveAction()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$params = $request->getPost();
|
||||
Application_Model_Playlist::saveSmartPlaylistCriteria($param['data']);
|
||||
|
||||
}
|
||||
|
||||
public function smartPlaylistGenerateAction()
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
$params = $request->getPost();
|
||||
$result = Application_Model_Playlist::generateSmartPlaylist($params['data']);
|
||||
die(json_encode($result));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class Application_Form_SmartPlaylistCriteria extends Zend_Form_SubForm
|
|||
"album_title" => "Album",
|
||||
"artist_name" => "Artist",
|
||||
"bit_rate" => "Bit Rate",
|
||||
"bmp" => "Bpm",
|
||||
"bpm" => "Bpm",
|
||||
"comments" => "Comments",
|
||||
"composer" => "Composer",
|
||||
"conductor" => "Conductor",
|
||||
|
@ -34,29 +34,6 @@ class Application_Form_SmartPlaylistCriteria extends Zend_Form_SubForm
|
|||
"year" => "Year"
|
||||
);
|
||||
|
||||
$criteriaTypes = array(
|
||||
|
||||
);
|
||||
|
||||
$stringCriteriaOptions = array(
|
||||
0 => "Select modifier",
|
||||
"contains" => "contains",
|
||||
"does not contain" => "does not contain",
|
||||
"is" => "is",
|
||||
"is not" => "is not",
|
||||
"starts with" => "starts with",
|
||||
"ends with" => "ends with"
|
||||
);
|
||||
|
||||
$numericCriteriaOptions = array(
|
||||
0 => "Select modifier",
|
||||
"is" => "is",
|
||||
"is not" => "is not",
|
||||
"is greater than" => "is greater than",
|
||||
"is less than" => "is less than",
|
||||
"is in the range" => "is in the range"
|
||||
);
|
||||
|
||||
$limitOptions = array(
|
||||
"hours" => "hours",
|
||||
"minutes" => "minutes",
|
||||
|
@ -94,7 +71,7 @@ class Application_Form_SmartPlaylistCriteria extends Zend_Form_SubForm
|
|||
$criteriaModifers->setValue('Select modifier');
|
||||
$criteriaModifers->setAttrib('class', 'input_select');
|
||||
$criteriaModifers->setDecorators(array('viewHelper'));
|
||||
$criteriaModifers->setMultiOptions($stringCriteriaOptions);
|
||||
$criteriaModifers->setMultiOptions(array('0' => 'Select modifier'));
|
||||
if ($i != 0){
|
||||
$criteriaModifers->setAttrib('disabled', 'disabled');
|
||||
}
|
||||
|
|
|
@ -45,6 +45,47 @@ class Application_Model_Playlist {
|
|||
"dc:description" => "Description",
|
||||
"dcterms:extent" => "Length"
|
||||
);
|
||||
|
||||
private static $modifier2CriteriaMap = array(
|
||||
"contains" => Criteria::LIKE,
|
||||
"does not contain" => Criteria::NOT_LIKE,
|
||||
"is" => Criteria::EQUAL,
|
||||
"is not" => Criteria::NOT_EQUAL,
|
||||
"starts with" => Criteria::LIKE,
|
||||
"ends with" => Criteria::LIKE,
|
||||
"is greater than" => Criteria::GREATER_THAN,
|
||||
"is less than" => Criteria::LESS_THAN,
|
||||
"is in the range" => Criteria::CUSTOM);
|
||||
|
||||
private static $criteria2PeerMap = array(
|
||||
0 => "Select criteria",
|
||||
"album_title" => CcFilesPeer::ALBUM_TITLE,
|
||||
"artist_name" => CcFilesPeer::ARTIST_NAME,
|
||||
"bit_rate" => CcFilesPeer::BIT_RATE,
|
||||
"bpm" => CcFilesPeer::BPM,
|
||||
"comments" => CcFilesPeer::COMMENTS,
|
||||
"composer" => CcFilesPeer::COMPOSER,
|
||||
"conductor" => CcFilesPeer::CONDUCTOR,
|
||||
"utime" => CcFilesPeer::UTIME,
|
||||
"mtime" => CcFilesPeer::MTIME,
|
||||
"disc_number" => CcFilesPeer::DISC_NUMBER,
|
||||
"genre" => CcFilesPeer::GENRE,
|
||||
"isrc_number" => CcFilesPeer::ISRC_NUMBER,
|
||||
"label" => CcFilesPeer::LABEL,
|
||||
"language" => CcFilesPeer::LANGUAGE,
|
||||
"length" => CcFilesPeer::LENGTH,
|
||||
"lyricist" => CcFilesPeer::LYRICIST,
|
||||
"mood" => CcFilesPeer::MOOD,
|
||||
"name" => CcFilesPeer::NAME,
|
||||
"orchestra" => CcFilesPeer::ORCHESTRA,
|
||||
"radio_station_name" => CcFilesPeer::RADIO_STATION_NAME,
|
||||
"rating" => CcFilesPeer::RATING,
|
||||
"sample_rate" => CcFilesPeer::SAMPLE_RATE,
|
||||
"soundcloud_id" => CcFilesPeer::SOUNDCLOUD_ID,
|
||||
"track_title" => CcFilesPeer::TRACK_TITLE,
|
||||
"track_num" => CcFilesPeer::TRACK_NUMBER,
|
||||
"year" => CcFilesPeer::YEAR
|
||||
);
|
||||
|
||||
|
||||
public function __construct($id=null, $con=null)
|
||||
|
@ -806,6 +847,139 @@ class Application_Model_Playlist {
|
|||
{
|
||||
CcPlaylistQuery::create()->findPKs($p_ids)->delete();
|
||||
}
|
||||
|
||||
|
||||
// smart playlist functions start
|
||||
/**
|
||||
* Saves smart playlist criteria
|
||||
* @param array $p_criteria
|
||||
*/
|
||||
public static function saveSmartPlaylistCriteria($p_criteria)
|
||||
{
|
||||
$data = self::organizeSmartPlyalistCriteria($p_criteria);
|
||||
// things we need to check
|
||||
// 1. limit value shouldn't be empty and has upperbound of 24 hrs
|
||||
// 2. sp_criteria or sp_criteria_modifier shouldn't be 0
|
||||
$multiplier = 1;
|
||||
$result = 0;
|
||||
$errors = array();
|
||||
if ($data['etc']['sp_limit_options'] == 'hours') {
|
||||
$multiplier = 60;
|
||||
}
|
||||
if ($data['etc']['sp_limit_options'] == 'hours' || $data['etc']['sp_limit_options'] == 'mins') {
|
||||
if ( $data['etc']['sp_limit_value'] == "" || intval($data['etc']['sp_limit_value']) == 0) {
|
||||
$error[] = "Litmit cannot be empty or 0";
|
||||
} else {
|
||||
$mins = $data['etc']['sp_limit_value'] * $multiplier;
|
||||
if ($mins > 14400) {
|
||||
$error[] = "Litmit cannot be more than 24 hrs";
|
||||
}
|
||||
}
|
||||
$errors[] = array("element"=>"sp_limit_value", "msg"=>$error);
|
||||
}
|
||||
|
||||
// format validation
|
||||
foreach ($data['criteria'] as $key=>$d){
|
||||
$error = array();
|
||||
// check for not selected select box
|
||||
if ($d['sp_criteria'] == "0" || $d['sp_criteria_modifier'] == "0"){
|
||||
$error[] = "You must select Criteria and Modifier";
|
||||
} else {
|
||||
// we need to take care 'length' specially since the column type is varchar
|
||||
if ($d['sp_criteria'] == 'length') {
|
||||
if (!preg_match("/(\d{2}):(\d{2}):(\d{2})/", $d['sp_criteria_value'])) {
|
||||
$error[] = "'Length' should be in '00:00:00' format";
|
||||
}
|
||||
}else{
|
||||
if (CcFilesPeer::getTableMap()->getColumn(self::$criteria2PeerMap[$d['sp_criteria']])->getType() == PropelColumnTypes::TIMESTAMP) {
|
||||
if (!preg_match("/(\d{4})-(\d{2})-(\d{2})/", $d['sp_criteria_value'])) {
|
||||
$error[] = "The value should be in timestamp format(eg. 0000-00-00 or 00-00-00 00:00:00";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($d['sp_criteria_value'] == "") {
|
||||
$error[] = "Value cannot be empty";
|
||||
}
|
||||
|
||||
$errors[] = array("element"=>"sp_criteria_".$key, "msg"=>$error);
|
||||
}
|
||||
$result = count($errors) > 0 ? 1 :0;
|
||||
return array("result"=>$result, "errors"=>$errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get smart playlist criteria
|
||||
* @param array $p_playlistId
|
||||
*/
|
||||
public static function getSmartPlaylistCriteria($p_playlistId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* generate list of tracks. This function saves creiteria and generate
|
||||
* tracks.
|
||||
* @param array $p_criteria
|
||||
*/
|
||||
public static function generateSmartPlaylist($p_criteria)
|
||||
{
|
||||
$result = self::saveSmartPlaylistCriteria($p_criteria);
|
||||
if ($result['result'] != 0) {
|
||||
return $result;
|
||||
}else{
|
||||
Logging::log($p_criteria);
|
||||
$data = self::organizeSmartPlyalistCriteria($p_criteria);
|
||||
$list = self::getListofFilesMeetCriteria($data['criteria']);
|
||||
}
|
||||
}
|
||||
|
||||
// this function return list of propel object
|
||||
private static function getListofFilesMeetCriteria($p_data)
|
||||
{
|
||||
$c = new Criteria();
|
||||
|
||||
foreach ($p_data as $criteria) {
|
||||
$spCriteria = self::$criteria2PeerMap[$criteria['sp_criteria']];
|
||||
$spCriteriaModifier = $criteria['sp_criteria_modifier'];
|
||||
$spCriteriaValue = $criteria['sp_criteria_value'];
|
||||
if ($spCriteriaModifier == "starts with") {
|
||||
$spCriteriaValue = "$spCriteriaValue%";
|
||||
} else if ($spCriteriaModifier == "ends with") {
|
||||
$spCriteriaValue = "%$spCriteriaValue";
|
||||
} else if ($spCriteriaModifier == "is in the range") {
|
||||
$spCriteriaValue = "$spCriteria > '$spCriteriaValue' AND $spCriteria < '$criteria[sp_criteria_extra]'";
|
||||
}
|
||||
$spCriteriaModifier = self::$modifier2CriteriaMap[$spCriteriaModifier];
|
||||
$c->add($spCriteria, $spCriteriaValue, $spCriteriaModifier);
|
||||
}
|
||||
try{
|
||||
$out = CcFilesPeer::doSelect($c);
|
||||
}catch(Exception $e){
|
||||
//Logging::log($e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static function organizeSmartPlyalistCriteria($p_criteria)
|
||||
{
|
||||
$fieldNames = array('sp_criteria', 'sp_criteria_modifier', 'sp_criteria_value', 'sp_criteria_extra');
|
||||
$output = array();
|
||||
foreach ($p_criteria as $ele) {
|
||||
$index = strrpos($ele['name'], '_');
|
||||
$fieldName = substr($ele['name'], 0, $index);
|
||||
if (in_array($fieldName, $fieldNames)) {
|
||||
$rowNum = intval(substr($ele['name'], $index+1));
|
||||
$output['criteria'][$rowNum][$fieldName] = trim($ele['value']);
|
||||
}else{
|
||||
$output['etc'][$ele['name']] = $ele['value'];
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
// smart playlist functions end
|
||||
|
||||
} // class Playlist
|
||||
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
<?php echo $this->element->getElement('sp_criteria_modifier_'.$i) ?>
|
||||
<?php echo $this->element->getElement('sp_criteria_value_'.$i) ?>
|
||||
<?php if ($i != 0) { ?>
|
||||
<a href='#' id='criteria_remove_<?php echo $i ?>'>Remove</a>
|
||||
<a href='#' id='criteria_remove_<?php echo $i ?>'>Remove </a>
|
||||
<?php } else { ?>
|
||||
<a href='#' id='criteria_add'>Add</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<a href='#' id='criteria_add'>Add</a>
|
||||
|
||||
</dd>
|
||||
|
||||
<dd id='sp_limit-element'>
|
||||
|
|
|
@ -3,34 +3,77 @@ $(document).ready(function() {
|
|||
});
|
||||
|
||||
function setSmartPlaylistEvents() {
|
||||
var form = $('#smart-playlist-form');
|
||||
var form = $('#smart-playlist-form');
|
||||
|
||||
form.find('a[id="criteria_add"]').click(function(){
|
||||
var div = $('dd[id="sp_criteria-element"]').children('div:visible:last').next();
|
||||
|
||||
form.find('a[id="criteria_add"]').click(function(){
|
||||
var div = $('dd[id="sp_criteria-element"]').children('div:visible:last').next(),
|
||||
add_button = $(this);
|
||||
|
||||
div.show();
|
||||
div.find('a[id^="criteria_remove"]').after(add_button);
|
||||
div.children().removeAttr('disabled');
|
||||
div = div.next();
|
||||
if(div.length === 0) {
|
||||
if (div.length === 0) {
|
||||
$(this).hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
form.find('a[id^="criteria_remove"]').click(function(){
|
||||
form.find('a[id^="criteria_remove"]').click(function(){
|
||||
var curr = $(this).parent();
|
||||
var curr_pos = curr.index();
|
||||
var list = curr.parent();
|
||||
var list_length = list.find("div:visible").length;
|
||||
var count = list_length - curr_pos;
|
||||
var next = curr.next();
|
||||
|
||||
for(var i=0; i<=count; i++) {
|
||||
var add_button = form.find('a[id="criteria_add"]');
|
||||
|
||||
/* assign next row to current row for all rows below and including
|
||||
* the row getting removed
|
||||
*/
|
||||
for (var i=0; i<=count; i++) {
|
||||
var criteria = next.find('[name^="sp_criteria"]').val();
|
||||
curr.find('[name^="sp_criteria"]').val(criteria);
|
||||
var modifier = next.find('[name^="sp_criteria_modifier"]').val();
|
||||
curr.find('[name^="sp_criteria_modifier"]').val(modifier);
|
||||
var criteria_value = next.find('[name^="sp_criteria_value"]').val();
|
||||
curr.find('[name^="sp_criteria_value"]').val(criteria_value);
|
||||
|
||||
/* if current and next row have the extra criteria value
|
||||
* (for 'is in the range' modifier), then assign the next
|
||||
* extra value to current and remove that element from
|
||||
* next row
|
||||
*/
|
||||
if (curr.find('[name^="sp_criteria_extra"]').length > 0
|
||||
&& next.find('[name^="sp_criteria_extra"]').length > 0) {
|
||||
|
||||
var criteria_extra = next.find('[name^="sp_criteria_extra"]').val();
|
||||
curr.find('[name^="sp_criteria_extra"]').val(criteria_extra);
|
||||
next.find('[name^="sp_criteria_extra"]').remove();
|
||||
next.find('span[id="sp_criteria_extra_label"]').remove();
|
||||
|
||||
/* if only the current row has the extra criteria value,
|
||||
* then just remove the current row's extra criteria element
|
||||
*/
|
||||
} else if (curr.find('[name^="sp_criteria_extra"]').length > 0
|
||||
&& next.find('[name^="sp_criteria_extra"]').length == 0) {
|
||||
curr.find('[name^="sp_criteria_extra"]').remove();
|
||||
curr.find('span[id="sp_criteria_extra_label"]').remove();
|
||||
|
||||
/* if only the next row has the extra criteria value,
|
||||
* then add the extra criteria element to current row
|
||||
* and assign next row's value to it
|
||||
*/
|
||||
} else if (next.find('[name^="sp_criteria_extra"]').length > 0) {
|
||||
var index_name = curr.find('[name^="sp_criteria_value"]').attr('id'),
|
||||
index_num = index_name.charAt(index_name.length-1),
|
||||
criteria_extra = next.find('[name^="sp_criteria_extra"]').val();
|
||||
|
||||
curr.find('[name^="sp_criteria_value"]')
|
||||
.after($('<input type="text" class="input_text">')
|
||||
.attr('id', 'sp_criteria_extra_'+index_num)
|
||||
.attr('name', 'sp_criteria_extra_'+index_num)).after('<span id="sp_criteria_extra_label"> to </span>');
|
||||
curr.find('[name^="sp_criteria_extra"]').val(criteria_extra);
|
||||
}
|
||||
|
||||
curr = next;
|
||||
next = curr.next();
|
||||
|
@ -44,6 +87,13 @@ function setSmartPlaylistEvents() {
|
|||
.end().hide();
|
||||
|
||||
list.next().show();
|
||||
|
||||
// always put 'add' button on the last row
|
||||
if (list.find('div:visible').length > 1) {
|
||||
list.find('div:visible:last').find('a[id^="criteria_remove"]').after(add_button);
|
||||
} else {
|
||||
list.find('div:visible:last').find('[name^="sp_criteria_value"]').after(add_button);
|
||||
}
|
||||
});
|
||||
|
||||
form.find('button[id="save_button"]').click(function(event){
|
||||
|
@ -74,6 +124,40 @@ function setSmartPlaylistEvents() {
|
|||
}
|
||||
$('button[id="save_button"]').text(button_text);
|
||||
});
|
||||
|
||||
form.find('select[id^="sp_criteria"]').change(function(){
|
||||
var criteria = $(this).val(),
|
||||
criteria_type = criteriaTypes[criteria],
|
||||
div = $(this);
|
||||
$(this).next().children().remove();
|
||||
|
||||
if (criteria_type == 's') {
|
||||
$.each(stringCriteriaOptions, function(key, value){
|
||||
div.next().append($('<option></option>')
|
||||
.attr('value', key)
|
||||
.text(value));
|
||||
});
|
||||
} else {
|
||||
$.each(numericCriteriaOptions, function(key, value){
|
||||
div.next().append($('<option></option>')
|
||||
.attr('value', key)
|
||||
.text(value));
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
form.find('select[id^="sp_criteria_modifier"]').change(function(){
|
||||
if ($(this).val() == 'is in the range') {
|
||||
var criteria_value = $(this).next(),
|
||||
index_name = criteria_value.attr('id'),
|
||||
index_num = index_name.charAt(index_name.length-1);
|
||||
|
||||
criteria_value.after($('<input type="text" class="input_text">')
|
||||
.attr('id', 'sp_criteria_extra_'+index_num)
|
||||
.attr('name', 'sp_criteria_extra_'+index_num)).after('<span id="sp_criteria_extra_label"> to </span>');
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
@ -84,3 +168,52 @@ function staticCallback() {
|
|||
function dynamicCallback() {
|
||||
|
||||
}
|
||||
|
||||
var criteriaTypes = {
|
||||
0 : "",
|
||||
"album_title" : "s",
|
||||
"artist_name" : "s",
|
||||
"bit_rate" : "n",
|
||||
"bmp" : "n",
|
||||
"comments" : "s",
|
||||
"composer" : "s",
|
||||
"conductor" : "s",
|
||||
"utime" : "n",
|
||||
"mtime" : "n",
|
||||
"disc_number" : "n",
|
||||
"genre" : "s",
|
||||
"isrc_number" : "s",
|
||||
"label" : "s",
|
||||
"language" : "s",
|
||||
"length" : "n",
|
||||
"lyricist" : "s",
|
||||
"mood" : "s",
|
||||
"name" : "s",
|
||||
"orchestra" : "s",
|
||||
"radio_station_name" : "s",
|
||||
"rating" : "n",
|
||||
"sample_rate" : "n",
|
||||
"soundcloud_id" : "n",
|
||||
"track_title" : "s",
|
||||
"track_num" : "n",
|
||||
"year" : "n"
|
||||
};
|
||||
|
||||
var stringCriteriaOptions = {
|
||||
"0" : "Select modifier",
|
||||
"contains" : "contains",
|
||||
"does not contain" : "does not contain",
|
||||
"is" : "is",
|
||||
"is not" : "is not",
|
||||
"starts with" : "starts with",
|
||||
"ends with" : "ends with"
|
||||
};
|
||||
|
||||
var numericCriteriaOptions = {
|
||||
"0" : "Select modifier",
|
||||
"is" : "is",
|
||||
"is not" : "is not",
|
||||
"is greater than" : "is greater than",
|
||||
"is less than" : "is less than",
|
||||
"is in the range" : "is in the range"
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue