Example #1
0
def get_url(url, post=None, get=None):
    post_params = urlencode(post or {})
    get_params = urlencode(get or {})
    if get:
        get_params = '?' + get_params

    # add post, get data and headers
    url = '%s%s' % (url, get_params)
    if post_params:
        request = Request(url, post_params)
    else:
        request = Request(url)

    # for discogs
    request.add_header('Accept-Encoding', 'gzip')
    request.add_header('User-Agent', USER_AGENT)

    url_sock = urlopen(request)
    enc = get_encoding_from_socket(url_sock)

    # unzip the response if needed
    data = url_sock.read()
    if url_sock.headers.get("content-encoding", "") == "gzip":
        data = gzip.GzipFile(fileobj=cBytesIO(data)).read()
    url_sock.close()
    content_type = url_sock.headers.get('Content-Type', '').split(';', 1)[0]
    domain = re.compile('\w+://([^/]+)/').search(url).groups(0)[0]
    print_d("Got %s data from %s" % (content_type, domain))
    return (data if content_type.startswith('image')
            else data.decode(enc))
Example #2
0
 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
Example #3
0
    def changed(self, items):
        """Alert other users that these items have changed.

        This causes a 'changed' signal. If a librarian is available
        this function will call its changed method instead, and all
        libraries that librarian manages may fire a 'changed' signal.

        The item list may be filtered to those items actually in the
        library. If a librarian is available, it will handle the
        filtering instead. That means if this method is delegated to
        the librarian, this library's changed signal may not fire, but
        another's might.
        """

        if not items:
            return
        if self.librarian and self in self.librarian.libraries.itervalues():
            print_d("Changing %d items via librarian." % len(items), self)
            self.librarian.changed(items)
        else:
            items = set(item for item in items if item in self)
            if not items:
                return
            print_d("Changing %d items directly." % len(items), self)
            self._changed(items)
Example #4
0
 def search_complete(self, res):
     self.disconnect(sci)
     if res:
         print_d(res)
         self.download(Soup.Message.new('GET', res[0]))
     else:
         return self.fail('No cover was found')
Example #5
0
def check_wrapper_changed(library, parent, songs):
    needs_write = filter(lambda s: s._needs_write, songs)

    if needs_write:
        win = WritingWindow(parent, len(needs_write))
        win.show()
        for song in needs_write:
            try:
                song._song.write()
            except AudioFileError as e:
                qltk.ErrorMessage(
                    None, _("Unable to edit song"),
                    _("Saving <b>%s</b> failed. The file "
                      "may be read-only, corrupted, or you "
                      "do not have permission to edit it.") %
                    util.escape(song('~basename'))).run()
                print_d("Couldn't save song %s (%s)" % (song("~filename"), e))

            if win.step():
                break
        win.destroy()

    changed = []
    for song in songs:
        if song._was_updated():
            changed.append(song._song)
        elif not song.valid() and song.exists():
            library.reload(song._song)
    library.changed(changed)
Example #6
0
 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:]
Example #7
0
 def _load_item(self, item):
     """Load (add) an item into this library"""
     # Subclasses should override this if they want to check
     # item validity; see `FileLibrary`.
     print_d("Loading %r." % item.key, self)
     self.dirty = True
     self._contents[item.key] = item
Example #8
0
    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:]
Example #9
0
 def get_data(self, key):
     """Gets the pattern for a given key"""
     try:
         return self.commands[key]
     except (KeyError, TypeError):
         print_d("Invalid key %s" % key)
         return None
Example #10
0
 def data(self):
     """A list of tuples of the persisted key:values in this class"""
     if self.FIELDS:
         return [(k, self.__getattribute__(k) if hasattr(self, k) else None) for k in self.FIELDS]
     else:
         print_d("No order specified for class %s" % type(self).__name__)
         return dict([(k, v) for k, v in self.__dict__.items() if self._should_store(k)])
Example #11
0
    def get_players(self):
        """ Returns (and caches) a list of the Squeezebox players available"""
        if self.players:
            return self.players
        pairs = self.__request("players 0 99", True).split(" ")

        def demunge(string):
            s = urllib.unquote(string)
            cpos = s.index(":")
            return (s[0:cpos], s[cpos + 1:])

        # Do a meaningful URL-unescaping and tuplification for all values
        pairs = map(demunge, pairs)

        # First element is always count
        count = int(pairs.pop(0)[1])
        self.players = []
        for pair in pairs:
            if pair[0] == "playerindex":
                playerindex = int(pair[1])
                self.players.append(SqueezeboxPlayerSettings())
            else:
                # Don't worry playerindex is always the first entry...
                self.players[playerindex][pair[0]] = pair[1]
        if self._debug:
            print_d("Found %d player(s): %s" %
                    (len(self.players), self.players))
        assert (count == len(self.players))
        return self.players
