Пример #1
0
def add_station(uri):
    """Fetches the URI content and extracts IRFiles"""

    irfs = []
    if isinstance(uri, unicode):
        uri = uri.encode('utf-8')

    if uri.lower().endswith(".pls") or uri.lower().endswith(".m3u"):
        try:
            sock = urllib.urlopen(uri)
        except EnvironmentError as e:
            encoding = util.get_locale_encoding()
            try:
                err = e.strerror.decode(encoding, 'replace')
            except (TypeError, AttributeError):
                err = e.strerror[1].decode(encoding, 'replace')
            qltk.ErrorMessage(None, _("Unable to add station"), err).run()
            return []

        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, err:
            qltk.ErrorMessage(None, _("Unable to add station"), err).run()
Пример #2
0
    def __edit_tag_name(self, renderer, path, new_tag, model):
        new_tag = ' '.join(new_tag.splitlines()).lower()
        row = model[path]
        if new_tag == row[TAG]:
            return
        elif not self.__songinfo.can_change(row[TAG]):
            # Can't remove the old tag.
            title = _("Invalid tag")
            msg = _(
                "Invalid tag <b>%s</b>\n\nThe files currently"
                " selected do not support editing this tag.") % util.escape(
                    row[TAG])
            qltk.ErrorMessage(self, title, msg).run()
        elif not self.__songinfo.can_change(new_tag):
            # Can't add the new tag.
            title = _("Invalid tag")
            msg = _("Invalid tag <b>%s</b>\n\nThe files currently"
                    " selected do not support editing this tag."
                    ) % util.escape(new_tag)
            qltk.ErrorMessage(self, title, msg).run()
        else:
            if new_tag in massagers.tags:
                fmt = massagers.tags[new_tag]
                v = util.unescape(row[VALUE])
                if not fmt.is_valid(v):
                    qltk.WarningMessage(
                        self, _("Invalid value"),
                        _("Invalid value: <b>%(value)s</b>\n\n%(error)s") % {
                            "value": row[VALUE],
                            "error": fmt.error
                        }).run()
                    return
                value = fmt.validate(v)
            else:
                value = row[VALUE]
                value = util.unescape(value)

            if row[ORIGVALUE] is None:
                # The tag hasn't been saved yet, so we can just update
                # the name in the model, and the value, since it
                # may have been re-validated.
                row[TAG] = new_tag
                row[VALUE] = value
            else:
                # The tag has been saved, so delete the old tag and
                # add a new one with the old (or sanitized) value.
                row[RENAMED] = row[EDITED] = True
                row[ORIGTAG] = row[TAG]
                row[TAG] = new_tag
Пример #3
0
    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")
Пример #4
0
    def __save(self, *data):
        """Save the cover and spawn the program to edit it if selected"""

        filename = self.name_combo.get_active_text()
        # Allow support for filename patterns
        pattern = Pattern(filename)
        filename = fsencode(pattern.format(self.song))
        file_path = os.path.join(self.dirname, filename)

        msg = (_('The file <b>%s</b> already exists.\n\nOverwrite?')
                % util.escape(filename))
        if (os.path.exists(file_path)
                and not qltk.ConfirmAction(None, _('File exists'), msg).run()):
            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.window.emit("artwork-changed", [self.song])

        self.main_win.destroy()
Пример #5
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)

        msg = (_('The file <b>%s</b> already exists.\n\nOverwrite?')
                % util.escape(filename))
        if (os.path.exists(file_path)
                and not qltk.ConfirmAction(None, _('File exists'), msg).run()):
            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.window.emit("artwork-changed", [self.song])

        self.main_win.destroy()
