Example #1
0
    def other(self, command):
        try:
            if command == "":
                return None

            output = execute_command(command, returnoutput=True)
            self.title["nowplaying"] = output
            return True
        except Exception as error:
            log.add_important_error(
                _("Executing '%(command)s' failed: %(error)s"), {
                    "command": command,
                    "error": error
                })
            return None
Example #2
0
    def connect(self):

        if not self.protothread.server_disconnected:
            return True

        valid_network_interface = self.protothread.validate_network_interface()

        if not valid_network_interface:
            message = _(
                "The network interface you specified, '%s', does not exist. Change or remove the specified "
                "network interface and restart Nicotine+.")
            log.add_important_error(message, self.protothread.interface)
            return False

        valid_listen_port = self.protothread.validate_listen_port()

        if not valid_listen_port:
            message = _(
                "The range you specified for client connection ports was "
                "{}-{}, but none of these were usable. Increase and/or ".
                format(self.protothread.portrange[0],
                       self.protothread.portrange[1]) +
                "move the range and restart Nicotine+.")
            if self.protothread.portrange[0] < 1024:
                message += "\n\n" + _(
                    "Note that part of your range lies below 1024, this is usually not allowed on"
                    " most operating systems with the exception of Windows.")
            log.add_important_error(message)
            return False

        self.protothread.server_connect()

        # Clear any potential messages queued up while offline
        self.queue.clear()

        addr = config.sections["server"]["server"]
        login = config.sections["server"]["login"]
        password = config.sections["server"]["passw"]

        log.add(_("Connecting to %(host)s:%(port)s"), {
            'host': addr[0],
            'port': addr[1]
        })
        self.queue.append(
            slskmessages.ServerConnect(addr, login=(login, password)))
        return True
Example #3
0
    def login(self, msg):
        """ Server code: 1 """

        log.add_msg_contents(msg)

        if msg.success:
            self.logged_in = True
            self.login_username = msg.username

            self.set_away_mode(config.sections["server"]["away"])
            self.watch_user(msg.username)

            if msg.ip_address is not None:
                self.user_ip_address = msg.ip_address

            self.transfers.server_login()
            self.search.server_login()
            self.userbrowse.server_login()
            self.userinfo.server_login()
            self.userlist.server_login()
            self.privatechats.server_login()
            self.chatrooms.server_login()

            if self.ui_callback:
                self.ui_callback.server_login()

            if msg.banner:
                log.add(msg.banner)

            self.interests.server_login()
            self.shares.send_num_shared_folders_files()

            self.queue.append(
                slskmessages.PrivateRoomToggle(
                    config.sections["server"]["private_chatrooms"]))
            self.pluginhandler.server_connect_notification()

        else:
            if msg.reason == "INVALIDPASS":
                self.ui_callback.invalid_password()
                return

            log.add_important_error(
                _("Unable to connect to the server. Reason: %s"), msg.reason)
Example #4
0
    def listenbrainz(self, username):
        """ Function to get the currently playing song via ListenBrainz API """

        if not username:
            log.add_important_error(
                _("ListenBrainz: Please provide your ListenBrainz username"))
            return None

        try:
            response = http_request(
                'https',
                'api.listenbrainz.org',
                '/1/user/{}/playing-now'.format(username),
                headers={'User-Agent': self.config.application_name})

        except Exception as error:
            log.add_important_error(
                _("ListenBrainz: Could not connect to ListenBrainz: %(error)s"
                  ), {'error': error})
            return None

        try:
            json_api = json.loads(response)['payload']

            if not json_api['playing_now']:
                log.add_important_error(
                    _("ListenBrainz: You don\'t seem to be listening to anything right now"
                      ))
                return None

            track = json_api['listens'][0]['track_metadata']

            self.title['artist'] = track['artist_name']
            self.title['title'] = track['track_name']
            self.title['album'] = track['release_name']
            self.title['nowplaying'] = '%s: %s - %s - %s' % (
                _('Playing now'), self.title['artist'], self.title['album'],
                self.title['title'])

            return True

        except Exception:
            log.add_important_error(
                _("ListenBrainz: Could not get current track from ListenBrainz: %(error)s"
                  ), {'error': str(response)})
        return None
