]> git.parisson.com Git - telemeta.git/commitdiff
add a cache to the webview (analyzers and graphers)
authorGuillaume Pellerin <yomguy@parisson.com>
Thu, 11 Nov 2010 16:18:22 +0000 (17:18 +0100)
committerGuillaume Pellerin <yomguy@parisson.com>
Thu, 11 Nov 2010 16:18:22 +0000 (17:18 +0100)
telemeta/cache.py [new file with mode: 0644]
telemeta/util/logger.py
telemeta/web/base.py

diff --git a/telemeta/cache.py b/telemeta/cache.py
new file mode 100644 (file)
index 0000000..b5f2fd9
--- /dev/null
@@ -0,0 +1,120 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2006-2010 Guillaume Pellerin
+
+# <yomguy@parisson.com>
+
+# This software is a computer program whose purpose is to stream audio
+# and video data through icecast2 servers.
+
+# This software is governed by the CeCILL license under French law and
+# abiding by the rules of distribution of free software. You can use,
+# modify and/ or redistribute the software under the terms of the CeCILL
+# license as circulated by CEA, CNRS and INRIA at the following URL
+# "http://www.cecill.info".
+
+# As a counterpart to the access to the source code and  rights to copy,
+# modify and redistribute granted by the license, users are provided only
+# with a limited warranty and the software's author, the holder of the
+# economic rights, and the successive licensors have only limited
+# liability.
+
+# In this respect, the user's attention is drawn to the risks associated
+# with loading, using,  modifying and/or developing or reproducing the
+# software by the user in light of its specific status of free software,
+# that may mean that it is complicated to manipulate, and that also
+# therefore means that it is reserved for developers and  experienced
+# professionals having in-depth computer knowledge. Users are therefore
+# encouraged to load and test the software's suitability as regards their
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
+# same conditions as regards security.
+
+# The fact that you are presently reading this means that you have had
+# knowledge of the CeCILL license and that you accept its terms.
+
+# Author: Guillaume Pellerin <yomguy@parisson.com>
+
+import os
+import xml.dom.minidom
+#import xml.dom.ext
+
+
+class TelemetaCache(object):
+    
+    def __init__(self, dir, params=None):
+        self.dir = dir
+        self.params = params
+        self.files = self.get_files()
+        
+    def get_files(self):
+        list = []
+        for root, dirs, files in os.walk(self.dir):
+            for file in files:
+                list.append(file)
+        return list
+    
+    def exists(self, file):
+        self.files = self.get_files()
+        return file in self.files
+            
+    def write_bin(self, data, file):
+        path = self.dir + os.sep + file
+        f = open(path, 'w')
+        f.write(data)
+        f.close()
+
+    def read_bin(self, file):
+        path = self.dir + os.sep + file
+        f = open(path,  'r')
+        data = f.read()
+        f.close()
+        return data
+        
+    def read_stream_bin(self, file):
+        path = self.dir + os.sep + file
+        chunk_size = 0x1000
+        f = open(path,  'r')
+        while True:
+            _chunk = f.read(chunk_size)
+            if not len(_chunk):
+                break
+            yield _chunk
+        f.close()
+
+    def write_stream_bin(self, chunk, file_object):
+        file_object.write(chunk)
+
+    def read_analyzer_xml(self, file):
+        list = []
+        path = self.dir + os.sep + file
+        doc = xml.dom.minidom.parse(path)
+        for data in doc.documentElement.getElementsByTagName('data') :
+            name = data.getAttribute('name')
+            id = data.getAttribute('id')
+            unit = data.getAttribute('unit')
+            value = data.getAttribute('value')
+            list.append({'name': name, 'id': id, 'unit': unit, 'value': value})
+        return list
+        
+    def write_analyzer_xml(self, data_list, file):
+        path = self.dir + os.sep + file
+        doc = xml.dom.minidom.Document()
+        root = doc.createElement('telemeta')
+        doc.appendChild(root)
+        for data in data_list:
+            name = data['name']
+            id = data['id']
+            unit = data['unit']
+            value = data['value']
+            node = doc.createElement('data')
+            node.setAttribute('name', name)
+            node.setAttribute('id', id)
+            node.setAttribute('unit', unit)
+            node.setAttribute('value', str(value))
+            root.appendChild(node)
+        f = open(path, "w")
+        f.write(xml.dom.minidom.Document.toprettyxml(doc))
+#        xml.dom.ext.PrettyPrint()
+        f.close()
index 41ed008610527786f9e3860f61418f278744f123..f9a032c8d2d3e3a27cddb5c23a4a80499d0cb7cb 100644 (file)
@@ -12,12 +12,6 @@ class Logger:
         self.logger.addHandler(self.hdlr)
         self.logger.setLevel(logging.INFO)
 
-    def write_info(self, message):
-        self.logger.info(message)
-
-    def write_error(self, message):
-        self.logger.error(message)
-
     def debug(self, msg):
-        self.logger.error(message)
+        self.logger.error('DEBUG : ' + message)
         
index aa98265ae09b3e6d1a49e36d8beb72080157f7b9..2165a82563b86e437d8707381fac0c8e218550cf 100644 (file)
@@ -56,21 +56,13 @@ from django.core.exceptions import ObjectDoesNotExist
 from telemeta.util.unaccent import unaccent
 from telemeta.util.unaccent import unaccent_icmp
 from telemeta.util.logger import Logger
