Merge branch 'devel' of dev.sourcefabric.org:airtime into devel

This commit is contained in:
Martin Konecny 2012-08-17 15:08:10 -04:00
commit 99437147dc
11 changed files with 133 additions and 38 deletions

View File

@ -484,16 +484,10 @@ class ApiController extends Zend_Controller_Action
if (is_null($file)) {
$file = Application_Model_StoredFile::Insert($md);
} else {
// path already exist
if ($file->getFileExistsFlag()) {
// file marked as exists
$return_hash['error'] = "File already exists in Airtime.";
return $return_hash;
} else {
// file marked as not exists
$file->setFileExistsFlag(true);
$file->setMetadata($md);
}
// If the file already exists we will update and make sure that
// it's marked as 'exists'.
$file->setFileExistsFlag(true);
$file->setMetadata($md);
}
}
else if ($mode == "modify") {

View File

@ -311,11 +311,25 @@ var AIRTIME = (function(AIRTIME){
}
function setFadeIcon(){
var contents = $("#spl_sortable");
var show = contents.is(":visible");
var empty = $(".spl_empty");
if (empty.length > 0) {
if (!show || empty.length > 0) {
$("#spl_crossfade").hide();
} else {
$("#spl_crossfade").show();
//get list of playlist contents
var list = contents.children();
//if first and last items are blocks, hide the fade icon
var first = list.first();
var last = list.last();
if (first.find(':first-child').children().attr('blockid') !== undefined &&
last.find(':first-child').children().attr('blockid') !== undefined) {
$("#spl_crossfade").hide();
} else {
$("#spl_crossfade").show();
}
}
}
@ -468,7 +482,9 @@ var AIRTIME = (function(AIRTIME){
fadeOut.show();
fadeOut.empty().append(json.fadeOut);
}
$pl.find("#crossfade_main").show();
if (json.fadeIn != null || json.fadeOut != null) {
$pl.find("#crossfade_main").show();
}
}
});
}
@ -889,6 +905,7 @@ var AIRTIME = (function(AIRTIME){
setPlaylistEntryEvents();
setCueEvents();
setFadeEvents();
setFadeIcon();
initialEvents();
setUpPlaylist();

View File

@ -239,16 +239,6 @@ function getRowIndex(ele) {
return index;
}
function setFadeIcon(){
var contents = $("#spl_sortable");
var show = contents.is(":visible");
if (show) {
$("#spl_crossfade").show();
} else {
$("#spl_crossfade").hide();
}
}
/* This function appends a '+' button for the last
* modifier row of each criteria.
* If there are no modifier rows, the '+' button

View File

@ -29,6 +29,7 @@ class EventContractor(Loggable):
some other event in the storage was morphed into this newer one.
Which should mean that the old event should be discarded.
"""
self.logger.info("Attempting to register: '%s'" % str(evt))
if self.event_registered(evt):
old_e = self.get_old_event(evt)
# TODO : Perhaps there are other events that we can "contract"
@ -42,11 +43,20 @@ class EventContractor(Loggable):
elif isinstance(evt, DeleteFile):
old_e.morph_into(evt)
return False
# Unregister the old event anyway, because we only want to keep
# track of the old one. This means that the old event cannot be
# morphed again and new events with the same path will only be
# checked against the newest event 'evt' in this case
self.unregister( old_e )
evt.add_safe_pack_hook( lambda : self.__unregister(evt) )
self.store[ evt.path ] = evt
return True # We actually added something, hence we return true.
def unregister(self, evt):
evt.reset_hook()
def __unregister(self, evt):
self.logger.info("Unregistering. Left: '%d'" % len(self.store.keys()))
try: del self.store[evt.path]
except Exception as e: self.unexpected_exception(e)
except Exception as e:
self.unexpected_exception(e)
self.logger.info("Unregistering. Left: '%d'" % len(self.store.keys()))

View File

@ -10,7 +10,7 @@ from media.monitor.exceptions import BadSongFile
class PathChannel(object):
def __init__(self, signal, path):
self.signal = signal
self.path = path
self.path = path
class EventRegistry(object):
"""
@ -59,6 +59,10 @@ class BaseEvent(Loggable):
self._pack_hook = lambda: None # no op
# into another event
def reset_hook(self):
self._pack_hook()
self._pack_hook = lambda: None
def exists(self): return os.path.exists(self.path)
@LazyProperty
@ -84,8 +88,8 @@ class BaseEvent(Loggable):
# pack will only throw an exception if it processes one file but this
# is a little bit hacky
try:
ret = self.pack()
self._pack_hook()
ret = self.pack()
return ret
except BadSongFile as e: return [e]
@ -95,7 +99,7 @@ class BaseEvent(Loggable):
self._raw_event = evt
self.path = evt.path
self.__class__ = evt.__class__
self.add_safe_pack_hook(evt._pack_hook)
# We don't transfer the _pack_hook over to the new event
return self
class FakePyinotify(object):
@ -104,8 +108,7 @@ class FakePyinotify(object):
instantiate objects from the classes below whenever we want to turn
a single event into multiple events
"""
def __init__(self, path):
self.pathname = path
def __init__(self, path): self.pathname = path
class OrganizeFile(BaseEvent, HasMetaData):
def __init__(self, *args, **kwargs):

View File

@ -88,7 +88,7 @@ class OrganizeListener(BaseListener, pyinotify.ProcessEvent, Loggable):
dispatcher.send(signal=self.signal, sender=self,
event=OrganizeFile(f))
flushed += 1
self.logger.info("Flushed organized directory with %d files" % flushed)
#self.logger.info("Flushed organized directory with %d files" % flushed)
@IncludeOnly(mmp.supported_extensions)
def process_to_organize(self, event):

View File

@ -20,7 +20,7 @@ class ManagerTimeout(threading.Thread,Loggable):
while True:
time.sleep(3)
self.manager.flush_organize()
self.logger.info("Force flushed organize...")
#self.logger.info("Force flushed organize...")
class Manager(Loggable):
"""

View File

@ -19,9 +19,9 @@ class RequestSync(threading.Thread,Loggable):
"""
def __init__(self, watcher, requests):
threading.Thread.__init__(self)
self.watcher = watcher
self.requests = requests
self.retries = 1
self.watcher = watcher
self.requests = requests
self.retries = 1
self.request_wait = 0.3
@LazyProperty
@ -124,9 +124,8 @@ class WatchSyncer(ReportHandler,Loggable):
try:
# If there is a strange bug anywhere in the code the next line
# should be a suspect
#if self.contractor.register( event ):
#self.push_queue( event )
self.push_queue( event )
if self.contractor.register(event): self.push_queue( event )
#self.push_queue( event )
except BadSongFile as e:
self.fatal_exception("Received bas song file '%s'" % e.path, e)
except Exception as e:

View File

@ -0,0 +1,70 @@
import unittest
from media.monitor.eventcontractor import EventContractor
#from media.monitor.exceptions import BadSongFile
from media.monitor.events import FakePyinotify, NewFile, MoveFile, \
DeleteFile
from mock import patch
class TestMMP(unittest.TestCase):
def test_event_registered(self):
ev = EventContractor()
e1 = NewFile( FakePyinotify('bullshit.mp3') )
e2 = MoveFile( FakePyinotify('bullshit.mp3') )
ev.register(e1)
self.assertTrue( ev.event_registered(e2) )
def test_get_old_event(self):
ev = EventContractor()
e1 = NewFile( FakePyinotify('bullshit.mp3') )
e2 = MoveFile( FakePyinotify('bullshit.mp3') )
ev.register(e1)
self.assertEqual( ev.get_old_event(e2), e1 )
def test_register(self):
ev = EventContractor()
e1 = NewFile( FakePyinotify('bullshit.mp3') )
e2 = DeleteFile( FakePyinotify('bullshit.mp3') )
self.assertTrue( ev.register(e1) )
# Check that morph_into is called when it should be
with patch.object(NewFile, 'morph_into', return_value='kimchi') \
as mock_method:
ret = ev.register(e2)
self.assertFalse(ret)
mock_method.assert_called_once_with(e2)
# This time we are not patching morph
self.assertFalse( ev.register(e2) )
# We did not an element
self.assertTrue( len(ev.store.keys()) == 1 )
morphed = ev.get_old_event(e2)
self.assertTrue( isinstance(morphed, DeleteFile) )
delete_ev = e1.safe_pack()[0]
print( ev.store )
self.assertEqual( delete_ev['mode'], u'delete')
self.assertTrue( len(ev.store.keys()) == 0 )
e3 = DeleteFile( FakePyinotify('horseshit.mp3') )
self.assertTrue( ev.register(e3) )
self.assertTrue( ev.register(e2) )
def test_register2(self):
ev = EventContractor()
p = 'bullshit.mp3'
events = [
NewFile( FakePyinotify(p) ),
NewFile( FakePyinotify(p) ),
DeleteFile( FakePyinotify(p) ),
NewFile( FakePyinotify(p) ),
NewFile( FakePyinotify(p) ), ]
actual_events = []
for e in events:
if ev.register(e):
actual_events.append(e)
self.assertEqual( len(ev.store.keys()), 1 )
packed = [ x.safe_pack() for x in actual_events ]
print(packed)
if __name__ == '__main__': unittest.main()

View File

@ -0,0 +1,12 @@
argparse==1.2.1
amqplib==1.0.2
PyDispatcher==2.0.3
anyjson==0.3.3
kombu==2.2.6
pyinotify==0.9.3
poster==0.8.1
pytz==2011k
wsgiref==0.1.2
configobj==4.7.2
mutagen==1.20
docopt==0.4.2