Example #12
0
    def rescan(self):
        """Scan for plugin changes or to initially load all plugins"""

        print_d("Rescanning..")

        removed, added = self.__scanner.rescan()

        # remember IDs of enabled plugin that get reloaded, so we can enable
        # them again
        reload_ids = []
        for name in removed:
            if name not in added:
                continue
            mod = self.__modules[name]
            for plugin in mod.plugins:
                if self.enabled(plugin):
                    reload_ids.append(plugin.id)

        for name in removed:
            # share the namespace with ModuleScanner for now
            self.__remove_module(name)

        # restore enabled state
        self.__enabled.update(reload_ids)

        for name in added:
            new_module = self.__scanner.modules[name]
            self.__add_module(name, new_module.module)

        print_d("Rescanning done.")
Example #13
0
    def enable(self, plugin, status, force=False):
        """Enable or disable a plugin."""

        if not force and self.enabled(plugin) == bool(status):
            return

        if not status:
            print_d("Disable %r" % plugin.id)
            for handler in plugin.handlers:
                handler.plugin_disable(plugin)

            self.__enabled.discard(plugin.id)

            instance = plugin.instance
            if instance and hasattr(instance, "disabled"):
                try:
                    instance.disabled()
                except Exception:
                    util.print_exc()
        else:
            print_d("Enable %r" % plugin.id)
            obj = plugin.get_instance()
            if obj and hasattr(obj, "enabled"):
                try:
                    obj.enabled()
                except Exception:
                    util.print_exc()
            for handler in plugin.handlers:
                handler.plugin_enable(plugin)
            self.__enabled.add(plugin.id)
Example #14
0
    def rename(self, song, newname, changed=None):
        """Rename the song in all libraries it belongs to.

        The 'changed' signal will fire for any library the song is in
        except if a set() is passed as changed.
        """
        # This needs to poke around inside the library directly.  If
        # it uses add/remove to handle the songs it fires incorrect
        # signals. If it uses the library's rename method, it breaks
        # the call for future libraries because the item's key has
        # changed. So, it needs to reimplement the method.
        re_add = []
        print_d("Renaming %r to %r" % (song.key, newname), self)
        for library in self.libraries.itervalues():
            try:
                del library._contents[song.key]
            except KeyError:
                pass
            else:
                re_add.append(library)
        song.rename(newname)
        for library in re_add:
            library._contents[song.key] = song
            if changed is None:
                library._changed({song})
            else:
                print_d("Delaying changed signal for %r." % library, self)
                changed.add(song)
Example #15
0
 def remove_songs(self, songs, library, leave_dupes=False):
     """
      Removes `songs` from this playlist if they are there,
      removing only the first reference if `leave_dupes` is True
     """
     changed = False
     for song in songs:
         # TODO: document the "library.masked" business
         if library.masked(song("~filename")):
             while True:
                 try:
                     self[self.index(song)] = song("~filename")
                 except ValueError:
                     break
                 else:
                     changed = True
         else:
             while song in self.songs:
                 print_d("Removing \"%s\" from playlist \"%s\"..."
                         % (song["~filename"], self.name))
                 self.songs.remove(song)
                 if leave_dupes:
                     changed = True
                     break
             else:
                 changed = True
         # Evict song from cache entirely
         try:
             del self._song_map_cache[song]
             print_d("Removed playlist cache for \"%s\"" % song["~filename"])
         except KeyError: pass
     return changed
Example #16
0
    def remove_songs(self, songs, leave_dupes=False):
        """Removes `songs` from this playlist if they are there,
         removing only the first reference if `leave_dupes` is True
        """
        print_d("Remove %d song(s) from %s?" % (len(songs), self.name))
        changed = False
        for song in songs:
            # TODO: document the "library.masked" business
            if self.library is not None and self.library.masked(song):
                while True:
                    try:
                        self._list[self.index(song)] = song("~filename")
                    except ValueError:
                        break
                    else:
                        changed = True
            else:
                while song in self._list:
                    self._list.remove(song)
                    changed = True
                    if leave_dupes:
                        break

        def songs_gone():
            return set(songs) - set(self._list)

        if changed:
            self.finalize()
            # Short-circuit logic will avoid the calculation
            if not leave_dupes or songs_gone():
                self._emit_changed(songs, "remove_songs")
        return changed
