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

    irfs = []

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

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

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

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

    irfs = []

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

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

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

    return irfs
Beispiel #3
0
def _get_stations_from(uri: str) -> List[IRFile]:
    """Fetches the URI content and extracts IRFiles
    :raise: `OSError`, or other socket-type errors
    :return: or else a list of stations found (possibly empty)"""

    irfs = []

    if (uri.lower().endswith(".pls") or uri.lower().endswith(".m3u")
            or uri.lower().endswith(".m3u8")):
        if not re.match('^([^/:]+)://', uri):
            # Assume HTTP if no protocol given. See #2731
            uri = 'http://' + uri
            print_d("Assuming http: %s" % uri)

        # Error handling outside
        sock = None
        try:
            sock = urlopen(uri, timeout=10)

            _, ext = splitext(uri.lower())
            if ext == ".pls":
                irfs = ParsePLS(sock)
            elif ext in (".m3u", ".m3u8"):
                irfs = ParseM3U(sock)
        finally:
            if sock:
                sock.close()
    else:
        try:
            irfs = [IRFile(uri)]
        except ValueError as msg:
            ErrorMessage(None, _("Unable to add station"), msg).run()

    return irfs
Beispiel #4
0
    def plugin_album(self, songs):

        songs.sort(key=sort_key_for)

        chooser = filechooser(save=False, title=songs[0]('album'))
        box = Gtk.HBox()
        rename = Gtk.CheckButton("Rename Files")
        rename.set_active(False)
        box.pack_start(rename, True, True, 0)
        append = Gtk.CheckButton("Append Metadata")
        append.set_active(True)
        box.pack_start(append, True, True, 0)
        box.show_all()
        chooser.set_extra_widget(box)

        resp = chooser.run()
        append = append.get_active()
        rename = rename.get_active()
        fn = chooser.get_filename()
        chooser.destroy()
        if resp != Gtk.ResponseType.ACCEPT:
            return

        global lastfolder
        lastfolder = dirname(fn)

        metadata = []
        names = []
        index = 0
        for line in open(fn, 'rU'):
            if index == len(metadata):
                names.append(line[:line.rfind('.')])
                metadata.append({})
            elif line == '\n':
                index = len(metadata)
            else:
                key, value = line[:-1].split('=', 1)
                value = value.decode('utf-8')
                try:
                    metadata[index][key].append(value)
                except KeyError:
                    metadata[index][key] = [value]

        if not (len(songs) == len(metadata) == len(names)):
            ErrorMessage(None, "Songs mismatch",
                         "There are %(select)d songs selected, but %(meta)d "
                         "songs in the file. Aborting." %
                         dict(select=len(songs), meta=len(metadata))).run()
            return

        for song, meta, name in zip(songs, metadata, names):
            for key, values in iteritems(meta):
                if append and key in song:
                    values = song.list(key) + values
                song[key] = '\n'.join(values)
            if rename:
                origname = song['~filename']
                newname = name + origname[origname.rfind('.'):]
                app.library.rename(origname, newname)
Beispiel #5
0
    def __add_stations(self, irfs: Collection[IRFile], uri: str) -> None:
        print_d(f"Got {len(irfs)} station(s) from {uri}")
        assert self.__fav_stations
        if not irfs:
            msg = ErrorMessage(
                self, _("No stations found"),
                _("No Internet radio stations were found at %s.") %
                util.escape(uri))
            msg.run()
            return

        fav_uris = {af("~uri") for af in self.__fav_stations}
        irfs = {af for af in irfs if af("~uri") not in fav_uris}
        if irfs:
            print_d(f"Adding {irfs} to favourites")
            self.__fav_stations.add(irfs)
        else:
            message = WarningMessage(
                self, _("Nothing to add"),
                _("All stations listed are already in your library."))
            message.run()
Beispiel #6
0
 def try_connecting(self):
     try:
         self.enabled()
         msg = (_("Connected to broker at %(host)s:%(port)d")
                % {'host': self.host, 'port': self.port})
         Message(Gtk.MessageType.INFO, app.window, "Success", msg).run()
     except IOError as e:
         template = _("Couldn't connect to %(host)s:%(port)d (%(msg)s)")
         msg = template % {'host': self.host, 'port': self.port, 'msg': e}
         print_w(msg)
         ErrorMessage(app.window, _("Connection error"), msg).run()
     yield
