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
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
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)
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
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
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
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
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