Example #5
0
    def lastfm(self, user):
        """ Function to get the last song played via Last.fm API """

        try:
            user, apikey = user.split(';')

        except ValueError:
            log.add_important_error(
                _("Last.fm: Please provide both your Last.fm username and API key"
                  ))
            return None

        try:
            response = http_request(
                "https",
                "ws.audioscrobbler.com",
                "/2.0/?method=user.getrecenttracks&user="******"&api_key=" + apikey + "&limit=1&format=json",
                headers={"User-Agent": self.config.application_name})

        except Exception as error:
            log.add_important_error(
                _("Last.fm: Could not connect to Audioscrobbler: %(error)s"),
                {"error": error})
            return None

        try:
            json_api = json.loads(response)
            lastplayed = json_api["recenttracks"]["track"]

            try:
                # In most cases, a list containing a single track dictionary is sent
                lastplayed = lastplayed[0]

            except KeyError:
                # On rare occasions, the track dictionary is not wrapped in a list
                pass

            self.title["artist"] = lastplayed["artist"]["#text"]
            self.title["title"] = lastplayed["name"]
            self.title["album"] = lastplayed["album"]["#text"]
            self.title["nowplaying"] = "%s: %s - %s - %s" % (
                _("Last played"), self.title["artist"], self.title["album"],
                self.title["title"])

        except Exception:
            log.add_important_error(
                _("Last.fm: Could not get recent track from Audioscrobbler: %(error)s"
                  ), {"error": response})
            return None

        return True
Example #6
0
    def lastfm(self, user):
        """ Function to get the last song played via lastfm api """

        import http.client
        import json

        try:
            (user, apikey) = user.split(';')
        except ValueError:
            log.add_important_error(
                _("lastfm: Please provide both your lastfm username and API key"
                  ))
            return None

        try:
            conn = http.client.HTTPSConnection("ws.audioscrobbler.com")
        except Exception as error:
            log.add_important_error(
                _("lastfm: Could not connect to audioscrobbler: %(error)s"),
                {"error": error})
            return None

        conn.request("GET",
                     "/2.0/?method=user.getrecenttracks&user="******"&api_key=" + apikey + "&limit=1&format=json",
                     headers={"User-Agent": "Nicotine+"})
        resp = conn.getresponse()
        data = resp.read().decode("utf-8")
        conn.close()

        if resp.status != 200 or resp.reason != "OK":
            log.add_important_error(
                _("lastfm: Could not get recent track from audioscrobbler: %(error)s"
                  ), {"error": str(data)})
            return None

        json_api = json.loads(data)
        lastplayed = json_api["recenttracks"]["track"][0]

        self.title["artist"] = lastplayed["artist"]["#text"]
        self.title["title"] = lastplayed["name"]
        self.title["album"] = lastplayed["album"]["#text"]
        self.title["nowplaying"] = "%s: %s - %s - %s" % (
            _("Last played"), self.title["artist"], self.title["album"],
            self.title["title"])

        return True
Example #7
0
    def get_np(self,
               callback=None,
               get_player=None,
               get_command=None,
               get_format=None):

        self.title_clear()

        if get_player is None:
            player = self.config.sections["players"]["npplayer"]
        else:
            player = get_player()

        if get_command is None:
            command = self.config.sections["players"]["npothercommand"]
        else:
            command = get_command()

        result = None

        try:
            if player == "lastfm":
                result = self.lastfm(command)
            elif player == "other":
                result = self.other(command)
            elif player == "mpris":
                result = self.mpris(command)

        except RuntimeError:
            log.add_important_error(
                _("Could not execute now playing code. Are you sure you picked the right player?"
                  ))
            return None

        if not result:
            return None

        # Since we need unicode instead of bytes we'll try to force such a
        # conversion. Individual player commands should have done this already
        # - this is a failsafe.

        for key, value in self.title.items():
            try:
                self.title[key] = str(value, "utf-8", "replace")
            except TypeError:
                self.title[key] = value  # already unicode

        if get_format is None:
            title = self.config.sections["players"]["npformat"]
        else:
            title = get_format()

        title = title.replace("%", "%%")  # Escaping user supplied % symbols
        title = title.replace("$t", "%(title)s")
        title = title.replace("$a", "%(artist)s")
        title = title.replace("$b", "%(album)s")
        title = title.replace("$c", "%(comment)s")
        title = title.replace("$n", "%(nowplaying)s")
        title = title.replace("$k", "%(track)s")
        title = title.replace("$l", "%(length)s")
        title = title.replace("$y", "%(year)s")
        title = title.replace("$r", "%(bitrate)s")
        title = title.replace("$f", "%(filename)s")
        title = title.replace("$p", "%(program)s")

        title = title % self.title
        title = ' '.join(
            (x for x in title.replace('\r', '\n').split('\n') if x))

        if title:
            if callback:
                callback(title)

            return title

        return None