Beispiel #7
0
    def plugin_album(self, songs):

        songs.sort(key=sort_key_for)

        chooser = filechooser(save=False, title=songs[0]('album'))
        box = Gtk.HBox()
        rename = Gtk.CheckButton("Rename Files")
        rename.set_active(False)
        box.pack_start(rename, True, True, 0)
        append = Gtk.CheckButton("Append Metadata")
        append.set_active(True)
        box.pack_start(append, True, True, 0)
        box.show_all()
        chooser.set_extra_widget(box)

        resp = chooser.run()
        append = append.get_active()
        rename = rename.get_active()
        fn = chooser.get_filename()
        chooser.destroy()
        if resp != Gtk.ResponseType.ACCEPT:
            return

        global lastfolder
        lastfolder = dirname(fn)

        metadata = []
        names = []
        index = 0
        for line in open(fn, 'r', encoding="utf-8"):
            if index == len(metadata):
                names.append(line[:line.rfind('.')])
                metadata.append({})
            elif line == '\n':
                index = len(metadata)
            else:
                key, value = line[:-1].split('=', 1)
                try:
                    metadata[index][key].append(value)
                except KeyError:
                    metadata[index][key] = [value]

        if not (len(songs) == len(metadata) == len(names)):
            ErrorMessage(
                None, "Songs mismatch",
                "There are %(select)d songs selected, but %(meta)d "
                "songs in the file. Aborting." %
                dict(select=len(songs), meta=len(metadata))).run()
            return

        self.update_files(songs, metadata, names, append=append, rename=rename)
Beispiel #8
0
 def plugin_songs(self, songs):
     if not self.selected_tag:
         return
     l = dict.fromkeys([song(self.selected_tag) for song in songs]).keys()
     # If no tags values were found, show an error dialog
     if list(l) == ['']:
         ErrorMessage(app.window, _('Search failed'),
                      _('Tag "%s" not found.') % self.selected_tag).run()
         return
     for a in l:
         # Only search for non-empty tags
         if a:
             a = quote(str(a).title().replace(' ', '_'))
             util.website(WIKI_URL % get_lang() + a)
Beispiel #9
0
def add_station(uri):
    """Fetches the URI content and extracts IRFiles
    Returns None in error, else a possibly filled list of stations"""

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

    if uri.lower().endswith(".pls") or uri.lower().endswith(".m3u"):
        try:
            sock = urlopen(uri)
        except EnvironmentError as e:
            print_d("Got %s from %s" % (uri, e))
            encoding = util.get_locale_encoding()
            try:
                err = e.strerror.decode(encoding, 'replace')
            except TypeError:
                err = e.strerror[1].decode(encoding, 'replace')
            except AttributeError:
                # Give up and display the exception - may be useful HTTP info
                err = str(e)
            ErrorMessage(None, _("Unable to add station"), escape(err)).run()
            return None

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

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

    return irfs
Beispiel #10
0
    def __add_station(self, uri):
        try:
            irfs = _get_stations_from(uri)
        except EnvironmentError as e:
            print_d("Got %s from %s" % (e, uri))
            msg = ("Couldn't add URL: <b>%s</b>)\n\n<tt>%s</tt>" %
                   (escape(str(e)), escape(uri)))
            ErrorMessage(None, _("Unable to add station"), msg).run()
            return
        if not irfs:
            ErrorMessage(
                None, _("No stations found"),
                _("No Internet radio stations were found at %s.") %
                util.escape(uri)).run()
            return

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

        if irfs:
            self.__fav_stations.add(irfs)
Beispiel #11
0
 def plugin_songs(self, songs):
     # Check this is a launch, not a configure
     if self.com_index:
         com = self.get_data(self.com_index)
         print_d("Running %s" % com)
         try:
             com.run(songs)
         except Exception as err:
             print_e("Couldn't run command %s: %s %s at" %
                     (com.name, type(err), err))
             ErrorMessage(
                 self.plugin_window,
                 _("Unable to run custom command %s" %
                   util.escape(self.com_index)),
                 util.escape(str(err))).run()
Beispiel #12
0
 def enabled(self):
     from gi.repository import GLib
     print_d("Starting %s" % self.PLUGIN_NAME)
     try:
         self._pid, fdin, fdout, fderr = GLib.spawn_async(
             argv=self.executable.split(),
             flags=GLib.SpawnFlags.SEARCH_PATH,
             standard_output=True,
             standard_input=True)
     except GLib.Error as e:
         msg = ((_("Couldn't run visualisations using '%s'") + " (%s)") %
                (escape(self.executable), escape(e.message)))
         ErrorMessage(title=_("Error"), description=msg,
                      parent=app.window).run()
     else:
         # self._stdin = os.fdopen(fdin, mode='w')
         print_d("Launched with PID: %s" % self._pid)
Beispiel #13
0
    def __add_station(self, uri):
        irfs = add_station(uri)
        if irfs is None:
            # Error, rather than empty list
            return
        if not irfs:
            ErrorMessage(
                None, _("No stations found"),
                _("No Internet radio stations were found at %s.") %
                util.escape(uri)).run()
            return

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

        if irfs:
            self.__fav_stations.add(irfs)