Example #17
0
 def __changed_and_signal_library(self, entry, section, name):
     config.set(section, name, str(entry.get_value()))
     print_d("Signalling \"changed\" to entire library. Hold tight...")
     # Cache over clicks
     self._songs = self._songs or app.library.values()
     copool.add(emit_signal, self._songs, funcid="library changed",
                name=_("Updating for new ratings"))
Example #18
0
def fetch_opml(url):
    try:
        outline = opml.parse(url)
    except IOError:
        print_d("Failed opening OPML %s" % url)
        return []
    GObject.idle_add(lambda: update_feeds([x.xmlUrl for x in outline]))
Example #19
0
    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()
Example #20
0
def init(icon=None, proc_title=None, name=None):
    global quodlibet

    print_d("Entering quodlibet.init")

    _gtk_init()
    _gtk_icons_init(get_image_dir(), icon)
    _gst_init()
    _dbus_init()
    _init_debug()

    from gi.repository import GLib

    if proc_title:
        GLib.set_prgname(proc_title)
        set_process_title(proc_title)
        # Issue 736 - set after main loop has started (gtk seems to reset it)
        GLib.idle_add(set_process_title, proc_title)

    if name:
        GLib.set_application_name(name)

    mkdir(get_user_dir(), 0750)

    print_d("Finished initialization.")
Example #21
0
    def quit_gtk(window):

        if before_quit is not None:
            before_quit()

        # disable plugins
        import quodlibet.plugins
        quodlibet.plugins.quit()

        # for debug: this will list active copools
        from quodlibet.util import copool
        copool.pause_all()

        # See which browser windows are open and save their names
        # so we can restore them on start
        from quodlibet.qltk.browser import LibraryBrowser
        LibraryBrowser.save()

        # destroy all open windows so they hide immediately on close:
        # destroying all top level windows doesn't work (weird errors),
        # so we hide them all and only destroy our tracked instances
        # (browser windows, tag editors, pref window etc.)
        from quodlibet.qltk import Window
        for toplevel in Gtk.Window.list_toplevels():
            toplevel.hide()

        for window in Window.windows:
            window.destroy()

        Gtk.main_quit()

        print_d("Quit GTK: done.")
Example #22
0
    def _try_build_device(self, object_path, block, fs):
        """Returns a Device instance or None.

        None if it wasn't a media player etc..
        """

        drive = self._drives.get(block["Drive"])
        if not drive:
            # I think this shouldn't happen, but check anyway
            return

        dev_path = dbus_barray_to_str(block["Device"])
        print_d("Found device: %r" % dev_path)

        media_player_id = get_media_player_id(self._udev, dev_path)
        if not media_player_id:
            print_d("%r not a media player" % dev_path)
            return
        protocols = get_media_player_protocols(media_player_id)

        device_id = drive["Id"]

        dev = self.create_device(object_path, unicode(device_id), protocols)
        icon_name = block["HintIconName"]
        if icon_name:
            dev.icon = icon_name
        return dev
Example #23
0
    def __init__(self, library):
        print_d("Creating Soundcloud Browser")
        super(SoundcloudBrowser, self).__init__(spacing=12)
        self.set_orientation(Gtk.Orientation.VERTICAL)

        if not self.instances():
            self._init(library)
        self._register_instance()

        self.connect('destroy', self.__destroy)
        self.connect('uri-received', self.__handle_incoming_uri)
        self.__auth_sig = self.api_client.connect('authenticated',
                                                  self.__on_authenticated)
        connect_destroy(self.library, 'changed', self.__changed)
        self.login_state = (State.LOGGED_IN if self.online
                            else State.LOGGED_OUT)
        self._create_searchbar(self.library)
        vbox = Gtk.VBox()
        vbox.pack_start(self._create_footer(), False, False, 6)
        vbox.pack_start(self._create_category_widget(), True, True, 0)
        vbox.pack_start(self.create_login_button(), False, False, 6)
        vbox.show()
        pane = qltk.ConfigRHPaned("browsers", "soundcloud_pos", 0.4)
        pane.show()
        pane.pack1(vbox, resize=False, shrink=False)
        self._songs_box = songs_box = Gtk.VBox(spacing=6)
        songs_box.pack_start(self._searchbox, False, True, 0)
        songs_box.show()
        pane.pack2(songs_box, resize=True, shrink=False)
        self.pack_start(pane, True, True, 0)
        self.show()
