Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorAntoine van Gelder <antoine@g7.org.za>2007-10-28 09:45:28 (GMT)
committer Antoine van Gelder <antoine@g7.org.za>2007-10-28 09:45:28 (GMT)
commit800e3caabcd9c85b0b2ae9299217ea31d0309545 (patch)
tree130af075b9cbc72eba462c58166c771739ded092 /util
parent49eb6ebd4760b4bfcf009f7e887a3ef9a547061d (diff)
Initial import
Diffstat (limited to 'util')
-rw-r--r--util/__init__.py0
-rw-r--r--util/audioplayer.py132
-rw-r--r--util/decorators.py64
-rw-r--r--util/journalpickler.py47
-rw-r--r--util/persistence.py81
-rw-r--r--util/persistence.py.args81
-rw-r--r--util/persistence.py.noargs75
7 files changed, 480 insertions, 0 deletions
diff --git a/util/__init__.py b/util/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/util/__init__.py
diff --git a/util/audioplayer.py b/util/audioplayer.py
new file mode 100644
index 0000000..911fa42
--- /dev/null
+++ b/util/audioplayer.py
@@ -0,0 +1,132 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import os
+import gst
+import logging
+
+from globals import Globals
+
+from util.decorators import Property
+
+
+class AudioPlayer(object):
+
+ def __init__(self):
+ pass
+
+
+ @Property
+ def uri():
+ def get(self): return self.__uri
+ def set(self, value):
+ if value is None or not os.path.exists(value):
+ logging.error('AudioPlayer- Invalid URI: %r', value)
+ return
+ self.__uri = value
+ size = os.path.getsize(self.__uri)
+ self.pipeline.get_by_name('source').set_property('location', self.__uri)
+ self.pipeline.get_by_name('source').set_property('mmapsize', size)
+
+
+ @Property
+ def raw():
+ def get(self):
+ if self.uri is None:
+ logging.error('AudioPlayer - No data')
+ return None
+ f = open(self.uri, 'r')
+ raw = f.read()
+ f.close()
+ return raw
+ def set(self, value):
+ temp = Globals.temporary_filename()
+ f = open(temp, 'w')
+ f.write(value)
+ f.close()
+ #self.source.set_property('location', temp)
+ #self.source.set_property('mmapsize', len(value))
+ self.uri = temp
+ logging.debug('AudioPlayer - set_raw wrote %d bytes to %s', len(value), temp)
+
+
+ @Property
+ def pipeline():
+ def get(self):
+ if self.__pipeline is None:
+ self.__pipeline = self.__build_pipeline()
+ return self.__pipeline
+
+
+ def play(self):
+ logging.debug('AudioPlayer - started playing sound')
+ self.pipeline.set_state(gst.STATE_PLAYING)
+ logging.debug('AudioPlayer - finished playing sound')
+
+
+
+ def __build_pipeline(self):
+ # pipeline
+ pipeline = gst.Pipeline('pipeline')
+
+ # add source
+ source = gst.element_factory_make('filesrc', 'source')
+ pipeline.add(source)
+
+ # add decoder
+ decoder = gst.element_factory_make('decodebin', 'decoder')
+ decoder.connect("new-decoded-pad", self.__new_decoded_pad) #, converter)
+ pipeline.add(decoder)
+ source.link(decoder)
+
+ # add converter
+ converter = gst.element_factory_make("audioconvert", "converter")
+ pipeline.add(converter)
+
+ # add output
+ sink = gst.element_factory_make('autoaudiosink', 'sink')
+ pipeline.add(sink)
+ converter.link(sink)
+
+ bus = pipeline.get_bus()
+ bus.add_signal_watch()
+ bus.connect('message', self.__on_audio_message)
+
+ return pipeline
+
+
+
+ # callbacks ##################################################################
+
+ def __new_decoded_pad(self, dbin, pad, islast): #, converter)
+ converter = self.pipeline.get_by_name('converter') # TODO - pass by arg
+ pad.link(converter.get_pad("sink"))
+
+
+ def __on_audio_message(self, bus, message):
+ t = message.type
+ #logging.debug('message: %r' % t)
+ if t == gst.MESSAGE_EOS:
+ self.pipeline.set_state(gst.STATE_NULL)
+ logging.debug('AudioPlayer - EOS')
+ elif t == gst.MESSAGE_ERROR:
+ self.pipeline.set_state(gst.STATE_NULL)
+ err, debug = message.parse_error()
+ logging.debug('AudioPlayer - Error: %r %r', err, debug)
+
+
+ # Not used
+ def __on_source_handoff(self, source, buffer, pad):
+ logging.debug('on_source_handoff(%r, %r, %r)', source, buffer, pad)
diff --git a/util/decorators.py b/util/decorators.py
new file mode 100644
index 0000000..cd00afc
--- /dev/null
+++ b/util/decorators.py
@@ -0,0 +1,64 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import sys
+
+
+# Courtesy of: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/465427
+DecoratorWithArgs = \
+ lambda decorator: lambda *args, **kwargs: lambda func: decorator(func, *args, **kwargs)
+
+
+
+def Property(function):
+ '''Property Decorator
+ Adapted from: http://wiki.python.org/moin/PythonDecoratorLibrary
+
+ Example:
+
+ class Foo(object):
+ @Property
+ def my_property():
+ def get(self): return self.__my_property
+ def set(self, value): self.__my_property = value # (optional)
+ def default(self): return 'some default value' # (optional)
+ '''
+
+ keys = 'set', 'del'
+ func_locals = {'doc':function.__doc__}
+
+ def fgetter(obj, name, getter, fdef):
+ attr_name = '_' + obj.__class__.__name__ + '__' + name
+ if not hasattr(obj, attr_name):
+ setattr(obj, attr_name, fdef(obj))
+ return getter(obj)
+
+ def introspect(frame, event, arg):
+ if event == 'return':
+ locals = frame.f_locals
+ func_locals.update(dict(('f' + k,locals.get(k)) for k in keys))
+ if locals.has_key('default'):
+ func_locals['fget'] = lambda obj : fgetter(obj, function.__name__, locals['get'], locals['default'])
+ else:
+ func_locals['fget'] = lambda obj : fgetter(obj, function.__name__, locals['get'], lambda x : None)
+
+ sys.settrace(None)
+ return introspect
+
+ sys.settrace(introspect)
+ function()
+
+ return property(**func_locals)
+
diff --git a/util/journalpickler.py b/util/journalpickler.py
new file mode 100644
index 0000000..36f9311
--- /dev/null
+++ b/util/journalpickler.py
@@ -0,0 +1,47 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import pickle # TODO -> why does cPickle bitch about needing persistence.Jokebook etc ?
+
+
+class JournalPickler:
+ '''Works with util.Persistence to persist objects to the Sugar Journal'''
+
+ def __init__(self, obj = None):
+ pass
+
+ def __set_dirty(self, obj, is_dirty):
+ obj.__dirty__ = False
+ for name, prop in obj.__properties__:
+ if prop.fget(obj).__class__ is list:
+ for item in prop.fget(obj):
+ if hasattr(item, '__dirty__'):
+ self.__set_dirty(item, is_dirty)
+
+
+ def dumps(self, obj, deep_dump):
+ self.__set_dirty(obj, False)
+ pickled = pickle.dumps(obj)
+ return pickled
+
+
+ def loads(self, pickled):
+ obj = pickle.loads(pickled)
+ self.__set_dirty(obj, False)
+ return obj
+
+
+dumps = lambda obj, deep=False : JournalPickler(obj).dumps(obj, deep)
+loads = JournalPickler().loads
diff --git a/util/persistence.py b/util/persistence.py
new file mode 100644
index 0000000..e73879b
--- /dev/null
+++ b/util/persistence.py
@@ -0,0 +1,81 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import sys
+
+
+class Persistent(type):
+ '''Metaclass providing object persistence'''
+ def __init__(cls, name, bases, dct):
+ super(Persistent, cls).__init__(name, bases, dct)
+
+ setattr(cls, '__dirty__', False)
+ setattr(cls, '__properties__', filter(_is_persistent, dct.iteritems()))
+
+ from util.journalpickler import dumps, loads
+ setattr(cls, 'dumps', dumps)
+ setattr(cls, 'loads', loads)
+
+
+
+def PersistentProperty(function):
+ '''Decorator to set up persistent properties
+ Adapted from: http://wiki.python.org/moin/PythonDecoratorLibrary
+ '''
+
+ func_locals = {'doc':function.__doc__}
+
+ def fgetter(obj, name, getter, fdef):
+ attr_name = '_' + obj.__class__.__name__ + '__' + name
+ if not hasattr(obj, attr_name):
+ setattr(obj, attr_name, fdef(obj))
+ return getter(obj)
+
+ def fsetter(obj, name, setter, value):
+ setattr(obj, '__dirty__', True) # TODO -> Propogate dirty flag up to any
+ # parent objects ?
+ return setter(obj, value)
+
+ def introspect(frame, event, arg):
+ if event == 'return':
+ locals = frame.f_locals
+ if locals.has_key('delete'):
+ func_locals['fdel'] = locals['delete']
+ if locals.has_key('set'):
+ func_locals['fset'] = \
+ lambda obj, value : fsetter(obj, function.__name__, locals['set'], value)
+ if locals.has_key('default'):
+ get_function = lambda obj : fgetter(obj, function.__name__, locals['get'], locals['default'])
+ else:
+ get_function = lambda obj : fgetter(obj, function.__name__, locals['get'], lambda x : None)
+ get_function.__decorator__ = PersistentProperty # tag the getter so we can id the
+ # decorator. Yeah, it's ugly.
+ func_locals['fget'] = get_function
+ sys.settrace(None)
+ return introspect
+ sys.settrace(introspect)
+ function()
+ return property(**func_locals)
+
+
+# a wee bit ugly
+def _is_persistent(item):
+ '''check if property is decorated with PersistentProperty decorator'''
+ prop = item[1]
+ return type(prop) is property and \
+ hasattr(prop.fget, '__decorator__') and \
+ prop.fget.__decorator__ is PersistentProperty
+
+
diff --git a/util/persistence.py.args b/util/persistence.py.args
new file mode 100644
index 0000000..1aa235f
--- /dev/null
+++ b/util/persistence.py.args
@@ -0,0 +1,81 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+
+import sys
+
+from util.decorators import DecoratorWithArgs
+
+
+class Persistent(type):
+ '''Metaclass providing object persistence'''
+ def __init__(cls, name, bases, dct):
+ super(Persistent, cls).__init__(name, bases, dct)
+
+ setattr(cls, '__dirty__', False)
+ setattr(cls, '__properties__', filter(_is_persistent, dct.iteritems()))
+
+ from util.journalpickler import dumps, loads
+ setattr(cls, 'dumps', dumps)
+ setattr(cls, 'loads', loads)
+
+
+@DecoratorWithArgs
+def PersistentProperty(function, default = None):
+ '''Decorator to set persistent properties'''
+ keys = 'fset', 'fdel'
+ func_locals = {'doc':function.__doc__}
+
+ def fgetter(obj, name, getter, default_value):
+ attr_name = '_' + obj.__class__.__name__ + '__' + name
+ if not hasattr(obj, attr_name):
+ setattr(obj, attr_name, default_value(obj))
+ return getter(obj)
+
+ def fsetter(obj, name, setter, value):
+ setattr(obj, '__dirty__', True)
+ return setter(obj, value)
+
+ def introspect(frame, event, arg):
+ if event == 'return':
+ locals = frame.f_locals
+ func_locals.update(dict((k,locals.get(k)) for k in keys))
+ if locals.has_key('fset'):
+ func_locals['fset'] = \
+ lambda obj, value : fsetter(obj, function.__name__, locals['fset'], value)
+ if default != None:
+ get_function = \
+ lambda obj : fgetter(obj, function.__name__, locals['fget'], lambda x : default)
+ else:
+ get_function = \
+ lambda obj : fgetter(obj, function.__name__, locals['fget'], lambda x : None)
+ get_function.decorator = PersistentProperty # tag the getter so we can id
+ # the decorator. Yeah, it's ugly.
+ func_locals['fget'] = get_function
+ sys.settrace(None)
+ return introspect
+
+ sys.settrace(introspect)
+ function()
+ return property(**func_locals)
+
+
+# a wee bit ugly
+def _is_persistent(item):
+ '''check if property is decorated with PersistentProperty decorator'''
+ prop = item[1]
+ return type(prop) is property and \
+ hasattr(prop.fget, 'decorator') and \
+ prop.fget.decorator is PersistentProperty
diff --git a/util/persistence.py.noargs b/util/persistence.py.noargs
new file mode 100644
index 0000000..bf982af
--- /dev/null
+++ b/util/persistence.py.noargs
@@ -0,0 +1,75 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+
+import sys
+
+
+def is_persistent(item):
+ prop = item[1]
+ return type(prop) is property and \
+ hasattr(prop.fget, 'decorator') and \
+ prop.fget.decorator is PersistentProperty
+
+
+class Persistent(type):
+ def __init__(cls, name, bases, dct):
+ # is_dirty
+ setattr(cls, '__dirty__', False)
+
+ # properties
+ setattr(cls, '__properties__', filter(is_persistent, dct.iteritems()))
+
+ super(Persistent, cls).__init__(name, bases, dct)
+
+
+def PersistentProperty(function):
+ function.decorator = PersistentProperty
+
+ keys = 'fset', 'fdel'
+ func_locals = {'doc':function.__doc__}
+
+ def fgetter(obj, name, getter, fdef):
+ attr_name = '_' + obj.__class__.__name__ + '__' + name
+ if not hasattr(obj, attr_name):
+ setattr(obj, attr_name, fdef(obj))
+ return getter(obj)
+
+ def fsetter(obj, name, setter, value):
+ setattr(obj, '__dirty__', True)
+ return setter(obj, value)
+
+ def probe_function(frame, event, arg):
+ if event == 'return':
+ locals = frame.f_locals
+ func_locals.update(dict((k,locals.get(k)) for k in keys))
+
+ if locals.has_key('fset'):
+ func_locals['fset'] = lambda obj, value : fsetter(obj, function.__name__, locals['fset'], value)
+
+ if locals.has_key('fdef'):
+ f = lambda obj : fgetter(obj, function.__name__, locals['fget'], locals['fdef'])
+ else:
+ f = lambda obj : fgetter(obj, function.__name__, locals['fget'], lambda x : None)
+ f.decorator = PersistentProperty # tag the getter
+ func_locals['fget'] = f
+
+ sys.settrace(None)
+ return probe_function
+ sys.settrace(probe_function)
+ function()
+ return property(**func_locals)
+
+