I have looked over quite a few posts on this here as well as googling for it. I have used other languages but still learning Python and I'm also not as familiar with classes so I think I'm down to something I just don't understand about the way classes act.
I wanted to work on an epub reading app and found roberto alasina's project called integrate and it was a good starting point but it didn't collect metadata and also the epub handling libs are not extracted enough for some of the other things I want to do. So I found dustjacket which is an epub reading class.
The reason I need to extract this further is I need to handle reads of data from multiple parts of the app and not just the reader itself. I plan on adding whoosh to it to enable searching and for the indexing I will need to read the chapters and then index the files. I can do this during the import of the book and don't really need a gui for the actual indexing part.
Anyway in dist jacket I have added logging and I can see that my method is correctly grabbing the table of contents from the epub:
def __parse_oebps(self, epub):
'''Construct the chapter list assuming that the ePub has files in OEBPS/.'''
# Parse the chapters
npoints = self.__toc.findall("//{%(tocns)s}navPoint" % {'tocns': self.__namespaces['ncx']})
for p in npoints:
#rt = p.getroottree()
#title = p.findtext("{%(tocns)s}text" % {'tocns': self.__namespaces['ncx']}) # Label text
title = p.find(
'{http://www.daisy.org/z3986/2005/ncx/}navLabel').find(
'{http://www.daisy.org/z3986/2005/ncx/}text').text
contentfile = p.find("{%(tocns)s}content[@src]" % {'tocns':self.__namespaces['ncx']}).attrib['src'] # Contentfile name
#if self.__has_oebps:
# #contentfile = "OEBPS/" + contentfile
# contentfile = "OEBPS/" + contentfile
# log.info("content file: %s", contentfile)
#return contentfile
#self.chapters.append(EpubChapter(epub, p.attrib['id'], p.attrib['playOrder'], contentfile, title))
if title and contentfile:
log.debug("Title: %s", title)
log.debug("content file: %s", contentfile)
self.chapters.append([title, contentfile])
return self.chapters
I put in the debug logging and can easily see that the instance is properly called from the class and that the title and contentfile is there. this is from the ebubtoc class and is called from this method in the epub class:
def __read_toc(self):
'''Construct the table of contents for this epub'''
self.__toc = EpubToc(self)
for l, c in self.__toc:
log.debug("Title: %s", l)
log.debug("content file: %s", c)
now when this method gets that data is when I get this error:
for l, c in self.__toc:
TypeError: iteration over non-sequence
I have no idea at this point what I'm doing wrong and why this is not working. I can post the rest of the classes I'm using if this is not enough.
Thanks
Your issue, as you show, is this line:
for l, c in self.__toc:
But self.__toc was declared to be:
self.__toc = EpubToc(self)
Bottom line is, you need to iterate over a list, not an object. Something like this should work, you might need a bit of tweaking to get it to work for your specific needs (possible the zip function, for instance)
for c in self.__toc.get_chapter_titles():