Example #24
0
    def send_nowplaying(self):
        data = {"s": self.session_id}
        for key, val in self.nowplaying_song.items():
            data[key] = val.encode("utf-8")
        print_d("Now playing song: %s - %s" % (self.nowplaying_song["a"], self.nowplaying_song["t"]))

        return self._check_submit(self.nowplaying_url, data)
Example #25
0
def add_station(uri):
    """Fetches the URI content and extracts IRFiles
    Returns None in error, else a possibly filled list of stations"""

    irfs = []

    if uri.lower().endswith(".pls") or uri.lower().endswith(".m3u"):
        try:
            sock = urlopen(uri)
        except EnvironmentError as err:
            err = text_type(err)
            print_d("Got %s from %s" % (uri, err))
            ErrorMessage(None, _("Unable to add station"), escape(err)).run()
            return None

        if uri.lower().endswith(".pls"):
            irfs = ParsePLS(sock)
        elif uri.lower().endswith(".m3u"):
            irfs = ParseM3U(sock)

        sock.close()
    else:
        try:
            irfs = [IRFile(uri)]
        except ValueError as err:
            ErrorMessage(None, _("Unable to add station"), err).run()

    return irfs
Example #26
0
def add_station(uri):
    """Fetches the URI content and extracts IRFiles
    Returns None in error, else a possibly filled list of stations"""

    irfs = []

    if uri.lower().endswith(".pls") or uri.lower().endswith(".m3u"):
        if not re.match('^([^/:]+)://', uri):
            # Assume HTTP if no protocol given. See #2731
            uri = 'http://' + uri
            print_d("Assuming http: %s" % uri)
        try:
            sock = urlopen(uri)
        except EnvironmentError as err:
            err = "%s\n\nURL: %s" % (text_type(err), uri)
            print_d("Got %s from %s" % (err, uri))
            ErrorMessage(None, _("Unable to add station"), escape(err)).run()
            return None

        if uri.lower().endswith(".pls"):
            irfs = ParsePLS(sock)
        elif uri.lower().endswith(".m3u"):
            irfs = ParseM3U(sock)

        sock.close()
    else:
        try:
            irfs = [IRFile(uri)]
        except ValueError as err:
            ErrorMessage(None, _("Unable to add station"), err).run()

    return irfs
Example #27
0
def register_translation(domain, localedir=None):
    """Register a translation domain

    Args:
        domain (str): the gettext domain
        localedir (pathlike): A directory used for translations, if None the
            system one will be used.
    Returns:
        GlibTranslations
    """

    global _debug_text, _translations, _initialized

    assert _initialized

    if localedir is None:
        iterdirs = iter_locale_dirs
    else:
        iterdirs = lambda: iter([localedir])

    for dir_ in iterdirs():
        try:
            t = gettext.translation(domain, dir_, class_=GlibTranslations)
        except OSError:
            continue
        else:
            print_d("Translations loaded: %r" % unexpand(t.path))
            break
    else:
        print_d("No translation found for the domain %r" % domain)
        t = GlibTranslations()

    t.set_debug_text(_debug_text)
    _translations[domain] = t
    return t
Example #28
0
    def __save(self, *data):
        """Save the cover and spawn the program to edit it if selected"""

        save_format = self.name_combo.get_active_text()
        # Allow use of patterns in creating cover filenames
        pattern = ArbitraryExtensionFileFromPattern(
            save_format.decode("utf-8"))
        filename = pattern.format(self.song)
        print_d("Using '%s' as filename based on %s" % (filename, save_format))
        file_path = os.path.join(self.dirname, filename)

        if os.path.exists(file_path):
            resp = ConfirmFileReplace(self, file_path).run()
            if resp != ConfirmFileReplace.RESPONSE_REPLACE:
                return

        try:
            f = open(file_path, 'wb')
            f.write(self.current_data)
            f.close()
        except IOError:
            qltk.ErrorMessage(None, _('Saving failed'),
                _('Unable to save "%s".') % file_path).run()
        else:
            if self.open_check.get_active():
                try:
                    util.spawn([self.cmd.get_text(), file_path])
                except:
                    pass

            app.cover_manager.cover_changed([self.song])

        self.main_win.destroy()
