def lookup(self, uri): '''Lookup the given URIs. Return type: list of mopidy.models.Track ''' logger.info("Lookup Plex uri '%s'", uri) parts = uri.split(':') if uri.startswith('plex:artist:'): # get all tracks for artist item_id = parts[2] plex_uri = '/library/metadata/{}/allLeaves'.format(item_id) elif uri.startswith('plex:album:'): # get all tracks for album item_id = parts[2] plex_uri = '/library/metadata/{}/children'.format(item_id) elif uri.startswith('plex:track:'): # get track item_id = parts[2] plex_uri = '/library/metadata/{}'.format(item_id) ret = [] for item in self.plex.query(plex_uri): plextrack = plexutils.buildItem(self.plex, item, '/library/metadata/{}'.format(item.attrib['ratingKey'])) ret.append(wrap_track(plextrack, self.backend.plex_uri)) return ret
def search(self, query=None, uris=None, exact=False): '''Search the library for tracks where field contains values. Parameters: query (dict) – one or more queries to search for - the dict's keys being: { 'any': *, # this is what we get without explicit modifiers 'albumartist': *, 'date': *, 'track_name': *, 'track_number': *, } uris (list of string or None) – zero or more URI roots to limit the search to exact (bool) – if the search should use exact matching Returns mopidy.models.SearchResult, which has these properties uri (string) – search result URI tracks (list of Track elements) – matching tracks artists (list of Artist elements) – matching artists albums (list of Album elements) – matching albums ''' logger.info("Searching Plex for track '%s'", query) if query is None: logger.debug('Ignored search without query') return SearchResult(uri='plex:search') if 'uri' in query and False: # TODO add uri limiting pass else: search_query = ' '.join(query.values()[0]) search_uri = 'plex:search:%s' % urllib.quote(search_query.encode('utf-8')) logger.info("Searching Plex with query '%s'", search_query) artists = [] tracks = [] albums = [] for hit in self.plex.searchAudio(search_query): logger.debug('Got plex hit from query "%s": %s', search_query, hit) if isinstance(hit, plexaudio.Artist): artists.append(wrap_artist(hit, self.backend.plex_uri)) elif isinstance(hit, plexaudio.Track): tracks.append(wrap_track(hit, self.backend.plex_uri)) elif isinstance(hit, plexaudio.Album): albums.append(wrap_album(hit, self.backend.plex_uri, self.backend.resolve_uri)) logger.debug("Got results: %s, %s, %s", artists, tracks, albums) return SearchResult( uri=search_uri, tracks=tracks, artists=artists, albums=albums )
def as_list(self): '''Get a list of the currently available playlists. Returns a list of `mopidy.models.Ref` objects referring to the playlists. In other words, no information about the playlists’ content is given.''' logger.debug('Playlist: as_list') logger.info("Playlists loaded") audiolists = [ l for l in self.plex.playlists() if l.playlistType == 'audio' ] return [ Ref(uri='plex:playlist:{}'.format(playlist.ratingKey), name=playlist.title) for playlist in audiolists ]
def translate_uri(self, uri): '''Convert custom URI scheme to real playable URI. MAY be reimplemented by subclass. This is very likely the only thing you need to override as a backend author. Typically this is where you convert any Mopidy specific URI to a real URI and then return it. If you can’t convert the URI just return None. Parameters: uri (string) – the URI to translate Return type: string or None if the URI could not be translated''' logger.debug("Playback.translate_uri Plex with uri '%s'", uri) _rx = re.compile(r'plex:track:(?P<track_id>\d+)').match(uri) if _rx is None: # uri unknown logger.info('Unkown uri: %s', uri) return None elem = plexutils.findKey(self.backend.plex, _rx.group('track_id')) logger.info('getting file parts for eleme %r', elem) try: p = list(elem.iterParts())[0].key # hackisly get direct url of first part return '%s%s?X-Plex-Token=%s' % (elem.server.baseurl, p, self.backend.plex.token) except Exception as e: logger.exception(e) logger.info('fallback to returning stream for elem %r', elem) return elem.getStreamUrl()
def __init__(self, config, audio): super(PlexBackend, self).__init__(audio=audio) self.config = config self.session = get_requests_session( proxy_config=config['proxy'], user_agent='%s/%s' % (mopidy_plex.Extension.dist_name, mopidy_plex.__version__)) type = config['plex']['type'] library = (config['plex']['library']) self.plex = None self.music = None if type == 'myplex': server = (config['plex']['server']) user = (config['plex']['username']) password = (config['plex']['password']) account = self.myplex_login(user, password) logger.info('Connecting to plex server: %s', server) self.plex = account.resource(server).connect(ssl=False) self.music = self.plex.library.section(library) elif type == 'direct': baseurl = (config['plex']['server']) token = (config['plex']['token']) self.plex = PlexServer(baseurl, token) self.music = self.plex.library.section(library) else: logger.error('Invalid value for plex backend type: %s', type) logger.info('Connected to plex server') logger.debug('Found music section on plex server %s: %s', self.plex, self.music) self.library_id = self.music.key self.uri_schemes = [ 'plex', ] self.library = PlexLibraryProvider(backend=self) self.playback = PlexPlaybackProvider(audio=audio, backend=self) self.playlists = PlexPlaylistsProvider(backend=self)