+from telemeta.cache import TelemetaCache
 import telemeta.web.pages as pages
 
 def render(request, template, data = None, mimetype = None):
     return render_to_response(template, data, context_instance=RequestContext(request), 
                               mimetype=mimetype)
 
-def stream_from_file(file):
-    chunk_size = 0x1000
-    f = open(file,  'r')
-    while True:
-        _chunk = f.read(chunk_size)
-        if not len(_chunk):
-            break
-        yield _chunk
-    f.close()
 
 def stream_from_processor(decoder, processor):
     while True:
@@ -88,7 +80,7 @@ class WebView:
     decoders = timeside.core.processors(timeside.api.IDecoder)
     encoders= timeside.core.processors(timeside.api.IEncoder)
     analyzers = timeside.core.processors(timeside.api.IAnalyzer)
-    logger = Logger('/tmp/telemeta.log')
+    cache = TelemetaCache(settings.TELEMETA_DATA_CACHE_DIR)
     
     def index(self, request):
         """Render the homepage"""
@@ -123,11 +115,12 @@ class WebView:
         else:
             grapher_id = 'waveform'
         
-        analyzers = [{'name':'','id':'','unit':'','value':''}]
-        # TODO: override timeside analyzer process when caching : write results to XML file in data/
-        self.analyzer_mode = 1
+        file = public_id + '.xml'
         
-        if self.analyzer_mode:
+        if self.cache.exists(file):
+            analyzers = self.cache.read_analyzer_xml(file)
+        else:
+            analyzers = []
             analyzers_sub = []
             if item.file:
                 audio = os.path.join(os.path.dirname(__file__), item.file.path)
@@ -139,25 +132,27 @@ class WebView:
                     self.pipe = self.pipe | subpipe
                 self.pipe.run()
                 
-            for analyzer in analyzers_sub:
-                if item.file:
-                    value = analyzer.result()
-                    if analyzer.id() == 'duration':
-                        approx_value = int(round(value))
-                        item.approx_duration = approx_value
-                        item.save()
-                        value = datetime.timedelta(0,value)
-                else:
-                    value = 'N/A'
-
-                analyzers.append({'name':analyzer.name(),
-                                  'id':analyzer.id(),
-                                  'unit':analyzer.unit(),
-                                  'value':str(value)})
+                for analyzer in analyzers_sub:
+                    if item.file:
+                        value = analyzer.result()
+                        if analyzer.id() == 'duration':
+                            approx_value = int(round(value))
+                            item.approx_duration = approx_value
+                            item.save()
+                            value = datetime.timedelta(0,value)
+                    else:
+                        value = 'N/A'
+
+                    analyzers.append({'name':analyzer.name(),
+                                      'id':analyzer.id(),
+                                      'unit':analyzer.unit(),
+                                      'value':str(value)})
+                
+            self.cache.write_analyzer_xml(analyzers, file)
 
         return render(request, template, 
                     {'item': item, 'export_formats': formats, 
-                    'visualizers': graphers, 'visualizer_id': grapher_id,'analysers': analyzers,
+                    'visualizers': graphers, 'visualizer_id': grapher_id,'analysers': analyzers,  #FIXME analysers
                     'audio_export_enabled': getattr(settings, 'TELEMETA_DOWNLOAD_ENABLED', False)
                     })
     
@@ -168,6 +163,7 @@ class WebView:
         pass
 
     def item_visualize(self, request, public_id, visualizer_id, width, height):
+        item = MediaItem.objects.get(public_id=public_id)
         mime_type = 'image/png'
         grapher_id = visualizer_id
         for grapher in self.graphers:
@@ -177,21 +173,19 @@ class WebView:
         if grapher.id() != grapher_id:
             raise Http404
         
-        media = settings.TELEMETA_DATA_CACHE_DIR + \
-                    os.sep + '_'.join([public_id,  grapher_id,  width,  height]) + '.png'
-
-        #graph.set_colors((255,255,255), 'purple')
+        file = '_'.join([public_id, grapher_id, width, height]) + '.png'
         
-        if not os.path.exists(media):
-            item = MediaItem.objects.get(public_id=public_id)
-            audio = os.path.join(os.path.dirname(__file__), item.file.path)
-            decoder  = timeside.decoder.FileDecoder(audio)
-            graph = grapher(width=int(width), height=int(height))
-            pipe = decoder | graph
-            pipe.run()
-            graph.render(media)
-
-        response = HttpResponse(stream_from_file(media), mimetype = mime_type)
+        if not self.cache.exists(file):
+            if item.file:
+                item = MediaItem.objects.get(public_id=public_id)
+                audio = os.path.join(os.path.dirname(__file__), item.file.path)
+                decoder  = timeside.decoder.FileDecoder(audio)
+                graph = grapher(width=int(width), height=int(height))
+                pipe = decoder | graph
+                pipe.run()
+                graph.render(self.cache.dir + os.sep + file)
+
+        response = HttpResponse(self.cache.read_stream_bin(file), mimetype = mime_type)
         return response
 
     def list_export_extensions(self):