Merge branch 'devel' of dev.sourcefabric.org:airtime into devel
This commit is contained in:
commit
dc2b4fed0a
|
@ -32,6 +32,7 @@ class ScheduleController extends Zend_Controller_Action
|
|||
->addActionContext('edit-show-instance', 'json')
|
||||
->addActionContext('dj-edit-show', 'json')
|
||||
->addActionContext('calculate-duration', 'json')
|
||||
->addActionContext('get-current-show', 'json')
|
||||
->initContext();
|
||||
|
||||
$this->sched_sess = new Zend_Session_Namespace("schedule");
|
||||
|
@ -116,6 +117,16 @@ class ScheduleController extends Zend_Controller_Action
|
|||
|
||||
$this->view->events = Application_Model_Show::getFullCalendarEvents($start, $end, $editable);
|
||||
}
|
||||
|
||||
public function getCurrentShowAction() {
|
||||
$currentShow = Application_Model_Show::GetCurrentShow();
|
||||
if (!empty($currentShow)) {
|
||||
$this->view->si_id = $currentShow[0]["instance_id"];
|
||||
$this->view->current_show = true;
|
||||
} else {
|
||||
$this->view->current_show = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function moveShowAction()
|
||||
{
|
||||
|
|
|
@ -86,6 +86,9 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm
|
|||
public function checkReliantFields($formData, $validateStartDate, $originalStartDate=null, $update=false, $instanceId=null) {
|
||||
$valid = true;
|
||||
|
||||
$hours;
|
||||
$minutes;
|
||||
|
||||
$start_time = $formData['add_show_start_date']." ".$formData['add_show_start_time'];
|
||||
$end_time = $formData['add_show_end_date_no_repeat']." ".$formData['add_show_end_time'];
|
||||
|
||||
|
@ -147,11 +150,113 @@ class Application_Form_AddShowWhen extends Zend_Form_SubForm
|
|||
$show_start->setTimezone(new DateTimeZone('UTC'));
|
||||
$show_end = new DateTime($end_time);
|
||||
$show_end->setTimezone(new DateTimeZone('UTC'));
|
||||
|
||||
$overlapping = Application_Model_Schedule::checkOverlappingShows($show_start, $show_end, $update, $instanceId);
|
||||
if ($overlapping) {
|
||||
$this->getElement('add_show_duration')->setErrors(array('Cannot schedule overlapping shows'));
|
||||
$valid = false;
|
||||
|
||||
if ($formData["add_show_repeats"]) {
|
||||
|
||||
//get repeating show end date
|
||||
if ($formData["add_show_no_end"]) {
|
||||
$date = Application_Model_Preference::GetShowsPopulatedUntil();
|
||||
|
||||
if (is_null($date)) {
|
||||
$populateUntilDateTime = new DateTime("now", new DateTimeZone('UTC'));
|
||||
Application_Model_Preference::SetShowsPopulatedUntil($populateUntilDateTime);
|
||||
} else {
|
||||
$populateUntilDateTime = clone $date;
|
||||
}
|
||||
|
||||
} elseif (!$formData["add_show_no_end"]) {
|
||||
$popUntil = $formData["add_show_end_date"]." ".$formData["add_show_end_time"];
|
||||
$populateUntilDateTime = new DateTime($popUntil, new DateTimeZone('UTC'));
|
||||
}
|
||||
|
||||
//get repeat interval
|
||||
if ($formData["add_show_repeat_type"] == 0) {
|
||||
$interval = 'P7D';
|
||||
} elseif ($formData["add_show_repeat_type"] == 1) {
|
||||
$interval = 'P14D';
|
||||
} elseif ($formData["add_show_repeat_type"] == 2) {
|
||||
$interval = 'P1M';
|
||||
}
|
||||
|
||||
/* Check first show
|
||||
* Continue if the first show does not overlap
|
||||
*/
|
||||
$overlapping = Application_Model_Schedule::checkOverlappingShows($show_start, $show_end, $update, $instanceId);
|
||||
|
||||
/* Check if repeats overlap with previously scheduled shows
|
||||
* Do this for each show day
|
||||
*/
|
||||
if (!$overlapping) {
|
||||
$startDow = date("w", $show_start->getTimestamp());
|
||||
foreach($formData["add_show_day_check"] as $day) {
|
||||
$repeatShowStart = clone $show_start;
|
||||
$repeatShowEnd = clone $show_end;
|
||||
$daysAdd=0;
|
||||
if ($startDow !== $day){
|
||||
if ($startDow > $day)
|
||||
$daysAdd = 6 - $startDow + 1 + $day;
|
||||
else
|
||||
$daysAdd = $day - $startDow;
|
||||
|
||||
$repeatShowStart->add(new DateInterval("P".$daysAdd."D"));
|
||||
$repeatShowEnd->add(new DateInterval("P".$daysAdd."D"));
|
||||
}
|
||||
while ($repeatShowStart->getTimestamp() < $populateUntilDateTime->getTimestamp()) {
|
||||
$overlapping = Application_Model_Schedule::checkOverlappingShows($repeatShowStart, $repeatShowEnd, $update, $instanceId);
|
||||
if ($overlapping) {
|
||||
$valid = false;
|
||||
$this->getElement('add_show_duration')->setErrors(array('Cannot schedule overlapping shows'));
|
||||
break 1;
|
||||
} else {
|
||||
$repeatShowStart->add(new DateInterval($interval));
|
||||
$repeatShowEnd->add(new DateInterval($interval));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$valid = false;
|
||||
$this->getElement('add_show_duration')->setErrors(array('Cannot schedule overlapping shows'));
|
||||
}
|
||||
} elseif ($formData["add_show_rebroadcast"]) {
|
||||
/* Check first show
|
||||
* Continue if the first show does not overlap
|
||||
*/
|
||||
$overlapping = Application_Model_Schedule::checkOverlappingShows($show_start, $show_end, $update, $instanceId);
|
||||
|
||||
if (!$overlapping) {
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$hours = ltrim($hours, '0');
|
||||
if ($minutes != "00") {
|
||||
$minutes = ltrim($minutes, '0');
|
||||
$durationToAdd = "PT".$hours."H".$minutes."I";
|
||||
} else {
|
||||
$minutes = "0";
|
||||
$durationToAdd = "PT".$hours."H";
|
||||
}
|
||||
|
||||
$abs_rebroadcast_start = $formData["add_show_rebroadcast_date_absolute_".$i]." ".
|
||||
$formData["add_show_rebroadcast_time_absolute_".$i];
|
||||
$rebroadcastShowStart = new DateTime($abs_rebroadcast_start);
|
||||
$rebroadcastShowStart->setTimezone(new DateTimeZone('UTC'));
|
||||
$rebroadcastShowEnd = clone $rebroadcastShowStart;
|
||||
$rebroadcastShowEnd->add(new DateInterval($durationToAdd));
|
||||
$overlapping = Application_Model_Schedule::checkOverlappingShows($rebroadcastShowStart, $rebroadcastShowEnd, $update, $instanceId);
|
||||
if ($overlapping) {
|
||||
$valid = false;
|
||||
$this->getElement('add_show_duration')->setErrors(array('Cannot schedule overlapping shows'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$valid = false;
|
||||
$this->getElement('add_show_duration')->setErrors(array('Cannot schedule overlapping shows'));
|
||||
}
|
||||
} else {
|
||||
$overlapping = Application_Model_Schedule::checkOverlappingShows($show_start, $show_end, $update, $instanceId);
|
||||
if ($overlapping) {
|
||||
$this->getElement('add_show_duration')->setErrors(array('Cannot schedule overlapping shows'));
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1351,6 +1351,7 @@ class Application_Model_Show {
|
|||
}
|
||||
|
||||
private static function advanceRepeatingDate($p_interval, $start, $timezone){
|
||||
$startDt = new DateTime($start, new DateTimeZone($timezone));
|
||||
if ($p_interval == 'P1M'){
|
||||
/* When adding months, there is a problem if we are on January 31st and add one month with PHP.
|
||||
* What ends up happening is that since February 31st doesn't exist, the date returned is
|
||||
|
|
|
@ -1734,6 +1734,10 @@ div.errors{
|
|||
background:url(images/icon_soundcloud_error2.png) no-repeat 0 0;
|
||||
width:21px;
|
||||
}
|
||||
.small-icon.now-playing {
|
||||
background:url(images/icon_nowplaying_n.png) no-repeat 0 0;
|
||||
height:8px;
|
||||
}
|
||||
.small-icon.progress {
|
||||
background:url(images/upload-icon.gif) no-repeat;
|
||||
background-color:black;
|
||||
|
|
|
@ -147,7 +147,8 @@ function dayClick(date, allDay, jsEvent, view){
|
|||
}
|
||||
|
||||
function viewDisplay( view ) {
|
||||
|
||||
view_name = view.name;
|
||||
|
||||
if(view.name === 'agendaDay' || view.name === 'agendaWeek') {
|
||||
|
||||
var calendarEl = this;
|
||||
|
@ -205,7 +206,8 @@ function viewDisplay( view ) {
|
|||
}
|
||||
|
||||
function eventRender(event, element, view) {
|
||||
|
||||
getCurrentShow();
|
||||
|
||||
$(element).data("event", event);
|
||||
|
||||
//only put progress bar on shows that aren't being recorded.
|
||||
|
@ -223,6 +225,13 @@ function eventRender(event, element, view) {
|
|||
|
||||
$(element).find(".fc-event-content").append(div);
|
||||
}
|
||||
|
||||
//need to add id for every event to find the current show
|
||||
if (view.name === 'agendaDay' || view.name === 'agendaWeek') {
|
||||
$(element).find(".fc-event-time").attr("id", event.id);
|
||||
} else if (view.name === 'month') {
|
||||
$(element).find(".fc-event-title").attr("id", event.id);
|
||||
}
|
||||
|
||||
//add the record/rebroadcast/soundcloud icons if needed
|
||||
if((view.name === 'agendaDay' || view.name === 'agendaWeek') && event.record === 1 && event.soundcloud_id === -1) {
|
||||
|
@ -247,11 +256,10 @@ function eventRender(event, element, view) {
|
|||
|
||||
//rebroadcast icon
|
||||
if((view.name === 'agendaDay' || view.name === 'agendaWeek') && event.rebroadcast === 1) {
|
||||
|
||||
$(element).find(".fc-event-time").before('<span id="'+event.id+'" class="small-icon rebroadcast"></span>');
|
||||
}
|
||||
|
||||
if(view.name === 'month' && event.rebroadcast === 1) {
|
||||
|
||||
$(element).find(".fc-event-title").after('<span id="'+event.id+'" class="small-icon rebroadcast"></span>');
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +318,7 @@ function getFullCalendarEvents(start, end, callback) {
|
|||
url = '/Schedule/event-feed';
|
||||
|
||||
var d = new Date();
|
||||
|
||||
|
||||
$.post(url, {format: "json", start: start_date, end: end_date, cachep: d.getTime()}, function(json){
|
||||
callback(json.events);
|
||||
});
|
||||
|
@ -330,6 +338,55 @@ function checkSCUploadStatus(){
|
|||
});
|
||||
}
|
||||
|
||||
function getCurrentShow(){
|
||||
var url = '/Schedule/get-current-show/format/json',
|
||||
id,
|
||||
$el;
|
||||
$.post(url, {format: "json"}, function(json) {
|
||||
if (json.current_show === true) {
|
||||
$el = $("div[class*=fc-event-time][id="+json.si_id+"]");
|
||||
if (view_name === 'agendaDay' || view_name === 'agendaWeek') {
|
||||
|
||||
/* Need to remove now-playing class because if user
|
||||
* is switching from week view to day view (and vice versa)
|
||||
* the icon may already be there from previous view
|
||||
*/
|
||||
$el.siblings().remove("span[class=small-icon now-playing]");
|
||||
if (!$el.siblings().hasClass("small-icon now-playing")) {
|
||||
if ($el.siblings().hasClass("small-icon recording")) {
|
||||
|
||||
/* Without removing recording icon, the now playing
|
||||
* icon will overwrite it.
|
||||
*/
|
||||
$el.siblings().remove("span[class=small-icon recording]");
|
||||
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span><span id="'+json.si_id+'" class="small-icon recording"></span>');
|
||||
} else if ($el.siblings().hasClass("small-icon rebroadcast")) {
|
||||
|
||||
/* Without removing rebroadcast icon, the now playing
|
||||
* icon will overwrite it.
|
||||
*/
|
||||
$el.siblings().remove("span[class=small-icon rebroadcast]");
|
||||
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span><span id="'+json.si_id+'" class="small-icon rebroadcast"></span>');
|
||||
} else {
|
||||
$el.before('<span id="'+json.si_id+'" class="small-icon now-playing"></span>');
|
||||
}
|
||||
}
|
||||
} else if (view_name === 'month') {
|
||||
if (!$("span[class*=fc-event-title][id="+json.si_id+"]").siblings().hasClass("small-icon now-playing")) {
|
||||
$("span[class*=fc-event-title][id="+json.si_id+"]").after('<span id="'+json.si_id+'" class="small-icon now-playing"></span>');
|
||||
}
|
||||
}
|
||||
}
|
||||
//remove icon from shows that have ended
|
||||
$(".now-playing").each(function(){
|
||||
id = $(this).attr("id");
|
||||
if (id != json.si_id) {
|
||||
$(this).remove("span[small-icon now-playing]");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addQtipToSCIcons(ele){
|
||||
var id = $(ele).attr("id");
|
||||
if($(ele).hasClass("progress")){
|
||||
|
@ -415,4 +472,7 @@ function alertShowErrorAndReload(){
|
|||
|
||||
$(document).ready(function(){
|
||||
setInterval( "checkSCUploadStatus()", 5000 );
|
||||
setInterval( "getCurrentShow()", 5000 );
|
||||
});
|
||||
|
||||
var view_name;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
[main]
|
||||
liquidsoap_tar_url = http://dl.dropbox.com/u/256410/airtime/liquidsoap.tar.gz
|
||||
liquidsoap_tar_url = http://dl.dropbox.com/u/256410/airtime/liquidsoap-1.0.1-full.tar.gz
|
||||
|
|
|
@ -149,6 +149,14 @@ def ubuntu_oneiric_64(fresh_os=True):
|
|||
if (fresh_os):
|
||||
create_fresh_os('Ubuntu_11.10_64')
|
||||
|
||||
def ubuntu_precise_64(fresh_os=True):
|
||||
if (fresh_os):
|
||||
create_fresh_os('Ubuntu_12.04_64')
|
||||
|
||||
def ubuntu_precise_32(fresh_os=True):
|
||||
if (fresh_os):
|
||||
create_fresh_os('Ubuntu_12.04_32')
|
||||
|
||||
def debian_squeeze_32(fresh_os=True):
|
||||
if (fresh_os):
|
||||
create_fresh_os('Debian_Squeeze_32', debian=True)
|
||||
|
@ -172,7 +180,7 @@ def compile_liquidsoap(filename="liquidsoap"):
|
|||
'libmad-ocaml-dev libtaglib-ocaml-dev libalsa-ocaml-dev libtaglib-ocaml-dev libvorbis-ocaml-dev ' + \
|
||||
'libspeex-dev libspeexdsp-dev speex libladspa-ocaml-dev festival festival-dev ' + \
|
||||
'libsamplerate-dev libxmlplaylist-ocaml-dev libxmlrpc-light-ocaml-dev libflac-dev ' + \
|
||||
'libxml-dom-perl libxml-dom-xpath-perl icecast2 patch autoconf libmp3lame-dev ' + \
|
||||
'libxml-dom-perl libxml-dom-xpath-perl patch autoconf libmp3lame-dev ' + \
|
||||
'libcamomile-ocaml-dev libcamlimages-ocaml-dev libtool libpulse-dev libjack-dev camlidl')
|
||||
|
||||
root = '/home/martin/src'
|
||||
|
@ -183,11 +191,11 @@ def compile_liquidsoap(filename="liquidsoap"):
|
|||
do_run('mv %s %s/liquidsoap.tar.gz' % (tmpPath, root))
|
||||
do_run('cd %s && tar xzf liquidsoap.tar.gz' % root)
|
||||
|
||||
do_run('cd %s/savonet && cp PACKAGES.minimal PACKAGES' % root)
|
||||
sed('%s/savonet/PACKAGES' % root, '#ocaml-portaudio', 'ocaml-portaudio')
|
||||
sed('%s/savonet/PACKAGES' % root, '#ocaml-alsa', 'ocaml-alsa')
|
||||
sed('%s/savonet/PACKAGES' % root, '#ocaml-pulseaudio', 'ocaml-pulseaudio')
|
||||
do_run('cd %s/savonet && ./bootstrap' % root)
|
||||
do_run('cd %s/savonet && ./configure' % root)
|
||||
do_run('cd %s/savonet && make' % root)
|
||||
get('%s/savonet/liquidsoap/src/liquidsoap' % root, filename)
|
||||
do_run('cd %s/liquidsoap-1.0.1-full && cp PACKAGES.minimal PACKAGES' % root)
|
||||
sed('%s/liquidsoap-1.0.1-full/PACKAGES' % root, '#ocaml-portaudio', 'ocaml-portaudio')
|
||||
sed('%s/liquidsoap-1.0.1-full/PACKAGES' % root, '#ocaml-alsa', 'ocaml-alsa')
|
||||
sed('%s/liquidsoap-1.0.1-full/PACKAGES' % root, '#ocaml-pulseaudio', 'ocaml-pulseaudio')
|
||||
do_run('cd %s/liquidsoap-1.0.1-full && ./bootstrap' % root)
|
||||
do_run('cd %s/liquidsoap-1.0.1-full && ./configure' % root)
|
||||
do_run('cd %s/liquidsoap-1.0.1-full && make' % root)
|
||||
get('%s/liquidsoap-1.0.1-full/liquidsoap-1.0.1/src/liquidsoap' % root, filename)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
exec 2>&1
|
||||
|
||||
ubuntu_versions=("ubuntu_lucid_32" "ubuntu_lucid_64" "ubuntu_maverick_32" "ubuntu_maverick_64" "ubuntu_natty_32" "ubuntu_natty_64" "ubuntu_oneiric_32" "ubuntu_oneiric_64" "debian_squeeze_32" "debian_squeeze_64")
|
||||
ubuntu_versions=("ubuntu_lucid_32" "ubuntu_lucid_64" "ubuntu_maverick_32" "ubuntu_maverick_64" "ubuntu_natty_32" "ubuntu_natty_64" "ubuntu_oneiric_32" "ubuntu_oneiric_64" "debian_squeeze_32" "debian_squeeze_64" "ubuntu_precise_32" "ubuntu_precise_64")
|
||||
|
||||
num1=${#ubuntu_versions[@]}
|
||||
|
||||
|
@ -10,6 +10,8 @@ mkdir -p ./upgrade_logs2
|
|||
|
||||
for i in $(seq 0 $(($num1 -1)));
|
||||
do
|
||||
echo "fab -f fab_liquidsoap_compile.py ${ubuntu_versions[$i]} compile_liquidsoap:filename=${ubuntu_versions[$i]} shutdown"
|
||||
fab -f fab_liquidsoap_compile.py ${ubuntu_versions[$i]} compile_liquidsoap:filename=${ubuntu_versions[$i]} shutdown 2>&1 #| tee "./upgrade_logs2/${ubuntu_versions[$i]}.log"
|
||||
|
||||
binfilename=`echo ${ubuntu_versions[$i]} | sed -e 's/ubuntu/liquidsoap/g' -e 's/debian/liquidsoap/g' -e 's/32/i386/g' -e 's/64/amd64/g'`
|
||||
echo "fab -f fab_liquidsoap_compile.py ${ubuntu_versions[$i]} compile_liquidsoap:filename=$binfilename shutdown"
|
||||
fab -f fab_liquidsoap_compile.py ${ubuntu_versions[$i]} compile_liquidsoap:filename=$binfilename shutdown 2>&1 #| tee "./upgrade_logs2/${ubuntu_versions[$i]}.log"
|
||||
done
|
||||
|
|
|
@ -29,7 +29,7 @@ class MediaMonitorCommon:
|
|||
return filter(lambda e: len(e) > 0, [ f.strip(" \n") for f in dirty_files ])
|
||||
|
||||
def find_command(self, directory, extra_arguments=""):
|
||||
""" Builds a find command that respects supported_file_formats list
|
||||
""" Builds a find command that respects supported_file_formats list
|
||||
Note: Use single quotes to quote arguments """
|
||||
ext_globs = [ "-iname '*.%s'" % ext for ext in self.supported_file_formats ]
|
||||
find_glob = ' -o '.join(ext_globs)
|
||||
|
@ -51,7 +51,7 @@ class MediaMonitorCommon:
|
|||
|
||||
def is_audio_file(self, filename):
|
||||
info = filename.split(".")
|
||||
if len(info) < 2: return false # handle cases like filename="mp3"
|
||||
if len(info) < 2: return False # handle cases like filename="mp3"
|
||||
return info[-1].lower() in self.supported_file_formats
|
||||
|
||||
#check if file is readable by "nobody"
|
||||
|
@ -101,7 +101,7 @@ class MediaMonitorCommon:
|
|||
will attempt to make the file world readable by modifying the file's permission's
|
||||
as well as the file's parent directory permissions. We should only call this function
|
||||
on files in Airtime's stor directory, not watched directories!
|
||||
|
||||
|
||||
Returns True if we were able to make the file world readable. False otherwise.
|
||||
"""
|
||||
original_file = pathname
|
||||
|
@ -278,7 +278,7 @@ class MediaMonitorCommon:
|
|||
|
||||
try:
|
||||
"""
|
||||
File name charset encoding is UTF-8.
|
||||
File name charset encoding is UTF-8.
|
||||
"""
|
||||
stdout = stdout.decode("UTF-8")
|
||||
except Exception:
|
||||
|
|
Loading…
Reference in New Issue