Пример #6
0
    def __mkdir(self, button):
        model, paths = self.get_selection().get_selected_rows()
        if len(paths) != 1:
            return

        path = paths[0]
        directory = model[path][0]

        dir_ = GetStringDialog(None, _("New Folder"),
                               _("Enter a name for the new folder:")).run()

        if not dir_:
            return

        dir_ = glib2fsn(dir_)
        fullpath = os.path.realpath(os.path.join(directory, dir_))

        try:
            os.makedirs(fullpath)
        except EnvironmentError as err:
            error = "<b>%s</b>: %s" % (err.filename, err.strerror)
            qltk.ErrorMessage(None, _("Unable to create folder"), error).run()
            return

        self.emit('test-expand-row', model.get_iter(path), path)
        self.expand_row(path, False)
Пример #7
0
def printError():
	exc_type, exc_value, exc_traceback = sys.exc_info()
	lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
	for line in lines:
		print(line)
	qltk.ErrorMessage(None, _('Error occured'),
                _('%s.') % lines).run()
Пример #8
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 Exception:
                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()

            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)
Пример #9
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)
        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._song])

        self.main_win.destroy()
 def __save_files(self, parent, model, library):
     win = WritingWindow(parent, len(model))
     was_changed = set()
     for song, track in [(r[0], r[2]) for r in model]:
         if song.get("tracknumber") == track:
             win.step()
             continue
         if not song.valid() and not qltk.ConfirmAction(
                 win, _("Tag may not be accurate"),
                 _("<b>%s</b> changed while the program was running. "
                   "Saving without refreshing your library may "
                   "overwrite other changes to the song.\n\n"
                   "Save this song anyway?") %
                 util.escape(fsdecode(song("~basename")))).run():
             break
         song["tracknumber"] = track
         try:
             song.write()
         except:
             util.print_exc()
             qltk.ErrorMessage(
                 win, _("Unable to save song"),
                 _("Saving <b>%s</b> failed. The file may be "
                   "read-only, corrupted, or you do not have "
                   "permission to edit it.") %
                 util.escape(fsdecode(song('~basename')))).run()
             library.reload(song, changed=was_changed)
             break
         was_changed.add(song)
         if win.step():
             break
     library.changed(was_changed)
     win.destroy()
Пример #11
0
    def __drag_data_get(self, view, ctx, sel, tid, etime):
        model, paths = self.get_selection().get_selected_rows()
        if tid == DND_QL:
            songs = [model[path][0] for path in paths
                     if model[path][0].can_add]
            if len(songs) != len(paths):
                qltk.ErrorMessage(
                    qltk.get_top_parent(self), _("Unable to copy songs"),
                    _("The files selected cannot be copied to other "
                      "song lists or the queue.")).run()
                Gdk.drag_abort(ctx, etime)
                return

            qltk.selection_set_songs(sel, songs)

            # DEM 2018/05/25: The below check is a deliberate repetition of
            # code in the drag-motion signal handler.  In MacOS/Quartz, the
            # context action is not propogated between event handlers for
            # drag-motion and drag-data-get using "ctx.get_actions()".  It is
            # unclear if this is a bug or expected behavior.  Regardless, the
            # context widget information is the same so identical behavior can
            # be achieved by simply using the same widget check as in the move
            # action.
            if Gtk.drag_get_source_widget(ctx) == self and \
                    not self.__force_copy:
                self.__drag_iters = list(map(model.get_iter, paths))
            else:
                self.__drag_iters = []
        else:
            uris = [model[path][0]("~uri") for path in paths]
            sel.set_uris(uris)
            self.__drag_iters = []
Пример #12
0
    def _show_sync_error(self, title, message):
        """
        Show an error message whenever a synchronization error occurs.

        :param title:   The title of the message popup.
        :param message: The error message.
        """
        qltk.ErrorMessage(self.main_vbox, title, message).run()
        print_e(title)
