Example #1
0
    def start(self):
        self.messages = []

        if not self.username or not self.password:
            self.messages.append((logging.ERROR, 'Username or Password not entered'))
            Log.Error('Username or Password not entered')
            return

        Log.Debug('bundle_path: "%s"', self.bundle_path)

        if not self.client:
            self.client = SpotifyClient(self)

        # Start server (if 'proxy_tracks' is enabled)
        if not self.server and self.proxy_tracks:
            self.server = Server(self)
            self.server.start()

        # Stop server if 'proxy_tracks' has been disabled
        if self.server and not self.proxy_tracks:
            self.server.stop()
            self.server = None

        # Update server preferences
        if self.server:
            self.server.supports_ranges = PREF_SS_RANGES.get(Prefs['proxy_ranges'], True)

        # Update reference on SpotifyClient
        self.client.server = self.server

        # start/restart the client
        self.client.start()
Example #2
0
class SpotifyHost(object):
    def __init__(self):
        self.client = None
        self.server = None

        self.messages = []
        self.start()

        self.search = SpotifySearch(self)

        self.session = requests.session()
        self.session_cached = CacheControl(self.session)

        self.containers = Containers(self)

        # Server detail
        self.server_name = None
        self.server_address = None
        self.server_version = None

        self.local_address = None

        # Private
        self.credits_data = None

    @property
    def username(self):
        return Prefs["username"]

    @property
    def password(self):
        return Prefs["password"]

    @property
    def proxy_tracks(self):
        return Prefs['proxy_tracks']

    @property
    def hostname(self):
        if Prefs['proxy_hostname']:
            # Custom hostname defined in preferences
            return Prefs['proxy_hostname']

        if self.local_address:
            # Hostname identified from <socket>.getsockname()
            return self.local_address

        if self.server_address:
            # Hostname identified from Plex API
            return self.server_address

        # Fallback to socket hostname
        return socket.gethostname()

    @property
    def sp(self):
        if not self.client:
            return None

        return self.client.sp

    @property
    def code_path(self):
        return Core.code_path

    @property
    def bundle_path(self):
        return os.path.abspath(os.path.join(self.code_path, '..'))

    @property
    def credits(self):
        if not self.credits_data:
            try:
                # Parse credits file
                self.credits_data = json.loads(Resource.Load('credits.json'))
            except (ValueError, TypeError):
                # Invalid credits file
                self.credits_data = {}

        return self.credits_data

    def preferences_updated(self):
        # Update logging levels
        logging_handler.setup()

        # Trigger a client restart
        self.start()

    def start(self):
        self.messages = []

        if not self.username or not self.password:
            self.messages.append((logging.ERROR, 'Username or Password not entered'))
            Log.Error('Username or Password not entered')
            return

        Log.Debug('bundle_path: "%s"', self.bundle_path)

        if not self.client:
            self.client = SpotifyClient(self)

        # Start server (if 'proxy_tracks' is enabled)
        if not self.server and self.proxy_tracks:
            self.server = Server(self)
            self.server.start()

        # Stop server if 'proxy_tracks' has been disabled
        if self.server and not self.proxy_tracks:
            self.server.stop()
            self.server = None

        # Update server preferences
        if self.server:
            self.server.supports_ranges = PREF_SS_RANGES.get(Prefs['proxy_ranges'], True)

        # Update reference on SpotifyClient
        self.client.server = self.server

        # start/restart the client
        self.client.start()

    def get(self, url, *args, **kwargs):
        try:
            return self.session.get(url, *args, **kwargs)
        except:
            return None

    def get_xml(self, url, *args, **kwargs):
        response = self.session.get(url, *args, **kwargs)
        if not response:
            return None

        return parse_xml(response.content)

    def refresh(self):
        self.refresh_server()
        self.refresh_local()

        Log.Info('Using the host/address "%s" for streaming', self.hostname)

    def refresh_server(self):
        Log.Debug('Refreshing server info...')

        # Determine local server name
        detail = self.get_xml('http://127.0.0.1:32400')

        if not detail:
            Log.Warn('"/" request failed, unable to retrieve info')
            return None

        self.server_name = detail.get('friendlyName')

        # Find server address and version
        servers = self.get_xml('http://127.0.0.1:32400/servers')

        if not servers:
            Log.Warn('"/servers" request failed, unable to retrieve server info')
            return None

        for server in servers.findall('Server'):
            if server.get('name').lower() == self.server_name.lower():
                self.server_address = server.get('address')
                self.server_version = server.get('version')
                break

        Log.Debug(
            'Updated server info - name: %s, address: %s, version: %s',
            self.server_name,
            self.server_address,
            self.server_version
        )

    def refresh_local(self):
        try:
            s_discovery = socket.socket(type=socket.SOCK_DGRAM)
            s_discovery.connect(('spotify.com', 80))

            netloc = s_discovery.getsockname()
            s_discovery.close()

            if len(netloc) != 2:
                self.local_address = None
                Log.Warn('Invalid response from getsockname(): %s', netloc)
                return

            self.local_address, _ = netloc
            Log.Debug('Updated local info - address: %s', self.local_address)
        except Exception, ex:
            self.local_address = None
            Log.Warn('Unable to discover local address - %s', ex)