Example #29
0
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
Example #30
0
 def plugin_songs(self, songs):
     songs = [s for s in songs if s.is_file]
     print_d("Trying to browse folders...")
     if not self._handle(songs):
         ErrorMessage(self.plugin_window,
                      _("Unable to open folders"),
                      _("No program available to open folders.")).run()
Example #31
0
 def restart_counting(self):
     self.play_count = START_COUNT
     print_d("Resetting play count")
Example #32
0
 def config_set(cls, name, value):
     """Saves a config string value for this plugin"""
     try:
         config.set(PM.CONFIG_SECTION, cls._config_key(name), value)
     except config.Error:
         print_d("Couldn't set config item '%s' to %r" % (name, value))
Example #33
0
 def save(self):
     print_d("Saving plugins: %d active" % len(self.__enabled))
     config.set(self.CONFIG_SECTION, self.CONFIG_OPTION,
                "\n".join(self.__enabled))
Example #34
0
    def _moveart(self, art_sets, pathfile_old, pathfile_new, song):

        path_old = os.path.dirname(os.path.realpath(pathfile_old))
        path_new = os.path.dirname(os.path.realpath(pathfile_new))
        if os.path.realpath(path_old) == os.path.realpath(path_new):
            return
        if (path_old in art_sets.keys() and not art_sets[path_old]):
            return

        # get art set for path
        images = []
        if path_old in art_sets.keys():
            images = art_sets[path_old]
        else:
            def glob_escape(s):
                for c in '[*?':
                    s = s.replace(c, '[' + c + ']')
                return s

            # generate art set for path
            art_sets[path_old] = images
            path_old_escaped = glob_escape(path_old)
            for suffix in self.IMAGE_EXTENSIONS:
                images.extend(glob.glob(os.path.join(path_old_escaped,
                                                     "*." + suffix)))
        if images:
            # set not empty yet, (re)process
            filenames = config.getstringlist("albumart", "search_filenames")
            moves = []
            for fn in filenames:
                fn = os.path.join(path_old, fn)
                if "<" in fn:
                    # resolve path
                    fnres = ArbitraryExtensionFileFromPattern(fn).format(song)
                    if fnres in images and fnres not in moves:
                        moves.append(fnres)
                elif "*" in fn:
                    moves.extend(f for f in glob.glob(fn)
                                     if f in images and f not in moves)
                elif fn in images and fn not in moves:
                    moves.append(fn)
            if len(moves) > 0:
                overwrite = config.getboolean("rename", "move_art_overwrite")
                for fnmove in moves:
                    try:
                        # existing files safeguarded until move successful,
                        # then deleted if overwrite set
                        fnmoveto = os.path.join(path_new,
                                                os.path.split(fnmove)[1])
                        fnmoveto_orig = ""
                        if os.path.exists(fnmoveto):
                            fnmoveto_orig = fnmoveto + ".orig"
                            if not os.path.exists(fnmoveto_orig):
                                os.rename(fnmoveto, fnmoveto_orig)
                            else:
                                suffix = 1
                                while os.path.exists(fnmoveto_orig +
                                                     "." + str(suffix)):
                                    suffix += 1
                                fnmoveto_orig = (fnmoveto_orig +
                                                 "." + str(suffix))
                                os.rename(fnmoveto, fnmoveto_orig)
                        print_d("Renaming image %r to %r" %
                                   (fnmove, fnmoveto), self)
                        shutil.move(fnmove, fnmoveto)
                        if overwrite and fnmoveto_orig:
                            os.remove(fnmoveto_orig)
                        images.remove(fnmove)
                    except Exception:
                        util.print_exc()
