def readepub(zf): global mw, basefile, ht, conf names = []; allnames = [] mw.waitcursor(True) for aa in zf.infolist(): #print aa.filename, aa.file_size, # Extract if conf.extract: try: dd = conf.data_dir + "/" + basefile + "/" + os.path.split(aa.filename)[0] if not os.path.isdir(dd): os.makedirs(dd) fh = zf.open(aa.filename) fff = dd + "/" + os.path.basename(aa.filename) # Only extract once: if not os.path.isfile(fff): mw.prog.set_text("Extracting '" + aa.filename + "'") usleep(1) fh2 = open(fff, "w+") while 1: sss = fh.readline() if sss == "": break fh2.write(sss) fh2.close() except: print_exception("Cannot extract file") if os.path.splitext(aa.filename)[1].find("htm") >= 0: names.append(aa.filename) allnames.append(aa.filename) #print #names.sort(cmp) #print names found = False for aa in allnames: if "toc.ncx" in aa: #print "Found toc", aa found = True fh = zf.open(aa) ht = TocHTMLParser(mw) while 1: sss = fh.readline() if sss == "": break ht.feed(sss) mw.add_text(sss, True) break # No TOC Open and parse all the [x]htm[l] files if not found: nnn = "000"; mw.update_tree("Start", nnn); mw.add_text_mark(nnn) for bbb in names: openHTML(zf, bbb) nnn = "999"; mw.update_tree("End", nnn); mw.add_text_mark(nnn) mw.waitcursor(False)
def html_tick(fname): global conf, mw conf.recurse = False try: fh = open(fname) ht = pubhtml.HTML_Parser(conf) ht.mw = mw ht.fh = fh ht.getimagecb = getimagecb ln = 0 mw.waitcursor(True) while 1: if conf.recurse: break sss = fh.readline() if ln % 10 == 0: mw.prog.set_text("Reading line: %d" % ln) usleep(1) ln += 1 if sss == "": break if conf.recurse: break if ht.feed(sss): break mw.add_text(sss, True) mw.fname = fname mw.waitcursor(False) except: print_exception("Opening HTML") mw.prog.set_text("Done Loading.") mw.hpaned.set_position(0) mw.gohome()
def reader_tick(): global conf try: readepub(zf) if not conf.nogui: # Seen this ebook before? seb = mw.conf.sql.get(conf.basefile) if seb and seb != "": #print "opening remembered file", seb openHTMLcb(seb) # Seen this html before? Go to offset. comp = conf.basefile + "/" + seb offs = mw.conf.sql.get(comp) if offs != None: #print "seen", mw.fname, offs iter = mw.buffer_1.get_iter_at_offset(int(offs)) mw.buffer_1.place_cursor(iter) mw.view.scroll_to_iter(iter, 0.2) #, True, 0, 0) # Load last selection comp = conf.basefile + "_sel" lsel = mw.conf.sql.get(comp) mw.sel_tree(lsel) #print "lastsel", comp, lsel else: #print "opening first link", conf.ht.firstlink openHTMLcb(conf.ht.firstlink) # Requested command line read if conf.read: mw.read_tts(None) except: print_exception("Reader tick")
def stop_tts(self): self.stopspeak = True try: pubutil.withps(self.stop_tts2) except: pubutil.print_exception("Cannot kill") #self.speech_pid.pid self.speech_pid = None self.butt4.set_label("_Read") return
def openHTML(zf, fname, mark = True): # Is it a tagged link? ppp = fname.find("#") spl = [] if spl >= 0: spl = fname.split("#") fname = spl[0] # Not loaded, load if mw.fname != fname: mw.clear(); mw.clear(True); found = False; fh = None try: fh = zf.open(fname) found = True except: #print "searching for", fname, sys.exc_info() # Search for it ... for aa in zf.infolist(): #print aa.filename, fname if os.path.basename(aa.filename) == fname: try: fh = zf.open(aa.filename) except: print_exception("No Zip File") return found = True break if not found: return False try: #ht = MyHTMLParser(mw) ht = pubhtml.HTML_Parser() ht.mw = mw; ht.mark = mark; ht.fh = fh mw.waitcursor(True) while 1: sss = fh.readline() if sss == "": break if ht.feed(sss): break mw.add_text(sss, True) mw.fname = fname mw.waitcursor(False) except: print_exception("Parsing HTML") # Jump to tag, if any if len(spl) > 1: #print "Jumping to", "'" + spl[1] + "'" mm = mw.buffer_1.get_mark(spl[1]) if mm: mw.view.scroll_to_mark(mm, 0.0, True, 0, 0) return True
def speak(self, cstr): fname = self.conf.data_dir + "/festival.txt" try: fh = open(fname, "w") fh.write(cstr) except: pubutil.print_exception("Cannot create festival file") return self.speech_pid = subprocess.Popen(["festival", "--tts", fname]) #print "started", self.speech_pid.pid gobject.timeout_add(100, self.check_speak)
def openHTMLcb(fname, addback = True): global gzf, backlist ret = False #print "openHTMLcb", fname try: if addback: backlist.append(fname) ret = openHTML(gzf, fname, False) gobject.timeout_add(100, size_tick) except: print_exception("Cannot load HTML") return ret
def sel_next(self, dir=False): #print "sel_next", self.lastsel try: # Move tree selection sel = self.treeview.get_selection() xmodel, xiter = sel.get_selected() next = xmodel.iter_next(xiter) if next: sel.select_iter(next) self.lastsel = xmodel.get_value(next, 0) self.tree_sel_row(self.treeview) except: pubutil.print_exception("sel_next") pass
def stop_tts(self): try: dl = os.listdir("/proc") for aa in dl: fname = "/proc/" + aa + "/stat" if os.path.isfile(fname): ff = open(fname, "r").read().split() if self.speech_pid.pid == int(ff[3]): os.kill(int(ff[0]), signal.SIGKILL) except: pubutil.print_exception("Cannot kill", self.speech_pid.pid) self.speech_pid = None self.butt4.set_label("Read") return
def openHTMLcb(fname, addback = True): global conf, gzf, backlist ret = False print "openHTMLcb", fname conf.recurse = True usleep(10) try: if addback: backlist.append(fname) ret = openHTML(gzf, fname, False) gobject.timeout_add(100, size_tick) except: print_exception("Cannot load HTML") conf.recurse = False return ret
def locateroot(): global gzf rootfile = "" try: fh = gzf.open("META-INF/container.xml") ht = RootHTMLParser() while 1: sss = fh.readline() if sss == "": break ht.feed(sss) if conf.rootf: print sss, rootfile = ht.rootfile except: print_exception("No meta data") return rootfile
def sel_tree(self, xstr): #print "sel_tree", self.lastsel try: sel = self.treeview.get_selection() xmodel, xiter = sel.get_selected() iter = xmodel.get_iter_root() while 1: if not iter: break xstr2 = xmodel.get_value(iter, 0) if xstr == xstr2: sel.select_iter(iter) break iter = xmodel.iter_next(iter) except: pubutil.print_exception("sel_tree") pass
def parse_ncx(fname): global conf ret = "", "" try: fh = zf.open(fname) ht = NcxHTMLParser(contentcb) conf.ht = ht while 1: sss = fh.readline() if sss == "": break ht.feed(sss) if conf.header: print sss, if not conf.nogui: mw.add_text(sss, True) ret = ht.title, ht.auth except: print_exception("Cannot parse .ncx file") return ret
def getimagecb(fname): global gzf, conf fullname = "" #print "Image callback", "'" + fname + "'" fh = None try: fh = gzf.open(fname) fullname = fname except: # Search for it ... for aa in zf.infolist(): if os.path.basename(aa.filename) == fname: fullname = aa.filename try: fh = gzf.open(aa.filename) except: print_exception("No image File") return break # Extract image file dd = conf.data_dir + "/" + conf.basefile + "/" + os.path.split(fullname)[0] if not os.path.isdir(dd): os.makedirs(dd) fname2 = dd + "/" + os.path.basename(fullname) if not os.path.isfile(fname2): try: fh2 = open(fname2, "w") while True: buff = fh.read() if len(buff) == 0: break fh2.write(buff) fh.close() fh2.close() except: print_exception("Cannot load image", fname) return pixbuf = gtk.gdk.pixbuf_new_from_file(fname2) return pixbuf
def parse_opf(fname): global conf ret = ("", "") try: fh = zf.open(fname) ht = OpfHTMLParser(content2cb) conf.ht = ht while 1: sss = fh.readline() if sss == "": break if conf.header: print sss, ht.feed(sss) if conf.header: print sss, if not conf.nogui: mw.add_text(sss, True) ret = (ht.title, ht.auth) except: print_exception("Cannot parse .opf file") return ret
def speak(self, cstr): fname = self.conf.data_dir + "/festival.txt" try: fh = open(fname, "w") fh.write(cstr) except: pubutil.print_exception("Cannot create festival file") return try: if FESTIVAL: self.speech_pid = subprocess.Popen( ["festival", "--tts", fname]) else: # This is more configurable, add option as it is displayed below. #self.speech_pid = subprocess.Popen(["espeak", "-f", fname, "-s", "100"]) self.speech_pid = subprocess.Popen( ["espeak", "-f", fname, "-v", "english-us"]) except: print "Cannot start TTS", sys.exc_info() #print "started", self.speech_pid.pid gobject.timeout_add(100, self.check_speak)
def getimagecb(fname): global gzf, conf print "Image callback", "'" + fname + "'" fh = None try: fh = gzf.open(fname) except: #sys.exc_info() #print "searching for", "'" + fname + "'" # Search for it ... for aa in zf.infolist(): #print "search", aa.filename, fname if os.path.basename(aa.filename) == fname: #print "found:", "'" + aa.filename + "'" try: fh = gzf.open(aa.filename) except: print_exception("No image File") return break # Extract image file fname2 = conf.data_dir + "/" + fname try: fh2 = open(fname2, "w") while True: buff = fh.read() if len(buff) == 0: break fh2.write(buff) fh.close() fh2.close() except: print_exception("Cannot load image", fname) return pixbuf = gtk.gdk.pixbuf_new_from_file(fname2) return pixbuf
def main(zf, fname=None): global mw, conf if not conf.nogui: mw = pubdisp.PubView(conf) mw.fname = "" mw.callback = openHTMLcb mw.bscallback = backcb if conf.nogui: reader_tick() else: if zf: gobject.timeout_add(100, reader_tick) else: gobject.timeout_add(100, html_tick, fname) if not conf.nogui: try: gtk.main() except: print_exception("gtk_main")
def sel_prev(self, dir=False): #print "sel_prev", self.lastsel cnt = 0 try: for aa in self.stags: if aa == self.lastsel and cnt > 0: #print "got:", self.xtags[cnt], self.stags[cnt] #print "prev:", self.xtags[cnt-1], self.stags[cnt-1] # Move tree selection sel = self.treeview.get_selection() xmodel, xiter = sel.get_selected() iter = xmodel.get_iter_root() old = None while 1: if not iter: break if xmodel.get_path(iter) == xmodel.get_path(xiter): break old = iter iter = xmodel.iter_next(iter) if old: sel.select_iter(old) self.lastsel = xmodel.get_value(old, 0) # Move in buffer mm = self.buffer_1.get_mark(self.xtags[cnt - 1]) if mm: # Internal tag self.view.scroll_to_mark(mm, 0.0, True, 0, 0) else: # This is an external link self.callback(self.xtags[cnt - 1]) self.view.grab_focus() self.gohome() break cnt += 1 except: pubutil.print_exception("sel_prev") pass
def size_tick(): #print "size_tick" try: mw.apply_size() except: print_exception("Reader tick")
args = conf.comline(sys.argv[1:]) if len(args) < 1: print "Usage: pyepub.py ebookfile" sys.exit(1) basefile = os.path.basename(args[0]) basefile = os.path.splitext(basefile)[0] basefile = basefile.translate(string.maketrans(" {}()", "_____")) conf.data_dir = os.path.expanduser("~/.pyepub") try: os.mkdir(conf.data_dir) except: pass try: conf.fname = args[0] zf = zipfile.ZipFile(args[0]) except: zf = None print_exception("Cannot open zipfile") gzf = zf main(zf)
def openHTML(zf, fname, mark=True): global conf found = False fh = None spl = [] ht = None conf.recurse = False # Is it a link with a tag? spl = fname.split("#") # Not loaded, load if mw.fname != spl[0]: mw.clearall() found = False fh = None usleep(1) try: fh = zf.open(spl[0]) found = True except: for aa in zf.infolist(): if os.path.basename(aa.filename) == os.path.basename(spl[0]): #print "found", aa.filename try: fh = zf.open(aa.filename) except: print_exception("No Zip File") return found = True break if not found: return False try: ht = pubhtml.HTML_Parser(conf) ht.mw = mw ht.mark = mark ht.fh = fh ht.getimagecb = getimagecb ln = 0 mw.waitcursor(True) while 1: if conf.recurse: break if mw.stopload: break sss = fh.readline() if mw.stopload: break if ln % 10 == 0: mw.prog.set_text("Reading line: %d" % ln) usleep(1) ln += 1 if sss == "": break if conf.recurse: break if ht.feed(sss): break mw.add_text(sss, True) mw.fname = spl[0] mw.waitcursor(False) except: print_exception("Parsing HTML") #if mw.stopload: # return mw.prog.set_text("Done Loading.") usleep(10) if mw.stopload: return # Jump to tag, if any if len(spl) > 1: #print "Jumping to", "'" + spl[1] + "'" mm = mw.buffer_1.get_mark(spl[1]) if mm: ii = mw.buffer_1.get_iter_at_mark(mm) mw.buffer_1.place_cursor(ii) mw.view.scroll_to_mark(mm, 0.0, True, 0, 0) else: mw.gohome() return True
def readepub(zf): global mw, conf names = [] allnames = [] if not conf.nogui: mw.waitcursor(True) if conf.extract: print "Extracting epub to:", conf.data_dir + "/" + conf.basefile + "/" for aa in zf.infolist(): if conf.list: print aa.filename, aa.file_size # Extract if conf.extract: try: dd = conf.data_dir + "/" + conf.basefile + "/" + os.path.split( aa.filename)[0] if not os.path.isdir(dd): os.makedirs(dd) fh = zf.open(aa.filename) fff = dd + "/" + os.path.basename(aa.filename) # Only extract once: if not os.path.isfile(fff): if not conf.nogui: tt = "Extracting '" + aa.filename + "'" mw.prog.set_text(tt[-18]) usleep(1) fh2 = open(fff, "w+") while 1: sss = fh.readline() if sss == "": break fh2.write(sss) fh2.close() except: print_exception("Cannot extract file") if os.path.splitext(aa.filename)[1].find("htm") >= 0: names.append(aa.filename) allnames.append(aa.filename) found = False ret1 = None ret2 = None '''rootfile = locateroot() print "rootfile:", rootfile if rootfile != "": found = True if ".ncx" in rootfile: ret1 = parse_ncs(rootfile) if ".opf" in rootfile: ret2 = parse_opf(rootfile)''' # Hack: to simplify parsing we search for an .ncx and .opf file if not found: for aa in allnames: if ".ncx" in aa: #print "Found toc", aa #found = True ret1 = parse_ncx(aa) break if not conf.nogui: mw.update_tree(" --------- ", "") # Fallback if not found: for aa in allnames: if ".opf" in aa: #print "Found opf", aa found = True ret2 = parse_opf(aa) break # Pick from the two optional places auth = ret1[0] try: if auth == "": auth = ret2[0] except: pass title = ret1[1] try: if title == "": title = ret2[1] except: pass if conf.title: print "'" + auth + "' '" + title + "'" if not conf.nogui: old = mw.get_title() mw.set_title(old + " '" + auth + "' '" + title + "'") if conf.nogui: return # No TOC Open and parse all the [x]htm[l] files if not found: nnn = "000" mw.update_tree("Start of Book", nnn) mw.add_text_mark(nnn) for bbb in names: openHTML(zf, bbb) nnn = "999" mw.update_tree("End", nnn) mw.add_text_mark(nnn) mw.waitcursor(False)
def readepub(zf): global mw, conf names = [] allnames = [] if not conf.nogui: mw.waitcursor(True) if conf.extract: print "Extracting epub to:", conf.data_dir + "/" + conf.basefile + "/" # Locate root meta data try: md = zf.open("META-INF/container.xml") if conf.rootf: print md.read() except: print "No meta data, guessing" for aa in zf.infolist(): if conf.list: print aa.filename, aa.file_size # Extract if conf.extract: try: dd = conf.data_dir + "/" + conf.basefile + "/" + os.path.split( aa.filename)[0] if not os.path.isdir(dd): os.makedirs(dd) fh = zf.open(aa.filename) fff = dd + "/" + os.path.basename(aa.filename) # Only extract once: if not os.path.isfile(fff): if not conf.nogui: tt = "Extracting '" + aa.filename + "'" mw.prog.set_text(tt[-18]) usleep(1) fh2 = open(fff, "w+") while 1: sss = fh.readline() if sss == "": break fh2.write(sss) fh2.close() except: print_exception("Cannot extract file") if os.path.splitext(aa.filename)[1].find("htm") >= 0: names.append(aa.filename) allnames.append(aa.filename) found = False ht = None ht2 = None for aa in allnames: if "toc.ncx" in aa: #print "Found toc", aa found = True fh = zf.open(aa) ht = TocHTMLParser(contentcb) conf.ht = ht while 1: sss = fh.readline() if sss == "": break ht.feed(sss) if conf.header: print sss, if not conf.nogui: mw.add_text(sss, True) break if 1: for aa in allnames: if "content.opf" in aa: if not conf.nogui: mw.update_tree("Legacy Entries:", []) #print "Found content", aa found = True fh = zf.open(aa) ht2 = ConHTMLParser(content2cb) while 1: sss = fh.readline() if sss == "": break if conf.header: print sss, ht2.feed(sss) if conf.header: print sss, if not conf.nogui: mw.add_text(sss, True) break auth = "" title = "" try: auth = ht.auth except: pass try: if auth == "": auth = ht2.auth except: pass try: title = ht.title except: pass try: if title == "": title = ht2.title except: pass if conf.title: print "'" + auth + "' '" + title + "'" if not conf.nogui: old = mw.get_title() mw.set_title(old + " '" + auth + "' '" + title + "'") if conf.nogui: return # No TOC Open and parse all the [x]htm[l] files if not found: nnn = "000" mw.update_tree("Start of Book", nnn) mw.add_text_mark(nnn) for bbb in names: openHTML(zf, bbb) nnn = "999" mw.update_tree("End", nnn) mw.add_text_mark(nnn) mw.waitcursor(False) return ht
def openHTML(zf, fname, mark=True): global conf # Is it a tagged link? ppp = fname.find("#") spl = [] if spl >= 0: spl = fname.split("#") fname = spl[0] # Not loaded, load if mw.fname != fname: #print "loading", fname mw.clear() mw.clear(True) found = False fh = None try: fh = zf.open(fname) found = True except: #print "searching for", fname, sys.exc_info() # Search for it ... for aa in zf.infolist(): #print aa.filename, fname if os.path.basename(aa.filename) == fname: try: fh = zf.open(aa.filename) except: print_exception("No Zip File") return found = True break if not found: return False try: ht = pubhtml.HTML_Parser(conf) ht.mw = mw ht.mark = mark ht.fh = fh ht.getimagecb = getimagecb ln = 0 mw.waitcursor(True) while 1: sss = fh.readline() if ln % 10 == 0: mw.prog.set_text("Reading line: %d" % ln) usleep(1) ln += 1 if sss == "": break if ht.feed(sss): break mw.add_text(sss, True) mw.fname = fname mw.waitcursor(False) except: print_exception("Parsing HTML") mw.prog.set_text("Done Reading.") usleep(10) # Jump to tag, if any if len(spl) > 1: #print "Jumping to", "'" + spl[1] + "'" mm = mw.buffer_1.get_mark(spl[1]) ii = mw.buffer_1.get_iter_at_mark(mm) if mm: mw.view.scroll_to_mark(mm, 0.0, True, 0, 0) else: mw.gohome() return True