def __copy_songs(self, songlist, songs):
        model, iter = self.__view.get_selection().get_selected()
        if not iter:
            return False

        device = model[iter][0]
        if not self.__check_device(device, _("Unable to copy songs")):
            return False

        self.__busy = True

        wlb = self.__statusbar
        wlb.setup(len(songs), _("Copying <b>%(song)s</b>"), {'song': ''})
        wlb.show()

        model = songlist.get_model()
        for song in songs:
            label = util.escape(song('~artist~title'))
            if wlb.step(song=label):
                wlb.hide()
                break

            if len(model) > 0:
                songlist.scroll_to_cell(model[-1].path)
            while Gtk.events_pending():
                Gtk.main_iteration()

            space, free = device.get_space()
            if free < os.path.getsize(song['~filename']):
                wlb.hide()
                qltk.WarningMessage(
                    self, _("Unable to copy song"),
                    _("There is not enough free space for this song.")).run()
                break

            status = device.copy(songlist, song)
            if isinstance(status, AudioFile):
                model.append([status])
                try:
                    self.__cache[device.bid].append(song)
                except KeyError:
                    pass
                self.__refresh_space(device)
            else:
                msg = _("<b>%s</b> could not be copied.") % label
                if type(status) == unicode:
                    msg += "\n\n" + util.escape(status)
                qltk.WarningMessage(self, _("Unable to copy song"), msg).run()

        if device.cleanup and not device.cleanup(wlb, 'copy'):
            pass
        else:
            wlb.hide()

        self.__busy = False
        return True
Esempio n. 2
0
    def __copy_songs(self, songs):
        model, iter = self.__view.get_selection().get_selected()
        if not iter:
            return False

        device = model[iter][0]
        if not self.__check_device(device, _("Unable to copy songs")):
            return False

        self.__busy = True

        wlb = self.__statusbar
        wlb.setup(len(songs),
                  _("Copying %(song)s") % {'song': '<b>%(song)s</b>'},
                  {'song': ''})
        wlb.show()

        for song in songs:
            label = util.escape(song('~artist~title'))
            if wlb.step(song=label):
                wlb.hide()
                break

            space, free = device.get_space()
            if free < os.path.getsize(song['~filename']):
                wlb.hide()
                qltk.WarningMessage(
                    self, _("Unable to copy song"),
                    _("There is not enough free space for this song.")).run()
                break

            status = device.copy(self, song)
            if isinstance(status, AudioFile):
                try:
                    self.__cache[device.bid].append(song)
                except KeyError:
                    pass
                self.__refresh_space(device)
            else:
                msg = _("%s could not be copied.") % util.bold(label)
                if type(status) == text_type:
                    msg += "\n\n" + util.escape(status)
                qltk.WarningMessage(self, _("Unable to copy song"), msg).run()

        if device.cleanup and not device.cleanup(wlb, 'copy'):
            pass
        else:
            wlb.hide()

        self.__busy = False
        return True
Esempio n. 3
0
    def __edit_tag(self, renderer, path, new_value, model):
        #pfps leaving the newline should be OK
        #        new_value = ', '.join(new_value.splitlines())
        path = Gtk.TreePath.new_from_string(path)
        entry = model[path][0]
        error_dialog = None

        if not massagers.is_valid(entry.tag, new_value):
            error_dialog = qltk.WarningMessage(
                self, _("Invalid value"),
                _("Invalid value: <b>%(value)s</b>\n\n%(error)s") % {
                    "value": new_value,
                    "error": massagers.error_message(entry.tag, new_value)
                })
        else:
            new_value = massagers.validate(entry.tag, new_value)

        comment = entry.value
        changed = comment.text != new_value
        identical = comment.shared and comment.complete
        if (changed and (identical or new_value)) \
                or (new_value and not identical):
            # only give an error if we would have applied the value
            if error_dialog is not None:
                error_dialog.run()
                return
            entry.value = Comment(new_value)
            entry.edited = True
            entry.deleted = False
            model.path_changed(path)
