def _group_add_service_and_commit(self, group, flags): print_d("name=%s, flags=%x, stype=%s, port=%d" % (self._real_name, flags, self.stype, self.port)) group.AddService('(iiussssqaay)', AVAHI_IF_UNSPEC, AvahiProtocol.UNSPEC, flags, self._real_name, self.stype, '', '', self.port, []) group.Commit()
def _wrap_class(lib, version, base, ptr, prefix, methods): for method in methods: name, ret, args = method[:3] if len(method) > 3 and method[-1] != version: continue try: func = getattr(lib, prefix + name) except AttributeError: # don't fail on missing ones, just in case.. print_d("missing libudev symbol: %r" % (prefix + name)) continue func.argtypes = args func.restype = ret def add_self(f, check_null=False): def check(*args): # the first arg is the pointer to the struct, check for # null pointers before passing it... args[0].contents return f(*args) return check if args and args[0] == ptr: setattr(ptr, name, add_self(func)) else: setattr(base, name, func)
def add(self, func, *args, **kwargs): """Register a routine to run in GLib main loop. func should be a function that returns a Python iterator (e.g. generator) that provides values until it should stop being called. Optional Keyword Arguments: priority -- priority to run at (default GLib.PRIORITY_LOW) funcid -- mutex/removal identifier for this function timeout -- use timeout_add (with given timeout) instead of idle_add (in milliseconds) Only one function with the same funcid can be running at once. Starting a new function with the same ID will stop the old one. If no funcid is given, the function itself is used. The funcid must be usable as a hash key. """ funcid = kwargs.pop("funcid", func) if funcid in self.__routines: remove(funcid) priority = kwargs.pop("priority", GLib.PRIORITY_LOW) timeout = kwargs.pop("timeout", None) print_d("Added copool function %r with id %r" % (func, funcid)) routine = _Routine(self, func, funcid, priority, timeout, args, kwargs) self.__routines[funcid] = routine routine.resume()
def _create_waveform(self, song, points): # Close any existing pipeline to avoid leaks self._clean_pipeline() if not song.is_file: return command_template = """ uridecodebin name=uridec ! audioconvert ! level name=audiolevel interval={} post-messages=true ! fakesink sync=false""" interval = int(song("~#length") * 1E9 / points) print_d("Computing data for each %.3f seconds" % (interval / 1E9)) command = command_template.format(interval) pipeline = Gst.parse_launch(command) pipeline.get_by_name("uridec").set_property("uri", song("~uri")) bus = pipeline.get_bus() self._bus_id = bus.connect("message", self._on_bus_message) bus.add_signal_watch() pipeline.set_state(Gst.State.PLAYING) self._pipeline = pipeline self._new_rms_vals = []
def handle_line(self, app, line): """Parses a command line and executes the command. Can not fail. Args: app (Application) line (fsnative) Returns: fsnative or None """ assert isinstance(line, fsnative) # only one arg supported atm parts = line.split(" ", 1) command = parts[0] args = parts[1:] print_d("command: %r(*%r)" % (command, args)) try: return self.run(app, command, *args) except CommandError as e: print_e(e) except: util.print_exc()
def run(self, app, name, *args): """Execute the command `name` passing args May raise CommandError """ if name not in self._commands: raise CommandError("Unknown command %r" % name) cmd, argcount, optcount = self._commands[name] if len(args) < argcount: raise CommandError("Not enough arguments for %r" % name) if len(args) > argcount + optcount: raise CommandError("Too many arguments for %r" % name) print_d("Running %r with params %s " % (cmd.__name__, args)) try: result = cmd(app, *args) except CommandError as e: raise CommandError("%s: %s" % (name, str(e))) else: if result is not None and not isinstance(result, fsnative): raise CommandError("%s: returned %r which is not fsnative" % (name, result)) return result
def __about_to_finish(self, playbin): print_d("About to finish (async)") try: uri = self._runner.call(self.__about_to_finish_sync, priority=GLib.PRIORITY_HIGH, timeout=0.5) except MainRunnerTimeoutError as e: # Due to some locks being held during this signal we can get # into a deadlock when a seek or state change event happens # in the mainloop before our function gets scheduled. # In this case abort and do nothing, which results # in a non-gapless transition. print_d("About to finish (async): %s" % e) return except MainRunnerAbortedError as e: print_d("About to finish (async): %s" % e) return except MainRunnerError: util.print_exc() return if uri is not None: print_d("About to finish (async): setting uri") playbin.set_property('uri', uri) print_d("About to finish (async): done")
def _update(self, player): if player.info: # Position in ms, length in seconds position = player.get_position() / 1000.0 length = player.info("~#length") remaining = length - position if length != 0: self._waveform_scale.set_position(position / length) else: print_d("Length reported as zero for %s" % player.info) self._waveform_scale.set_position(0) self._elapsed_label.set_time(position) self._remaining_label.set_time(remaining) self._remaining_label.set_disabled(not player.seekable) self._elapsed_label.set_disabled(not player.seekable) self.set_sensitive(player.seekable) else: self._waveform_scale.set_placeholder(True) self._remaining_label.set_disabled(True) self._elapsed_label.set_disabled(True) self.set_sensitive(player.seekable) self._waveform_scale.queue_draw()
def _add_service(self): assert not self._group assert not self._group_id try: bus = dbus.SystemBus() server_obj = bus.get_object(self.DBUS_NAME, self.DBUS_PATH_SERVER) server = dbus.Interface(server_obj, self.DBUS_INTERFACE_SERVER) group_path = server.EntryGroupNew() group_obj = bus.get_object(self.DBUS_NAME, group_path) group = dbus.Interface(group_obj, self.DBUS_INTERFACE_ENTRY_GROUP) self._group_id = group.connect_to_signal( "StateChanged", self._group_state_change) flags = AvahiPublishFlags.NONE print_d("name=%s, flags=%x, stype=%s, port=%d" % ( self._real_name, flags, self.stype, self.port)) group.AddService( AVAHI_IF_UNSPEC, AvahiProtocol.UNSPEC, dbus.UInt32(flags), self._real_name, self.stype, dbus.String(), dbus.String(), dbus.UInt16(self.port), []) group.Commit() self._group = group except dbus.DBusException: self._remove_service()
def plugin_on_song_started(self, song): if (song is None and config.get("memory", "order") != "onesong" and not app.player.paused): browser = app.window.browser if not browser.can_filter('album'): return albumlib = app.library.albums albumlib.load() if browser.can_filter_albums(): keys = browser.list_albums() values = [albumlib[k] for k in keys] else: keys = set(browser.list("album")) values = [a for a in albumlib if a("album") in keys] if self.use_weights: # Select 3% of albums, or at least 3 albums nr_albums = int(min(len(values), max(0.03 * len(values), 3))) chosen_albums = random.sample(values, nr_albums) album_scores = sorted(self._score(chosen_albums)) for score, album in album_scores: print_d("%0.2f scored by %s" % (score, album("album"))) album = max(album_scores)[1] else: album = random.choice(values) if album is not None: self.schedule_change(album)
def plugin_songs(self, songs): # Check this is a launch, not a configure if self.chosen_site: url_pat = self.get_url_pattern(self.chosen_site) pat = Pattern(url_pat) urls = set() for song in songs: # Generate a sanitised AudioFile; allow through most tags subs = AudioFile() for k in (USER_TAGS + MACHINE_TAGS): vals = song.comma(k) if vals: try: encoded = text_type(vals).encode('utf-8') subs[k] = (encoded if k == 'website' else quote_plus(encoded)) # Dodgy unicode problems except KeyError: print_d("Problem with %s tag values: %r" % (k, vals)) url = str(pat.format(subs)) if not url: print_w("Couldn't build URL using \"%s\"." "Check your pattern?" % url_pat) return # Grr, set.add() should return boolean... if url not in urls: urls.add(url) website(url)
def init(app_id): if not dbus: return try: bus = dbus.Bus(dbus.Bus.TYPE_SESSION) manager = bus.get_object("org.gnome.SessionManager", "/org/gnome/SessionManager") iface = dbus.Interface(manager, "org.gnome.SessionManager") client_path = iface.RegisterClient(app_id, "") if client_path is None: # https://github.com/quodlibet/quodlibet/issues/2435 print_w("Broken session manager implementation, likely LXDE") return client = bus.get_object("org.gnome.SessionManager", client_path) client_priv = dbus.Interface(client, "org.gnome.SessionManager.ClientPrivate") def end_session_cb(*args): print_d("GSM sent EndSession: going down") client_priv.EndSessionResponse(True, "") app.quit() def query_end_session_cb(*args): print_d("GSM sent QueryEndSession") client_priv.EndSessionResponse(True, "") client_priv.connect_to_signal("QueryEndSession", query_end_session_cb) client_priv.connect_to_signal("EndSession", end_session_cb) except dbus.DBusException: print_d("Connecting with the gnome session manager failed") else: print_d("Connected with gnome session manager: %s" % client_path)
def failure(source, msg): name = source.__class__.__name__ print_d("Didn't get cover from {0}: {1}".format(name, msg)) source.disconnect_by_func(success) source.disconnect_by_func(failure) if not cancellable or not cancellable.is_cancelled(): run()
def _on_bus_message(self, bus, message): if message.type == Gst.MessageType.ERROR: error, debug = message.parse_error() print_d("Error received from element {name}: {error}".format( name=message.src.get_name(), error=error)) print_d("Debugging information: {}".format(debug)) elif message.type == Gst.MessageType.ELEMENT: structure = message.get_structure() if structure.get_name() == "level": rms_db = structure.get_value("rms") if rms_db: # Calculate average of all channels (usually 2) rms_db_avg = sum(rms_db) / len(rms_db) # Normalize dB value to value between 0 and 1 rms = pow(10, (rms_db_avg / 20)) self._new_rms_vals.append(rms) else: print_w("Got unexpected message of type {}" .format(message.type)) elif message.type == Gst.MessageType.EOS: self._clean_pipeline() # Update the waveform with the new data self._rms_vals = self._new_rms_vals self._waveform_scale.reset(self._rms_vals) self._waveform_scale.set_placeholder(False) self._update_redraw_interval() # Clear temporary reference to the waveform data del self._new_rms_vals
def success(source, result): name = source.__class__.__name__ print_d('Successfully got cover from {0}'.format(name)) source.disconnect_by_func(success) source.disconnect_by_func(failure) if not cancellable or not cancellable.is_cancelled(): callback(True, result)
def _create_waveform(self, song, points): # Close any existing pipelines to avoid warnings if hasattr(self, "_pipeline") and self._pipeline: self._pipeline.set_state(Gst.State.NULL) command_template = """ filesrc name=fs ! decodebin ! audioconvert ! level name=audiolevel interval={} post-messages=true ! fakesink sync=false""" interval = int(song("~#length") * 1E9 / points) print_d("Computing data for each %.3f seconds" % (interval / 1E9)) command = command_template.format(interval) pipeline = Gst.parse_launch(command) pipeline.get_by_name("fs").set_property("location", song("~filename")) bus = pipeline.get_bus() self._bus_id = bus.connect("message", self._on_bus_message) bus.add_signal_watch() pipeline.set_state(Gst.State.PLAYING) self._pipeline = pipeline self._rms_vals = []
def _create_waveform(self, song, points): # Close any existing pipelines to avoid warnings if hasattr(self, "_pipeline") and self._pipeline: self._pipeline.set_state(Gst.State.NULL) self._clean_pipeline() command_template = """ filesrc name=fs ! decodebin ! audioconvert ! level name=audiolevel interval={} post-messages=true ! fakesink sync=false""" interval = int(song("~#length") * 1E9 / points) print_d("Computing data for each %.3f seconds" % (interval / 1E9)) command = command_template.format(interval) pipeline = Gst.parse_launch(command) pipeline.get_by_name("fs").set_property("location", song("~filename")) bus = pipeline.get_bus() self._bus_id = bus.connect("message", self._on_bus_message) bus.add_signal_watch() pipeline.set_state(Gst.State.PLAYING) self._pipeline = pipeline self._new_rms_vals = []
def _remove_empty_dirs(self): """ Delete all empty sub-directories from the given path. """ for root, dirs, __ in os.walk(self.expanded_destination, topdown=False): for dirname in dirs: dir_path = os.path.realpath(os.path.join(root, dirname)) if not os.listdir(dir_path): entry = Entry(None) entry.filename = dir_path entry.tag = Entry.Tags.IN_PROGRESS_DELETE iter_ = self.model.append(row=self._make_model_row(entry)) print_d(_('Removing "{}"').format(entry.filename)) self.c_songs_delete += 1 try: os.rmdir(dir_path) except Exception as ex: entry.tag = Entry.Tags.RESULT_FAILURE + ': ' + str(ex) self._update_model_value(iter_, 'tag', entry.tag) print_exc() self.c_files_failed += 1 else: entry.tag = Entry.Tags.RESULT_SUCCESS self._update_model_value(iter_, 'tag', entry.tag) self.c_files_delete += 1 self._update_sync_summary()
def _group_add_service_and_commit(self, group, flags): print_d("name=%s, flags=%x, stype=%s, port=%d" % ( self._real_name, flags, self.stype, self.port)) group.AddService('(iiussssqaay)', AVAHI_IF_UNSPEC, AvahiProtocol.UNSPEC, flags, self._real_name, self.stype, '', '', self.port, []) group.Commit()
def _update_sync_summary(self): """ Update the synchronization summary text field. """ sync_summary_prefix = _('Synchronization has:') + self.summary_sep sync_summary = [] if self.c_files_copy > 0 or self.c_files_skip > 0: text = [] counter = self.c_files_copy text.append( ngettext('written {count}/{total} file', 'written {count}/{total} files', counter).format(count=counter, total=self.c_songs_copy)) if self.c_files_skip > 0: counter = self.c_files_skip text.append( ngettext('(skipped {count} existing file)', '(skipped {count} existing files)', counter).format(count=counter)) sync_summary.append(self.summary_sep.join(text)) if self.c_files_dupes > 0: counter = self.c_files_dupes sync_summary.append( ngettext('skipped {count}/{total} duplicate file', 'skipped {count}/{total} duplicate files', counter).format(count=counter, total=self.c_song_dupes)) if self.c_files_delete > 0: counter = self.c_files_delete sync_summary.append( ngettext('deleted {count}/{total} file', 'deleted {count}/{total} files', counter).format(count=counter, total=self.c_songs_delete)) if self.c_files_failed > 0: counter = self.c_files_failed sync_summary.append( ngettext('failed to sync {count} file', 'failed to sync {count} files', counter).format(count=counter)) if self.c_files_skip_previous > 0: counter = self.c_files_skip_previous sync_summary.append( ngettext('skipped {count} file synchronized previously', 'skipped {count} files synchronized previously', counter).format(count=counter)) sync_summary_text = self.summary_sep_list.join(sync_summary) sync_summary_text = sync_summary_prefix + sync_summary_text self.status_progress.set_label(sync_summary_text) print_d(sync_summary_text)
def __show_quodlibet_uri(uri): if uri.path.startswith("/prefs/plugins/"): from .pluginwin import PluginWindow print_d("Showing plugin prefs resulting from URI (%s)" % (uri, )) return PluginWindow().move_to(uri.path[len("/prefs/plugins/"):]) else: return False
def _create_waveform(self, song, points): # Close any existing pipeline to avoid leaks self._clean_pipeline() if not song.is_file: return command_template = """ uridecodebin name=uridec ! audioconvert ! level name=audiolevel interval={} post-messages=true ! fakesink sync=false""" interval = int(song("~#length") * 1E9 / points) if not interval: return print_d("Computing data for each %.3f seconds" % (interval / 1E9)) command = command_template.format(interval) pipeline = Gst.parse_launch(command) pipeline.get_by_name("uridec").set_property("uri", uri2gsturi(song("~uri"))) bus = pipeline.get_bus() self._bus_id = bus.connect("message", self._on_bus_message, points) bus.add_signal_watch() pipeline.set_state(Gst.State.PLAYING) self._pipeline = pipeline self._new_rms_vals = []
def _add_service(self): assert not self._group assert not self._group_id try: bus = dbus.SystemBus() server_obj = bus.get_object(self.DBUS_NAME, self.DBUS_PATH_SERVER) server = dbus.Interface(server_obj, self.DBUS_INTERFACE_SERVER) group_path = server.EntryGroupNew() group_obj = bus.get_object(self.DBUS_NAME, group_path) group = dbus.Interface(group_obj, self.DBUS_INTERFACE_ENTRY_GROUP) self._group_id = group.connect_to_signal("StateChanged", self._group_state_change) flags = AvahiPublishFlags.NONE print_d("name=%s, flags=%x, stype=%s, port=%d" % (self._real_name, flags, self.stype, self.port)) group.AddService(AVAHI_IF_UNSPEC, AvahiProtocol.UNSPEC, dbus.UInt32(flags), self._real_name, self.stype, dbus.String(), dbus.String(), dbus.UInt16(self.port), []) group.Commit() self._group = group except dbus.DBusException: self._remove_service()
def plugin_on_song_started(self, song): one_song = app.player_options.single if song is None and not one_song and not app.player.paused: browser = app.window.browser if self.disabled_for_browser(browser): return albumlib = app.library.albums albumlib.load() if browser.can_filter_albums(): keys = browser.list_albums() values = [albumlib[k] for k in keys] else: keys = set(browser.list("album")) values = [a for a in albumlib if a("album") in keys] if self.use_weights: # Select 3% of albums, or at least 3 albums nr_albums = int(min(len(values), max(0.03 * len(values), 3))) chosen_albums = random.sample(values, nr_albums) album_scores = sorted(self._score(chosen_albums)) for score, album in album_scores: print_d("%0.2f scored by %s" % (score, album("album"))) album = max(album_scores)[1] else: album = random.choice(values) if album is not None: self.schedule_change(album)
def remove(self, funcid): """Stop a registered routine.""" routine = self._get(funcid) routine.pause() del self.__routines[funcid] print_d("Removed copool function id %r" % funcid)
def _start_preview(self, button): """ Start the generation of export paths for all songs. :param button: The start preview button. """ print_d(_('Starting synchronization preview')) self.running = True # Summary labels self.status_operation.set_label( _('Synchronization preview in progress.')) self.status_operation.set_visible(True) self.status_progress.set_visible(False) self.status_duplicates.set_visible(False) self.status_deletions.set_visible(False) # Change button visibility self.preview_start_button.set_visible(False) self.preview_stop_button.set_visible(True) self.c_songs_copy = self.c_song_dupes = self.c_songs_delete = 0 if self._run_preview() is None: return self._stop_preview() self.sync_start_button.set_sensitive(True) print_d(_('Finished synchronization preview'))
def _start_sync(self, button): """ Start the song synchronization. :param button: The start sync button. """ # Check sort column sort_columns = [ c.get_title() for c in self.details_tree.get_columns() if c.get_sort_indicator() ] if 'Status' in sort_columns: self._show_sync_error( _('Unable to sync'), _('Cannot start synchronization while ' 'sorting by <b>Status</b>.')) return print_d(_('Starting song synchronization')) self.running = True # Summary labels self.status_operation.set_label(_('Synchronization in progress.')) self.status_duplicates.set_visible(False) self.status_deletions.set_visible(False) # Change button visibility self.sync_start_button.set_visible(False) self.sync_stop_button.set_visible(True) if not self._run_sync(): return self._stop_sync() print_d(_('Finished song synchronization'))
def _get_songs_from_queries(self): """ Build a list of songs to be synchronized, filtered using the selected saved searches. :return: A list of the selected songs. """ enabled_queries = [] for query_name, query in self.queries.items(): query_config = self.CONFIG_QUERY_PREFIX + query_name if self.config_get_bool(query_config): enabled_queries.append(query) if not enabled_queries: self._show_sync_error( _('No saved searches selected'), _('Please select at least one saved search.')) return [] selected_songs = [] for song in app.library.itervalues(): if any(query.search(song) for query in enabled_queries): selected_songs.append(song) if not selected_songs: self._show_sync_error(_('No songs in the selected saved searches'), _('All selected saved searches are empty.')) return [] print_d(_('Found {} songs to synchronize').format(len(selected_songs))) return selected_songs
def _on_bus_message(self, bus, message): if message.type == Gst.MessageType.ERROR: error, debug = message.parse_error() print_d("Error received from element {name}: {error}".format( name=message.src.get_name(), error=error)) print_d("Debugging information: {}".format(debug)) elif message.type == Gst.MessageType.ELEMENT: structure = message.get_structure() if structure.get_name() == "level": rms_db = structure.get_value("rms") # Calculate average of all channels (usually 2) rms_db_avg = sum(rms_db) / len(rms_db) # Normalize dB value to value between 0 and 1 rms = pow(10, (rms_db_avg / 20)) self._new_rms_vals.append(rms) else: print_w("Got unexpected message of type {}".format( message.type)) elif message.type == Gst.MessageType.EOS: self._clean_pipeline() # Update the waveform with the new data self._rms_vals = self._new_rms_vals self._waveform_scale.reset(self._rms_vals) self._waveform_scale.set_placeholder(False) self._update_redraw_interval() # Clear temporary reference to the waveform data del self._new_rms_vals
def run(self, app, name, *args): """Execute the command `name` passing args May raise CommandError """ if name not in self._commands: raise CommandError("Unknown command %r" % name) cmd, argcount, optcount = self._commands[name] if len(args) < argcount: raise CommandError("Not enough arguments for %r" % name) if len(args) > argcount + optcount: raise CommandError("Too many arguments for %r" % name) print_d("Running %r with params %s " % (cmd.__name__, args)) try: result = cmd(app, *args) except CommandError as e: raise CommandError("%s: %s" % (name, str(e))) else: if result is not None and not isinstance(result, fsnative): raise CommandError( "%s: returned %r which is not fsnative" % (name, result)) return result
def __about_to_finish_sync(self): """Returns a tuple (ok, next_song). ok is True if the next song should be set. """ print_d("About to finish (sync)") # Chained oggs falsely trigger a gapless transition. # At least for radio streams we can safely ignore it because # transitions don't occur there. # https://github.com/quodlibet/quodlibet/issues/1454 # https://bugzilla.gnome.org/show_bug.cgi?id=695474 if self.song.multisong: print_d("multisong: ignore about to finish") return (False, None) if config.getboolean("player", "gst_disable_gapless"): print_d("Gapless disabled") return (False, None) # this can trigger twice, see issue 987 if self._in_gapless_transition: return (False, None) self._in_gapless_transition = True print_d("Select next song in mainloop..") self._source.next_ended() print_d("..done.") return (True, self._source.current)
def plugin_songs(self, songs): # Check this is a launch, not a configure if self.chosen_site: url_pat = self.get_url_pattern(self.chosen_site) pat = Pattern(url_pat) urls = set() for song in songs: # Generate a sanitised AudioFile; allow through most tags subs = AudioFile() for k in (USER_TAGS + MACHINE_TAGS): vals = song.comma(k) if vals: try: encoded = unicode(vals).encode('utf-8') subs[k] = (encoded if k == 'website' else quote_plus(encoded)) # Dodgy unicode problems except KeyError: print_d("Problem with %s tag values: %r" % (k, vals)) url = str(pat.format(subs)) if not url: print_w("Couldn't build URL using \"%s\"." "Check your pattern?" % url_pat) return # Grr, set.add() should return boolean... if url not in urls: urls.add(url) website(url)
def go_to(self, song_or_iter, explicit=False, source=None): """Switch the current active song to song. song can be an Gtk.TreeIter or AudioFile. explicit should be True of the action comes from the user. source should be this model or None. """ assert source is None or source is self print_d("Told to go to %r" % getattr(song_or_iter, "key", song_or_iter)) iter_ = None if isinstance(song_or_iter, Gtk.TreeIter): iter_ = song_or_iter elif song_or_iter is not None: # We were told to go to a song that was valid but couldn't find it. # Set it as last current so it gets set current when we find it in # the future. self.last_current = song_or_iter iter_ = self.find(song_or_iter) if explicit: self.current_iter = self.order.set_explicit(self, iter_) else: self.current_iter = self.order.set_implicit(self, iter_) return self.current_iter
def __about_to_finish_sync(self): """Returns the next song uri to play or None""" print_d("About to finish (sync)") # Chained oggs falsely trigger a gapless transition. # At least for radio streams we can safely ignore it because # transitions don't occur there. # https://github.com/quodlibet/quodlibet/issues/1454 # https://bugzilla.gnome.org/show_bug.cgi?id=695474 if self.song.multisong: print_d("multisong: ignore about to finish") return # mod + gapless deadlocks # https://github.com/quodlibet/quodlibet/issues/2780 if isinstance(self.song, ModFile): return if config.getboolean("player", "gst_disable_gapless"): print_d("Gapless disabled") return # this can trigger twice, see issue 987 if self._in_gapless_transition: return self._in_gapless_transition = True print_d("Select next song in mainloop..") self._source.next_ended() print_d("..done.") song = self._source.current if song is not None: return song("~uri")
def __destroy_pipeline(self): print_d("Destroying Gstreamer pipeline") self._remove_plugin_elements() if self.__bus_id: bus = self.bin.get_bus() bus.disconnect(self.__bus_id) bus.remove_signal_watch() self.__bus_id = None if self.__atf_id: self.bin.disconnect(self.__atf_id) self.__atf_id = None if self._seeker is not None: self._seeker.destroy() self._seeker = None self.notify("seekable") if self.bin: self.bin.set_state(Gst.State.NULL) self.bin.get_state(timeout=STATE_CHANGE_TIMEOUT) # BufferingWrapper cleanup self.bin.destroy() self.bin = None self._in_gapless_transition = False self._ext_vol_element = None self._int_vol_element = None self._ext_mute_element = None self._eq_element = None
def send(self): """ Send the request and receive HTTP headers. Some of the body might get downloaded too. """ print_d('Sending {1} request to {0}'.format(self._uri, self.message.method)) session.send_async(self.message, self.cancellable, self._sent, None)
def _get_saved_searches(self): filename = self.PATTERNS_FILE + ".saved" self._url_pats = StandaloneEditor.load_values(filename) # Failing all else... if not len(self._url_pats): print_d("No saved searches found in %s. Using defaults." % filename) self._url_pats = self.DEFAULT_URL_PATS
def _enable_server(self): port_num = get_port_num() print_d("Starting MPD server on port %d" % port_num) self._server = MPDServer(app, self, port_num) try: self._server.start() except ServerError as e: print_w(str(e))
def _enable_server(self): port_num = get_port_num() print_d("Starting MPD server on port %d" % port_num) self._server = MPDServer(app, self, port_num) try: self._server.start() except ServerError as e: print_w(e)
def _make_unique(entry, old_duplicate): """ Mark the given entry as a unique file. """ print_d(entry.filename) entry.tag = Entry.Tags.PENDING_COPY self.c_songs_copy += 1 if old_duplicate: self.c_song_dupes -= 1 _update_warnings()
def _make_duplicate(entry, old_unique): """ Mark the given entry as a duplicate. """ print_d(entry.filename) entry.tag = Entry.Tags.SKIP_DUPLICATE self.c_song_dupes += 1 if old_unique: self.c_songs_copy -= 1 _update_warnings()
def _sent(self, message): if self.cancellable.is_cancelled(): return self.emit('send-failure', Exception('Cancelled')) if 300 <= message.get_property('status-code') < 400: return # redirection, wait for another emission of got-headers self.istream = Gio.MemoryInputStream.new() self.message.connect('got-chunk', self._chunk) print_d('Sent request to {0}'.format(self._uri)) self.emit('sent', self.message)
def _sent(self, session, task, data): try: self.istream = session.send_finish(task) print_d('Sent {1} request to {0}'.format(self._uri, self.message.method)) self.emit('sent', self.message) except GLib.GError as e: print_w('Failed sending request to {0}'.format(self._uri)) self.emit('send-failure', e)
def _repeat(app, value): po = app.player_options if value in ["0", "off"]: po.repeat = False elif value in ["1", "on"]: print_d("Enabling repeat") po.repeat = True elif value in ["t", "toggle"]: po.repeat = not po.repeat
def update_pattern(cls, pattern_text): """Saves `pattern_text` to disk (and caches)""" if pattern_text == cls.__pattern_text: return cls.__pattern_text = pattern_text cls.__refresh_pattern() cls.refresh_all() print_d("Saving pattern for %s to %s" % (cls.__name__, cls._PATTERN_FN)) with open(cls._PATTERN_FN, "w") as f: f.write(pattern_text + "\n")
def test_looks_in_path(self): path_dirs = set(os.environ['PATH'].split(os.path.pathsep)) dirs = path_dirs - set(os.defpath.split(os.path.pathsep)) for d in dirs: if os.path.isdir(d): for file_path in os.listdir(d): if os.access(os.path.join(d, file_path), os.X_OK): print_d("Testing %s" % file_path) self.failUnless(iscommand(file_path)) return
def _do_upgrade(self, func): assert self._loaded_version is not None assert self._version is not None old_version = self._loaded_version new_version = self._version if old_version != new_version: print_d("Config upgrade: %d->%d (%r)" % ( old_version, new_version, func)) func(self, old_version, new_version)