예제 #1
0
    def __save_files(self, parent, model, library):
        win = WritingWindow(parent, len(model))
        was_changed = set()
        all_done = False
        for entry in model.itervalues():
            song, track = entry.song, entry.tracknumber
            if song.get("tracknumber") == track:
                win.step()
                continue
            if not song.valid():
                win.hide()
                dialog = OverwriteWarning(self, song)
                resp = dialog.run()
                win.show()
                if resp != OverwriteWarning.RESPONSE_SAVE:
                    break
            song["tracknumber"] = track
            try:
                song.write()
            except AudioFileError:
                util.print_exc()
                WriteFailedError(self, song).run()
                library.reload(song, changed=was_changed)
                break
            was_changed.add(song)
            if win.step():
                break
        else:
            all_done = True

        library.changed(was_changed)
        win.destroy()
        self.save.set_sensitive(not all_done)
        self.revert.set_sensitive(not all_done)
예제 #2
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))
        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()
            win.step()
        win.destroy()
        while gtk.events_pending():
            gtk.main_iteration()

    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)
예제 #3
0
    def __save(self, addreplace, library):
        pattern_text = gdecode(self.combo.get_child().get_text())
        pattern = TagsFromPattern(pattern_text)
        model = self.view.get_model()
        add = bool(addreplace.get_active())
        win = WritingWindow(self, len(model))
        win.show()

        was_changed = set()

        all_done = False
        for entry in ((model and model.itervalues()) or []):
            song = entry.song
            changed = False
            if not song.valid():
                win.hide()
                dialog = OverwriteWarning(self, song)
                resp = dialog.run()
                win.show()
                if resp != OverwriteWarning.RESPONSE_SAVE:
                    break

            for i, h in enumerate(pattern.headers):
                text = entry.get_match(h)
                if text:
                    can_multiple = song.can_multiple_values(h)
                    if not add or h not in song or not can_multiple:
                        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 AudioFileError:
                    util.print_exc()
                    WriteFailedError(self, song).run()
                    library.reload(song, changed=was_changed)
                    break
                was_changed.add(song)

            if win.step():
                break
        else:
            all_done = True

        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(not all_done)
예제 #4
0
    def __save(self, addreplace, library):
        pattern_text = self.combo.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))

        was_changed = []

        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(util.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(util.fsdecode(song('~basename'))))
                        ).run()
                    library.reload(song, changed=was_changed)
                    break
                was_changed.append(song)

            if win.step(): break

        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(False)
예제 #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 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)
 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()
예제 #7
0
    def __rename(self, library):
        model = self.view.get_model()
        win = WritingWindow(self, len(model))
        was_changed = []
        skip_all = False
        self.view.freeze_child_notify()

        rows = [(row[0], row[1], row[2].decode('utf-8')) for row in model]
        for song, oldname, newname in rows:
            try:
                newname = util.fsnative(newname)
                library.rename(song, newname, changed=was_changed)
            except StandardError:
                util.print_exc()
                if skip_all: continue
                RESPONSE_SKIP_ALL = 1
                buttons = (_("Ignore _All Errors"), RESPONSE_SKIP_ALL,
                           gtk.STOCK_STOP, gtk.RESPONSE_CANCEL,
                           _("_Continue"), gtk.RESPONSE_OK)
                msg = qltk.Message(
                    gtk.MESSAGE_ERROR, win, _("Unable to rename file"),
                    _("Renaming <b>%s</b> to <b>%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.") %(
                    util.escape(util.fsdecode(oldname)),
                    util.escape(util.fsdecode(newname))),
                    buttons=gtk.BUTTONS_NONE)
                msg.add_buttons(*buttons)
                msg.set_default_response(gtk.RESPONSE_OK)
                resp = msg.run()
                skip_all |= (resp == RESPONSE_SKIP_ALL)
                # Preserve old behavior: shift-click is Ignore All
                mods = gtk.gdk.display_get_default().get_pointer()[3]
                skip_all |= mods & gtk.gdk.SHIFT_MASK
                library.reload(song, changed=was_changed)
                if resp != gtk.RESPONSE_OK and resp != RESPONSE_SKIP_ALL:
                    break
            if win.step(): break

        self.view.thaw_child_notify()
        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(False)
