[xiph-cvs] cvs commit: positron/positron add_file.py audiofile.py cmd_add.py cmd_rebuild.py cmd_sync.py config.py

Stan Seibert volsung at xiph.org
Sun Jun 8 18:04:46 PDT 2003



volsung     03/06/08 21:04:46

  Modified:    positron add_file.py audiofile.py cmd_add.py cmd_rebuild.py
                        cmd_sync.py config.py
  Log:
  Vorbis support in positron.  Turn it on with oggvorbis_support=true in
  ~/.positron/config

Revision  Changes    Path
1.3       +14 -18    positron/positron/add_file.py

Index: add_file.py
===================================================================
RCS file: /usr/local/cvsroot/positron/positron/add_file.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- add_file.py	24 May 2003 19:29:09 -0000	1.2
+++ add_file.py	9 Jun 2003 01:04:46 -0000	1.3
@@ -18,13 +18,13 @@
 
 import os
 from os import path
-from audiofile import MP3File
+import audiofile
 from neuros import Neuros
 import util
 
-mp3file = MP3File()
 
-def gen_filelist(neuros, prefix, suffix, target_prefix, silent=False):
+def gen_filelist(neuros, prefix, suffix, target_prefix,
+                 allowed_types, silent=False):
     filelist = []
     fullname = path.join(prefix, suffix)
 
@@ -37,13 +37,14 @@
         fullname = path.join(prefix, name)
         
         if path.isfile(fullname):
-            if not mp3file.detect(fullname):
+            metadata = audiofile.detect(fullname)
+            if metadata == None or metadata["type"] not in allowed_types:
                 if not silent:
-                    print "Skipping %s.  Not a recognized audio format." \
+                    print "Skipping %s.  Not a supported audio format." \
                           % (fullname,)
             elif neuros.is_valid_hostpath(fullname):
                 # Don't need to copy files already on the Neuros
-                filelist.append((None, fullname))
+                filelist.append((None, fullname, metadata))
             else:
                 targetname = neuros.mangle_hostpath(path.join(target_prefix,
                                                               name))
@@ -52,11 +53,11 @@
                         print "Skipping %s because %s already exists." \
                               % (fullname, targetname)
                 else:
-                    filelist.append((fullname, targetname))
+                    filelist.append((fullname, targetname, metadata))
                     
         elif path.isdir(fullname):
             filelist.extend(gen_filelist(neuros, prefix, name, target_prefix,
-                                         silent))
+                                         allowed_types, silent))
         else:
             if not silent:
                 print "Ignoring %s.  Not a file or directory." % (fullname)
@@ -64,19 +65,14 @@
     return filelist
 
 
-def add_track(neuros, sourcename, targetname, recording=None):
-
-    if sourcename == None:
-        # File already on Neuros
-        info = mp3file.get_info(targetname)
-    else:
-        # File needs to be copied to Neuros
-        info = mp3file.get_info(sourcename)
+def add_track(neuros, sourcename, targetname, metadata, recording=None):
+    if sourcename != None:
         util.copy_file(sourcename, targetname)
 
     # Create DB entry
