def __init__(self,conf,directory,stdscr): self._lock = RLock() self._curseslock = RLock() with self._lock: self._conf = conf self._window = stdscr self._audiobook = AudioBook(conf,directory) curses.curs_set(0) gobject.threads_init() self._mainloop = glib.MainLoop() if conf.default_bindings: charmap = { "^L":"redraw", "q":"quit", " ":"play_pause", "KEY_LEFT":"seek -10", "h":"seek -10", "KEY_RIGHT":"seek +10", "l":"seek +10", "u":"volume +0.1", "d":"volume -0.1", "KEY_UP":"up", "KEY_DOWN":"down", "KEY_HOME":"begin", "KEY_END":"end", "KEY_PPAGE":"ppage", "KEY_NPAGE":"npage", "^I":"swap_view", "*":"mark *", "^J":"select {b}", "1":"buffer store 1", "2":"buffer store 2", "3":"buffer store 3", "4":"buffer store 4", "5":"buffer store 5", "6":"buffer store 6", "7":"buffer store 7", "8":"buffer store 8", "9":"buffer store 9", "0":"buffer store 0", ":":"buffer store :", "+":"buffer store +", "-":"buffer store -", "=":"buffer clear", "KEY_BACKSPACE":"buffer erase"} else: charmap = {} for binding in conf.bind: if len(binding)==2: charmap[binding[0]] = binding[1] elif len(binding)==1: del charmap[binding[0]] (volume_geom, status_geom, reader_geom, select_geom) = self._compute_geom() charmap["KEY_RESIZE"] = "resize" self._reader = Reader(curseslock=self._curseslock, geom=reader_geom, charmap=charmap, fifopath=conf.cmdpipe) self._reader.connect("event",self._on_event) with self._curseslock: self._actuator = Actuator(audiobook=self._audiobook, reader=self._reader) self._volume = Volume(curseslock=self._curseslock, audiobook=self._audiobook, geom=volume_geom) self._status = Status(curseslock=self._curseslock, conf=conf, audiobook=self._audiobook, geom=status_geom, interval=1) self._select = Select(curseslock=self._curseslock, conf=conf, geom=select_geom, audiobook=self._audiobook, reader=self._reader) self._gobject_thread = Thread(target=self._mainloop.run, name="GobjectLoop")
class CursesUI(object): def __init__(self,conf,directory,stdscr): self._lock = RLock() self._curseslock = RLock() with self._lock: self._conf = conf self._window = stdscr self._audiobook = AudioBook(conf,directory) curses.curs_set(0) gobject.threads_init() self._mainloop = glib.MainLoop() if conf.default_bindings: charmap = { "^L":"redraw", "q":"quit", " ":"play_pause", "KEY_LEFT":"seek -10", "h":"seek -10", "KEY_RIGHT":"seek +10", "l":"seek +10", "u":"volume +0.1", "d":"volume -0.1", "KEY_UP":"up", "KEY_DOWN":"down", "KEY_HOME":"begin", "KEY_END":"end", "KEY_PPAGE":"ppage", "KEY_NPAGE":"npage", "^I":"swap_view", "*":"mark *", "^J":"select {b}", "1":"buffer store 1", "2":"buffer store 2", "3":"buffer store 3", "4":"buffer store 4", "5":"buffer store 5", "6":"buffer store 6", "7":"buffer store 7", "8":"buffer store 8", "9":"buffer store 9", "0":"buffer store 0", ":":"buffer store :", "+":"buffer store +", "-":"buffer store -", "=":"buffer clear", "KEY_BACKSPACE":"buffer erase"} else: charmap = {} for binding in conf.bind: if len(binding)==2: charmap[binding[0]] = binding[1] elif len(binding)==1: del charmap[binding[0]] (volume_geom, status_geom, reader_geom, select_geom) = self._compute_geom() charmap["KEY_RESIZE"] = "resize" self._reader = Reader(curseslock=self._curseslock, geom=reader_geom, charmap=charmap, fifopath=conf.cmdpipe) self._reader.connect("event",self._on_event) with self._curseslock: self._actuator = Actuator(audiobook=self._audiobook, reader=self._reader) self._volume = Volume(curseslock=self._curseslock, audiobook=self._audiobook, geom=volume_geom) self._status = Status(curseslock=self._curseslock, conf=conf, audiobook=self._audiobook, geom=status_geom, interval=1) self._select = Select(curseslock=self._curseslock, conf=conf, geom=select_geom, audiobook=self._audiobook, reader=self._reader) self._gobject_thread = Thread(target=self._mainloop.run, name="GobjectLoop") def getGeom(self): with self._lock: return Geometry.fromWindow(self._window) def _compute_geom(self): with self._lock: topgeom = self.getGeom() volume_geom = Geometry( h=min(Volume.HEIGHT,topgeom.h), w=min(Volume.WIDTH,topgeom.w), y=max(0,topgeom.h-Volume.HEIGHT), x=max(0,topgeom.w-Volume.WIDTH)) status_geom = Geometry( h=min(Status.HEIGHT,topgeom.h), w=topgeom.w-volume_geom.w, y=max(0,topgeom.h-Status.HEIGHT), x=0) statusvol_h = max(Volume.HEIGHT,Status.HEIGHT) reader_geom = Geometry( h=min(Reader.HEIGHT,topgeom.h-statusvol_h), w=topgeom.w, y=max(0,topgeom.h-statusvol_h-Reader.HEIGHT), x=0) select_geom = Geometry( h=max(0,topgeom.h-statusvol_h-Reader.HEIGHT), w=topgeom.w, y=0, x=0) return (volume_geom,status_geom,reader_geom,select_geom) def _on_event(self,obj,event): data = event.split() if len(data)>0: cmd = data[0] if cmd=="resize": with self._lock: self._update_layout() return True elif cmd=="redraw": with self._lock: self._reader.update() self._volume.update() self._status.update() self._select.update() return True elif cmd=="quit": self.quit() return True return False def _update_layout(self): with self._lock: with self._curseslock: (volume_geom,status_geom,reader_geom,select_geom) = self._compute_geom() self._reader.setGeom(reader_geom) self._volume.setGeom(volume_geom) self._status.setGeom(status_geom) self._select.setGeom(select_geom) def quit(self): """Shut down the audiobook player. """ with self._lock: self._audiobook.pause() self._mainloop.quit() self._audiobook.quit() self._reader.quit() def run(self,filename,position): """Run the audiobook player. Arguments: filename The filename to start playing at. (Or None to let the player decide.) position The position to start playing at in nanoseconds. (Or none to let the player decide.) """ try: self._audiobook.gst().set_property("volume",self._conf.volume) if(self._conf.autoplay): self._audiobook.play(filename,position) else: self._audiobook.seek(filename,position) self._gobject_thread.start() self._reader.run() except (KeyboardInterrupt, SystemExit): self.quit()