Travis Shirk avatar Travis Shirk committed 472b6fe

Table of contents Tag accessor

Comments (0)

Files changed (3)

examples/chapters.py

 if len(sys.argv) > 1:
     tag.parse(sys.argv[1])
 
-if tag.toc:
-    print("=== Table of contents:", tag.toc.element_id)
-    print("--- description:", tag.toc.description)
-    print("--- toplevel:", tag.toc.toplevel)
-    print("--- ordered:", tag.toc.ordered)
-    print("--- child_ids:", tag.toc.child_ids)
+for toc in tag.table_of_contents:
+    print("=== Table of contents:", toc.element_id)
+    print("--- description:", toc.description)
+    print("--- toplevel:", toc.toplevel)
+    print("--- ordered:", toc.ordered)
+    print("--- child_ids:", toc.child_ids)
 
 tag.chapters.set("a brand new chapter", (16234, 21546))
 tag.chapters.set("another brand new chapter", (21567, 30000), (654221, 765543))
 
 # Given a list of chapter IDs from the table of contents access each chapter
 print("+" * 80)
-for chap_id in tag.toc.child_ids:
-    print(chap_id)
-    printChapter(tag.chapters[chap_id])
+for toc in tag.table_of_contents:
+    print("toc:", toc.element_id)
+    for chap_id in toc.child_ids:
+        print(chap_id)
+        printChapter(tag.chapters[chap_id])
 print("+" * 80)
 
+
+## Brand new frames
+tag = Tag()
+toc = tag.table_of_contents.set("toc", toplevel=True,
+                                child_ids=["intro", "chap1", "chap2", "chap3"],
+                                description=u"Table of Contents")
+toc2 = tag.table_of_contents.set("toc2")
+toc.child_ids.append(toc2.element_id)
+chap4 = tag.chapters.set("chap4", times=(100, 200))
+toc2.child_ids.append(chap4.element_id)
+
+try:
+    tag.table_of_contents.set("oops", toplevel=True)
+except ValueError as ex:
+    print("Expected:", ex)
+

src/eyed3/id3/frames.py

     TOP_LEVEL_FLAG_BIT = 6
     ORDERED_FLAG_BIT   = 7
 
-    def __init__(self, id=TOC_FID, elem_id=None, toplevel=True, ordered=True,
+    def __init__(self, id=TOC_FID, element_id=None, toplevel=True, ordered=True,
                  child_ids=None, description=None):
         assert(id == TOC_FID)
         super(TocFrame, self).__init__(id)
 
-        self.element_id = elem_id
+        self.element_id = element_id
         self.toplevel = toplevel
         self.ordered = ordered
         self.child_ids = child_ids or []

src/eyed3/id3/tag.py

         self._unique_file_ids = UniqueFileIdAccessor(self.frame_set)
         self._user_urls = UserUrlsAccessor(self.frame_set)
         self._chapters = ChaptersAccessor(self.frame_set)
+        self._tocs = TocAccessor(self.frame_set)
         self._popularities = PopularitiesAccessor(self.frame_set)
         self.file_info = None
 
                     frames.MusicCDIdFrame(toc=toc)
 
     @property
-    def toc(self):
-        for toc_frame in self.frame_set[frames.TOC_FID]:
-            if toc_frame.toplevel:
-                return toc_frame
-        return None
-
-    @property
     def images(self):
         return self._images
 
     def chapters(self):
         return self._chapters
 
+    @property
+    def table_of_contents(self):
+        return self._tocs
+
 
 ##
 # This class is for storing information about a parsed file. It containts info 
         raise IndexError("chapter '%s' not found" % elem_id)
 
 
+class TocAccessor(AccessorBase):
+    def __init__(self, fs):
+        def match_func(frame, element_id):
+            return frame.element_id == element_id
+        super(TocAccessor, self).__init__(frames.TOC_FID, fs, match_func)
+
+    def __iter__(self):
+        tocs = list(self._fs[self._fid] or [])
+        for toc_frame in tocs:
+            # Find and put top level at the front of the list
+            if toc_frame.toplevel:
+                tocs.remove(toc_frame)
+                tocs.insert(0, toc_frame)
+                break
+
+        for toc in tocs:
+            yield toc
+
+    @requireUnicode("description")
+    def set(self, element_id, toplevel=False, ordered=True, child_ids=None,
+            description=u""):
+        flist = self._fs[frames.TOC_FID] or []
+
+        # Enforce one top-level
+        if toplevel:
+            for toc in flist:
+                if toc.toplevel:
+                    raise ValueError("There may only be one top-level "
+                                     "table of contents. Toc '%s' is current "
+                                     "top-level." % toc.element_id)
+        for toc in flist:
+            if toc.element_id == element_id:
+                # update
+                toc.toplevel = toplevel
+                toc.ordered = ordered
+                toc.child_ids = child_ids
+                toc.description = description
+                return toc
+
+        toc = frames.TocFrame(element_id=element_id, toplevel=toplevel,
+                              ordered=ordered, child_ids=child_ids,
+                              description=description)
+        self._fs[frames.TOC_FID] = toc
+        return toc
+
+    def remove(self, element_id):
+        return super(ChaptersAccessor, self).remove(element_id)
+
+    def get(self, element_id):
+        return super(ChaptersAccessor, self).get(element_id)
+
+    def __getitem__(self, elem_id):
+        '''Overiding the index based __getitem__ for one indexed with table
+        of contents element IDs.'''
+        for toc in (self._fs[frames.TOC_FID] or []):
+            if toc.element_id == elem_id:
+                return toc
+        raise IndexError("toc '%s' not found" % elem_id)
+
+
 
 import string
 class TagTemplate(string.Template):
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.