Example #35
0
    def _rename(self, library):
        model = self.view.get_model()
        win = WritingWindow(self, len(model))
        win.show()
        was_changed = set()
        skip_all = self.__skip_interactive
        self.view.freeze_child_notify()
        should_move_art = config.getboolean("rename", "move_art")
        moveart_sets = {}
        remove_empty_dirs = config.getboolean("rename", "remove_empty_dirs")

        for entry in itervalues(model):
            if entry.new_name is None:
                continue
            song = entry.song
            old_name = entry.name
            old_pathfile = song['~filename']
            new_name = entry.new_name
            new_pathfile = ""
            # ensure target is a full path
            if os.path.abspath(new_name) != \
                   os.path.abspath(os.path.join(os.getcwd(), new_name)):
                new_pathfile = new_name
            else:
                # must be a relative pattern, so prefix the path
                new_pathfile = \
                    os.path.join(os.path.dirname(old_pathfile), new_name)

            try:
                library.rename(song, text2fsn(new_name), changed=was_changed)
            except Exception:
                util.print_exc()
                if skip_all:
                    continue
                RESPONSE_SKIP_ALL = 1
                msg = qltk.Message(
                    Gtk.MessageType.ERROR, win, _("Unable to rename file"),
                    _("Renaming <b>%(old-name)s</b> to <b>%(new-name)s</b> "
                      "failed. Possibly the target file already exists, "
                      "or you do not have permission to make the "
                      "new file or remove the old one.") % {
                        "old-name": util.escape(old_name),
                        "new-name": util.escape(new_name),
                      },
                    buttons=Gtk.ButtonsType.NONE)
                msg.add_button(_("Ignore _All Errors"), RESPONSE_SKIP_ALL)
                msg.add_icon_button(_("_Stop"), Icons.PROCESS_STOP,
                                    Gtk.ResponseType.CANCEL)
                msg.add_button(_("_Continue"), Gtk.ResponseType.OK)
                msg.set_default_response(Gtk.ResponseType.OK)
                resp = msg.run()
                skip_all |= (resp == RESPONSE_SKIP_ALL)
                # Preserve old behavior: shift-click is Ignore All
                mods = Gdk.Display.get_default().get_pointer()[3]
                skip_all |= mods & Gdk.ModifierType.SHIFT_MASK
                library.reload(song, changed=was_changed)
                if resp != Gtk.ResponseType.OK and resp != RESPONSE_SKIP_ALL:
                    break

            if should_move_art:
                self._moveart(moveart_sets, old_pathfile, new_pathfile, song)

            if remove_empty_dirs:
                path_old = os.path.dirname(old_pathfile)
                if not os.listdir(path_old):
                    try:
                        os.rmdir(path_old)
                        print_d("Removed empty directory: %r" % path_old, self)
                    except Exception:
                        util.print_exc()

            if win.step():
                break

        self.view.thaw_child_notify()
        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(False)
Example #36
0
 def __shuffle_updated(self, widget, shuffle_cls):
     if self.__inhibit:
         return
     print_d("New shuffle mode: %s" % shuffle_cls.name)
     config.set("memory", "shuffle_mode", shuffle_cls.name)
     self.__compose_order()
Example #37
0
 def __repeat_updated(self, widget, repeat_cls):
     if self.__inhibit:
         return
     print_d("New repeat mode: %s" % repeat_cls.name)
     config.set("memory", "repeat_mode", repeat_cls.name)
     self.__compose_order()
Example #38
0
 def _on_songs_received(self, client, songs):
     new = len(self.add(songs))
     print_d("Got %d songs (%d new)." % (len(songs), new))
     self.emit('changed', songs)
Example #39
0
 def applicationShouldTerminate_(self, sender):
     print_d("osx: block termination")
     # FIXME: figure out why idle_add is needed here
     from gi.repository import GLib
     GLib.idle_add(app.quit)
     return False
Example #40
0
 def __song_started(self, player, song):
     if isinstance(song, SoundcloudFile):
         print_d("Getting comments for %s (%s)" % (song("title"), song.key))
         self.client.get_comments(song.track_id)
Example #41
0
 def _override_exceptions():
     print_d("Enabling custom exception handler.")
     sys.excepthook = ExceptionDialog.excepthook
Example #42
0
 def _emit_changed(self, songs, msg=""):
     if self.library and not self.inhibit and songs:
         print_d("Emitting changed (%s) for %d song(s) from playlist %s " %
                 (msg, len(songs), self))
         self.library.emit('changed', songs)
Example #43
0
 def plugin_playlist(self, playlist):
     print_d("Running playlist plugin for %s" % playlist)
     return self._handle_songs(playlist.songs, playlist)
Example #44
0
 def applicationShouldHandleReopen_hasVisibleWindows_(
         self, ns_app, flag):
     print_d("osx: handle reopen")
     app.present()
     return True