-    record = (info["title"], None, info["artist"], info["album"],
-              info["genre"], recording, info["length"], info["size"] // 1024,
+    record = (metadata["title"], None, metadata["artist"], metadata["album"],
+              metadata["genre"], recording, metadata["length"],
+              metadata["size"] // 1024,
               neuros.hostpath_to_neurospath(targetname))
     # Add entry to database
     neuros.db["audio"].add_record(record)

<p><p>1.2       +82 -50    positron/positron/audiofile.py

Index: audiofile.py
===================================================================
RCS file: /usr/local/cvsroot/positron/positron/audiofile.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- audiofile.py	22 May 2003 04:42:52 -0000	1.1
+++ audiofile.py	9 Jun 2003 01:04:46 -0000	1.2
@@ -14,60 +14,38 @@
 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
 # or FITNESS FOR A PARTICULAR PURPOSE.  See the license for more details.
 
-import MP3Info
+from types import *
+import os
 from os import path
+import string
 
-def copy_file (src_filename, dest_filename):
-    blocksize = 1048576
-    src = file(src_filename, "rb")
-    dest = file(dest_filename, "wb")
-
-    block = src.read(blocksize)
-    while block != "":
-        dest.write(block)
-        block = src.read(blocksize)
-
-    src.close()
-    dest.close()
-
-
-class AudioFile:
-    """Base class for various formats.  Defines common operatons and API.
-
-    Do not instantiate this class.  It will not do what you want."""
-    
-    active = False
-
-    def detect(self, filename):
-        self._fail("detect")
-
-    def get_info(self, filename):
-        self._fail("open")
-
-    def _fail(self, funcname):
-        raise Error("Someone forgot to implement %s.%s()."
-                    % (self.__class__.__name__, funcname))
-
-class MP3File(AudioFile):
-    def detect(self, filename):
-        try:
-            f = file(filename, "rb")
-            m = MP3Info.MP3Info(f)
-        except MP3Info.Error:
-            f.close()
-            return False
-        except IOError:
-            return False
-        
-        return True
+import MP3Info
 
-    def get_info(self, filename):
+def detect(filename):
+    metadata = None
+
+    for detect_func in detect_functions:
+        metadata = detect_func(filename)
+        if metadata != None:
+            break
+    else:
+        metadata = None
+
+    if metadata != None and metadata["title"] == None:
+        # Must have title
+        metadata["title"] = path.split(filename)[1]
+
+    return metadata
+
+def detect_mp3(filename):
+    try:
         f = file(filename, "rb")
 
         mp3info = MP3Info.MP3Info(f)
 
         header = mp3info.mpeg
-        info = { "size" : header.filesize,
+        info = { "type" : "mp3",
+                 "size" : header.filesize,
                  "length" : header.length,
                  "title" : mp3info.title,
                  "artist" : mp3info.artist,
@@ -79,10 +57,64 @@
             if info[key] == "":
                 info[key] = None
 
-        # Must have title
-        if info["title"] == None:
-            info["title"] = path.split(filename)[1]
+        f.close()
 
+    except MP3Info.Error:
         f.close()
+        return None
+    except IOError:
+        return None
+    except OSError:
+        return None            
+
+    return info
+
+def detect_oggvorbis(filename):
+    try:
+        vf = ogg.vorbis.VorbisFile(filename)
+        vc = vf.comment()
+        vi = vf.info()        
+
+        info = { "type" : "oggvorbis",
+                 "size" : os.stat(filename).st_size,
+                 "length" : int(vf.time_total(-1)),
+                 "title" : None,
+                 "artist" : None,
+                 "album" : None,
+                 "genre" : None }
+
+        actual_keys = map(string.lower, vc.keys())
         
-        return info
+        for tag in ("title","artist","album","genre"):
+            if tag in actual_keys:
+                value = vc[tag]
+                # Force these to be single valued
+                if type(value) == ListType or type(value) == TupleType:
+                    value = value[0]
+
+                # Convert from Unicode back to normal string since
+                # the Neuros can't do Unicode anyway.
+                #
+                # I will probably burn in i18n hell for this.
+                info[tag] = str(value)
+
+    except ogg.vorbis.VorbisError:
+        return None
+    except IOError:
+        return None
+    except OSError:
+        return None
+
+    return info
+
+
+# Only put the ogg vorbis detection code in the list if
+# we have the python module needed.
+
+detect_functions = [detect_mp3]
+
+try:
+     import ogg.vorbis
+     detect_functions.append(detect_oggvorbis)
+except ImportError:
+    pass

<p><p>1.3       +6 -5      positron/positron/cmd_add.py

Index: cmd_add.py
===================================================================
RCS file: /usr/local/cvsroot/positron/positron/cmd_add.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cmd_add.py	25 May 2003 22:30:03 -0000	1.2
+++ cmd_add.py	9 Jun 2003 01:04:46 -0000	1.3
@@ -82,21 +82,22 @@
         print "Generating file list..."
         for arg in args[:-1]:
             (prefix, suffix) = path.split(arg)
-            filelist.extend(gen_filelist(neuros, prefix, suffix, args[-1]))
+            filelist.extend(gen_filelist(neuros, prefix, suffix, args[-1],
+                                         config.supported_music_types()))
             
 
     if len(filelist) == 0:
         print "No files left to add!"
     elif len(filelist) == 1:
-        (sourcename, targetname) = filelist[0]
+        (sourcename, targetname, metadata) = filelist[0]
         print "Adding %s to the Neuros..." % (sourcename,),
-        add_track(neuros, sourcename, targetname)
+        add_track(neuros, sourcename, targetname, metadata)
         print
     else:
         print "Adding %d tracks to the Neuros..." % (len(filelist),)
-        for (sourcename, targetname) in filelist:
+        for sourcename, targetname, metadata in filelist:
             print "  %s..." % (sourcename,)
-            add_track(neuros, sourcename, targetname)
+            add_track(neuros, sourcename, targetname, metadata)
 
     if config.sort_database:
         print "\nSorting tracks..."

<p><p>1.4       +9 -8      positron/positron/cmd_rebuild.py

Index: cmd_rebuild.py
===================================================================
RCS file: /usr/local/cvsroot/positron/positron/cmd_rebuild.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- cmd_rebuild.py	25 May 2003 23:22:34 -0000	1.3
+++ cmd_rebuild.py	9 Jun 2003 01:04:46 -0000	1.4
@@ -56,10 +56,10 @@
         return "FM "+str[:-1]+"."+str[-1:]
     
 def test_recording(neuros, s):
-    return neuros.hostpath_to_neurospath(s).lower().startswith("c:/woid_record")
+    return neuros.hostpath_to_neurospath(s[0]).lower().startswith("c:/woid_record")
 
 def test_hisi(neuros, s):
-    return neuros.hostpath_to_neurospath(s).lower().startswith("c:/woid_hisi")
+    return neuros.hostpath_to_neurospath(s[0]).lower().startswith("c:/woid_hisi")
 
 
 def list_split(list, test_func):
@@ -85,8 +85,9 @@
 
         print "\nFinding existing audio files on the Neuros..."
         # Now we need to find all the files to readd them to the database.
-        filelist = [item[1] for item in
+        filelist = [item[1:] for item in
                     gen_filelist(neuros,"",neuros.mountpoint,"",
+                                 config.supported_music_types(),
                                  silent=True)]
 
         test_rec_func = lambda s: test_recording(neuros, s)
@@ -99,14 +100,14 @@
 
         print "\nAdding music tracks to audio database..."
         audio_db = neuros.open_db("audio")
-        for track in rest:
+        for track,metadata in rest:
             print "  "+path.basename(track)
-            add_track(neuros, None, track)
+            add_track(neuros, None, track, metadata)
 
         print "\nAdding recordings to audio database..."
-        for track in recordings:
+        for track,metadata in recordings:
             print "  "+path.basename(track)
-            add_track(neuros, None, track,
+            add_track(neuros, None, track, metadata,
                       recording=recording_source(track))
         if config.sort_database:
             audio_db.sort()
@@ -114,7 +115,7 @@
 
         print "\nAdding HiSi clips to unidedhisi database..."
         unidedhisi_db = neuros.open_db("unidedhisi")
-        for track in hisi:
+        for track,metadata in hisi:
             basename = path.basename(track)
             print "  "+basename
             record = (basename, hisi_source(track),

<p><p>1.3       +3 -2      positron/positron/cmd_sync.py

Index: cmd_sync.py
===================================================================
RCS file: /usr/local/cvsroot/positron/positron/cmd_sync.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- cmd_sync.py	25 May 2003 23:22:34 -0000	1.2
+++ cmd_sync.py	9 Jun 2003 01:04:46 -0000	1.3
@@ -89,6 +89,7 @@
             
             for item in os.listdir(source):
                 filelist.extend(gen_filelist(neuros, source, item, targetdir,
+                                             config.supported_music_types(),
                                              silent=True))
 
         # Cut explicitly deleted files
@@ -122,10 +123,10 @@
             else:
                 print "Copying %d new tracks."% (len(filelist),)
                 
-            for (sourcename, targetname) in filelist:
+            for sourcename, targetname, metadata in filelist:
                 basename = path.basename(sourcename)
                 print "    %s..." % (basename,)
-                add_track(neuros, sourcename, targetname)
+                add_track(neuros, sourcename, targetname, metadata)
 
 
     if config.recordingdir == None:

<p><p>1.2       +26 -2     positron/positron/config.py

Index: config.py
===================================================================
RCS file: /usr/local/cvsroot/positron/positron/config.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- config.py	22 May 2003 04:42:52 -0000	1.1
+++ config.py	9 Jun 2003 01:04:46 -0000	1.2
@@ -72,6 +72,7 @@
         self.recordingdir = None
         self.neuros_musicdir = "MUSIC"
         self.sort_database = True
+        self.oggvorbis_support = False
         self.syncdirs = []
 
     def set_config_dir(self, config_dir):
@@ -97,6 +98,17 @@
         if not path.exists(self.config_filenames["recordings"]):
             self.clear_recordings()
 
+    def supported_music_types(self):
+        """Convenience method for getting the list of music types enabled
+        in the config file"""
+
+        types = ["mp3"]
+
+        if self.oggvorbis_support:
+            types.append("oggvorbis")
+
+        return types
+
     # --------- Config file methods ---------
 
     def _read_key_value_pair(self, tokenizer):
@@ -193,6 +205,13 @@
                         raise Error(tokenizer.error_leader()
                                     +"Non boolean value '%s' given for %s",
                                     (value, key))
+                elif key == "oggvorbis_support":
+                    try:
+                        self.oggvorbis_support = parse_boolean(value)
+                    except Error:
+                        raise Error(tokenizer.error_leader()
+                                    +"Non boolean value '%s' given for %s",
+                                    (value, key))
                 else:
                     print tokenizer.error_leader() \
                           + "Ignoring unknown option %s" % (key,)
@@ -218,9 +237,14 @@
         if self.sort_database:
             sort_database_value = "true"
         else:
-            sort_database_value = "false"
-            
+            sort_database_value = "false"            
         f.write("sort_database=%s\n" % (sort_database_value,))
+
+        if self.oggvorbis_support:
+            oggvorbis_support_value = "true"
+        else:
+            oggvorbis_support_value = "false"
+        f.write("oggvorbis_support=%s\n" % (oggvorbis_support_value,))
 
         for (src,dest) in self.syncdirs:
             f.write("\nbegin sync\n")

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list