def run(self, songs): """ Runs this command on `songs`, splitting into multiple calls if necessary """ args = [] if self.parameter: value = GetStringDialog(None, _("Input value"), _("Value for %s?") % self.parameter).run() self.command = self.command.format(**{self.parameter: value}) print_d("Actual command=%s" % self.command) for song in songs: arg = str(self.__pat.format(song)) if not arg: print_w("Couldn't build shell command using \"%s\"." "Check your pattern?" % self.pattern) break if not self.unique: args.append(arg) elif arg not in args: args.append(arg) max = int((self.max_args or 10000)) com_words = self.command.split(" ") while args: print_d( "Running %s with %d substituted arg(s) (of %d%s total)..." % (self.command, min(max, len(args)), len(args), " unique" if self.unique else "")) util.spawn(com_words + args[:max]) args = args[max:]
def _set_status(self, text): print_d("Setting status to \"%s\"..." % text) result, mid = self.client.publish(self.topic, text) if result != mqtt.MQTT_ERR_SUCCESS: print_w("Couldn't publish to %s at %s:%d (%s)" % (self.topic, self.host, self.port, result)) self.status = text
def __request(self, line, raw=False, want_reply=True): """ Send a request to the server, if connected, and return its response """ line = line.strip() if not (self.is_connected or line.split()[0] == 'login'): print_d("Can't do '%s' - not connected" % line.split()[0], self) return None if self._debug: print_(">>>> \"%s\"" % line) try: self.telnet.write(line + "\n") if not want_reply: return None raw_response = self.telnet.read_until("\n").strip() except socket.error as e: print_w("Couldn't communicate with squeezebox (%s)" % e) self.failures += 1 if self.failures >= self._MAX_FAILURES: print_w("Too many Squeezebox failures. Disconnecting") self.is_connected = False return None response = raw_response if raw else urllib.unquote(raw_response) if self._debug: print_("<<<< \"%s\"" % (response,)) return response[len(line) - 1:] if line.endswith("?")\ else response[len(line) + 1:]
def __init__(self, hostname="localhost", port=9090, user="", password="", library_dir='', current_player=0, debug=False): self._debug = debug self.failures = 0 self.delta = 600 # Default in ms self.config = SqueezeboxServerSettings(locals()) if hostname: del self.config["self"] del self.config["current_player"] self.current_player = int(current_player) or 0 try: if self._debug: print_d("Trying %s..." % self.config) self.telnet = Telnet(hostname, port, self._TIMEOUT) except socket.error: print_w(_("Couldn't talk to %s") % (self.config,)) else: result = self.__request("login %s %s" % (user, password)) if result != (6 * '*'): raise SqueezeboxException( "Couldn't log in to squeezebox: response was '%s'" % result) self.is_connected = True self.failures = 0 print_d("Connected to Squeezebox Server! %s" % self) # Reset players (forces reload) self.players = [] self.get_players()
def run(self, songs): """ Runs this command on `songs`, splitting into multiple calls if necessary """ args = [] if self.parameter: value = GetStringDialog(None, _("Input value"), _("Value for %s?") % self.parameter).run() self.command = self.command.format(**{self.parameter: value}) print_d("Actual command=%s" % self.command) for song in songs: arg = str(self.__pat.format(song)) if not arg: print_w("Couldn't build shell command using \"%s\"." "Check your pattern?" % self.pattern) break if not self.unique: args.append(arg) elif arg not in args: args.append(arg) max = int((self.max_args or 10000)) com_words = self.command.split(" ") while args: print_d("Running %s with %d substituted arg(s) (of %d%s total)..." % (self.command, min(max, len(args)), len(args), " unique" if self.unique else "")) util.spawn(com_words + args[:max]) args = args[max:]
def plugin_playlist(self, playlist): # TODO - only get coordinator nodes, somehow self.device: SoCo = soco.discovery.any_soco() device = self.device if not device: qltk.ErrorMessage( app.window, _("Error finding Sonos device(s)"), _("Error finding Sonos. Please check settings")).run() else: sonos_pls = device.get_sonos_playlists() pl_id_to_name = {pl.item_id: pl.title for pl in sonos_pls} print_d("Sonos playlists: %s" % pl_id_to_name) ret = GetSonosPlaylistDialog(pl_id_to_name).run(playlist.name) if ret: spl_id, name = ret if spl_id: spl: DidlPlaylistContainer = next(s for s in sonos_pls if s.item_id == spl_id) print_w(f"Replacing existing Sonos playlist {spl!r}") device.remove_sonos_playlist(spl) print_d(f"Creating new playlist {name!r}") spl = device.create_sonos_playlist(name) task = Task("Sonos", _("Export to Sonos playlist"), stop=self.__cancel_add) copool.add(self.__add_songs, task, playlist.songs, spl, funcid="sonos-playlist-save")
def __request(self, line, raw=False, want_reply=True): """ Send a request to the server, if connected, and return its response """ line = line.strip() if not (self.is_connected or line.split()[0] == 'login'): print_d("Can't do '%s' - not connected" % line.split()[0], self) return None if self._debug: print_(">>>> \"%s\"" % line) try: self.telnet.write(line + "\n") if not want_reply: return None raw_response = self.telnet.read_until("\n").strip() except socket.error as e: print_w("Couldn't communicate with squeezebox (%s)" % e) self.failures += 1 if self.failures >= self._MAX_FAILURES: print_w("Too many Squeezebox failures. Disconnecting") self.is_connected = False return None response = raw_response if raw else urllib.unquote(raw_response) if self._debug: print_("<<<< \"%s\"" % (response, )) return response[len(line) - 1:] if line.endswith("?")\ else response[len(line) + 1:]
def init(): global device_manager if not dbus: return device_manager = None print_d(_("Initializing device backend.")) try_text = _("Trying '%s'") if device_manager is None: print_d(try_text % "UDisks2") try: device_manager = UDisks2Manager() except (LookupError, dbus.DBusException): pass if device_manager is None: print_d(try_text % "UDisks1") try: device_manager = UDisks1Manager() except (LookupError, dbus.DBusException): pass if device_manager is None: print_w(_("Couldn't connect to a device backend.")) else: print_d(_("Device backend initialized.")) return device_manager
def init(): global device_manager if not dbus: return device_manager = None print_d(_("Initializing device backend.")) try_text = _("Trying '%s'") #DKD maintainers will change the naming of dbus, app stuff #in january 2010 or so (already changed in trunk), so try both if device_manager is None: print_d(try_text % "DeviceKit Disks") try: device_manager = DKD(("DeviceKit", "Disks")) except (LookupError, dbus.DBusException): pass if device_manager is None: print_d(try_text % "UDisks") try: device_manager = DKD(("UDisks",)) except (LookupError, dbus.DBusException): pass if device_manager is None: print_d(try_text % "HAL") try: device_manager = HAL() except (LookupError, dbus.DBusException): pass if device_manager is None: print_w(_("Couldn't connect to a device backend.")) else: print_d(_("Device backend initialized.")) return device_manager
def control(c): import quodlibet from quodlibet import const if not is_running(): quodlibet.exit(_("Quod Libet is not running."), notify_startup=True) else: try: # This is a total abuse of Python! Hooray! signal.signal(signal.SIGALRM, lambda: "" + 2) signal.alarm(1) f = file(const.CONTROL, "w") signal.signal(signal.SIGALRM, signal.SIG_IGN) f.write(c) f.close() except (OSError, IOError, TypeError): print_w(_("Unable to write to %s. Removing it.") % const.CONTROL) try: os.unlink(const.CONTROL) except OSError: pass if c != 'focus': raise quodlibet.exit(True, notify_startup=True) else: quodlibet.exit(notify_startup=True)
def __init__(self): bus_name = "org.freedesktop.UDisks" interface = "org.freedesktop.UDisks" path = "/org/freedesktop/UDisks" super(UDisks1Manager, self).__init__(bus_name) error = False try: udev.init() except OSError: print_w("UDisks: " + _("Could not find '%s'.") % "libudev") error = True else: self.__udev = udev.Udev.new() if get_mpi_dir() is None: print_w("UDisks: " + _("Could not find '%s'.") % "media-player-info") error = True if error: raise LookupError obj = self._system_bus.get_object(bus_name, path) self.__interface = dbus.Interface(obj, interface) self.__devices = {} self.__interface.connect_to_signal('DeviceAdded', self.__device_added) self.__interface.connect_to_signal('DeviceRemoved', self.__device_removed)
def __remove(self, iters, smodel): def song_at(itr): return smodel[smodel.get_path(itr)][0] def remove_from_model(iters, smodel): for it in iters: smodel.remove(it) model, iter = self.__selected_playlists() if iter: playlist = model[iter][0] # A {iter: song} dict, exhausting `iters` once. removals = {iter_remove: song_at(iter_remove) for iter_remove in iters} if not removals: print_w("No songs selected to remove") return if self._query is None or not self.get_filter_text(): # Calling playlist.remove_songs(songs) won't remove the # right ones if there are duplicates remove_from_model(removals.keys(), smodel) self.__rebuild_playlist_from_songs_model(playlist, smodel) # Emit manually self.library.emit('changed', removals.values()) else: playlist.remove_songs(removals.values(), True) remove_from_model(iters, smodel) print_d("Removed %d song(s) from %s" % (len(removals), playlist)) self.changed(playlist) self.activate()
def __init__(self, dkd_name): self.__bus = ".".join(dkd_name) self.__path = "/".join(dkd_name) super(DKD, self).__init__("org.freedesktop.%s" % self.__bus) error = False try: udev.init() except OSError: print_w(_("%s: Could not find %s.") % (self.__bus, libudev)) error = True else: self.__udev = udev.Udev.new() if self.__get_mpi_dir() is None: print_w(_("%s: Could not find %s.") % (self.__bus, "media-player-info")) error = True if error: raise LookupError interface = "org.freedesktop.%s" % self.__bus path = "/org/freedesktop/%s" % self.__path obj = self._system_bus.get_object(interface, path) self.__interface = dbus.Interface(obj, interface) self.__interface.connect_to_signal('DeviceAdded', self.__device_added) self.__interface.connect_to_signal('DeviceRemoved', self.__device_removed)
def _load_items(filename): """Load items from disk. In case of an error returns default or an empty list. """ try: with open(filename, "rb") as fp: data = fp.read() except EnvironmentError: print_w("Couldn't load library file from: %r" % filename) return [] try: items = load_audio_files(data) except SerializationError: # there are too many ways this could fail util.print_exc() # move the broken file out of the way try: shutil.copy(filename, filename + ".not-valid") except EnvironmentError: util.print_exc() return [] return items
def _load_items(filename): """Load items from disk. In case of an error returns default or an empty list. """ try: with open(filename, "rb") as fp: data = fp.read() except EnvironmentError: print_w("Couldn't load library file from: %r" % filename) return [] try: items = load_audio_files(data) except SerializationError: # there are too many ways this could fail util.print_exc() # move the broken file out of the way try: shutil.copy(filename, filename + ".not-valid") except EnvironmentError: util.print_exc() return [] return items
def set_process_title(title): """Sets process name as visible in ps or top. Requires ctypes libc and is almost certainly *nix-only. See issue 736 """ if os.name == "nt": return try: libc = load_library(["libc.so.6", "c"])[0] prctl = libc.prctl except (OSError, AttributeError): print_d("Couldn't find module libc.so.6 (ctypes). " "Not setting process title.") else: prctl.argtypes = [ ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ctypes.c_ulong, ] prctl.restype = ctypes.c_int PR_SET_NAME = 15 data = ctypes.create_string_buffer(title.encode("utf-8")) res = prctl(PR_SET_NAME, ctypes.addressof(data), 0, 0, 0) if res != 0: print_w("Setting the process title failed")
def init(): global device_manager if not dbus: return device_manager = None print_d(_("Initializing device backend.")) try_text = _("Trying '%s'") if device_manager is None: print_d(try_text % "UDisks2") try: device_manager = UDisks2Manager() except (LookupError, dbus.DBusException): pass if device_manager is None: print_d(try_text % "UDisks1") try: device_manager = UDisks1Manager() except (LookupError, dbus.DBusException): pass if device_manager is None: print_w(_("Couldn't connect to a device backend.")) else: print_d(_("Device backend initialized.")) return device_manager
def _set_status(self, text): print_d("Setting status to \"%s\"..." % text) result, mid = self.client.publish(self.topic, text) if result != mqtt.MQTT_ERR_SUCCESS: print_w("Couldn't publish to %s at %s:%d (%s)" % (self.topic, self.host, self.port, result)) self.status = text
def init(): global device_manager if not dbus: return device_manager = None print_d(_("Initializing device backend.")) try_text = _("Trying '%s'") #DKD maintainers will change the naming of dbus, app stuff #in january 2010 or so (already changed in trunk), so try both if device_manager is None: print_d(try_text % "DeviceKit Disks") try: device_manager = DKD(("DeviceKit", "Disks")) except (LookupError, dbus.DBusException): pass if device_manager is None: print_d(try_text % "UDisks") try: device_manager = DKD(("UDisks", )) except (LookupError, dbus.DBusException): pass if device_manager is None: print_w(_("Couldn't connect to a device backend.")) else: print_d(_("Device backend initialized.")) return device_manager
def __remove_songs(self, iters, smodel): def song_at(itr): return smodel[smodel.get_path(itr)][0] def remove_from_model(iters, smodel): for it in iters: smodel.remove(it) model, iter = self.__selected_playlists() if iter: playlist = model[iter][0] # Build a {iter: song} dict, exhausting `iters` once. removals = { iter_remove: song_at(iter_remove) for iter_remove in iters } if not removals: print_w("No songs selected to remove") return if self._query is None or not self.get_filter_text(): # Calling playlist.remove_songs(songs) won't remove the # right ones if there are duplicates remove_from_model(removals.keys(), smodel) self.__rebuild_playlist_from_songs_model(playlist, smodel) # Emit manually self.songs_lib.emit('changed', removals.values()) else: playlist.remove_songs(removals.values(), True) remove_from_model(removals.keys(), smodel) print_d("Removed %d song(s) from %s" % (len(removals), playlist))
def _import_playlists(self, fns) -> Tuple[int, int]: """ Import m3u / pls playlists into QL Returns the (total playlists, total songs) added TODO: move this to Playlists library and watch here for new playlists """ total_pls = 0 total_songs = 0 for filename in fns: name = _name_for(filename) with open(filename, "rb") as f: if filename.endswith(".m3u") or filename.endswith(".m3u8"): playlist = parse_m3u(f, name, songs_lib=self.songs_lib, pl_lib=self.pl_lib) elif filename.endswith(".pls"): playlist = parse_pls(f, name, songs_lib=self.songs_lib, pl_lib=self.pl_lib) else: print_w("Unsupported playlist type for '%s'" % filename) continue # Import all the songs in the playlist to the *songs* library total_songs += len(self.songs_lib.add(playlist)) total_pls += 1 return total_pls, total_songs
def __init__(self, dkd_name): self.__bus = ".".join(dkd_name) self.__path = "/".join(dkd_name) super(DKD, self).__init__("org.freedesktop.%s" % self.__bus) error = False try: udev.init() except OSError: print_w(_("%s: Could not find 'libudev'.") % self.__bus) error = True else: self.__udev = udev.Udev.new() if self.__get_mpi_dir() is None: print_w( _("%s: Could not find %s.") % (self.__bus, "media-player-info")) error = True if error: raise LookupError interface = "org.freedesktop.%s" % self.__bus path = "/org/freedesktop/%s" % self.__path obj = self._system_bus.get_object(interface, path) self.__interface = dbus.Interface(obj, interface) self.__devices = {} self.__interface.connect_to_signal('DeviceAdded', self.__device_added) self.__interface.connect_to_signal('DeviceRemoved', self.__device_removed)
def __init__(self): bus_name = "org.freedesktop.UDisks" interface = "org.freedesktop.UDisks" path = "/org/freedesktop/UDisks" super(UDisks1Manager, self).__init__(bus_name) error = False try: udev.init() except OSError: print_w(_("%s: Could not find 'libudev'.") % "UDisks") error = True else: self.__udev = udev.Udev.new() if get_mpi_dir() is None: print_w( _("%s: Could not find %s.") % ("UDisks", "media-player-info")) error = True if error: raise LookupError obj = self._system_bus.get_object(bus_name, path) self.__interface = dbus.Interface(obj, interface) self.__devices = {} self.__interface.connect_to_signal('DeviceAdded', self.__device_added) self.__interface.connect_to_signal('DeviceRemoved', self.__device_removed)
def __init__(self, orders, base_cls): assert issubclass(base_cls, Order) super(PluggableOrders, self).__init__(orders) self.base_cls = base_cls if PluginManager.instance: PluginManager.instance.register_handler(self) else: print_w("No plugin manager found")
def __init__(self, orders, base_cls): assert issubclass(base_cls, Order) super(PluggableOrders, self).__init__(orders) self.base_cls = base_cls if PluginManager.instance: PluginManager.instance.register_handler(self) else: print_w("No plugin manager found")
def dump_queue(klass): if klass.queue: print_d(f"Saving scrobble queue to {klass.SCROBBLER_CACHE_FILE}") try: with open(klass.SCROBBLER_CACHE_FILE, 'wb') as disk_queue_file: pickle_dump(klass.queue, disk_queue_file) except (EnvironmentError, PickleError) as e: print_w(f"Couldn't persist scrobble queue ({e})")
def process_IN_CREATE(self, event): if not event.dir: self._log(event) # Just remember that they've been created, will process later path = os.path.join(event.path, event.name) if os.path.exists(path): self._being_created.add(path) else: print_w("Couldn't find %s" % path)
def process_IN_CREATE(self, event): if not event.dir: self._log(event) # Just remember that they've been created, will process later path = os.path.join(event.path, event.name) if os.path.exists(path): self._being_created.add(path) else: print_w("Couldn't find %s" % path)
def move_root(self, old_root: str, new_root: fsnative) \ -> Generator[None, None, None]: """ Move the root for all songs in a given (scan) directory. We avoid dereferencing the destination, to allow users things like: 1. Symlink new_path -> old_root 2. Move QL root to new_path 3. Remove symlink 4. Move audio files: old_root -> new_path """ old_path = Path(normalize_path(old_root, canonicalise=True)).expanduser() new_path = Path(normalize_path(new_root)).expanduser() if not old_path.is_dir(): raise ValueError(f"Source {old_path!r} is not a directory") if not new_path.is_dir(): raise ValueError(f"Destination {new_path!r} is not a directory") print_d( f"{self._name}: checking {len(self.values())} item(s) for {old_path!r}" ) missing: Set[AudioFile] = set() changed = set() total = len(self) if not total: return with Task(_("Library"), _("Moving library files")) as task: yield for i, song in enumerate(list(self.values())): task.update(i / total) key = normalize_path(song.key) path = Path(key) if old_path in path.parents: # TODO: more Pathlib-friendly dir replacement... new_key = key.replace(str(old_path), str(new_path), 1) new_key = normalize_path(new_key, canonicalise=False) if new_key == key: print_w(f"Substitution failed for {key!r}") # We need to update ~filename and ~mountpoint song.sanitize() song.write() if self.move_song(song, new_key): changed.add(song) else: missing.add(song) elif not (i % 1000): print_d(f"Not moved, for example: {key!r}") if not i % 100: yield self.changed(changed) if missing: print_w(f"Couldn't find {len(list(missing))} files: {missing}") yield self.save() print_d(f"Done moving to {new_path!r}.")
def background_check_wrapper_changed(library, songs): need_write = [s for s in songs if s._needs_write] for song in need_write: try: song._song.write() except AudioFileError as e: print_w("Couldn't save song %s (%s)" % (song("~filename"), e)) _inform_library_of_changed(library, songs)
def playlists(self): for lib in self.libraries.values(): if isinstance(lib, PlaylistLibrary): return lib try: return lib.playlists except AttributeError: pass print_w(f"No playlist library found: {self.libraries}") raise ValueError("No playlists library found")
def background_check_wrapper_changed(library, songs): for song in songs: if not song._needs_write: continue try: song._song.write() except AudioFileError as e: print_w("Couldn't save song %s (%s)" % (song("~filename"), e)) _inform_library_of_changed(library, songs)
def query_with_refresh(self, text, sort=None, star=STAR): """Queries Soundcloud for some (more) relevant results, then filters""" current = self._contents.values() try: query = SoundcloudQuery(text, star=star) self.client.get_tracks(query.terms) except SoundcloudQuery.error as e: print_w("Couldn't filter for query '%s' (%s)" % (text, e)) return current filtered = query.filter(current) print_d("Filtered %d results to %d" % (len(current), len(filtered))) return filtered
def query_with_refresh(self, text, sort=None, star=STAR): """Queries Soundcloud for some (more) relevant results, then filters""" current = self._contents.values() try: query = SoundcloudQuery(text, star=star) self.client.get_tracks(query.terms) except SoundcloudQuery.error as e: print_w("Couldn't filter for query '%s' (%s)" % (text, e)) return current filtered = query.filter(current) print_d("Filtered %d results to %d" % (len(current), len(filtered))) return filtered
def try_connecting(self): try: self.enabled() msg = (_("Connected to broker at %(host)s:%(port)d") % {'host': self.host, 'port': self.port}) Message(Gtk.MessageType.INFO, app.window, "Success", msg).run() except IOError as e: template = _("Couldn't connect to %(host)s:%(port)d (%(msg)s)") msg = template % {'host': self.host, 'port': self.port, 'msg': e} print_w(msg) ErrorMessage(app.window, _("Connection error"), msg).run() yield
def try_connecting(self): try: self.enabled() msg = (_("Connected to broker at %(host)s:%(port)d") % {'host': self.host, 'port': self.port}) Message(Gtk.MessageType.INFO, app.window, "Success", msg).run() except IOError as e: template = _("Couldn't connect to %(host)s:%(port)d (%(msg)s)") msg = template % {'host': self.host, 'port': self.port, 'msg': e} print_w(msg) ErrorMessage(app.window, _("Connection error"), msg).run() yield
def __get_media_player_id(self, devpath): """DKD is for high-level device stuff. The info if the device is a media player and what protocol/formats it supports can only be retrieved through libudev""" try: dev = get_device_from_path(self.__udev, devpath) except Exception: print_w("Failed to retrieve udev properties for %r" % devpath) util.print_exc() return try: return dev["ID_MEDIA_PLAYER"] except KeyError: return None
def _on_failure(self, req: HTTPRequest, _exc: Exception, data: Any) -> None: """Callback for HTTP failures.""" code = req.message.get_property('status-code') if code in (401, ): print_w("User session no longer valid, logging out.") if self.access_token: # Could call log_out to persist, but we're probably about to refresh... self.access_token = None self._refresh_tokens() else: print_w("Refreshing didn't work either, oh dear.") self.log_out()
def save(self, filename=None): """Save the library to the given filename, or the default if `None`""" if filename is None: filename = self.filename print_d("Saving contents to %r." % filename, self) try: dump_items(filename, self.get_content()) except EnvironmentError: print_w("Couldn't save library to path: %r" % filename) else: self.dirty = False
def save(self, filename=None): """Save the library to the given filename, or the default if `None`""" if filename is None: filename = self.filename print_d("Saving contents to %r." % filename, self) try: dump_items(filename, self.get_content()) except EnvironmentError: print_w("Couldn't save library to path: %r" % filename) else: self.dirty = False
def init_devices(): global devices load_pyc = os.name == 'nt' modules = load_dir_modules(dirname(__file__), package=__package__, load_compiled=load_pyc) for mod in modules: try: devices.extend(mod.devices) except AttributeError: print_w("%r doesn't contain any devices." % mod.__name__) devices.sort()
def init_devices(): global devices load_pyc = util.is_windows() or util.is_osx() modules = load_dir_modules(dirname(__file__), package=__package__, load_compiled=load_pyc) for mod in modules: try: devices.extend(mod.devices) except AttributeError: print_w("%r doesn't contain any devices." % mod.__name__) devices.sort(key=lambda d: repr(d))
def init_devices(): global devices load_pyc = util.is_windows() or util.is_osx() modules = load_dir_modules(dirname(__file__), package=__package__, load_compiled=load_pyc) for mod in modules: try: devices.extend(mod.devices) except AttributeError: print_w("%r doesn't contain any devices." % mod.__name__) devices.sort(key=lambda d: repr(d))
def init_devices(): global devices load_pyc = os.name == 'nt' modules = load_dir_modules(dirname(__file__), package=__package__, load_compiled=load_pyc) for mod in modules: try: devices.extend(mod.devices) except AttributeError: print_w("%r doesn't contain any devices." % mod.__name__) devices.sort()
def __get_media_player_id(self, devpath): """DKD is for high-level device stuff. The info if the device is a media player and what protocol/formats it supports can only be retrieved through libudev""" try: dev = get_device_from_path(self.__udev, devpath) except Exception: print_w("Failed to retrieve udev properties for %r" % devpath) util.print_exc() return try: return dev["ID_MEDIA_PLAYER"] except KeyError: return None
def __init__(self, songs_lib: SongFileLibrary, Confirmer=ConfirmationPrompt): super().__init__(spacing=6) self._lists = ObjectModelSort(model=ObjectStore()) self._lists.set_default_sort_func(ObjectStore._sort_on_value) self.songs_lib = songs_lib try: self.pl_lib: PlaylistLibrary = songs_lib.playlists except (AttributeError, TypeError): print_w("No playlist library available") else: model = self._lists.get_model() print_d(f"Reading playlists from library: {self.pl_lib}") for playlist in self.pl_lib: model.append(row=[playlist]) # this is instanced with the necessary gtkdialog-settings, and afterwards # its run-method is called to get a to-be-compared Gtk.ResponseType self.Confirmer = Confirmer self.set_orientation(Gtk.Orientation.VERTICAL) self.__render = self.__create_cell_renderer() self.__view = view = self.__create_playlists_view(self.__render) self.__embed_in_scrolledwin(view) self.__configure_buttons(songs_lib) self.__configure_dnd(view) self.__connect_signals(view) self._sb_box = self.__create_searchbar(songs_lib) self._rh_box = None self._main_box = self.__create_box() self.show_all() for child in self.get_children(): child.show_all() if hasattr(self, "pl_lib"): self._ids = [ self.pl_lib.connect('removed', self.__removed), self.pl_lib.connect('added', self.__added), self.pl_lib.connect('changed', self.__changed), ] print_d( f"Connected signals: {self._ids} from {self.pl_lib!r} for {self}" ) else: self._ids = [] self.connect("destroy", self._destroy)
def MusicFile(filename): """Returns a AudioFile instance or None""" lower = filename.lower() for ext in _extensions: if lower.endswith(ext): try: return _infos[ext](filename) except: print_w("Error loading %r" % filename) if const.DEBUG: util.print_exc() return else: print_w("Unknown file extension %r" % filename) return
def __search_thread(self, engine, query, replace): """Creates searching threads which call the callback function after they are finished""" clean_query = self.__cleanup_query(query, replace) result = [] try: result = engine().start(clean_query, self.overall_limit) except Exception: print_w("[AlbumArt] %s: %r" % (engine.__name__, query)) print_exc() self.finished += 1 #progress is between 0..1 progress = float(self.finished) / len(self.engine_list) GLib.idle_add(self.callback, result, progress)
def MusicFile(filename): """Returns a AudioFile instance or None""" lower = filename.lower() for ext in _extensions: if lower.endswith(ext): try: return _infos[ext](filename) except: print_w("Error loading %r" % filename) if const.DEBUG: util.print_exc() return else: print_w("Unknown file extension %r" % filename) return
def _import_playlists(self, fns, library): added = 0 for filename in fns: name = _name_for(filename) with open(filename, "rb") as f: if filename.endswith(".m3u") or filename.endswith(".m3u8"): playlist = parse_m3u(f, name, library=library) elif filename.endswith(".pls"): playlist = parse_pls(f, name, library=library) else: print_w("Unsupported playlist type for '%s'" % filename) continue self.changed(playlist) library.add(playlist) added += 1 return added
def _get_saved_commands(cls): filename = cls.COMS_FILE print_d("Loading saved commands from '%s'..." % filename) coms = None try: with open(filename, "r", encoding="utf-8") as f: coms = JSONObjectDict.from_json(Command, f.read()) except (IOError, ValueError) as e: print_w("Couldn't parse saved commands (%s)" % e) # Failing all else... if not coms: print_d("No commands found in %s. Using defaults." % filename) coms = {c.name: c for c in cls.DEFAULT_COMS} print_d("Loaded commands: %s" % coms.keys()) return coms
def from_list(cls, json_objects, raise_errors=True): new = cls() for j in json_objects: if not isinstance(j, JSONObject): msg = "Incorrect type (%s) found in list of objects" % j.__class__.__name__ if raise_errors: raise TypeError(msg) else: print_d(msg) else: if not j.name and raise_errors: raise ValueError("Null key for %s object %s" % (cls.__name__, j)) if j.name in new: print_w("Duplicate %s found named '%s'. Removing..." % (cls.__name__, j.name)) new[j.name] = j return new
def create_device(self, backend_id, device_id, protocols): """backend_id is the string that gets passed to the backend so it can identify the device. device_id should be a something including the device serial (so it's unique) and maybe the model name.""" device = None for prots in (protocols, ['storage']): klass = get_by_protocols(prots) if klass is None: break try: device = klass(backend_id, device_id) except TypeError: pass #rockboxed iPod else: break if device is None: print_w(_("%r is not a supported device.") % device_id) return device
def init(klass, library): model = klass.__lists.get_model() for playlist in os.listdir(PLAYLISTS): try: playlist = FileBackedPlaylist(PLAYLISTS, FileBackedPlaylist.unquote(playlist), library=library) model.append(row=[playlist]) except EnvironmentError: print_w("Invalid Playlist '%s'" % playlist) pass klass._ids = [ library.connect('removed', klass.__removed), library.connect('added', klass.__added), library.connect('changed', klass.__changed), ] klass.load_pattern()
def _python_init(): import sys if sys.version_info < MinVersions.PYTHON: actual = Version(sys.version_info[:3]) print_w("Python %s required. %s found." % (MinVersions.PYTHON, actual)) # The default regex escaping function doesn't work for non-ASCII. # Use a blacklist of regex-specific characters instead. def re_esc(str, BAD="/.^$*+?{,\\[]|()<>#=!:"): needs_escape = lambda c: (c in BAD and "\\" + c) or c return "".join(map(needs_escape, str)) re.escape = re_esc __builtin__.__dict__["print_"] = print_ __builtin__.__dict__["print_d"] = print_d __builtin__.__dict__["print_e"] = print_e __builtin__.__dict__["print_w"] = print_w
def _get_saved_searches(cls): filename = cls.COMS_FILE print_d("Loading saved commands from '%s'..." % filename) coms = None try: with open(filename) as f: coms = JSONObjectDict.from_json(Command, f.read()) except IOError: pass except ValueError as e: print_w("Couldn't parse saved commands (%s)" % e) # Failing all else... if not coms: print_d("No commands found in %s. Using defaults." % filename) coms = dict([(c.name, c) for c in cls.DEFAULT_COMS]) print_d("Loaded commands: %s" % coms.keys()) return coms
def from_json(cls, ItemKind, json_str): """ Factory method for building from an input string, a JSON map of {item_name1: {key:value, key2:value2...}, item_name2:...} """ new = cls(ItemKind) try: data = json.loads(json_str) except ValueError: print_w("Broken JSON: %s" % json_str) else: for name, blob in data.items(): try: new[name] = ItemKind(**blob) except TypeError as e: raise IOError("Couldn't instantiate %s from JSON (%s)" % (ItemKind.__name__, e)) return new
def get_media_player_id(udev_ctx, dev_path): """Get the ID_MEDIA_PLAYER key for a specific device path e.g. /dev/sdc Returns the str ID or None. """ try: devs = get_devices_from_path(udev_ctx, dev_path) except Exception: print_w("Failed to retrieve udev properties for %r" % dev_path) util.print_exc() return for dev in devs: try: return dev["ID_MEDIA_PLAYER"] except KeyError: continue
def save(self, filename=None): """ Takes a list of `JSONObject` objects and returns the data serialised as a JSON string, also writing (prettily) to file `filename` if specified. """ print_d("Saving %d %s(s) to JSON.." % (len(self), self.Item.__name__)) try: obj_dict = dict([(o.name, dict(o.data)) for o in self.values()]) except AttributeError: raise json_str = json.dumps(obj_dict, indent=4) if filename: try: with open(filename, "wb") as f: f.write(json_str) except IOError as e: print_w("Couldn't write JSON for %s object(s) (%s)" % (type(self).__name__, e)) return json_str
def load_items(filename, default=None): """Load items from disk. In case of an error returns default or an empty list. """ if default is None: default = [] try: fp = open(filename, "rb") except EnvironmentError: if const.DEBUG or os.path.exists(filename): print_w("Couldn't load library from: %r" % filename) return default # pickle makes 1000 read syscalls for 6000 songs # read the file into memory so that there are less # context switches. saves 40% CPU time.. try: data = fp.read() except IOError: fp.close() return default try: items = pickle.loads(data) except Exception: # there are too many ways this could fail util.print_exc() # move the broken file out of the way try: shutil.copy(filename, filename + ".not-valid") except EnvironmentError: util.print_exc() # try to skip items for which the class is missing # XXX: we assume the items are dict subclasses here.. while nothing # else does items = unpickle_save(data, default) return items