Example #45
0
 def enabled(self):
     self.__enabled = True
     print_d("Plugin enabled - accepting new songs.")
Example #46
0
def init_backend(backend, librarian):
    import quodlibet.player
    print_d("Initializing audio backend (%s)" % backend)
    backend = quodlibet.player.init(backend)
    device = backend.init(librarian)
    return device
Example #47
0
 def __destroy(self, *args):
     print_d(f"Destroying Soundcloud Browser {self}")
     if not self.instances():
         self._destroy()
Example #48
0
 def disabled(self):
     self.__enabled = False
     print_d("Plugin disabled - not accepting any new songs.")
     QLSubmitQueue.dump_queue()
Example #49
0
 def __changed(self, library, songs):
     print_d("Updating view")
     self.activate()
Example #50
0
 def song_excluded(self, song):
     if self.exclude and Query(self.exclude).search(song):
         print_d("%s is excluded by %s" %
                 (song("~artist~title"), self.exclude))
         return True
     return False
Example #51
0
 def process_default(self, event):
     print_d('Uncaught event for %s' % (event.maskname if event else "??"))
Example #52
0
 def activate(self):
     print_d("Refreshing browser for query \"%r\"" % self.__filter)
     songs = self.library.query(self.get_filter_text())
     self.songs_selected(songs)
