]> git.parisson.com Git - deefuzzer.git/commitdiff
add metadata functions
authorGuillaume Pellerin <yomguy@parisson.com>
Fri, 3 Apr 2009 21:10:24 +0000 (21:10 +0000)
committerGuillaume Pellerin <yomguy@parisson.com>
Fri, 3 Apr 2009 21:10:24 +0000 (21:10 +0000)
tools/__init__.py
tools/mp3.py [new file with mode: 0644]
tools/ogg.py [new file with mode: 0644]
tools/tools.py [new file with mode: 0644]

index 3181cdbbbfa74ffa0693faefabc2314c79fede7e..89f1866b9ab55e66b276821c904637649ba35eaa 100644 (file)
@@ -1,3 +1,5 @@
 # -*- coding: utf-8 -*-
 from xmltodict import *
 from PyRSS2Gen import *
+from mp3 import *
+from ogg import *
diff --git a/tools/mp3.py b/tools/mp3.py
new file mode 100644 (file)
index 0000000..7b8c591
--- /dev/null
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2006-2009 Guillaume Pellerin <pellerin@parisson.com>
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://svn.parisson.org/telemeta/TelemetaLicense.
+#
+# Author: Guillaume Pellerin <pellerin@parisson.com>
+
+import os
+import string
+from mutagen.easyid3 import EasyID3
+from mutagen.mp3 import MP3
+
+EasyID3.valid_keys["comment"]="COMM::'XXX'"
+
+class Mp3:
+    """An MP3 file object"""
+    
+    def __init__(self, media):
+        self.media = media
+        self.item_id = ''
+        self.source = self.media
+        self.options = {}
+        self.bitrate_default = '192'
+        self.cache_dir = os.sep + 'tmp'
+        self.keys2id3 = {'title': 'TIT2',
+                    'artist': 'TPE1',
+                    'album': 'TALB',
+                    'date': 'TDRC',
+                    'comment': 'COMM',
+                    'genre': 'TCON',
+                    }
+        self.metadata = self.get_metadata()
+        self.description = self.get_description()
+        self.mime_type = self.get_mime_type()
+        self.extension = self.get_file_extension()
+        #self.args = self.get_args()
+                    
+    def get_format(self):
+        return 'MP3'
+    
+    def get_file_extension(self):
+        return 'mp3'
+
+    def get_mime_type(self):
+        return 'audio/mpeg'
+
+    def get_description(self):
+        return "MPEG audio Layer III"
+
+    def get_metadata(self):
+        m = MP3(self.media, ID3=EasyID3)
+        metadata = {}
+        for key in self.keys2id3.keys():
+            try:
+                metadata[key] = m[key][0]
+            except:
+                pass
+        return metadata
+
+    def decode(self):
+        try:
+            os.system('sox "'+self.media+'" -s -q -r 44100 -t wav "' \
+                        +self.cache_dir+os.sep+self.item_id+'"')
+            return self.cache_dir+os.sep+self.metadata['title']+'.wav'
+        except:
+            raise IOError('ExporterError: decoder is not compatible.')
+
+    def write_tags(self):
+        """Write all ID3v2.4 tags by mapping dub2id3_dict dictionnary with the
+            respect of mutagen classes and methods"""
+        id3 = id3.ID3(self.media)
+        for tag in self.metadata.keys():
+            if tag in self.dub2id3_dict.keys():
+                frame_text = self.dub2id3_dict[tag]
+                value = self.metadata[tag]
+                frame = mutagen.id3.Frames[frame_text](3,value)
+                try:
+                    id3.add(frame)
+                except:
+                    raise IOError('ExporterError: cannot tag "'+tag+'"')
+        try:
+            id3.save()
+        except:
+            raise IOError('ExporterError: cannot write tags')
+
+    def get_args(self, options=None):
+        """Get process options and return arguments for the encoder"""
+        args = []
+        if not options is None: 
+            self.options = options
+            if not ( 'verbose' in self.options and self.options['verbose'] != '0' ):
+                args.append('-S')
+            if 'mp3_bitrate' in self.options:
+                args.append('-b ' + self.options['mp3_bitrate'])
+            else:
+                args.append('-b '+self.bitrate_default)
+            #Copyrights, etc..
+            args.append('-c -o')
+        else:
+            args.append('-S -c -o')
+
+        for tag in self.metadata.keys():
+            if tag in self.dub2args_dict.keys():
+                arg = self.dub2args_dict[tag]
+                value = self.metadata[tag]
+                args.append('--' + arg)
+                args.append('"' + value + '"')
+
+        return args
+
diff --git a/tools/ogg.py b/tools/ogg.py
new file mode 100644 (file)
index 0000000..b0fef85
--- /dev/null
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2007 Parisson SARL
+# Copyright (c) 2006-2007 Guillaume Pellerin <pellerin@parisson.com>
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://svn.parisson.org/telemeta/TelemetaLicense.
+#
+# Author: Guillaume Pellerin <pellerin@parisson.com>
+
+import os
+import string
+import subprocess
+
+from telemeta.export.core import *
+from telemeta.export.api import IExporter
+from mutagen.oggvorbis import OggVorbis
+
+class OggExporter(ExporterCore):
+    """Defines methods to export to OGG Vorbis"""
+
+    implements(IExporter)
+    
+    def __init__(self):
+        self.item_id = ''
+        self.metadata = {}
+        self.description = ''
+        self.info = []
+        self.source = ''
+        self.dest = ''
+        self.options = {}
+        self.bitrate_default = '192'
+        self.buffer_size = 0xFFFF
+        self.dub2args_dict = {'creator': 'artist',
+                             'relation': 'album'
+                             }
+        
+    def get_format(self):
+        return 'OGG'
+    
+    def get_file_extension(self):
+        return 'ogg'
+
+    def get_mime_type(self):
+        return 'application/ogg'
+
+    def get_description(self):
+        return 'FIXME'
+
+    def get_file_info(self):
+        try:
+            file_out1, file_out2 = os.popen4('ogginfo "'+self.dest+'"')
+            info = []
+            for line in file_out2.readlines():
+                info.append(clean_word(line[:-1]))
+            self.info = info
+            return self.info
+        except:
+            raise IOError('ExporterError: file does not exist.')
+
+    def set_cache_dir(self,path):
+       self.cache_dir = path
+
+    def decode(self):
+        try:
+            os.system('oggdec -o "'+self.cache_dir+os.sep+self.item_id+
+                      '.wav" "'+self.source+'"')
+            return self.cache_dir+os.sep+self.item_id+'.wav'
+        except:
+            raise IOError('ExporterError: decoder is not compatible.')
+
+    def write_tags(self):
+        media = OggVorbis(self.dest)
+        for tag in self.metadata.keys():
+            media[tag] = str(self.metadata[tag])
+        media.save()
+
+    def get_args(self,options=None):
+        """Get process options and return arguments for the encoder"""
+        args = []
+        if not options is None:
+            self.options = options
+            if not ('verbose' in self.options and self.options['verbose'] != '0'):
+                args.append('-Q ')
+            if 'ogg_bitrate' in self.options:
+                args.append('-b '+self.options['ogg_bitrate'])
+            elif 'ogg_quality' in self.options:
+                args.append('-q '+self.options['ogg_quality'])
+            else:
+                args.append('-b '+self.bitrate_default)
+        else:
+            args.append('-Q -b '+self.bitrate_default)
+
+        for tag in self.metadata.keys():
+            value = clean_word(self.metadata[tag])
+            args.append('-c %s="%s"' % (tag, value))
+            if tag in self.dub2args_dict.keys():
+                arg = self.dub2args_dict[tag]
+                args.append('-c %s="%s"' % (arg, value))
+
+        return args
+
+    def process(self, item_id, source, metadata, options=None):
+        self.item_id = item_id
+        self.source = source
+        self.metadata = metadata
+        self.args = self.get_args(options)
+        self.ext = self.get_file_extension()
+        self.args = ' '.join(self.args)
+        self.command = 'sox "%s" -s -q -r 44100 -t wav -c2 - | oggenc %s -' % (self.source, self.args)
+
+        # Pre-proccessing
+        self.dest = self.pre_process(self.item_id,
+                                        self.source,
+                                        self.metadata,
+                                        self.ext,
+                                        self.cache_dir,
+                                        self.options)
+
+        # Processing (streaming + cache writing)
+        stream = self.core_process(self.command, self.buffer_size, self.dest)
+        for chunk in stream:
+            yield chunk
+    
+        # Post-proccessing
+        #self.post_process(self.item_id,
+                        #self.source,
+                        #self.metadata,
+                        #self.ext,
+                        #self.cache_dir,
+                        #self.options)
+
diff --git a/tools/tools.py b/tools/tools.py
new file mode 100644 (file)
index 0000000..e2db650
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2007-2009 Guillaume Pellerin <yomguy@parisson.com>
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://svn.parisson.org/deefuzz/wiki/DefuzzLicense.
+#
+# Author: Guillaume Pellerin <yomguy@parisson.com>
+
+import os
+import re
+import sys
+import time
+import datetime
+import string
+import random
+
+def clean_word(word) :
+    """ Return the word without excessive blank spaces, underscores and
+    characters causing problem to exporters"""
+    word = re.sub("^[^\w]+","",word)    #trim the beginning
+    word = re.sub("[^\w]+$","",word)    #trim the end
+    word = re.sub("_+","_",word)        #squeeze continuous _ to one _
+    word = re.sub("^[^\w]+","",word)    #trim the beginning _
+    #word = string.replace(word,' ','_')
+    #word = string.capitalize(word)
+    dict = '&[];"*:,'
+    for letter in dict:
+        word = string.replace(word,letter,'_')
+    return word
\ No newline at end of file