def on_xmms_playlist_changed(self, pls, type, id, pos, newpos): if pos is None and \ type in (xmmsclient.PLAYLIST_CHANGED_ADD, xmmsclient.PLAYLIST_CHANGED_MOVE, xmmsclient.PLAYLIST_CHANGED_REMOVE): self._reload() signals.emit('need-redraw')
def run( self, **kwargs ): if not self.initialized: if not self.init( **kwargs ): return False hasError = False self.resetMainLoopBudget() try: signals.emitNow('app.pre_start') EditorModuleManager.get().startAllModules() self.getProject().getAssetLibrary().scanProject() signals.emitNow('app.start') signals.dispatchAll() self.saveConfig() EditorModuleManager.get().tellAllModulesAppReady() signals.emit('app.ready') #main loop while self.running: self.doMainLoop() except Exception, e: #TODO: popup a alert window? logging.exception( e ) hasError = True
def pushCommand(self, cmd, redo=False): if not cmd.hasHistory(): return cmd.redo() if not self.canUndo(): #TODO: Warning about non-undoable action pass assert not hasattr(cmd, 'inStack') count = len(self.undoStack) cmd.inStack = True cmd.merged = False if count > 0: lastCommand = self.undoStack[count - 1] if cmd.canMerge(lastCommand): cmd.merged = True if count >= self.stackLimit: self.undoStack.pop(0) self.undoStack.append(cmd) if cmd.redo() == False: #failed self.undoStack.pop() return False if not redo: signals.emit('command.new', cmd, self) self.redoStack = [] else: signals.emit('command.redo', cmd, self) return True
def pushCommand( self, cmd, redo = False ): if not cmd.hasHistory(): return cmd.redo() if not self.canUndo(): #TODO: Warning about non-undoable action pass assert not hasattr( cmd, 'inStack' ) count = len( self.undoStack ) cmd.inStack = True cmd.merged = False if count>0: lastCommand = self.undoStack[ count - 1 ] if cmd.canMerge( lastCommand ): cmd.merged = True if count >= self.stackLimit: self.undoStack.pop( 0 ) self.undoStack.append( cmd ) if cmd.redo() == False: #failed self.undoStack.pop() return False if not redo: signals.emit( 'command.new', cmd, self ) self.redoStack = [] else: signals.emit( 'command.redo', cmd, self ) return True
def _loop(self): previous_buffer = '' while self.connected: try: gevent.sleep() # Force a yield. We want to be fair to other connections newdata = self.socket.recv(512) lines = (previous_buffer + newdata).split('\r\n') if not newdata: # No data returned from recv - assume connection is broken self.disconnect('Connection reset by peer') continue # If newdata cuts off the end of a command, store it and we'll get the rest next time through if not newdata.endswith('\r\n'): previous_buffer = lines.pop() else: previous_buffer = '' # Clear it out for the next time round for line in lines: message = line.strip() if message == '': continue # Ignore empty messages self.raw_logger.debug('<' + message) signals.emit('server incoming', (self, line)) except socket.error, e: self.disconnect(e[1]) # Element 1 is the error message continue
def server_event(server, data, prefix): data = data.strip() cmd_match = re.match("(?P<command>[^ ]+) (?P<params>.*)", data) command, params = cmd_match.group('command'), cmd_match.group('params') params = _process_params(params) signals.emit('event %s' % command.lower(), (server, params, prefix))
def insert_marked(self, pos=None): m = self.marked_data.values() if not m: w, p = self.get_focus() if w is None: return m = [w.mid] idl = coll.IDList() idl.ids += m if pos is None: self.xs.playlist_add_collection(idl, ['id'], sync=False) else: self.xs.playlist_insert_collection(int(pos), idl, ['id'], sync=False) n = len(idl.ids) pos_s = pos is not None and "at position %d" % (pos + 1) or '' msg = "added %d song%s to playlist %s" % (n, n > 1 and 's' or '', pos_s) signals.emit('show-message', msg)
def run(self, **kwargs): if not self.initialized: if not self.init(**kwargs): return False hasError = False self.resetMainLoopBudget() try: signals.emitNow('app.pre_start') EditorModuleManager.get().startAllModules() self.getProject().getAssetLibrary().scanProject() signals.emitNow('app.start') signals.dispatchAll() self.saveConfig() EditorModuleManager.get().tellAllModulesAppReady() signals.emit('app.ready') #main loop while self.running: self.doMainLoop() except Exception, e: #TODO: popup a alert window? logging.exception(e) hasError = True
def unloadModule(self, m): self.moduleChanged = True if m.isDependentUnloaded(): signals.emit('module.unload', m) m.unload() return True else: return False
def unloadModule( self, m ): self.moduleChanged = True if m.isDependentUnloaded(): signals.emit('module.unload',m) m.unload() return True else: return False
def _on_collection_changed(self, r): if not r.iserror(): v = r.value() signals.emit('xmms-collection-changed', v['name'], v['type'], v.get('namespace'), v.get('newname'))
def _on_playlist_changed(self, r): if not r.iserror(): v = r.value() signals.emit('xmms-playlist-changed', v['name'], v['type'], v.get('id'), v.get('position'), v.get('newposition'))
def on_medialib_entry_changed(self, mid): if mid in self.song_widgets: del self.song_widgets[mid] for pos in self.feeder.id_positions(mid): try: del self.row_widgets[pos] except KeyError: pass signals.emit('need-redraw')
def on_xmms_collection_changed(self, pls, type, namespace, newname): if namespace == 'Playlists' and type != xmmsclient.COLLECTION_CHANGED_UPDATE: if pls == self.cur_active: self.cur_active = newname self.clear_attrs() self._set_active_attr(None, self.cur_active) signals.emit('need-redraw')
def _update(self): self.ctx['status'] = HeaderBar.status_desc[self.status] self.ctx['elapsed'] = util.humanize_time(self.time) if 'duration' in self.info: self.ctx['total'] = util.humanize_time(self.info['duration']) self.text.set_text(self.parser.eval(self.ctx)) self._invalidate() signals.emit('need-redraw')
def on_xmms_playlist_changed(self, pls, type, id, pos, newpos): if pls != self.pls: return if type != xmmsclient.PLAYLIST_CHANGED_ADD: self.row_widgets = {} self.set_focus(self.focus) signals.emit('need-redraw')
def _namelist(self, server, params, prefix): if server == self.server and params[-2] == self.name: # params[0] is the channel nicks = [] #TODO: Make this do things for user in self.namelist_split.finditer(params[-1]): nick = user.group('nick') if nick in self.nicks: continue # Ignore this nick self.nicks[nick] = Nick(server, nick, mode=user.group('mode')) signals.emit('channel name reply', (server, self, nicks))
def on_xmms_collection_changed(self, pls, type, namespace, newname): if namespace == 'Playlists': if type == xmmsclient.COLLECTION_CHANGED_RENAME: try: del self._walkers[pls] if pls == self.active_pls: self.load(newname) except KeyError: pass signals.emit('need-redraw')
def run(self): self.lyrics.set_info("searching...") signals.emit('need-redraw') results = lyricwiki.get_google_results(self.query) if self.abort: return self.lyrics.show_results(results)
def unregisterModule(self, m): if m.alive: if m.isDependentUnloaded(): self.moduleChanged = True m.unload() del self.modules[m.getName()] self.moduleQueue.remove(m) signals.emit( 'module.unregister', m ) else: return False
def unregisterModule(self, m): if m.alive: if m.isDependentUnloaded(): self.moduleChanged = True m.unload() del self.modules[m.getName()] self.moduleQueue.remove(m) signals.emit('module.unregister', m) else: return False
def queue_current(self): item = super(ArtistWalker, self)._get_raw(self.focus) if item is None: return None song_id = None for song in self.mpc.find('artist', item): sid = self.mpc.addid(song['file']) if song_id is None: song_id = sid signals.emit('user_notification', 'Adding artist "%s"' % item) return song_id
def queue_current(self): item = super(AlbumWalker, self)._get_raw(self.focus) if item is None: return None song_id = None for song in self.mpc.find('artist', self.artist, 'album', item['album']): sid = self.mpc.addid(song['file']) if song_id is None: song_id = sid signals.emit('user_notification', 'Adding album "%s" - %s' % (item['album'], self.artist)) return song_id
def registerAssetNode(self, node): path = node.getNodePath() logging.info('register: %s' % repr(node)) if self.assetTable.has_key(path): raise Exception('unclean path: %s', path) self.assetTable[path] = node signals.emit('asset.register', node) for child in node.getChildren(): self.registerAssetNode(child) node.restoreMetaData() return node
def registerAssetNode( self, node ): path = node.getNodePath() logging.info( 'register: %s' % repr(node) ) if self.assetTable.has_key(path): raise Exception( 'unclean path: %s', path) self.assetTable[path] = node signals.emit( 'asset.register', node ) for child in node.getChildren(): self.registerAssetNode(child) node.restoreMetaData() return node
def undoCommand(self, popCommandOnly=False): count = len(self.undoStack) if count > 0: cmd = self.undoStack[count - 1] if not popCommandOnly: if cmd.undo() == False: return False self.undoStack.pop() self.redoStack.append(cmd) signals.emit('command.undo', cmd, self) if cmd.merged: return self.undoCommand(popCommandOnly) else: return True return False
def undoCommand( self, popCommandOnly = False ): count = len( self.undoStack ) if count>0: cmd = self.undoStack[ count-1 ] if not popCommandOnly: if cmd.undo() == False: return False self.undoStack.pop() self.redoStack.append( cmd ) signals.emit( 'command.undo', cmd, self ) if cmd.merged: return self.undoCommand( popCommandOnly ) else: return True return False
def main_loop(self): self.size = self.ui.get_cols_rows() xmmsfd = self.xs.xmms.get_fd() stdinfd = sys.stdin.fileno() while True: if self.need_redraw: self.redraw() input_keys = None w = self.xs.xmms.want_ioout() and [xmmsfd] or [] try: (i, o, e) = select.select([xmmsfd, stdinfd, self._pipe[0]], w, []) except select.error: i = [xmmsfd, stdinfd] if not self.xs.connected: print >> sys.stderr, "disconnected from server" sys.exit(0) # TODO for fd in i: if fd == xmmsfd: self.xs.ioin() elif fd == stdinfd: input_keys = self.ui.get_input() elif fd == self._pipe[0]: os.read(self._pipe[0], 1) if o and o[0] == xmmsfd: self.xs.ioout() if not input_keys: continue self.statusarea.clear_message() for k in input_keys: if self.show_key: signals.emit('show-message', 'key: %s' % config.urwid_key_to_key(k)) self.show_key = False continue try: if k == 'window resize': self.size = self.ui.get_cols_rows() signals.emit('window-resized', self.size) elif self.view.keypress(self.size, k) is None: continue elif self.cm.run_key(k, self.view.body.get_contexts() + [self]): continue elif k == ':': self.show_command_prompt() else: signals.emit('show-message', "unbound key: %s" % k, 'error') except commands.CommandError, e: signals.emit('show-message', "command error: %s" % e, 'error')
def show_results(self, results): try: self.lock.acquire() if self.widget_list[-1] != self.rlb: self.widget_list[-1] = self.rlb self.set_focus(self.rlb) if results: self.rlb.set_rows([widgets.LyricResultWidget(r[0], r[1]) for r in results]) self.set_info() else: self.set_info("no results found :/") self._invalidate() signals.emit('need-redraw') finally: self.lock.release()
def show_results(self, results): try: self.lock.acquire() if self.widget_list[-1] != self.rlb: self.widget_list[-1] = self.rlb self.set_focus(self.rlb) if results: self.rlb.set_rows( [widgets.LyricResultWidget(r[0], r[1]) for r in results]) self.set_info() else: self.set_info("no results found :/") self._invalidate() signals.emit('need-redraw') finally: self.lock.release()
def cmd_save(self, args): # TODO: playlists and playlist types/options args = args.strip() if not args: raise commands.CommandError, 'need some args' name = args q = self.input.edit_text if q and not coll_parser_pattern_rx.search(q): q = ' '.join(['~'+s for s in q.split()]) try: c = coll.coll_parse(q) except ValueError: raise commands.CommandError, 'invalid collection' self.xs.coll_save(c, name, 'Collections', sync=False) signals.emit('show-message', "saved collection %s with pattern %s" % (name, q))
def set_lyrics(self, lyrics): try: self.lock.acquire() in_list_w = self.widget_list[-1] if in_list_w != self.llbw: self.widget_list[-1] = self.llbw if self.focus_item == in_list_w: self.set_focus(self.llbw) if not self.info.get('lyrics'): self.info[('client/generic', 'lyrics')] = lyrics self.llb.set_rows([urwid.Text(l) for l in lyrics.split('\n')]) self.set_info() self._invalidate() signals.emit('need-redraw') finally: self.lock.release()
def cmd_save(self, args): # TODO: playlists and playlist types/options args = args.strip() if not args: raise commands.CommandError, 'need some args' name = args q = self.input.edit_text if q and not coll_parser_pattern_rx.search(q): q = ' '.join(['~' + s for s in q.split()]) try: c = coll.coll_parse(q) except ValueError: raise commands.CommandError, 'invalid collection' self.xs.coll_save(c, name, 'Collections', sync=False) signals.emit('show-message', "saved collection %s with pattern %s" % (name, q))
def insert_by_field(self, field, pos=None): w, p = self.get_focus() if w is None: return info = self.xs.medialib_get_info(w.mid) if field not in info: raise commands.CommandError("the song doesn't have a value for '%s'" % field) c = coll.Equals(field=field, value=info[field].encode('utf-8')) if pos is None: self.xs.playlist_add_collection(c, ['id'], sync=False) else: self.xs.playlist_insert_collection(int(pos), c, ['id'], sync=False) pos_s = pos is not None and "at position %d" % (pos+1) or '' msg = 'added songs matching %s="%s" to playlist %s' % (field, info[field], pos_s) signals.emit('show-message', msg)
def loadModule( self, m, loadDep=True ): if m.alive: return True m.loading = True for n in m.getActualDependency(): m1 = self.affirmModule(n) if m1 == m: continue if not m1.alive: if not loadDep: m.loading = False return False if m1.loading: raise Exception('cyclic dependency:%s -> %s'%( m.getName(), m1.getName()) ) self.loadModule( m1 ) m1.dependent.append( m ) t0 = time.clock() m.load() # print 'loading module', m.getName(), ( time.clock() - t0 ) * 1000 m.loading=False signals.emit('module.load',m) return True
def __call__(self): """Goes back to idling and emits the MPD events to the system.""" # Grab events and idle events = self.fetch_idle() self.send_idle() # Emit events, force redraw if necessary redraw = False for event in events: redraw |= signals.emit('idle_'+event) if redraw: self._mainloop.draw_screen()
def _options_update(self): newflags = self._get_flags() if newflags == self._flags: return False message = None onoff = lambda b: 'On' if b else 'Off' for mode in self._flags_keys: if mode == 'Update': continue if mode == 'Crossfade': if newflags['Crossfade'] != self._flags['Crossfade']: message = '%s set to %s seconds' % (mode, newflags[mode]) elif newflags[mode] != self._flags[mode]: message = '%s mode is %s' % (mode, onoff(newflags[mode])) if message is not None: signals.emit('user_notification', message) self._flags = newflags return self._render_flags()
def __call__(self): """Goes back to idling and emits the MPD events to the system.""" # Grab events and idle events = self.fetch_idle() self.send_idle() # Emit events, force redraw if necessary redraw = False for event in events: redraw |= signals.emit('idle_' + event) if redraw: self._mainloop.draw_screen()
def queue_current(self): item = super(TrackWalker, self)._get_raw(self.focus) if item is None: return None song = self.mpc.find('file', item['file']) if song == []: return None song = song[0] song_id = self.mpc.addid(song['file']) #TODO: Do this like self._format, this is ugly. try: name = item['title'] except KeyError as e: name = item['file'] try: artist = item['artist'] except KeyError as e: artist = config.format.empty_tag signals.emit('user_notification', 'Adding "%s" by %s' % (name, artist)) return song_id
def loadModule(self, m, loadDep=True): if m.alive: return True m.loading = True for n in m.getActualDependency(): m1 = self.affirmModule(n) if m1 == m: continue if not m1.alive: if not loadDep: m.loading = False return False if m1.loading: raise Exception('cyclic dependency:%s -> %s' % (m.getName(), m1.getName())) self.loadModule(m1) m1.dependent.append(m) t0 = time.clock() m.load() # print 'loading module', m.getName(), ( time.clock() - t0 ) * 1000 m.loading = False signals.emit('module.load', m) return True
def load_tab(self, n, wrap=False): tlen = len(self.tabs) if n >= tlen or n < 0: if wrap: n = n % tlen else: return self.prev_tab = self.cur_tab self.cur_tab = n self._update_tabbar_string() self.tab_w._w = self.tabs[n][1] if hasattr(self.tabs[self.cur_tab][1], "tab_loaded"): self.tabs[self.cur_tab][1].tab_loaded() if hasattr(self.tabs[self.prev_tab][1], "tab_unloaded"): self.tabs[self.prev_tab][1].tab_unloaded() signals.emit('need-redraw')
def process_query(self, q): try: self.lock.acquire() caption = 'quick search: ' if q: if coll_parser_pattern_rx.search(q): caption = 'pattern search: ' else: q = ' '.join(['~'+s for s in q.split()]) else: self.lb.walker.clear_cache() try: self.lb.collection = coll.coll_parse(q) except ValueError: signals.emit('show-message', "bad pattern", 'error') self.input.set_caption(caption) signals.emit('need-redraw') self.app.notify() finally: self.lock.release()
def insert_by_field(self, field, pos=None): w, p = self.get_focus() if w is None: return info = self.xs.medialib_get_info(w.mid) if field not in info: raise commands.CommandError( "the song doesn't have a value for '%s'" % field) c = coll.Equals(field=field, value=info[field].encode('utf-8')) if pos is None: self.xs.playlist_add_collection(c, ['id'], sync=False) else: self.xs.playlist_insert_collection(int(pos), c, ['id'], sync=False) pos_s = pos is not None and "at position %d" % (pos + 1) or '' msg = 'added songs matching %s="%s" to playlist %s' % ( field, info[field], pos_s) signals.emit('show-message', msg)
def process_query(self, q): try: self.lock.acquire() caption = 'quick search: ' if q: if coll_parser_pattern_rx.search(q): caption = 'pattern search: ' else: q = ' '.join(['~' + s for s in q.split()]) else: self.lb.walker.clear_cache() try: self.lb.collection = coll.coll_parse(q) except ValueError: signals.emit('show-message', "bad pattern", 'error') self.input.set_caption(caption) signals.emit('need-redraw') self.app.notify() finally: self.lock.release()
def registerModule(self, module, **option): if not isinstance(module, EditorModule): raise Exception('Module expected, given:%s' % type(module)) self.moduleChanged = True name = module.getName() if self.getModule(name): raise Exception('Module name duplicated:%s' % name) self.modules[name] = module self.moduleQueue.append(module) module._app = self._app module._manager = self module.regIndex = len(self.moduleQueue) - 1 module.moduleIndex = None module.alive = False module.active = False module.loading = False module.dependent = [] signals.emit('module.register', module)
def _search_init(self, reverse=False): signals.emit('search_begin', self._search_submit) self._search_reverse = reverse
def set_info(self, msg=""): self.info_w.set_text(msg) self._invalidate() signals.emit('need-redraw')
def update(self): super(MPDClient, self).__getattr__('update')() signals.emit('user_notification', 'Database update started!')
def _onRemoteArgument(data, output): #warning: comes from another thread signals.emit('app.remote', data, output)