Example #53
0
def main(argv):
    import quodlibet

    quodlibet.init_cli()

    try:
        # we want basic commands not to import gtk (doubles process time)
        assert "gi.repository.Gtk" not in sys.modules
        sys.modules["gi.repository.Gtk"] = None
        startup_actions, cmds_todo = process_arguments(argv)
    finally:
        sys.modules.pop("gi.repository.Gtk", None)

    quodlibet.init()

    from quodlibet import app
    from quodlibet.qltk import add_signal_watch, Icons
    add_signal_watch(app.quit)

    import quodlibet.player
    import quodlibet.library
    from quodlibet import config
    from quodlibet import browsers
    from quodlibet import util

    app.name = "Quod Libet"
    app.id = "quodlibet"
    quodlibet.set_application_info(Icons.QUODLIBET, app.id, app.name)

    config.init(os.path.join(quodlibet.get_user_dir(), "config"))

    library_path = os.path.join(quodlibet.get_user_dir(), "songs")

    print_d("Initializing main library (%s)" %
            (quodlibet.util.path.unexpand(library_path)))

    library = quodlibet.library.init(library_path)
    app.library = library

    # this assumes that nullbe will always succeed
    from quodlibet.player import PlayerError
    wanted_backend = os.environ.get("QUODLIBET_BACKEND",
                                    config.get("player", "backend"))
    backend_traceback = None
    for backend in [wanted_backend, "nullbe"]:
        try:
            player = quodlibet.player.init_player(backend, app.librarian)
        except PlayerError:
            backend_traceback = format_exc()
        else:
            break
    app.player = player

    os.environ["PULSE_PROP_media.role"] = "music"
    os.environ["PULSE_PROP_application.icon_name"] = "quodlibet"

    browsers.init()

    from quodlibet.qltk.songlist import SongList, get_columns

    headers = get_columns()
    SongList.set_all_column_headers(headers)

    for opt in config.options("header_maps"):
        val = config.get("header_maps", opt)
        util.tags.add(opt, val)

    in_all = ("~filename ~uri ~#lastplayed ~#rating ~#playcount ~#skipcount "
              "~#added ~#bitrate ~current ~#laststarted ~basename "
              "~dirname").split()
    for Kind in browsers.browsers:
        if Kind.headers is not None:
            Kind.headers.extend(in_all)
        Kind.init(library)

    pm = quodlibet.init_plugins("no-plugins" in startup_actions)

    if hasattr(player, "init_plugins"):
        player.init_plugins()

    from quodlibet.qltk import unity
    unity.init("quodlibet.desktop", player)

    from quodlibet.qltk.songsmenu import SongsMenu
    SongsMenu.init_plugins()

    from quodlibet.util.cover import CoverManager
    app.cover_manager = CoverManager()
    app.cover_manager.init_plugins()

    from quodlibet.plugins.playlist import PLAYLIST_HANDLER
    PLAYLIST_HANDLER.init_plugins()

    from quodlibet.plugins.query import QUERY_HANDLER
    QUERY_HANDLER.init_plugins()

    from gi.repository import GLib

    def exec_commands(*args):
        for cmd in cmds_todo:
            try:
                resp = cmd_registry.run(app, *cmd)
            except CommandError:
                pass
            else:
                if resp is not None:
                    print_(resp, end="")

    from quodlibet.qltk.quodlibetwindow import QuodLibetWindow, PlayerOptions
    # Call exec_commands after the window is restored, but make sure
    # it's after the mainloop has started so everything is set up.
    app.window = window = QuodLibetWindow(
        library,
        player,
        restore_cb=lambda: GLib.idle_add(exec_commands,
                                         priority=GLib.PRIORITY_HIGH))

    app.player_options = PlayerOptions(window)

    from quodlibet.qltk.debugwindow import MinExceptionDialog
    from quodlibet.qltk.window import on_first_map
    if backend_traceback is not None:

        def show_backend_error(window):
            d = MinExceptionDialog(
                window, _("Audio Backend Failed to Load"),
                _("Loading the audio backend '%(name)s' failed. "
                  "Audio playback will be disabled.") %
                {"name": wanted_backend}, backend_traceback)
            d.run()

        # so we show the main window first
        on_first_map(app.window, show_backend_error, app.window)

    from quodlibet.plugins.events import EventPluginHandler
    pm.register_handler(EventPluginHandler(library.librarian, player))

    from quodlibet.mmkeys import MMKeysHandler
    from quodlibet.remote import Remote, RemoteError
    from quodlibet.commands import registry as cmd_registry, CommandError
    from quodlibet.qltk.tracker import SongTracker, FSInterface
    try:
        from quodlibet.qltk.dbus_ import DBusHandler
    except ImportError:
        DBusHandler = lambda player, library: None

    mmkeys_handler = MMKeysHandler(app)
    mmkeys_handler.start()

    current_path = os.path.join(quodlibet.get_user_dir(), "current")
    fsiface = FSInterface(current_path, player)
    remote = Remote(app, cmd_registry)
    try:
        remote.start()
    except RemoteError:
        exit_(1, True)

    DBusHandler(player, library)
    tracker = SongTracker(library.librarian, player, window.playlist)

    from quodlibet.qltk import session
    session.init("quodlibet")

    quodlibet.enable_periodic_save(save_library=True)

    if "start-playing" in startup_actions:
        player.paused = False

    # restore browser windows
    from quodlibet.qltk.browser import LibraryBrowser
    GLib.idle_add(LibraryBrowser.restore,
                  library,
                  player,
                  priority=GLib.PRIORITY_HIGH)

    def before_quit():
        print_d("Saving active browser state")
        try:
            app.browser.save()
        except NotImplementedError:
            pass

        print_d("Shutting down player device %r." % player.version_info)
        player.destroy()

    quodlibet.main(window, before_quit=before_quit)

    app.player_options.destroy()
    quodlibet.finish_first_session(app.id)
    mmkeys_handler.quit()
    remote.stop()
    fsiface.destroy()

    tracker.destroy()
    quodlibet.library.save()

    config.save()

    print_d("Finished shutdown.")
Example #54
0
 def _log(self, event):
     print_d('%s for "%s" on %s' % (event.maskname, event.name, event.path))
Example #55
0
 def get_winner(self, albums):
     print_d("Weights: %s " % self.plugin.weights)
     scores = self.plugin._score(albums)
     print_d("Scores: %s" % scores)
     return max(scores)[1]
Example #56
0
 def disabled(self):
     if self.running:
         self.running = False
     if self.notifier:
         print_d("Stopping inotify watch...")
         self.notifier.stop()
Example #57
0
 def __init__(self, name=None):
     print_d("Initializing SongFileLibrary \"%s\"." % name)
     super(SongFileLibrary, self).__init__(name)
Example #58
0
 def _show(self, line):
     self.text_buffer.set_text(line)
     self._start_clearing_from += 1
     print_d("♪ %s ♪" % line.strip())
     return False
Example #59
0
 def unmask(self, point):
     print_d("Unmasking %r." % point, self)
     items = self._masked.pop(point, {})
     if items:
         self.add(items.values())
Example #60
0
 def filter_text(self, text):
     self.__searchbar.set_text(text)
     if SoundcloudQuery(text).is_parsable:
         self.activate()
     else:
         print_d("Not parsable: %s" % text)