def activatefilelist(self): # before recentering we remove the focus from the playlist in order # to prevent wrong songchanged events being issued (which would lead to # wrong songs being played on the secondary player) self.bottom() self.playlist._recenter() hub.notify(events.activatefilelist())
def run(self): # process events, request and subscription requests coming from # the client while not self.done: type, obj = self._receiveobject() if type == _EVENT: log.debug("server: client sends event '%s'" % obj) hub.notify(obj, priority=-50) elif type == _REQUEST: log.debug("server: requesting %s for client" % `obj`) # extract id rid, obj = obj result = hub.request(obj, priority=-50) log.debug("server: got answer %s" % `result`) # be careful, handler may not exist anymore? try: self.handler._sendobject(_RESULT, (rid, result)) except: pass elif type == _SUBSCRIBE: log.debug("server: client requests subscription for '%s'" % `obj`) # be careful, maybe handler does not exists anymore? try: self.handler.subscribe(obj) except: pass else: log.debug("server: servernetworkreceiver exits: type=%s" % type) self.done = True self.handler.done = True
def keypressed(self, event): if self.hasfocus(): key = event.key # XXX: do we need own keybindings for help? if key in self.keybindings["selectnext"]: self.first = min(self._outputlen(self.iw)-self.ih, self.first+1) elif key in self.keybindings["selectprev"]: self.first = max(0, self.first-1) elif key in self.keybindings["selectnextpage"]: self.first = min(self._outputlen(self.iw)-self.ih, self.first+self.ih) elif key in self.keybindings["selectprevpage"]: self.first = max(0, self.first-self.iw) elif key in self.keybindings["selectfirst"]: self.first = 0 elif key in self.keybindings["selectlast"]: self.first = self._outputlen(self.iw)-self.ih else: self.hide() raise hub.TerminateEventProcessing return self.update() if self.autoclosetime: hub.notify(events.sendeventin(self.hidewindowevent, self.autoclosetime, replace=1)) raise hub.TerminateEventProcessing
def focuschanged(self, event): if self.hasfocus(): sbar = [("PyTone %s" % version.version, config.colors.statusbar.key)] sbar += statusbar.separator sbar += [(version.copyright, config.colors.statusbar.description)] sbar += statusbar.terminate hub.notify(events.statusbar_update(0, sbar))
def addsongdb(self, id, config): """ add songdb with id defined by config return id (or None if player is turned off) """ type = config.type if type=="off": return None if type=="local": import songdbs.sqlite songdb = songdbs.sqlite.songdb(id, config, self.songdbhub) elif type=="remote": import songdbs.remote songdb = songdbs.remote.songdb(id, config.networklocation, self.songdbhub) for postprocessor_name in config.postprocessors: try: metadata.get_metadata_postprocessor(postprocessor_name) except: raise RuntimeError("Unkown metadata postprocesor '%s' for database '%r'" % (postprocessor_name, id)) self.songdbids.append(id) songdb.setName("song database thread (id=%s)" % id) songdb.start() if config.autoregisterer: hub.notify(events.autoregistersongs(id)) hub.notify(events.autoregisterplaylists(id)) return id
def work(self): if self.isplaying(): if ( self.playbackinfo.send_played_skipped_events and self.playbackinfo.song and (self.playbackinfo.song.length < 10 or self.playbackinfo.time > 0.8*self.playbackinfo.song.length) ): song = self.playbackinfo.song hub.notify(events.song_played(song.songdbid, song, time.time()-self.playbackinfo.time)) self.playbackinfo.send_played_skipped_events = False self.play() # request a new song, if none is playing and the player wants to play if self.isstopped() and self.wantplay: self.requestnextsong() # process incoming events self.channel.process() # and notify the rest of any changes in the playback status self.updatestatus() # Now the queue of all pending events has been # cleared. Depending on the player status we can now wait for # further incoming events. if not self.isplaying(): # We sleep a little bit to prevent being overly active # when the event channel is spilled by messages time.sleep(0.2) # In this case, we can safely block since we will be waked # up by any message on the event channel. Thus, event if # we want to request a new song, we can rely on an event # signaling the addition of a new song to the playlist. # Before doing so, we release the player device self._playerreleasedevice() self.channel.process(block=True)
def selectionchanged(self, event): if self.player and self.items[selection] != event.item: if isinstance(event.item, item.song): hub.notify(events.playerplaysong(self.player, event.item)) elif isinstance(event.item, services.playlist.playlistitem): hub.notify(events.playerplaysong(self.player, event.item.song)) self.items[selection] = event.item self.update()
def __init__(self, screen, maxh, maxw, channel): messagewin.messagewin.__init__(self, screen, maxh, maxw, channel, config.colors.helpwindow, _("PyTone Help"), [], config.helpwindow.autoclosetime) sbar = statusbar.generatedescription("general", "showhelp") hub.notify(events.statusbar_update(2, sbar))
def hide(self): """ hide window """ try: self.panel.hide() except: pass else: hub.notify(events.focuschanged())
def focuschanged(self, event): if self.hasfocus(): sbar = statusbar.generatedescription("general", "volumedown") sbar += statusbar.separator sbar += statusbar.generatedescription("general", "volumeup") sbar += statusbar.terminate hub.notify(events.statusbar_update(0, sbar))
def hide(self): """ hide window """ try: self.panel.hide() except: pass else: hub.notify(events.focuschanged())
def bottom(self): """ bring window to bottom""" try: self.panel.bottom() except: pass else: hub.notify(events.focuschanged())
def bottom(self): """ bring window to bottom""" try: self.panel.bottom() except: pass else: hub.notify(events.focuschanged())
def __init__(self, screen, maxh, maxw, channel): messagewin.messagewin.__init__(self, screen, maxh, maxw, channel, config.colors.helpwindow, _("PyTone Help"), [], config.helpwindow.autoclosetime) sbar = statusbar.generatedescription("general", "showhelp") hub.notify(events.statusbar_update(2, sbar))
def show(self): self._resize() self.first = 0 self.top() self.update() if self.autoclosetime: hub.notify(events.sendeventin(self.hidewindowevent, self.autoclosetime, replace=1))
def playernext(self, event): """immediately play next song""" if event.playerid == self.id: # mark playing of song as skipped if it belongs to a playlist if self.playbackinfo.send_played_skipped_events and self.playbackinfo.song: song = self.playbackinfo.song hub.notify(events.song_skipped(song.songdbid, song)) # we also prevent this song from being registered as played self.playbackinfo.send_played_skipped_events = False self.requestnextsong(manual=1)
def statusbar_showmessage(self, event): self.message = event.message if self.message: # make message disappear after a certain time hub.notify(events.sendeventin(self.removemessageevent, 2, replace=1)) self.update() # we want to get a message out immediately, so we force its output curses.panel.update_panels() curses.doupdate()
def show(self): self._resize() self.first = 0 self.top() self.update() if self.autoclosetime: hub.notify( events.sendeventin(self.hidewindowevent, self.autoclosetime, replace=1))
def work(self): # TODO we could look for the next event and set the # timeout accordingly self.channel.process(block=True, timeout=0.5) acttime = time.time() for alarmtime, event, repeat in self.alarms: if alarmtime <= acttime: hub.notify(event) self.alarms.remove((alarmtime, event, repeat)) if repeat: self.alarms.append((alarmtime + repeat, event, repeat))
def top(self): """ bring window to top""" try: self.panel.top() # The following call fixes the redrawing problem when switching between # the filelist and the playlist window reported by Dag Wieers. curses.panel.update_panels() except: pass else: hub.notify(events.focuschanged())
def work(self): # TODO we could look for the next event and set the # timeout accordingly self.channel.process(block=True, timeout=0.5) acttime = time.time() for alarmtime, event, repeat in self.alarms: if alarmtime <= acttime: hub.notify(event) self.alarms.remove((alarmtime, event, repeat)) if repeat: self.alarms.append((alarmtime+repeat, event, repeat))
def updatestatusbar(self): sbar = [] if self.playlist.selected is not None: sbar += statusbar.generatedescription("playlistwindow", "deleteitem") sbar += statusbar.separator sbar += statusbar.generatedescription("playlistwindow", "moveitemup") sbar += statusbar.separator sbar += statusbar.generatedescription("playlistwindow", "moveitemdown") sbar += statusbar.separator sbar += statusbar.generatedescription("playlistwindow", "activatefilelist") hub.notify(events.statusbar_update(0, sbar))
def playlistaddsongtop(self, event): if event.song: song = self._checksong(event.song) if song: newitem = playlistitem(song) for i in range(len(self.items)): if not self.items[i].hasbeenplayed(): self.insert(i, newitem) break else: self.append(newitem) self._playitem(newitem) self._updateplaystarttimes() hub.notify(events.playerplaysong(self.playerid, newitem)) self.notifyplaylistchanged()
def requestinput(self, event): inputwin.requestinput(self, event) if self.inputprompt: self.inputprompt = self.inputprompt + " " sbar = [] sbar += [("Enter", config.colors.statusbar.key), (": " + _("ok"), config.colors.statusbar.description)] sbar += statusbar.separator sbar += [("ESC", config.colors.statusbar.key), (": " + _("cancel"), config.colors.statusbar.description)] sbar += statusbar.terminate hub.notify(events.statusbar_update(0, sbar)) self.update()
def playlistaddsongtop(self, event): if event.song: song = self._checksong(event.song) if song: newitem = playlistitem(song) for i in range(len(self.items)): if not self.items[i].hasbeenplayed(): self.insert(i, newitem) break else: self.append(newitem) self._playitem(newitem) self._updateplaystarttimes() hub.notify(events.playerplaysong(self.playerid, newitem)) self.notifyplaylistchanged()
def requestinput(self, event): inputwin.requestinput(self, event) if self.inputprompt: self.inputprompt = self.inputprompt + " " sbar = [] sbar += [("Enter", config.colors.statusbar.key), (": "+_("ok"), config.colors.statusbar.description)] sbar += statusbar.separator sbar += [("ESC", config.colors.statusbar.key), (": "+_("cancel"), config.colors.statusbar.description)] sbar += statusbar.terminate hub.notify(events.statusbar_update(0, sbar)) self.update()
def updatestatusbar(self): sbar = [] if len(self.items.shistory)>0: sbar += statusbar.generatedescription("filelistwindow", "dirup") sbar += statusbar.separator if self.items.isdirselected(): sbar += statusbar.generatedescription("filelistwindow", "dirdown") sbar += statusbar.separator sbar += statusbar.generatedescription("filelistwindow", "adddirtoplaylist") sbar += statusbar.separator elif self.items.issongselected(): sbar += statusbar.generatedescription("filelistwindow", "addsongtoplaylist") sbar += statusbar.separator sbar += statusbar.generatedescription("filelistwindow", "activateplaylist") hub.notify(events.statusbar_update(0, sbar))
def _song_skipped(self, song): """register skipping of song""" log.debug("skipping song: %r" % song) if not isinstance(song, item.song): log.error("_update_song: song has to be an item.song instance, not a %r instance" % song.__class__) return self._txn_begin() try: self.cur.execute("UPDATE songs SET skipcount = skipcount+1 WHERE id = ?", [song.id]) song.skipcount += 1 except: self._txn_abort() raise else: self._txn_commit() hub.notify(events.songchanged(self.id, song))
def updatestatusbar(self): sbar = [] if len(self.items.shistory)>0: sbar += statusbar.generatedescription("filelistwindow", "dirup") sbar += statusbar.separator if self.items.isdirselected(): sbar += statusbar.generatedescription("filelistwindow", "dirdown") sbar += statusbar.separator sbar += statusbar.generatedescription("filelistwindow", "adddirtoplaylist") sbar += statusbar.separator elif self.items.issongselected(): sbar += statusbar.generatedescription("filelistwindow", "addsongtoplaylist") sbar += statusbar.separator sbar += statusbar.generatedescription("filelistwindow", "activateplaylist") hub.notify(events.statusbar_update(0, sbar))
def updatestatusbar(self): sbar = [] if self.playlist.selected is not None: sbar += statusbar.generatedescription("playlistwindow", "deleteitem") sbar += statusbar.separator sbar += statusbar.generatedescription("playlistwindow", "moveitemup") sbar += statusbar.separator sbar += statusbar.generatedescription("playlistwindow", "moveitemdown") sbar += statusbar.separator sbar += statusbar.generatedescription("playlistwindow", "activatefilelist") hub.notify(events.statusbar_update(0, sbar))
def _song_played(self, song, date_played): """register playing of song""" log.debug("playing song: %r" % song) if not isinstance(song, item.song): log.error("_update_song: song has to be an item.song instance, not a %r instance" % song.__class__) return self._txn_begin() try: self.cur.execute("INSERT INTO playstats (song_id, date_played) VALUES (?, ?)", [song.id, date_played]) self.cur.execute("UPDATE songs SET playcount = playcount+1, date_lastplayed = ? WHERE id = ?", [date_played, song.id]) song.playcount += 1 song.date_lastplayed = date_played song.dates_played.append(date_played) except: self._txn_abort() raise else: self._txn_commit() hub.notify(events.songchanged(self.id, song))
def keypressed(self, event): key = event.key if key in self.keybindings["volumeup"]: self.changevolume(self.stepsize) elif key in self.keybindings["volumedown"]: self.changevolume(-self.stepsize) else: if self.hasfocus(): self.hide() raise hub.TerminateEventProcessing return self.update() if config.mixerwindow.autoclosetime: hub.notify(events.sendeventin(self.hidewindowevent, config.mixerwindow.autoclosetime, replace=1)) raise hub.TerminateEventProcessing
def keypressed(self, event): key = event.key if key in self.keybindings["volumeup"]: self.changevolume(self.stepsize) elif key in self.keybindings["volumedown"]: self.changevolume(-self.stepsize) else: if self.hasfocus(): self.hide() raise hub.TerminateEventProcessing return self.update() if config.mixerwindow.autoclosetime: hub.notify( events.sendeventin(self.hidewindowevent, config.mixerwindow.autoclosetime, replace=1)) raise hub.TerminateEventProcessing
def keypressed(self, event): if self.hasfocus(): key = event.key if key in self.keybindings["selectnext"]: self.playlist.selectnext() elif key in self.keybindings["selectprev"]: self.playlist.selectprev() elif key in self.keybindings["selectnextpage"]: self.playlist.selectnextpage() elif key in self.keybindings["selectprevpage"]: self.playlist.selectprevpage() elif key in self.keybindings["selectfirst"]: self.playlist.selectfirst() elif key in self.keybindings["selectlast"]: self.playlist.selectlast() elif key in self.keybindings["activatefilelist"]: self.activatefilelist() elif key in self.keybindings["moveitemup"]: self.playlist.moveitemup() elif key in self.keybindings["moveitemdown"]: self.playlist.moveitemdown() elif key in self.keybindings["deleteitem"]: self.playlist.deleteselected() elif key in self.keybindings["playselectedsong"]: self.playlist.playselected() elif key in self.keybindings["shuffle"]: hub.notify(events.playlistshuffle()) elif key in self.keybindings["rescan"]: self.playlist.rescanselection(True) elif ord("0")<=key<=ord("5"): self.playlist.rateselection(key-ord("1")+1) elif key in self.keybindings["filelistjumptoselectedsong"]: self.playlist.filelistjumptoselected() self.activatefilelist() else: return self.update() raise hub.TerminateEventProcessing
def rescanselection(self, force): if (isinstance(self.getselected(), item.basedir) or (isinstance(self.getselected(), item.filesystemdir) and self.getselected().isbasedir())): # instead of rescanning of a whole filesystem we start the autoregisterer self.win.sendmessage( _("Scanning for songs in database '%s'...") % self.getselected().songdbid) hub.notify(events.autoregistersongs(self.getselected().songdbid)) elif isinstance(self.getselected(), item.playlists): self.win.sendmessage( _("Rescanning playlists in database '%s'...") % self.getselected().songdbid) hub.notify( events.autoregisterplaylists(self.getselected().songdbid)) else: if self.isdirselected(): # distribute songs over songdbs # Note that we have to ensure that only dbitem.song (and not item.song) instances # are sent to the db songs = self.getselected().getcontentsrecursive() else: songs = [self.getselected()] self.win.sendmessage(_("Rescanning %d song(s)...") % len(songs)) dsongs = {} for song in songs: dsongs.setdefault(song.songdbid, []).append(song) for songdbid, songs in list(dsongs.items()): if songs: hub.notify( events.autoregisterer_rescansongs( songdbid, songs, force))
def keypressed(self, event): if self.hasfocus(): key = event.key if key in self.keybindings["selectnext"]: self.playlist.selectnext() elif key in self.keybindings["selectprev"]: self.playlist.selectprev() elif key in self.keybindings["selectnextpage"]: self.playlist.selectnextpage() elif key in self.keybindings["selectprevpage"]: self.playlist.selectprevpage() elif key in self.keybindings["selectfirst"]: self.playlist.selectfirst() elif key in self.keybindings["selectlast"]: self.playlist.selectlast() elif key in self.keybindings["activatefilelist"]: self.activatefilelist() elif key in self.keybindings["moveitemup"]: self.playlist.moveitemup() elif key in self.keybindings["moveitemdown"]: self.playlist.moveitemdown() elif key in self.keybindings["deleteitem"]: self.playlist.deleteselected() elif key in self.keybindings["playselectedsong"]: self.playlist.playselected() elif key in self.keybindings["shuffle"]: hub.notify(events.playlistshuffle()) elif key in self.keybindings["rescan"]: self.playlist.rescanselection(True) elif ord("0") <= key <= ord("5"): self.playlist.rateselection(key - ord("1") + 1) elif key in self.keybindings["filelistjumptoselectedsong"]: self.playlist.filelistjumptoselected() self.activatefilelist() else: return self.update() raise hub.TerminateEventProcessing
def _add_song(self, song): """add song metadata to database""" log.debug("adding song: %r" % song) if not isinstance(song, metadata.song_metadata): log.error("add_song: song has to be a meta.song instance, not a %r instance" % song.__class__) return self._txn_begin() try: # query and register artist, album_artist and album if song.artist: song.artist_id, newartist = self._queryregisterindex("artists", ["name"], [song.artist]) else: song.artist_id, newartist = None, False if song.album_artist: song.album_artist_id, newartist2 = self._queryregisterindex("artists", ["name"], [song.album_artist]) newartist = newartist or newartist2 if song.album: song.album_id, newalbum = self._queryregisterindex("albums", ["artist_id", "name"], [song.album_artist_id, song.album]) else: song.album_id, newalbum = None, False else: song.album_artist_id = None song.album_id = None newalbum = False # pickle the comments and lyrics lists comments = dumps(song.comments) lyrics = dumps(song.lyrics) # register song self.cur.execute(self._song_insert, [getattr(song, columnname) for columnname in songcolumns_w_indices] + [comments, lyrics]) self.cur.execute("SELECT id FROM songs WHERE url = ?", (song.url,)) r = self.cur.fetchone() song_id = r["id"] # register song tags newtag = False for tag in song.tags: tag_id, newtag2 = self._queryregisterindex("tags", ["name"], [tag]) newtag = newtag or newtag2 self.cur.execute("INSERT INTO taggings (song_id, tag_id) VALUES (?, ?)", (song_id, tag_id)) except: self._txn_abort() raise else: self._txn_commit() if newartist: hub.notify(events.artistschanged(self.id)) if newalbum: hub.notify(events.albumschanged(self.id)) if newtag: hub.notify(events.tagschanged(self.id))
def saveplaylisthandler(self, name, key): name = name.strip() if key == ord("\n") and name != "" and self.items: songs = [item.song for item in self.items if item.song.songdbid == self.songdbid ] hub.notify(events.add_playlist(self.songdbid, name, songs)) # also write playlist to filesystem if name[-4:] != ".m3u": name = name + ".m3u" try: name = os.path.join(config.general.playlistdir, name) file = open(name, "w", encoding="utf-8") for item in self.items: if item.song.url.startswith("file://"): dbstats = hub.request(requests.getdatabasestats(item.song.songdbid)) path = os.path.join(dbstats.basedir, item.song.url[7:]) else: path = item.song.url file.write("%s\n" % path) file.close() except (IOError, OSError): pass
def run(self): """ main loop of control thread """ skipcount = 0 while not self.done: try: key = self.screen.getch() if key==27: # handle escape sequence (e.g. alt+key) key = self.screen.getch()+1024 if key==curses.KEY_MOUSE: mouse = curses.getmouse() x, y = mouse[1:3] state = mouse[4] hub.notify(events.mouseevent(y, x, state)) elif key==curses.KEY_RESIZE: self.resizeterminal() elif key in self.keybindings["exit"]: curses.halfdelay(5) key = self.screen.getch() curses.halfdelay(1) if key in self.keybindings["exit"]: break elif key!=-1: hub.notify(events.keypressed(key), 50) self.channel.process() # update screen if key == -1 or skipcount >= config.general.throttleoutput: curses.panel.update_panels() curses.doupdate() skipcount = 0 else: skipcount += 1 except KeyboardInterrupt: pass
def mouseevent(self, event): if self.enclose(event.y, event.x): y, x = self.stdscrtowin(event.y, event.x) self.top() if event.state & curses.BUTTON1_CLICKED: if x == self.ix + self.iw and self.hasscrollbar: scrollbarbegin, scrollbarheight = self.scrollbardimensions( self.items.top, len(self.items)) if y == self.iy + 1: self.items.selectprev() elif y == self.iy + self.ih - 2: self.items.selectnext() elif self.iy < y < scrollbarbegin: self.items.selectprevpage() elif scrollbarbegin + scrollbarheight <= y < self.iy + self.ih - 2: self.items.selectnextpage() elif self.items.selectbylinenumber(y-self.iy) and \ self.isclickonstring(y, x) and \ self.items.isdirselected(): self.items.dirdown() elif event.state & curses.BUTTON1_DOUBLE_CLICKED: if self.items.selectbylinenumber(y-self.iy) and \ self.isclickonstring(y, x): if self.items.issongselected(): songtoadd = self.items.getselected() self.lastadded = None hub.notify(events.playlistaddsongs([songtoadd])) else: self.lastadded = None self.items.insertrecursiveselection() elif event.state & curses.BUTTON3_CLICKED: self.items.dirup() else: return self.update() raise hub.TerminateEventProcessing
def mouseevent(self, event): if self.enclose(event.y, event.x): y, x = self.stdscrtowin(event.y, event.x) self.top() if event.state & curses.BUTTON1_CLICKED: if x==self.ix+self.iw and self.hasscrollbar: scrollbarbegin, scrollbarheight = self.scrollbardimensions(self.items.top, len(self.items)) if y==self.iy+1: self.items.selectprev() elif y==self.iy+self.ih-2: self.items.selectnext() elif self.iy<y<scrollbarbegin: self.items.selectprevpage() elif scrollbarbegin+scrollbarheight<=y<self.iy+self.ih-2: self.items.selectnextpage() elif self.items.selectbylinenumber(y-self.iy) and \ self.isclickonstring(y, x) and \ self.items.isdirselected(): self.items.dirdown() elif event.state & curses.BUTTON1_DOUBLE_CLICKED: if self.items.selectbylinenumber(y-self.iy) and \ self.isclickonstring(y, x): if self.items.issongselected(): songtoadd = self.items.getselected() self.lastadded = None hub.notify(events.playlistaddsongs([songtoadd])) else: self.lastadded = None self.items.insertrecursiveselection() elif event.state & curses.BUTTON3_CLICKED: self.items.dirup() else: return self.update() raise hub.TerminateEventProcessing
def _delete_song(self, song): """delete song from database""" log.debug("delete song: %r" % song) if not isinstance(song, item.song): log.error("_delete_song: song has to be a item.song instance, not a %r instance" % song.__class__) self._txn_begin() try: # remove song self.cur.execute("DELETE FROM songs WHERE id = ?", [song.id]) # remove corresponding album and artists deletedalbum = self._checkremoveindex("albums", "songs", ["album_id"], song.album_id) deletedartist = self._checkremoveindex("artists", "songs", ["album_artist_id", "artist_id"], song.artist_id) deletedartist |= self._checkremoveindex("artists", "songs", ["album_artist_id", "artist_id"], song.album_artist_id) # query tags in order to be able to delete them (as opposed to album_id, etc., # they are not stored in item.song) tag_ids = [] for r in self.cur.execute("""SELECT DISTINCT tags.id AS tag_id FROM tags JOIN taggings ON (taggings.tag_id =tags.id) WHERE taggings.song_id = ?""", [song.id]): tag_ids.append(r["tag_id"]) # remove taggings deletedtag = False self.cur.execute("DELETE FROM taggings WHERE song_id = ?", [song.id]) for tag_id in tag_ids: deletedtag |= self._checkremoveindex("tags", "taggings", ["tag_id"], tag_id) except: self._txn_abort() raise else: self._txn_commit() if deletedartist: hub.notify(events.artistschanged(self.id)) if deletedalbum: hub.notify(events.albumschanged(self.id)) if deletedtag: hub.notify(events.tagschanged(self.id))
def searchhandler(self, searchstring, key): if key == curses.KEY_BACKSPACE: if self.searchpositions: self.items.selectbynr(self.searchpositions.pop()) elif key in self.keybindings["repeatsearch"]: self.items.selectbyregexp(searchstring, includeselected=False) elif key == ord("\n"): self.searchpositions = [] self.searchstring = searchstring hub.notify(events.activatefilelist()) elif key == 1023: if self.searchpositions: self.items.selectbynr(self.searchpositions.pop()) self.searchpositions = [] self.searchstring = searchstring hub.notify(events.activatefilelist()) else: self.searchpositions.append(self.items.selected) self.items.selectbyregexp(searchstring) # We explicitely issue a selectionchanged event because the # selectbyregexp doesn't do this due to the focus being on the # searchstring input window hub.notify(events.selectionchanged(self.items.getselected())) self.update()
def searchhandler(self, searchstring, key): if key == curses.KEY_BACKSPACE: if self.searchpositions: self.items.selectbynr(self.searchpositions.pop()) elif key in self.keybindings["repeatsearch"]: self.items.selectbyregexp(searchstring, includeselected=False) elif key == ord("\n"): self.searchpositions = [] self.searchstring = searchstring hub.notify(events.activatefilelist()) elif key == 1023: if self.searchpositions: self.items.selectbynr(self.searchpositions.pop()) self.searchpositions = [] self.searchstring = searchstring hub.notify(events.activatefilelist()) else: self.searchpositions.append(self.items.selected) self.items.selectbyregexp(searchstring) # We explicitely issue a selectionchanged event because the # selectbyregexp doesn't do this due to the focus being on the # searchstring input window hub.notify(events.selectionchanged(self.items.getselected())) self.update()
def rescanselection(self, force): if ( isinstance(self.getselected(), item.basedir) or ( isinstance(self.getselected(), item.filesystemdir) and self.getselected().isbasedir()) ): # instead of rescanning of a whole filesystem we start the autoregisterer self.win.sendmessage(_("Scanning for songs in database '%s'...") % self.getselected().songdbid) hub.notify(events.autoregistersongs(self.getselected().songdbid)) elif isinstance(self.getselected(), item.playlists): self.win.sendmessage(_("Rescanning playlists in database '%s'...") % self.getselected().songdbid) hub.notify(events.autoregisterplaylists(self.getselected().songdbid)) else: if self.isdirselected(): # distribute songs over songdbs # Note that we have to ensure that only dbitem.song (and not item.song) instances # are sent to the db songs = self.getselected().getcontentsrecursive() else: songs = [self.getselected()] self.win.sendmessage(_("Rescanning %d song(s)...") % len(songs)) dsongs = {} for song in songs: dsongs.setdefault(song.songdbid, []).append(song) for songdbid, songs in dsongs.items(): if songs: hub.notify(events.autoregisterer_rescansongs(songdbid, songs, force))
def keypressed(self, event): key = event.key if key in self.keybindings["refresh"]: self.refresh() elif key in self.keybindings["playlistdeleteplayedsongs"]: hub.notify(events.playlistdeleteplayedsongs()) elif key in self.keybindings["playlistclear"]: hub.notify(events.playlistclear()) hub.notify(events.activatefilelist()) elif key in self.keybindings["playlistreplay"]: hub.notify(events.playlistreplay()) elif key in self.keybindings["playlistsave"]: hub.notify(events.playlistsave()) elif key in self.keybindings["playlistload"]: hub.notify(events.playlistload()) elif key in self.keybindings["playlisttoggleautoplaymode"]: hub.notify(events.playlisttoggleautoplaymode()) elif key in self.keybindings["showhelp"]: if self.filelistwin.hasfocus(): context = "filelistwindow" elif self.playlistwin.hasfocus(): context = "playlistwindow" else: context = None self.helpwin.showhelp(context) elif key in self.keybindings["showlog"]: self.logwin.show() elif key in self.keybindings["showstats"]: self.statswin.show() elif key in self.keybindings["showiteminfolong"]: self.iteminfowinlong.show() elif key in self.keybindings["showlyrics"]: self.lyricswin.show() elif key in self.keybindings["togglelayout"]: self.layout = self.layout == "onecolumn" and "twocolumn" or "onecolumn" self.resizeterminal() else: log.debug("unknown key: %d" % key)
del config.keybindings.general.volumeup del config.keybindings.general.volumedown # now we start the plugins for pluginmodule, pluginconfig in plugins: plugin_class = pluginmodule.plugin if plugin_class: plugin = plugin_class(self.channel, pluginconfig, self) plugin.start() self.channel.subscribe(events.keypressed, self.keypressed) self.channel.subscribe(events.activateplaylist, self.activateplaylist) self.channel.subscribe(events.activatefilelist, self.activatefilelist) self.channel.subscribe(events.quit, self.quit) hub.notify(events.activatefilelist()) def run(self): """ main loop of control thread """ skipcount = 0 while not self.done: try: key = self.screen.getch() if key==27: # handle escape sequence (e.g. alt+key) key = self.screen.getch()+1024 if key==curses.KEY_MOUSE: mouse = curses.getmouse() x, y = mouse[1:3]
def moveitemdown(self): "move selected item down, if not last" if self.selected is not None and self.selected<len(self)-1: hub.notify(events.playlistmovesongdown(self.getselected().id))
def playselected(self): item = self.getselected() if item: hub.notify(events.playlistplaysong(item.id))
def rescanselection(self, force): if self.selected is not None: song = self.getselectedsong() hub.notify(events.autoregisterer_rescansongs(song.songdbid, [song], force))
def keypressed(self, event): key = event.key if key in self.keybindings["playerstart"] and self.paused: hub.notify(events.playerstart(self.playerid)) elif key in self.keybindings[ "playerpause"] and not self.paused and not self.stopped: hub.notify(events.playerpause(self.playerid)) elif key in self.keybindings["playerstart"]: hub.notify(events.playerstart(self.playerid)) elif key in self.keybindings["playernextsong"]: hub.notify(events.playernext(self.playerid)) elif key in self.keybindings["playerprevioussong"]: hub.notify(events.playerprevious(self.playerid)) elif key in self.keybindings["playerrewind"]: hub.notify(events.playerseekrelative(self.playerid, -2)) elif key in self.keybindings["playerforward"]: hub.notify(events.playerseekrelative(self.playerid, 2)) elif key in self.keybindings["playerstop"]: hub.notify(events.playerstop(self.playerid)) elif key in self.keybindings["playerplayfaster"]: hub.notify(events.playerplayfaster(self.playerid)) elif key in self.keybindings["playerplayslower"]: hub.notify(events.playerplayslower(self.playerid)) elif key in self.keybindings["playerspeedreset"]: hub.notify(events.playerspeedreset(self.playerid)) elif key in self.keybindings["playerratecurrentsong1"]: if self.song: self.song.rate(1) elif key in self.keybindings["playerratecurrentsong2"]: if self.song: self.song.rate(2) elif key in self.keybindings["playerratecurrentsong3"]: if self.song: self.song.rate(3) elif key in self.keybindings["playerratecurrentsong4"]: if self.song: self.song.rate(4) elif key in self.keybindings["playerratecurrentsong5"]: if self.song: self.song.rate(5) else: return raise hub.TerminateEventProcessing
def updatestatusbar(self): if self.song and not self.paused and self.keybindings["playerpause"]: sbar = statusbar.generatedescription("general", "playerpause") else: sbar = statusbar.generatedescription("general", "playerstart") hub.notify(events.statusbar_update(1, sbar))
def _notifyselectionchanged(self): """ helper routine, which issues a selectionchanged event, if window corresponding to list has focus """ if self.win.hasfocus(): hub.notify(events.selectionchanged(self.getselected()))
def filelistjumptoselected(self): song = self.getselectedsong() if song is not None: hub.notify(events.filelistjumptosong(song))
def keypressed(self, event): if self.hasfocus(): key = event.key if key in self.keybindings["selectnext"]: self.items.selectnext() elif key in self.keybindings["selectprev"]: self.items.selectprev() elif key in self.keybindings["selectnextpage"]: self.items.selectnextpage() elif key in self.keybindings["selectprevpage"]: self.items.selectprevpage() elif key in self.keybindings["selectfirst"]: self.items.selectfirst() elif key in self.keybindings["selectlast"]: self.items.selectlast() elif key in self.keybindings["dirdown"] and \ self.items.isdirselected(): self.items.dirdown() elif key in self.keybindings["dirup"]: self.items.dirup() elif key in self.keybindings["addsongtoplaylist"] and \ self.items.issongselected(): songtoadd = self.items.getselected() if self.items.selected is not self.lastadded: self.lastadded = self.items.selected hub.notify(events.playlistaddsongs([songtoadd])) self.items.selectrelative(+1) elif key in self.keybindings["adddirtoplaylist"] and \ self.items.isdirselected(): itemtoadd = self.items.getselected() if self.items.selected is not self.lastadded: self.lastadded = self.items.selected self.items.insertrecursiveselection() self.items.selectrelative(+1) elif key in self.keybindings["playselectedsong"] and \ self.items.issongselected(): songtoplay = self.items.getselected() hub.notify(events.playlistaddsongtop(songtoplay)) elif key in self.keybindings["activateplaylist"]: hub.notify(events.activateplaylist()) elif key in self.keybindings[ "insertrandomlist"] and self.items.isdirselected(): self.items.randominsertrecursiveselection() elif key in self.keybindings["repeatsearch"]: if self.searchstring: self.items.selectbyregexp(self.searchstring, includeselected=False) elif key in self.keybindings["search"]: hub.notify( events.requestinput(_("Search"), "", self.searchhandler)) elif key in self.keybindings["focus"]: hub.notify( events.requestinput(_("Focus on"), "", self.focus_on_handler)) elif key in self.keybindings["rescan"]: self.items.rescanselection(force=True) self.items.selectrelative(+1) elif key in self.keybindings["toggledelete"]: self.items.toggledeleteselection() elif ord("a") <= key - 1024 <= ord("z") or ord( "A") <= key - 1024 <= ord("Z"): self.items.selectbyletter(chr(key - 1024)) elif ord("0") <= key <= ord("5"): if self.items.rateselection(key - ord("1") + 1): self.items.selectrelative(+1) else: return if self.items.selected != self.lastadded: self.lastadded = None self.update() raise hub.TerminateEventProcessing
def focuschanged(self, event): if self.hasfocus(): self.lastadded = None hub.notify(events.selectionchanged(self.items.getselected())) self.update()
def sendmessage(self, message): hub.notify(events.statusbar_showmessage(message)) # allow message to be processed self.channel.process()