Beispiel #14
0
 def _handle_songs(self, songs, playlist=None):
     # Check this is a launch, not a configure
     if self.com_index:
         com = self.get_data(self.com_index)
         if len(songs) > com.warn_threshold:
             if not confirm_multi_song_invoke(
                     self, com.name, len(songs)):
                 print_d("User decided not to run on %d songs" % len(songs))
                 return
         print_d("Running %s on %d song(s)" % (com, len(songs)))
         try:
             com.run(songs, playlist and playlist.name)
         except Exception as err:
             print_e("Couldn't run command %s: %s %s at:"
                     % (com.name, type(err), err, ))
             print_exc()
             ErrorMessage(
                 self.plugin_window,
                 _("Unable to run custom command %s") %
                 util.escape(self.com_index),
                 util.escape(str(err))).run()
Beispiel #15
0
    def plugin_album(self, album):
        discid = calculate_discid(album)

        try:
            stat, discs = CDDB.query(discid, **CLIENTINFO)
        except IOError:
            ErrorMessage(None, _("Timeout"), _(
                "Query could not be executed, connection timed out")).run()
            return

        if stat in (200, 211):
            xcode = 'utf8:utf8'
            dlg = Gtk.Dialog(title=_('Select an album'))
            dlg.set_border_width(6)
            dlg.set_resizable(False)
            dlg.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
            dlg.add_buttons(Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
            dlg.vbox.set_spacing(6)
            dlg.set_default_response(Gtk.ResponseType.CANCEL)
            model = Gtk.ListStore(str, str, str, str, str, str)
            for disc in discs:
                model.append(
                    [disc[s] for s in ('title', 'category', 'disc_id')] * 2)
            box = Gtk.ComboBox(model=model)
            box.set_active(0)
            for i in range(3):
                crt = Gtk.CellRendererText()
                box.pack_start(crt, True)
                box.add_attribute(crt, "text", i)
            discinfo = Gtk.Label()
            crosscode = Gtk.ListStore(str)
            crosscode.append(['utf8:utf8'])
            crosscode.append(['latin1:latin2'])
            crosscode.append(['latin1:cp1251'])
            crosscode.append(['latin1:sjis'])
            crosscode.append(['latin1:euc-jp'])
            cbo = Gtk.ComboBox(
                model=crosscode, entry_text_column=0, has_entry=True)
            cbo.set_active(0)

            def update_discinfo(combo):
                xcode = cbo.get_child().get_text()
                model = combo.get_model()
                t, c, d, title, cat, discid = model[box.get_active()]
                info = query(cat, discid, xcode=xcode)
                discinfo.set_markup(
                    make_info_label(info, album, discs[0]['disc_id']))

            def crosscode_cddbinfo(combo):
                try:
                    xf, xt = combo.get_child().get_text().split(':')
                    for row in model:
                        for show, store in zip(range(0, 3), range(3, 6)):
                            row[show] = row[store].encode(
                                xf, 'replace').decode(xt, 'replace')
                except:
                    for row in model:
                        for show, store in zip(range(0, 3), range(3, 6)):
                            row[show] = row[store]
                update_discinfo(box)

            cbo.connect('changed', crosscode_cddbinfo)
            box.connect('changed', update_discinfo)
            update_discinfo(box)
            dlg.vbox.pack_start(Gtk.Label(
                _("Select the album you wish to retrieve.")), True, True, 0)
            dlg.vbox.pack_start(box, True, True, 0)
            dlg.vbox.pack_start(discinfo, True, True, 0)
            dlg.vbox.pack_start(cbo, True, True, 0)
            dlg.vbox.show_all()
            resp = dlg.run()

            xcode = cbo.get_child().get_text()
            if resp == Gtk.ResponseType.OK:
                t, c, d, title, cat, discid = model[box.get_active()]
                (disc, track) = query(cat, discid, xcode=xcode)
                keys = track.keys()
                keys.sort()
                for key, song in zip(keys, album):
                    if 'artist' in disc:
                        song['artist'] = disc['artist']
                    if 'title' in disc:
                        song['album'] = disc['title']
                    if 'year' in disc:
                        song['date'] = disc['year']
                    if 'genre' in disc:
                        song['genre'] = disc['genre']
                    s = track[key].split("/")
                    if len(s) == 2:
                        song['artist'] = s[0]
                        song['title'] = s[1]
                    else:
                        song['title'] = track[key]
                    song['tracknumber'] = '%d/%d' % (key + 1, len(album))
            dlg.destroy()
        else:
            n = len(album)
            albumname = album[0]('album')
            if not albumname:
                albumname = ngettext('%d track', '%d tracks', n) % n
            ErrorMessage(None, _("CDDB lookup failed (%s)" % stat),
                    ngettext(u"%(title)s and %(count)d more…",
                        u"%(title)s and %(count)d more…", n - 1) % {
                        'title': album[0]('~basename'), 'count':
                        n - 1}).run()
 def _error_msg(self, message):
     title = _("Error in %s") % self.PLUGIN_NAME
     ErrorMessage(app.window, title, message).run()