Commits

Travis Shirk  committed ee5c953

Chapters access from Tag, example program, etc.

  • Participants
  • Parent commits 35cb007

Comments (0)

Files changed (3)

File examples/chapters.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+################################################################################
+#  Copyright (C) 2012  Travis Shirk <travis@pobox.com>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+################################################################################
+from __future__ import print_function
+import sys
+from eyed3.id3.tag import Tag
+
+def printChapter(chapter):
+    # The element ID is the unique key for this chapter
+    print("== Chapter '%s'" % chapter.element_id)
+    # Start and end time - tuple
+    print("-- Start time: %d; End time: %d" % chapter.times)
+    # Start and end offset - tuple. None is used to set to "no offset"
+    print("-- Start offset: %s; End offset: %s" %
+          tuple((str(o) for o in chapter.offsets)))
+
+tag = Tag()
+if len(sys.argv) > 1:
+    tag.parse(sys.argv[1])
+
+tag.chapters.set("a brand new chapter", (16234, 21546))
+tag.chapters.set("another brand new chapter", (21567, 30000), (654221, 765543))
+tag.chapters.set("final chapter", (40000, 50000))
+
+tag.chapters.set("oops", (21567, 30000), (654221, 765543))
+tag.chapters.remove("oops")
+
+chapter_frame = tag.chapters.get("final chapter")
+chapter_frame.element_id = b"Final Chapter"
+chapter_frame.offsets = (800000, None)
+
+print("-" * 80)
+for chap in tag.chapters:
+    print(chap)
+    printChapter(chap)
+print("-" * 80)

File src/eyed3/id3/frames.py

         if self.ordered:
             flags[ORDERED_FLAG_BIT] = 1
 
-        data = (self.element_id + '\x00' +
+        data = (self.element_id.encode('ascii') + '\x00' +
                 bin2bytes(flags) + dec2bytes(len(self.child_ids)))
 
         for id in self.child_ids:
     <Optional embedded sub-frames>
     '''
 
-    def __init__(self, id=CHAPTER_FID):
+    NO_OFFSET = 4294967295
+    '''No offset value, aka "\xff\xff\xff\xff"'''
+
+    def __init__(self, id=CHAPTER_FID, element_id=None, times=None,
+                 offsets=None, sub_frames=None):
         assert(id == CHAPTER_FID)
         super(ChapterFrame, self).__init__(id)
-        self.element_id = None
-        self.times = StartEndTuple(None, None)
-        self.offsets = StartEndTuple(None, None)
-        self.sub_frames = FrameSet()
+        self.element_id = element_id
+        self.times = times or StartEndTuple(None, None)
+        self.offsets = offsets or StartEndTuple(None, None)
+        self.sub_frames = sub_frames or FrameSet()
 
     def parse(self, data, frame_header):
         from .headers import TagHeader, ExtendedTagHeader
         data = data[4:]
         end = bytes2dec(data[:4])
         data = data[4:]
-        self.offsets = StartEndTuple(start, end)
+        self.offsets = StartEndTuple(start if start != self.NO_OFFSET else None,
+                                     end if end != self.NO_OFFSET else None)
 
         if data:
             dummy_tag_header = TagHeader(self.header.version)
                                             ExtendedTagHeader())
 
     def render(self):
-        data = self.element_id + '\x00'
+        data = self.element_id.encode('ascii') + '\x00'
 
         for n in self.times + self.offsets:
             if n is not None:

File src/eyed3/id3/tag.py

         self._user_texts = UserTextsAccessor(self.frame_set)
         self._unique_file_ids = UniqueFileIdAccessor(self.frame_set)
         self._user_urls = UserUrlsAccessor(self.frame_set)
+        self._chapters = ChaptersAccessor(self.frame_set)
         self.file_info = None
 
     def parse(self, fileobj, version=ID3_ANY_VERSION):
 
         return retval
 
+    @property
+    def chapters(self):
+        return self._chapters
+
 
 ##
 # This class is for storing information about a parsed file. It containts info 
         return super(UserUrlsAccessor, self).get(description)
 
 
+class ChaptersAccessor(AccessorBase):
+    def __init__(self, fs):
+        def match_func(frame, element_id):
+            return frame.element_id == element_id
+        super(ChaptersAccessor, self).__init__(frames.CHAPTER_FID, fs,
+                                               match_func)
+    def set(self, element_id, times, offsets=(None, None), sub_frames=None):
+        flist = self._fs[frames.CHAPTER_FID] or []
+        for chap in flist:
+            if chap.element_id == element_id:
+                # update
+                chap.times, chap.offsets = times, offsets
+                chap.sub_frames = sub_frames
+                return chap
+
+        chap = frames.ChapterFrame(element_id=element_id,
+                                   times=times, offsets=offsets,
+                                   sub_frames=sub_frames or [])
+        self._fs[frames.CHAPTER_FID] = chap
+        return chap
+
+    def remove(self, element_id):
+        return super(ChaptersAccessor, self).remove(element_id)
+
+    def get(self, element_id):
+        return super(ChaptersAccessor, self).get(element_id)
+
 import string
 class TagTemplate(string.Template):
     idpattern = r'[_a-z][_a-z0-9:]*'