예제 #8
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)
예제 #9
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)
예제 #10
0
 def __save_files(self, parent, model, library):
     win = WritingWindow(parent, len(model))
     was_changed = []
     for row in model:
         song = row[0]
         track = row[2]
         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(util.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(util.fsdecode(song('~basename'))))).run()
             library.reload(song, changed=was_changed)
             break
         was_changed.append(song)
         if win.step(): break
     library.changed(was_changed)
     win.destroy()
예제 #11
0
    def __rename(self, library):
        model = self.view.get_model()
        win = WritingWindow(self, len(model))
        win.show()
        was_changed = set()
        skip_all = False
        self.view.freeze_child_notify()

        for entry in model.itervalues():
            song = entry.song
            new_name = entry.new_name
            old_name = entry.name
            if new_name is None:
                continue

            try:
                library.rename(song, fsnative(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 win.step():
                break

        self.view.thaw_child_notify()
        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(False)
예제 #12
0
    def __remove_images(self, menu_item, songs):
        win = WritingWindow(self.plugin_window, len(songs))
        win.show()

        for song in songs:
            if song.has_images and song.can_change_images:
                song.clear_images()

            if win.step():
                break

        win.destroy()
        self.plugin_finish()
예제 #13
0
    def __rename(self, library):
        model = self.view.get_model()
        win = WritingWindow(self, len(model))
        win.show()
        was_changed = set()
        skip_all = False
        self.view.freeze_child_notify()

        # FIXME: encoding/decoding mess
        rows = [(row[0], row[1], row[2].decode('utf-8')) for row in model]
        for song, oldname, newname in rows:
            try:
                newname = util.fsnative(newname)
                library.rename(song, newname, changed=was_changed)
            except StandardError:
                util.print_exc()
                if skip_all:
                    continue
                RESPONSE_SKIP_ALL = 1
                buttons = (_("Ignore _All Errors"), RESPONSE_SKIP_ALL,
                           Gtk.STOCK_STOP, Gtk.ResponseType.CANCEL,
                           _("_Continue"), Gtk.ResponseType.OK)
                msg = qltk.Message(
                    Gtk.MessageType.ERROR,
                    win,
                    _("Unable to rename file"),
                    _("Renaming <b>%s</b> to <b>%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.") % (util.escape(
                          fsdecode(oldname)), util.escape(fsdecode(newname))),
                    buttons=Gtk.ButtonsType.NONE)
                msg.add_buttons(*buttons)
                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 win.step():
                break

        self.view.thaw_child_notify()
        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(False)
예제 #14
0
파일: embedded.py 프로젝트: yaoml/quodlibet
    def __remove_images(self, menu_item, songs):
        win = WritingWindow(self.plugin_window, len(songs))
        win.show()

        for song in songs:
            if song.has_images and song.can_change_images:
                try:
                    song.clear_images()
                except AudioFileError:
                    util.print_exc()

            if win.step():
                break

        win.destroy()
        self.plugin_finish()
예제 #15
0
    def __rename(self, library):
        model = self.view.get_model()
        win = WritingWindow(self, len(model))
        win.show()
        was_changed = set()
        skip_all = False
        self.view.freeze_child_notify()

        for entry in model.itervalues():
            song = entry.song
            new_name = entry.new_name
            old_name = entry.name
            if new_name is None:
                continue

            try:
                library.rename(song, fsnative(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 win.step():
                break

        self.view.thaw_child_notify()
        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(False)
예제 #16
0
    def __remove_images(self, menu_item, songs):
        win = WritingWindow(self.plugin_window, len(songs))
        win.show()

        for song in songs:
            if song.has_images and song.can_change_images:
                song.clear_images()

            if win.step():
                break

        win.destroy()
        self.plugin_finish()
예제 #17
0
    def __set_image(self, menu_item, songs):
        win = WritingWindow(self.plugin_window, len(songs))
        win.show()

        for song in songs:
            if song.can_change_images:
                fileobj = song.find_cover()
                if fileobj:
                    path = fileobj.name
                    image = EmbeddedImage.from_path(path)
                    if image:
                        song.set_image(image)

            if win.step():
                break

        win.destroy()
        self.plugin_finish()
예제 #18
0
    def __remove_images(self, menu_item, songs):
        win = WritingWindow(self.plugin_window, len(songs))
        win.show()

        for song in songs:
            if song.has_images and song.can_change_images:
                try:
                    song.clear_images()
                except AudioFileError:
                    util.print_exc()

            if win.step():
                break

        win.destroy()
        self.plugin_finish()
예제 #19
0
파일: embedded.py 프로젝트: yaoml/quodlibet
    def __set_image(self, menu_item, songs):
        win = WritingWindow(self.plugin_window, len(songs))
        win.show()

        for song in songs:
            if song.can_change_images:
                fileobj = app.cover_manager.get_cover(song)
                if fileobj:
                    path = fileobj.name
                    image = EmbeddedImage.from_path(path)
                    if image:
                        try:
                            song.set_image(image)
                        except AudioFileError:
                            util.print_exc()

            if win.step():
                break

        win.destroy()
        self.plugin_finish()
예제 #20
0
    def __set_image(self, menu_item, songs):
        win = WritingWindow(self.plugin_window, len(songs))
        win.show()

        for song in songs:
            if song.can_change_images:
                fileobj = app.cover_manager.get_cover(song)
                if fileobj:
                    path = fileobj.name
                    image = EmbeddedImage.from_path(path)
                    if image:
                        song.set_image(image)

            if win.step():
                break

        win.destroy()
        self.plugin_finish()
예제 #21
0
def check_wrapper_changed(library, parent, songs):
    need_write = [s for s in songs if s._needs_write]

    if need_write:
        win = WritingWindow(parent, len(need_write))
        win.show()
        for song in need_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_w("Couldn't save song %s (%s)" % (song("~filename"), e))

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

    _inform_library_of_changed(library, songs)
예제 #22
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)
예제 #23
0
    def __save_files(self, save, revert, model, library):
        updated = {}
        deleted = {}
        added = {}
        renamed = {}
        for row in model:
            if row[EDITED] and not (row[DELETED] or row[RENAMED]):
                if row[ORIGVALUE] is not None:
                    updated.setdefault(row[TAG], [])
                    updated[row[TAG]].append((util.decode(row[VALUE]), util.decode(row[ORIGVALUE])))
                else:
                    added.setdefault(row[TAG], [])
                    added[row[TAG]].append(util.decode(row[VALUE]))
            if row[EDITED] and row[DELETED]:
                if row[ORIGVALUE] is not None:
                    deleted.setdefault(row[TAG], [])
                    deleted[row[TAG]].append(util.decode(row[ORIGVALUE]))

            if row[EDITED] and row[RENAMED] and not row[DELETED]:
                renamed.setdefault(row[TAG], [])
                renamed[row[TAG]].append(
                    (util.decode(row[ORIGTAG]), util.decode(row[VALUE]), util.decode(row[ORIGVALUE]))
                )

        was_changed = []
        songs = self.__songinfo.songs
        win = WritingWindow(self, len(songs))
        for song in songs:
            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(util.fsdecode(song("~basename"))),
                ).run()
            ):
                break

            changed = False
            for key, values in updated.iteritems():
                for (new_value, old_value) in values:
                    new_value = util.unescape(new_value)
                    if song.can_change(key):
                        if old_value is None:
                            song.add(key, new_value)
                        else:
                            song.change(key, old_value, new_value)
                        changed = True
            for key, values in added.iteritems():
                for value in values:
                    value = util.unescape(value)
                    if song.can_change(key):
                        song.add(key, value)
                        changed = True
            for key, values in deleted.iteritems():
                for value in values:
                    value = util.unescape(value)
                    if song.can_change(key) and key in song:
                        song.remove(key, value)
                        changed = True
            save_rename = []
            for new_tag, values in renamed.iteritems():
                for old_tag, new_value, old_value in values:
                    old_tag = util.unescape(old_tag)
                    old_value = util.unescape(old_value)
                    new_value = util.unescape(new_value)
                    if song.can_change(new_tag) and song.can_change(old_tag) and old_tag in song:
                        if not is_special(new_value):
                            song.remove(old_tag, old_value)
                            save_rename.append((new_tag, new_value))
                        elif is_missing(new_value):
                            value = strip_missing(old_value)
                            song.remove(old_tag, old_value)
                            save_rename.append((new_tag, new_value))
                        else:
                            save_rename.append((new_tag, song[old_tag]))
                            song.remove(old_tag, None)
                        changed = True
            for tag, value in save_rename:
                song.add(tag, value)

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

            if win.step():
                break

        win.destroy()
        library.changed(was_changed)
        for b in [save, revert]:
            b.set_sensitive(False)
예제 #24
0
    def __save_files(self, save, revert, model, library):
        updated = {}
        deleted = {}
        added = {}
        renamed = {}
        for row in model:
            if row[EDITED] and not (row[DELETED] or row[RENAMED]):
                if row[ORIGVALUE] is not None:
                    updated.setdefault(row[TAG], [])
                    updated[row[TAG]].append(
                        (decode(row[VALUE]), decode(row[ORIGVALUE])))
                else:
                    added.setdefault(row[TAG], [])
                    added[row[TAG]].append(decode(row[VALUE]))
            if row[EDITED] and row[DELETED]:
                if row[ORIGVALUE] is not None:
                    deleted.setdefault(row[TAG], [])
                    deleted[row[TAG]].append(decode(row[ORIGVALUE]))

            if row[EDITED] and row[RENAMED] and not row[DELETED]:
                renamed.setdefault(row[TAG], [])
                renamed[row[TAG]].append(
                    (decode(row[ORIGTAG]), decode(row[VALUE]),
                     decode(row[ORIGVALUE])))

        was_changed = set()
        songs = self.__songinfo.songs
        win = WritingWindow(self, len(songs))
        win.show()
        for song in songs:
            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(util.fsdecode(song("~basename")))).run():
                break

            changed = False
            for key, values in updated.iteritems():
                for (new_value, old_value) in values:
                    new_value = util.unescape(new_value)
                    if song.can_change(key):
                        if old_value is None:
                            song.add(key, new_value)
                        else:
                            song.change(key, old_value, new_value)
                        changed = True
            for key, values in added.iteritems():
                for value in values:
                    value = util.unescape(value)
                    if song.can_change(key):
                        song.add(key, value)
                        changed = True
            for key, values in deleted.iteritems():
                for value in values:
                    value = util.unescape(value)
                    if song.can_change(key) and key in song:
                        song.remove(key, value)
                        changed = True
            save_rename = []
            for new_tag, values in renamed.iteritems():
                for old_tag, new_value, old_value in values:
                    old_tag = util.unescape(old_tag)
                    old_value = util.unescape(old_value)
                    new_value = util.unescape(new_value)
                    if (song.can_change(new_tag) and song.can_change(old_tag)
                            and old_tag in song):
                        if not is_special(new_value):
                            song.remove(old_tag, old_value)
                            save_rename.append((new_tag, new_value))
                        elif is_missing(new_value):
                            value = strip_missing(old_value)
                            song.remove(old_tag, old_value)
                            save_rename.append((new_tag, new_value))
                        else:
                            save_rename.append((new_tag, song[old_tag]))
                            song.remove(old_tag, None)
                        changed = True
            for tag, value in save_rename:
                song.add(tag, value)

            if changed:
                try:
                    song.write()
                except:
                    util.print_exc()
                    qltk.ErrorMessage(
                        self, _("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

        win.destroy()
        library.changed(was_changed)
        for b in [save, revert]:
            b.set_sensitive(False)
예제 #25
0
    def __save_files(self, save, revert, model, library):
        updated = {}
        deleted = {}
        added = {}
        renamed = {}

        for entry in model.values():
            if entry.edited and not (entry.deleted or entry.renamed):
                if entry.origvalue is not None:
                    l = updated.setdefault(entry.tag, [])
                    l.append((entry.value, entry.origvalue))
                else:
                    l = added.setdefault(entry.tag, [])
                    l.append(entry.value)

            if entry.edited and entry.deleted:
                if entry.origvalue is not None:
                    l = deleted.setdefault(entry.tag, [])
                    l.append(entry.origvalue)

            if entry.edited and entry.renamed and not entry.deleted:
                l = renamed.setdefault(entry.tag, [])
                l.append((entry.origtag, entry.value, entry.origvalue))

        was_changed = set()
        songs = self.__songinfo.songs
        win = WritingWindow(self, len(songs))
        win.show()
        all_done = False
        for song in songs:
            if not song.valid():
                win.hide()
                dialog = OverwriteWarning(self, song)
                resp = dialog.run()
                win.show()
                if resp != OverwriteWarning.RESPONSE_SAVE:
                    break

            changed = False
            for key, values in updated.items():
                for (new_value, old_value) in values:
                    if song.can_change(key):
                        if old_value is None:
                            song.add(key, new_value.text)
                        else:
                            song.change(key, old_value.text, new_value.text)
                        changed = True

            for key, values in added.items():
                for value in values:
                    if song.can_change(key):
                        song.add(key, value.text)
                        changed = True

            for key, values in deleted.items():
                for value in values:
                    if not value.shared:
                        # In case it isn't shared we don't know the actual
                        # values to remove. But we know that in that case
                        # we merge all values into one Comment so just removing
                        # everything for that key is OK.
                        song.remove(key, None)
                        changed = True
                    elif key in song:
                        song.remove(key, value.text)
                        changed = True

            save_rename = []
            for new_tag, values in renamed.items():
                for old_tag, new_value, old_value in values:
                    if (song.can_change(new_tag) and old_tag in song):
                        if not new_value.is_special():
                            song.remove(old_tag, old_value.text)
                            save_rename.append((new_tag, new_value))
                        elif new_value.is_missing():
                            song.remove(old_tag, old_value)
                            save_rename.append((new_tag, new_value))
                        else:
                            save_rename.append(
                                (new_tag, Comment(song[old_tag])))
                            song.remove(old_tag, None)
                        changed = True

            for tag, value in save_rename:
                song.add(tag, value.text)

            if changed:
                try:
                    song.write()
                except AudioFileError:
                    util.print_exc()
                    WriteFailedError(self, song).run()
                    library.reload(song, changed=was_changed)
                    break
                was_changed.add(song)

            if win.step():
                break
        else:
            all_done = True

        win.destroy()
        library.changed(was_changed)
        for b in [save, revert]:
            b.set_sensitive(not all_done)
예제 #26
0
    def __save_files(self, parent, model, library):
        win = WritingWindow(parent, len(model))
        was_changed = set()
        all_done = False
        for entry in model.values():
            song, track = entry.song, entry.tracknumber
            if song.get("tracknumber") == track:
                win.step()
                continue
            if not song.valid():
                win.hide()
                dialog = OverwriteWarning(self, song)
                resp = dialog.run()
                win.show()
                if resp != OverwriteWarning.RESPONSE_SAVE:
                    break
            song["tracknumber"] = track
            try:
                song.write()
            except AudioFileError:
                util.print_exc()
                WriteFailedError(self, song).run()
                library.reload(song, changed=was_changed)
                break
            was_changed.add(song)
            if win.step():
                break
        else:
            all_done = True

        library.changed(was_changed)
        win.destroy()
        self.save.set_sensitive(not all_done)
        self.revert.set_sensitive(not all_done)
예제 #27
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()

        all_done = False
        for entry in ((model and model.itervalues()) or []):
            song = entry.song
            changed = False
            if not song.valid():
                win.hide()
                dialog = OverwriteWarning(self, song)
                resp = dialog.run()
                win.show()
                if resp != OverwriteWarning.RESPONSE_SAVE:
                    break

            for i, h in enumerate(pattern.headers):
                text = entry.get_match(h)
                if text:
                    can_multiple = song.can_multiple_values(h)
                    if not add or h not in song or not can_multiple:
                        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:
                    util.print_exc()
                    WriteFailedError(self, song).run()
                    library.reload(song, changed=was_changed)
                    break
                was_changed.add(song)

            if win.step():
                break
        else:
            all_done = True

        win.destroy()
        library.changed(was_changed)
        self.save.set_sensitive(not all_done)
예제 #28
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)
예제 #29
0
    def __save_files(self, save, revert, model, library):
        updated = {}
        deleted = {}
        added = {}
        renamed = {}

        for entry in itervalues(model):
            if entry.edited and not (entry.deleted or entry.renamed):
                if entry.origvalue is not None:
                    l = updated.setdefault(entry.tag, [])
                    l.append((entry.value, entry.origvalue))
                else:
                    l = added.setdefault(entry.tag, [])
                    l.append(entry.value)

            if entry.edited and entry.deleted:
                if entry.origvalue is not None:
                    l = deleted.setdefault(entry.tag, [])
                    l.append(entry.origvalue)

            if entry.edited and entry.renamed and not entry.deleted:
                l = renamed.setdefault(entry.tag, [])
                l.append((entry.origtag, entry.value, entry.origvalue))

        was_changed = set()
        songs = self.__songinfo.songs
        win = WritingWindow(self, len(songs))
        win.show()
        all_done = False
        for song in songs:
            if not song.valid():
                win.hide()
                dialog = OverwriteWarning(self, song)
                resp = dialog.run()
                win.show()
                if resp != OverwriteWarning.RESPONSE_SAVE:
                    break

            changed = False
            for key, values in iteritems(updated):
                for (new_value, old_value) in values:
                    if song.can_change(key):
                        if old_value is None:
                            song.add(key, new_value.text)
                        else:
                            song.change(key, old_value.text, new_value.text)
                        changed = True

            for key, values in iteritems(added):
                for value in values:
                    if song.can_change(key):
                        song.add(key, value.text)
                        changed = True

            for key, values in iteritems(deleted):
                for value in values:
                    if not value.shared:
                        # In case it isn't shared we don't know the actual
                        # values to remove. But we know that in that case
                        # we merge all values into one Comment so just removing
                        # everything for that key is OK.
                        song.remove(key, None)
                        changed = True
                    elif key in song:
                        song.remove(key, value.text)
                        changed = True

            save_rename = []
            for new_tag, values in iteritems(renamed):
                for old_tag, new_value, old_value in values:
                    if (song.can_change(new_tag) and old_tag in song):
                        if not new_value.is_special():
                            song.remove(old_tag, old_value.text)
                            save_rename.append((new_tag, new_value))
                        elif new_value.is_missing():
                            song.remove(old_tag, old_value)
                            save_rename.append((new_tag, new_value))
                        else:
                            save_rename.append(
                                (new_tag, Comment(song[old_tag])))
                            song.remove(old_tag, None)
                        changed = True

            for tag, value in save_rename:
                song.add(tag, value.text)

            if changed:
                try:
                    song.write()
                except AudioFileError:
                    util.print_exc()
                    WriteFailedError(self, song).run()
                    library.reload(song, changed=was_changed)
                    break
                was_changed.add(song)

            if win.step():
                break
        else:
            all_done = True

        win.destroy()
        library.changed(was_changed)
        for b in [save, revert]:
            b.set_sensitive(not all_done)