Esempio n. 4
0
 def __check_device(self, device, message):
     if not device.is_connected():
         qltk.WarningMessage(
             self, message,
             _("%s is not connected.") %
             util.bold(util.escape(device['name']))).run()
         return False
     return True
Esempio n. 5
0
def ParsePLS(file):
    data = {}

    lines = file.readlines()
    if not lines or "[playlist]" not in lines.pop(0):
        return []

    for line in lines:
        try:
            head, val = line.strip().split("=", 1)
        except (TypeError, ValueError):
            continue
        else:
            head = head.lower()
            if head.startswith("length") and val == "-1":
                continue
            else:
                data[head] = val.decode('utf-8', 'replace')

    count = 1
    files = []
    warnings = []
    while True:
        if "file%d" % count in data:
            filename = data["file%d" % count].encode('utf-8', 'replace')
            if filename.lower()[-4:] in [".pls", ".m3u"]:
                warnings.append(filename)
            else:
                irf = IRFile(filename)
                for key in ["title", "genre", "artist"]:
                    try:
                        irf[key] = data["%s%d" % (key, count)]
                    except KeyError:
                        pass
                try:
                    irf["~#length"] = int(data["length%d" % count])
                except (KeyError, TypeError, ValueError):
                    pass
                files.append(irf)
        else:
            break
        count += 1

    if warnings:
        qltk.WarningMessage(
            None, _("Unsupported file type"),
            _("Station lists can only contain locations of stations, "
              "not other station lists or playlists. The following locations "
              "cannot be loaded:\n%s") %
            "\n  ".join(map(util.escape, warnings))
        ).run()

    return files
Esempio n. 6
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
Esempio n. 7
0
    def __delete_songs(self, songs):
        model, iter = self.__view.get_selection().get_selected()
        if not iter:
            return False

        device = model[iter][0]
        if not self.__check_device(device, _("Unable to delete songs")):
            return False

        dialog = DeleteDialog.for_songs(self, songs)
        if dialog.run() != DeleteDialog.RESPONSE_DELETE:
            return False

        self.__busy = True

        wlb = self.__statusbar
        wlb.setup(
            len(songs),
            _("Deleting %(song)s") % {"song": "<b>%(song)s</b>"},
            {'song': ''})
        wlb.show()

        for song in songs:
            label = util.escape(song('~artist~title'))
            if wlb.step(song=label):
                wlb.hide()
                break

            status = device.delete(self, song)
            if status is True:
                try:
                    self.__cache[device.bid].remove(song)
                except (KeyError, ValueError):
                    pass
                self.__refresh_space(device)
            else:
                msg = _("%s could not be deleted.") % util.bold(label)
                if type(status) == unicode:
                    msg += "\n\n%s" % status
                qltk.WarningMessage(
                    self, _("Unable to delete song"), msg).run()

        if device.cleanup and not device.cleanup(wlb, 'delete'):
            pass
        else:
            wlb.hide()

        self.__busy = False
Esempio n. 8
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))
Esempio n. 9
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)
Esempio n. 10
0
 def __edit_tag(self, renderer, path, new_value, model):
     new_value = ', '.join(new_value.splitlines())
     row = model[path]
     if row[TAG] in massagers.tags:
         fmt = massagers.tags[row[TAG]]
         if not fmt.is_valid(new_value):
             qltk.WarningMessage(
                 self, _("Invalid value"),
                 _("Invalid value: <b>%(value)s</b>\n\n%(error)s") % {
                 "value": new_value, "error": fmt.error}).run()
             return
         else:
             new_value = fmt.validate(new_value)
     tag = self.__songinfo.get(row[TAG], None)
     if row[VALUE].split('<')[0] != new_value or (
             tag and tag.shared and not tag.complete):
         row[VALUE] = util.escape(new_value)
         row[EDITED] = True
         row[DELETED] = False