Пример #13
0
 def __drag_data_received(self, view, ctx, x, y, sel, tid, etime, library):
     # TreeModelSort doesn't support GtkTreeDragDestDrop.
     view.emit_stop_by_name('drag-data-received')
     model = view.get_model()
     if tid == DND_QL:
         filenames = qltk.selection_get_filenames(sel)
         songs = list(filter(None, [library.get(f) for f in filenames]))
         if not songs:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         try:
             path, pos = view.get_dest_row_at_pos(x, y)
         except TypeError:
             playlist = XSPFBackedPlaylist.from_songs(PLAYLISTS, songs,
                                                      library)
             GLib.idle_add(self._select_playlist, playlist)
         else:
             playlist = model[path][0]
             playlist.extend(songs)
         self.changed(playlist)
         Gtk.drag_finish(ctx, True, False, etime)
         # Cause a refresh to the dragged-to playlist if it is selected
         # so that the dragged (duplicate) track(s) appears
         if playlist is self.__get_name_of_current_selected_playlist():
             model, plist_iter = self.__selected_playlists()
             songlist = qltk.get_top_parent(self).songlist
             self.activate(resort=not songlist.is_sorted())
     else:
         if tid == DND_URI_LIST:
             uri = sel.get_uris()[0]
             name = os.path.basename(uri)
         elif tid == DND_MOZ_URL:
             data = sel.get_data()
             uri, name = data.decode('utf16', 'replace').split('\n')
         else:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         name = _name_for(name or os.path.basename(uri))
         try:
             sock = urlopen(uri)
             if uri.lower().endswith('.pls'):
                 playlist = parse_pls(sock, name, library=library)
             elif (uri.lower().endswith('.m3u') or
                     uri.lower().endswith('.m3u8')):
                 playlist = parse_m3u(sock, name, library=library)
             else:
                 raise IOError
             library.add(playlist.songs)
             self.changed(playlist)
             Gtk.drag_finish(ctx, True, False, etime)
         except IOError:
             Gtk.drag_finish(ctx, False, False, etime)
             qltk.ErrorMessage(
                 qltk.get_top_parent(self),
                 _("Unable to import playlist"),
                 _("Quod Libet can only import playlists in the M3U/M3U8 "
                   "and PLS formats.")).run()
Пример #14
0
 def __drag_data_received(self, view, ctx, x, y, sel, tid, etime, library):
     # TreeModelSort doesn't support GtkTreeDragDestDrop.
     view.emit_stop_by_name('drag-data-received')
     model = view.get_model()
     if tid == DND_QL:
         filenames = qltk.selection_get_filenames(sel)
         songs = listfilter(None, [library.get(f) for f in filenames])
         if not songs:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         try:
             path, pos = view.get_dest_row_at_pos(x, y)
         except TypeError:
             playlist = FileBackedPlaylist.from_songs(PLAYLISTS, songs,
                                                      library)
             GLib.idle_add(self._select_playlist, playlist)
         else:
             playlist = model[path][0]
             playlist.extend(songs)
         self.changed(playlist)
         Gtk.drag_finish(ctx, True, False, etime)
     else:
         if tid == DND_URI_LIST:
             uri = sel.get_uris()[0]
             name = os.path.basename(uri)
         elif tid == DND_MOZ_URL:
             data = sel.get_data()
             uri, name = data.decode('utf16', 'replace').split('\n')
         else:
             Gtk.drag_finish(ctx, False, False, etime)
             return
         name = name or os.path.basename(uri) or _("New Playlist")
         uri = uri.encode('utf-8')
         try:
             sock = urlopen(uri)
             f = NamedTemporaryFile()
             f.write(sock.read())
             f.flush()
             if uri.lower().endswith('.pls'):
                 playlist = parse_pls(f.name, library=library)
             elif uri.lower().endswith('.m3u'):
                 playlist = parse_m3u(f.name, library=library)
             else:
                 raise IOError
             library.add_filename(playlist)
             if name:
                 playlist.rename(name)
             self.changed(playlist)
             Gtk.drag_finish(ctx, True, False, etime)
         except IOError:
             Gtk.drag_finish(ctx, False, False, etime)
             qltk.ErrorMessage(
                 qltk.get_top_parent(self),
                 _("Unable to import playlist"),
                 _("Quod Libet can only import playlists in the M3U "
                   "and PLS formats.")).run()
