From: Olivier Guilyardi Date: Fri, 27 Nov 2009 17:32:05 +0000 (+0000) Subject: - move id() into to IProcessor, all processors are required to implement this static... X-Git-Tag: 0.3.2~218 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=f7f2fe27b72d59e7e4d3a1ae5343a4c48735efc2;p=timeside.git - move id() into to IProcessor, all processors are required to implement this static method - MetaProcessor now ensures that all id's are wellformed and unique and raise an exception otherwise - add id() to all encoders and decoders, and make it static in analyzers and graphers - remove underscores and shorten a couple of id's, see the doc of IProcessor.id() --- diff --git a/analyze/api.py b/analyze/api.py index 46d4ab9..187dc29 100644 --- a/analyze/api.py +++ b/analyze/api.py @@ -24,10 +24,6 @@ from timeside.api import IProcessor class IAnalyzer(IProcessor): """Media item analyzer driver interface""" - @staticmethod - def id(): - """Return a short id alphanumeric, lower-case string.""" - @staticmethod def name(): """Return the analyzer name, such as "Mean Level", "Max level", diff --git a/analyze/channels.py b/analyze/channels.py index cb7e0fb..e09c6ab 100644 --- a/analyze/channels.py +++ b/analyze/channels.py @@ -28,8 +28,9 @@ class ChannelAnalyser(AudioProcessor): implements(IAnalyzer) - def id(self): - return "nb_channels" + @staticmethod + def id(): + return "nchannels" def name(self): return "Channels" diff --git a/analyze/dc.py b/analyze/dc.py index 0509809..28d0a68 100644 --- a/analyze/dc.py +++ b/analyze/dc.py @@ -28,7 +28,8 @@ class MeanDCShiftAnalyser(AudioProcessor): implements(IAnalyzer) - def id(self): + @staticmethod + def id(): return "dc" def name(self): diff --git a/analyze/duration.py b/analyze/duration.py index e69d31d..4ea9401 100644 --- a/analyze/duration.py +++ b/analyze/duration.py @@ -29,7 +29,8 @@ class DurationAnalyzer(AudioProcessor): implements(IAnalyzer) - def id(self): + @staticmethod + def id(): return "duration" def name(self): diff --git a/analyze/encoding.py b/analyze/encoding.py index e6ba192..3ca3b92 100644 --- a/analyze/encoding.py +++ b/analyze/encoding.py @@ -28,7 +28,8 @@ class EncodingAnalyser(AudioProcessor): implements(IAnalyzer) - def id(self): + @staticmethod + def id(): return "encoding" def name(self): diff --git a/analyze/format.py b/analyze/format.py index b86c1cf..681afc3 100644 --- a/analyze/format.py +++ b/analyze/format.py @@ -28,7 +28,8 @@ class FormatAnalyser(AudioProcessor): implements(IAnalyzer) - def id(self): + @staticmethod + def id(): return "format" def name(self): diff --git a/analyze/max_level.py b/analyze/max_level.py index 8768d76..95c2303 100644 --- a/analyze/max_level.py +++ b/analyze/max_level.py @@ -28,8 +28,9 @@ class MaxLevelAnalyzer(AudioProcessor): implements(IAnalyzer) - def id(self): - return "max_level" + @staticmethod + def id(): + return "maxlevel" def name(self): return "Maximum peak level" @@ -40,4 +41,4 @@ class MaxLevelAnalyzer(AudioProcessor): def render(self, media_item, options=None): self.pre_process(media_item) samples = self.get_samples() - return numpy.round(20*numpy.log10(numpy.max(samples)),2) \ No newline at end of file + return numpy.round(20*numpy.log10(numpy.max(samples)),2) diff --git a/analyze/mean_level.py b/analyze/mean_level.py index 3443c9a..ae9424d 100644 --- a/analyze/mean_level.py +++ b/analyze/mean_level.py @@ -28,8 +28,9 @@ class MeanLevelAnalyser(AudioProcessor): implements(IAnalyzer) - def id(self): - return "mean_level" + @staticmethod + def id(): + return "meanlevel" def name(self): return "Mean RMS level" diff --git a/analyze/resolution.py b/analyze/resolution.py index 60a17a0..b138205 100644 --- a/analyze/resolution.py +++ b/analyze/resolution.py @@ -28,7 +28,8 @@ class ResolutionAnalyser(AudioProcessor): implements(IAnalyzer) - def id(self): + @staticmethod + def id(): return "resolution" def name(self): @@ -48,4 +49,4 @@ class ResolutionAnalyser(AudioProcessor): if '32' in self.encoding: return 32 else: - return '' \ No newline at end of file + return '' diff --git a/analyze/samplerate.py b/analyze/samplerate.py index 638e9f8..8093537 100644 --- a/analyze/samplerate.py +++ b/analyze/samplerate.py @@ -28,7 +28,8 @@ class SampleRateAnalyzer(AudioProcessor): implements(IAnalyzer) - def id(self): + @staticmethod + def id(): return "samplerate" def name(self): diff --git a/api.py b/api.py index e2f62b9..48a7cf5 100644 --- a/api.py +++ b/api.py @@ -20,5 +20,14 @@ from timeside.component import Interface class IProcessor(Interface): - pass + + @staticmethod + def id(): + """Return a short alphanumeric, lower-case string which uniquely + identify this processor. Only letters and digits are allowed. + An exception will be raised by MetaProcessor if the id is malformed or + not unique amongst registered processors. + + Typically this identifier is likely to be used during HTTP requests + and be passed as a GET parameter. Thus it should be as short as possible.""" diff --git a/core.py b/core.py index 94e636c..c797db4 100644 --- a/core.py +++ b/core.py @@ -19,6 +19,7 @@ from timeside.component import * from timeside.api import IProcessor +import re __all__ = ['Processor', 'Component', 'implements', 'processors', 'TimeSideError'] @@ -26,15 +27,28 @@ class TimeSideError(Exception): """Exception base class for errors in TimeSide.""" # FIXME: is this redundant with Django's error handling ? -_processors = [] +_processors = {} class MetaProcessor(MetaComponent): - """Metaclass of the Processor class, used mainly for ensuring uniqueness of - processor id's""" + """Metaclass of the Processor class, used mainly for ensuring that processor + id's are wellformed and unique""" + + valid_id = re.compile("^[a-z][a-z0-9]*$") + def __new__(cls, name, bases, d): new_class = MetaComponent.__new__(cls, name, bases, d) - id = "fixme" - _processors.append((id, new_class)) + if new_class in implementations(IProcessor): + id = str(new_class.id()) + if _processors.has_key(id): + raise TimeSideError("%s and %s have the same id: '%s'" + % (new_class.__name__, _processors[id].__name__, id)) + if not MetaProcessor.valid_id.match(id): + raise TimeSideError("%s has a malformed id: '%s'" + % (new_class.__name__, id)) + + + _processors[id] = new_class + return new_class class Processor(Component): diff --git a/decode/core.py b/decode/core.py index abbe37c..c7a5afe 100644 --- a/decode/core.py +++ b/decode/core.py @@ -55,7 +55,7 @@ class SubProcessPipe: self.output = self.proc.stdout -class DecoderCore(Component): +class DecoderCore(Processor): """Defines the main parts of the decoding tools : paths, metadata parsing, data streaming thru system command""" diff --git a/decode/flac.py b/decode/flac.py index 44733d7..b9b02c2 100644 --- a/decode/flac.py +++ b/decode/flac.py @@ -33,6 +33,10 @@ class FlacDecoder(DecoderCore): implements(IDecoder) + @staticmethod + def id(): + return "flacdec" + def format(self): return 'FLAC' diff --git a/decode/mp3.py b/decode/mp3.py index 8f1f1e5..dc2c968 100644 --- a/decode/mp3.py +++ b/decode/mp3.py @@ -36,6 +36,10 @@ class Mp3Decoder(DecoderCore): def __init__(self): self.command = 'sox -t mp3 "%s" -q -b 16 -r 44100 -t wav -c2 - ' + @staticmethod + def id(): + return "mp3dec" + def format(self): return 'MP3' diff --git a/decode/ogg.py b/decode/ogg.py index 280b3c7..3e22af0 100644 --- a/decode/ogg.py +++ b/decode/ogg.py @@ -32,6 +32,10 @@ class OggDecoder(DecoderCore): implements(IDecoder) + @staticmethod + def id(): + return "oggdec" + def format(self): return 'OggVorbis' diff --git a/decode/wav.py b/decode/wav.py index 8012f28..be23402 100644 --- a/decode/wav.py +++ b/decode/wav.py @@ -31,6 +31,10 @@ class WavDecoder(DecoderCore): implements(IDecoder) + @staticmethod + def id(): + return "wavdec" + def format(self): return 'WAV' diff --git a/encode/flac.py b/encode/flac.py index 8312e90..3f43dbe 100644 --- a/encode/flac.py +++ b/encode/flac.py @@ -38,6 +38,10 @@ class FlacEncoder(EncoderCore): 'relation': 'album' } + @staticmethod + def id(): + return "flacenc" + def format(self): return 'FLAC' diff --git a/encode/mp3.py b/encode/mp3.py index e38f5b8..51fdf87 100644 --- a/encode/mp3.py +++ b/encode/mp3.py @@ -51,6 +51,11 @@ class Mp3Encoder(EncoderCore): 'publisher': 'tc', #comment 'date': 'ty', #year } + + @staticmethod + def id(): + return "mp3enc" + def format(self): return 'MP3' diff --git a/encode/ogg.py b/encode/ogg.py index 84dd8c7..ef19863 100644 --- a/encode/ogg.py +++ b/encode/ogg.py @@ -37,6 +37,10 @@ class OggVorbisEncoder(EncoderCore): 'relation': 'album' } + @staticmethod + def id(): + return "oggenc" + def format(self): return 'OggVorbis' diff --git a/encode/wav.py b/encode/wav.py index f1b8017..54b8199 100644 --- a/encode/wav.py +++ b/encode/wav.py @@ -33,6 +33,10 @@ class WavEncoder(EncoderCore): def __init__(self): pass + @staticmethod + def id(): + return "wavenc" + def format(self): return 'WAV' diff --git a/graph/api.py b/graph/api.py index af1ed7a..fa1e941 100644 --- a/graph/api.py +++ b/graph/api.py @@ -25,10 +25,6 @@ from timeside.api import IProcessor class IGrapher(IProcessor): """Media item visualizer driver interface""" - @staticmethod - def id(): - """Return a short id alphanumeric, lower-case string.""" - @staticmethod def name(): """Return the graph name, such as "Waveform", "Spectral view", diff --git a/graph/spectrogram_audiolab.py b/graph/spectrogram_audiolab.py index dc14fe1..b731fa6 100644 --- a/graph/spectrogram_audiolab.py +++ b/graph/spectrogram_audiolab.py @@ -32,8 +32,10 @@ class SpectrogramGrapherAudiolab(Processor): bg_color = None color_scheme = None - def id(self): - return "spectrogram_audiolab" + @staticmethod + def id(): + #FIXME: too long + underscore discouraged + return "spectrogram" def name(self): return "Spectrogram (audiolab)" diff --git a/graph/waveform_audiolab.py b/graph/waveform_audiolab.py index 4aeefc3..62de030 100644 --- a/graph/waveform_audiolab.py +++ b/graph/waveform_audiolab.py @@ -32,8 +32,10 @@ class WaveFormGrapherAudiolab(Processor): bg_color = None color_scheme = None - def id(self): - return "waveform_audiolab" + @staticmethod + def id(): + #FIXME: too long + underscore discouraged + return "waveform" def name(self): return "Waveform (audiolab)" diff --git a/tests/listprocessors.py b/tests/listprocessors.py index bf12c42..840c087 100644 --- a/tests/listprocessors.py +++ b/tests/listprocessors.py @@ -7,6 +7,6 @@ def list_processors(interface, prefix=""): list_processors(i, prefix + " ") processors = timeside.processors(interface, False) for p in processors: - print prefix + " " + p.__name__ + print prefix + " %s [%s]" % (p.__name__, p.id()) list_processors(timeside.api.IProcessor)