Virgil Dupras avatar Virgil Dupras committed 59a541b

Caught up with the default branch.

Comments (0)

Files changed (5)

hsaudiotag/ogg.py

 
 from __future__ import with_statement
 from struct import unpack
+import re
 
 from .util import FileOrPath
 
+RE_STARTS_WITH_DIGIT = re.compile(r"^\d+")
+
 class InvalidFileError(Exception):
     pass
 
 class VorbisComment(object):
     def __init__(self, data):
         def get_field(field_name):
-            data = meta_data.get(field_name, '')
-            return unicode(data, u'utf-8')
+            try:
+                data = meta_data[field_name]
+            except KeyError:
+                data = meta_data.get(field_name.lower(), b'')
+            return unicode(data, 'utf-8')
         
         [vendor_string_length] = unpack('<I', data[:4])
         meta_data_offset = vendor_string_length + 4
             splitted = value.split('=')
             meta_data[splitted[0]] = splitted[1]
             offset += length + 4
-        self.artist = get_field('ARTIST')
-        self.album = get_field('ALBUM')
-        self.title = get_field('TITLE')
-        self.genre = get_field('GENRE')
-        self.track = int(meta_data.get('TRACKNUMBER', 0))
-        self.comment = get_field('COMMENT')
-        self.year = get_field('DATE')
+        self.artist = get_field(b'ARTIST')
+        self.album = get_field(b'ALBUM')
+        self.title = get_field(b'TITLE')
+        self.genre = get_field(b'GENRE')
+        track_str = get_field(b'TRACKNUMBER')
+        m = RE_STARTS_WITH_DIGIT.match(track_str)
+        self.track = int(m.group(0)) if m else 0
+        self.comment = get_field(b'COMMENT')
+        self.year = get_field(b'DATE')
         if not self.year:
             description = get_field('DESCRIPTION')
             if u'YEAR: ' in description:
         
         #Seek last page to get sample count. It's impossible to not have at least one page in
         #the last 64kb.
-        fp.seek(-0x10000, 2)
+        SEEK_OFFSET = min(0x10000, self.size)
+        fp.seek(-SEEK_OFFSET, 2)
         last_data = fp.read()
         last_offset = last_data.rfind(VorbisPage.OGG_PAGE_ID)
-        to_seek = 0x10000 - last_offset
+        to_seek = SEEK_OFFSET - last_offset
         fp.seek(-to_seek, 2)
         page = VorbisPage(fp)
         if not page.valid:

hsaudiotag/tests/ogg_test.py

     eq_(0xf79, o.audio_offset)
     eq_(103168 - 0xf79, o.audio_size)
 
+def test_lowercase_fieldnames():
+    # Support ogg files with lowercase fieldnames (artist, album, etc.)
+    o = ogg.Vorbis(TestData.filepath('ogg/lowercase.ogg'))
+    eq_(o.artist, 'The White Stripes')
+    eq_(o.album, 'The White Stripes')
+    eq_(o.title, 'Astro')
+
+def test_track_with_slash():
+    # A track number field with a slash (for example, 1/20) is supported and will return the first
+    # number of the field.
+    # FILE NOTE: Because I had added 4 bytes to the TRACKNUMBER field in the test file and that I
+    # wasn't sure where I had to adjust the vorbis comment offset other than just in front of the
+    # field, I removed 4 bytes in the otherwise unused TRACKTOTAL (now TRACKT) field.
+    o = ogg.Vorbis(TestData.filepath('ogg/track_with_slash.ogg'))
+    eq_(o.track, 18)
+
+def test_small():
+    # Previously, a small (<64kb) OGG file couldn't be read due to a hardcoded 64kb offset. Tix #2.
+    o = ogg.Vorbis(TestData.filepath('ogg/small.ogg'))
+    eq_(o.bitrate, 60)
+    eq_(o.duration, 4)
+
 def verify_emptyness(o):
     eq_(0, o.bitrate)
     eq_(0, o.sample_rate)
Add a comment to this file

hsaudiotag/tests/testdata/ogg/lowercase.ogg

Binary file added.

Add a comment to this file

hsaudiotag/tests/testdata/ogg/small.ogg

Binary file added.

Add a comment to this file

hsaudiotag/tests/testdata/ogg/track_with_slash.ogg

Binary file added.

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.