Пример #15
0
    def __save(self, addreplace, library):
        pattern_text = self.combo.get_child().get_text().decode('utf-8')
        pattern = TagsFromPattern(pattern_text)
        model = self.view.get_model()
        add = bool(addreplace.get_active())
        win = WritingWindow(self, len(model))
        win.show()

        was_changed = set()

        for row in (model or []):
            song = row[0]
            changed = False
            if not song.valid() and not qltk.ConfirmAction(
                self, _("Tag may not be accurate"),
                _("<b>%s</b> changed while the program was running. "
                  "Saving without refreshing your library may "
                  "overwrite other changes to the song.\n\n"
                  "Save this song anyway?") % (
                util.escape(fsdecode(song("~basename"))))
                ).run():
                break

            for i, h in enumerate(pattern.headers):
                if row[i + 2]:
                    text = row[i + 2].decode("utf-8")
                    if not add or h not in song or not song.multiple_values:
                        song[h] = text
                        changed = True
                    else:
                        for val in text.split("\n"):
                            if val not in song.list(h):
                                song.add(h, val)
                                changed = True

            if changed:
                try:
                    song.write()
                except:
                    qltk.ErrorMessage(
                        self, _("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(fsdecode(song('~basename'))))
                        ).run()
                    library.reload(song, changed=was_changed)
                    break
                was_changed.add(song)

            if win.step():
                break

        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(False)
Пример #16
0
 def __eject(self, button):
     model, iter = self.__view.get_selection().get_selected()
     if iter:
         device = model[iter][0]
         status = device.eject()
         if status is not True:
             msg = _("Ejecting %s failed.") % util.bold(device['name'])
             if status:
                 msg += "\n\n%s" % status
             qltk.ErrorMessage(self, _("Unable to eject device"), msg).run()
Пример #17
0
 def enabled(self):
     print_d("Debug is set to %s" % self._debug)
     self.active = True
     self.init_server()
     self.server.pause()
     if not self.server.is_connected:
         qltk.ErrorMessage(
             None, _("Error finding Squeezebox server"),
             _("Error finding %s. Please check settings") %
             self.server.config).run()
Пример #18
0
 def __check_markup(self, apply):
     try:
         f = AudioFile({"~filename": "dummy"})
         Pango.parse_markup(XMLFromPattern(self.text) % f, -1, u"\u0000")
     except (ValueError, GLib.GError), e:
         qltk.ErrorMessage(
             self, _("Invalid pattern"),
             _("The pattern you entered was invalid. Make sure you enter "
               "&lt; and &gt; as \\&lt; and \\&gt; and that your tags are "
               "balanced.\n\n%s") % util.escape(str(e))).run()
         apply.stop_emission('clicked')
Пример #19
0
    def __rmdir(self, button):
        model, paths = self.get_selection().get_selected_rows()
        if len(paths) != 1:
            return

        directory = model[paths[0]][0]
        try:
            os.rmdir(directory)
        except EnvironmentError, err:
            error = "<b>%s</b>: %s" % (err.filename, err.strerror)
            qltk.ErrorMessage(None, _("Unable to delete folder"), error).run()
            return
Пример #20
0
 def __check_markup(self, apply):
     try:
         validate_markup_pattern(self.text, self._alternative_markup,
                                 self._links)
     except ValueError as e:
         qltk.ErrorMessage(
             self, _("Invalid pattern"),
             _("The pattern you entered was invalid. Make sure you enter "
               "&lt; and &gt; as \\&lt; and \\&gt; and that your tags are "
               "balanced.\n\n%s") % util.escape(str(e))).run()
         apply.stop_emission('clicked')
     return False
Пример #21
0
 def _rename(self, path, newname):
     playlist = self._lists[path][0]
     try:
         playlist.rename(newname)
     except ValueError as s:
         qltk.ErrorMessage(None, _("Unable to rename playlist"), s).run()
     else:
         row = self._lists[path]
         child_model = self.model
         child_model.remove(self._lists.convert_iter_to_child_iter(
             row.iter))
         child_model.append(row=[playlist])
         self._select_playlist(playlist, scroll=True)
Пример #22
0
    def __add_new_tag(self, model, tag, value):
        if (tag in self.__songinfo and not self.__songinfo.multiple_values):
            title = _("Unable to add tag")
            msg = _(
                "Unable to add <b>%s</b>\n\nThe files currently"
                " selected do not support multiple values.") % util.escape(tag)
            qltk.ErrorMessage(self, title, msg).run()
            return

        iters = [row.iter for row in model if row[TAG] == tag]
        row = [tag, util.escape(value), True, True, False, None, False, None]
        if len(iters):
            model.insert_after(iters[-1], row=row)
        else:
            model.append(row=row)
Пример #23
0
 def plugin_playlist(self, playlist):
     self.init_server()
     if not self.server.is_connected:
         qltk.ErrorMessage(
             None,
             _("Error finding Squeezebox server"),
             _("Error finding %s. Please check settings") %
             self.server.config
         ).run()
     else:
         name = self.__get_playlist_name(name=playlist.name)
         if name:
             task = Task("Squeezebox", _("Export to Squeezebox playlist"),
                         stop=self.__cancel_add)
             copool.add(self.__add_songs, task, playlist.songs, name,
                        funcid="squeezebox-playlist-save")
Пример #24
0
    def __edit_tag_name(self, renderer, path, new_tag, model):
        new_tag = ' '.join(new_tag.splitlines()).lower()
        path = Gtk.TreePath.new_from_string(path)
        entry = model[path][0]
        if new_tag == entry.tag:
            return
        elif not self.__songinfo.can_change(new_tag):
            # Can't add the new tag.
            title = _("Invalid tag")
            msg = _("Invalid tag <b>%s</b>\n\nThe files currently"
                    " selected do not support editing this tag."
                    ) % util.escape(new_tag)
            qltk.ErrorMessage(self, title, msg).run()
        else:
            # FIXME: In case this is a special one we only
            # validate one value and never write it back..

            text = entry.value.text
            if not massagers.is_valid(new_tag, text):
                qltk.WarningMessage(
                    self, _("Invalid value"),
                    _("Invalid value: <b>%(value)s</b>\n\n%(error)s") % {
                        "value": text,
                        "error": massagers.error_message(new_tag, text)
                    }).run()
                return
            text = massagers.validate(new_tag, text)

            if entry.origvalue is None:
                # The tag hasn't been saved yet, so we can just update
                # the name in the model, and the value, since it
                # may have been re-validated.
                entry.tag = new_tag
                entry.value = Comment(text)
            else:
                # The tag has been saved, so delete the old tag and
                # add a new one with the old (or sanitized) value.
                entry.renamed = entry.edited = True
                entry.origtag = entry.tag
                entry.tag = new_tag
                if not entry.value.is_special():
                    entry.value = Comment(text)

            entry.canedit = True

            model.row_changed(path, model.get_iter(path))
Пример #25
0
    def __upload(self, song):
        filename = song["~filename"]
        basename = song("~basename")
        dirname = os.path.basename(os.path.dirname(filename))
        target = os.path.join(dirname, basename)

        # Avoid spurious calls to ifp mkdir; this can take a long time
        # on a noisy USB line.
        if dirname not in self.__madedir:
            os.system("ifp mkdir %r> /dev/null 2>/dev/null" % dirname)
            self.__madedir.append(dirname)
        if os.system("ifp upload %r %r > /dev/null" % (filename, target)):
            qltk.ErrorMessage(
                None, _("Error uploading"),
                _("Unable to upload <b>%s</b>. The device may be "
                  "out of space, or turned off.") % (
                util.escape(filename))).run()
            return True
Пример #26
0
    def __rmdir(self, button):
        model, paths = self.get_selection().get_selected_rows()
        if len(paths) != 1:
            return

        directory = model[paths[0]][0]
        try:
            os.rmdir(directory)
        except EnvironmentError as err:
            error = "<b>%s</b>: %s" % (err.filename, err.strerror)
            qltk.ErrorMessage(None, _("Unable to delete folder"), error).run()
            return

        ppath = Gtk.TreePath(paths[0][:-1])
        expanded = self.row_expanded(ppath)
        self.emit('test-expand-row', model.get_iter(ppath), ppath)
        if expanded:
            self.expand_row(ppath, False)
Пример #27
0
    def __add_station(self, uri):
        irfs = add_station(uri)

        if not irfs:
            qltk.ErrorMessage(
                None, _("No stations found"),
                _("No Internet radio stations were found at %s.") %
                util.escape(uri)).run()
            return

        irfs = filter(lambda station: station not in self.__fav_stations, irfs)
        if not irfs:
            qltk.WarningMessage(
                None, _("Unable to add station"),
                _("All stations listed are already in your library.")).run()

        if irfs:
            self.__fav_stations.add(irfs)
Пример #28
0
    def __preview(self, songs):
        model = self.view.get_model()
        if songs is None:
            songs = [e.song for e in model.itervalues()]

        pattern_text = self.combo.get_child().get_text().decode("utf-8")

        try:
            pattern = FileFromPattern(pattern_text)
        except ValueError:
            qltk.ErrorMessage(
                self, _("Path is not absolute"),
                _("The pattern\n\t<b>%s</b>\ncontains / but "
                  "does not start from root. To avoid misnamed "
                  "folders, root your pattern by starting "
                  "it with / or ~/.") % (
                util.escape(pattern))).run()
            return
        else:
            if pattern:
                self.combo.prepend_text(pattern_text)
                self.combo.write(NBP)

        # native paths
        orignames = [song["~filename"] for song in songs]
        newnames = [pattern.format(song) for song in songs]
        for f in self.filter_box.filters:
            if f.active:
                newnames = f.filter_list(orignames, newnames)

        model.clear()
        for song, newname in zip(songs, newnames):
            entry = Entry(song)
            entry.new_name = fsdecode(newname)
            model.append(row=[entry])

        self.preview.set_sensitive(False)
        self.save.set_sensitive(bool(pattern_text))
        for song in songs:
            if not song.is_file:
                self.set_sensitive(False)
                break
        else:
            self.set_sensitive(True)
Пример #29
0
 def __import(self, activator, library):
     filt = lambda fn: fn.endswith(".pls") or fn.endswith(".m3u")
     from quodlibet.qltk.chooser import FileChooser
     chooser = FileChooser(self, _("Import Playlist"), filt, get_home_dir())
     files = chooser.run()
     chooser.destroy()
     for filename in files:
         if filename.endswith(".m3u"):
             playlist = parse_m3u(filename, library=library)
         elif filename.endswith(".pls"):
             playlist = parse_pls(filename, library=library)
         else:
             qltk.ErrorMessage(
                 qltk.get_top_parent(self), _("Unable to import playlist"),
                 _("Quod Libet can only import playlists in the M3U "
                   "and PLS formats.")).run()
             return
         self.changed(playlist)
         library.add(playlist)
Пример #30
0
    def __rmdir(self, button):
        model, paths = self.get_selection().get_selected_rows()

        directories = [model[path][0] for path in paths]
        print_d("Deleting %d empty directories" % len(directories))
        for directory in directories:
            try:
                os.rmdir(directory)
            except EnvironmentError as err:
                error = "<b>%s</b>: %s" % (err.filename, err.strerror)
                qltk.ErrorMessage(None, _("Unable to delete folder"),
                                  error).run()
                return

        ppath = Gtk.TreePath(paths[0][:-1])
        expanded = self.row_expanded(ppath)
        self.emit('test-expand-row', model.get_iter(ppath), ppath)
        if expanded:
            self.expand_row(ppath, False)