Example #8
0
    def mpris(self, player):
        """ Function to get the currently playing song via dbus mpris v2 interface """

        # https://media.readthedocs.org/pdf/mpris2/latest/mpris2.pdf

        from gi.repository import Gio  # pylint: disable=import-error
        self.bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)

        dbus_mpris_service = 'org.mpris.MediaPlayer2.'
        dbus_mpris_player_service = 'org.mpris.MediaPlayer2.Player'
        dbus_mpris_path = '/org/mpris/MediaPlayer2'
        dbus_property = 'org.freedesktop.DBus.Properties'

        if not player:

            dbus_proxy = Gio.DBusProxy.new_sync(self.bus,
                                                Gio.DBusProxyFlags.NONE, None,
                                                'org.freedesktop.DBus',
                                                '/org/freedesktop/DBus',
                                                'org.freedesktop.DBus', None)

            names = dbus_proxy.ListNames()
            players = []

            for name in names:
                if name.startswith(dbus_mpris_service):
                    players.append(name[len(dbus_mpris_service):])

            if not players:
                log.add_important_error(
                    _("MPRIS: Could not find a suitable MPRIS player."))
                return None

            player = players[0]
            if len(players) > 1:
                log.add(
                    _("Found multiple MPRIS players: %(players)s. Using: %(player)s"
                      ), {
                          'players': players,
                          'player': player
                      })
            else:
                log.add(_("Auto-detected MPRIS player: %s."), player)

        try:
            dbus_proxy = Gio.DBusProxy.new_sync(self.bus,
                                                Gio.DBusProxyFlags.NONE, None,
                                                dbus_mpris_service + player,
                                                dbus_mpris_path, dbus_property,
                                                None)

            metadata = dbus_proxy.Get('(ss)', dbus_mpris_player_service,
                                      'Metadata')

        except Exception as exception:
            log.add_important_error(
                _("MPRIS: Something went wrong while querying %(player)s: %(exception)s"
                  ), {
                      'player': player,
                      'exception': exception
                  })
            return None

        self.title['program'] = player
        list_mapping = [('xesam:artist', 'artist')]

        for (source, dest) in list_mapping:
            try:
                self.title[dest] = '+'.join(metadata[source])
            except KeyError:
                self.title[dest] = '?'

        mapping = [('xesam:title', 'title'), ('xesam:album', 'album'),
                   ('xesam:contentCreated', 'year'),
                   ('xesam:comment', 'comment'),
                   ('xesam:audioBitrate', 'bitrate'),
                   ('xesam:url', 'filename'), ('xesak:trackNumber', 'track')]

        for (source, dest) in mapping:
            try:
                self.title[dest] = str(metadata[source])
            except KeyError:
                self.title[dest] = '?'

        # The length is in microseconds, and be represented as a signed 64-bit integer.
        try:
            self.title['length'] = self.get_length_time(
                metadata['mpris:length'] // 1000000)
        except KeyError:
            self.title['length'] = '?'

        if self.title['artist'] != "":
            self.title['nowplaying'] += self.title['artist']

        if self.title['title'] != "":
            self.title['nowplaying'] += " - " + self.title['title']

        return True