Exemplo n.º 1
0
    def test_find_exact_combines_results_from_all_backends(self):
        track1 = Track(uri='dummy1:a')
        track2 = Track(uri='dummy2:a')
        result1 = SearchResult(tracks=[track1])
        result2 = SearchResult(tracks=[track2])

        self.library1.search.return_value.get.return_value = result1
        self.library2.search.return_value.get.return_value = result2

        result = self.core.library.find_exact({'any': ['a']})

        self.assertIn(result1, result)
        self.assertIn(result2, result)
        self.library1.search.assert_called_once_with(query=dict(any=['a']),
                                                     uris=None,
                                                     exact=True)
        self.library2.search.assert_called_once_with(query=dict(any=['a']),
                                                     uris=None,
                                                     exact=True)
Exemplo n.º 2
0
    def search(self, query=None, uris=None, exact=False):

        result = []

        self.backend.calmradio.do_search(' '.join(query['any']))

        for channel in self.backend.calmradio.search_results:
            result.append(self.channel_to_track(channel))

        return SearchResult(tracks=result)
Exemplo n.º 3
0
    def search(self, query=None, uris=None):

        if not query:
            return

        if 'uri' in query:
            search_query = ''.join(query['uri'])
            url = urlparse(search_query)
            if 'soundcloud.com' in url.netloc:
                logger.info('Resolving SoundCloud for \'%s\'', search_query)
                return SearchResult(
                    uri='soundcloud:search',
                    tracks=self.backend.remote.resolve_url(search_query))
        else:
            search_query = simplify_search_query(query)
            logger.info('Searching SoundCloud for \'%s\'', search_query)
            return SearchResult(
                uri='soundcloud:search',
                tracks=self.backend.remote.search(search_query))
Exemplo n.º 4
0
    def test_list(self):
        self.backend.library.dummy_find_exact_result = SearchResult(
            tracks=[
                Track(uri='dummy:a', name='A', artists=[
                    Artist(name='A Artist')])])

        self.sendRequest('list "artist" "artist" "foo"')

        self.assertInResponse('Artist: A Artist')
        self.assertInResponse('OK')
Exemplo n.º 5
0
    def test_search_accepts_query_dict_instead_of_kwargs(self):
        track1 = Track(uri="dummy1:a")
        track2 = Track(uri="dummy2:a")
        result1 = SearchResult(tracks=[track1])
        result2 = SearchResult(tracks=[track2])

        self.library1.search.return_value.get.return_value = result1
        self.library2.search.return_value.get.return_value = result2

        result = self.core.library.search({"any": ["a"]})

        assert result1 in result
        assert result2 in result
        self.library1.search.assert_called_once_with(query={"any": ["a"]},
                                                     uris=None,
                                                     exact=False)
        self.library2.search.assert_called_once_with(query={"any": ["a"]},
                                                     uris=None,
                                                     exact=False)
Exemplo n.º 6
0
    def test_find_accepts_query_dict_instead_of_kwargs(self):
        track1 = Track(uri='dummy1:a')
        track2 = Track(uri='dummy2:a')
        result1 = SearchResult(tracks=[track1])
        result2 = SearchResult(tracks=[track2])

        self.library1.find_exact().get.return_value = result1
        self.library1.find_exact.reset_mock()
        self.library2.find_exact().get.return_value = result2
        self.library2.find_exact.reset_mock()

        result = self.core.library.find_exact(dict(any=['a']))

        self.assertIn(result1, result)
        self.assertIn(result2, result)
        self.library1.find_exact.assert_called_once_with(
            query=dict(any=['a']), uris=None)
        self.library2.find_exact.assert_called_once_with(
            query=dict(any=['a']), uris=None)
Exemplo n.º 7
0
    def test_find_accepts_query_dict_instead_of_kwargs(self):
        track1 = Track(uri='dummy1:a')
        track2 = Track(uri='dummy2:a')
        result1 = SearchResult(tracks=[track1])
        result2 = SearchResult(tracks=[track2])

        self.library1.search.return_value.get.return_value = result1
        self.library2.search.return_value.get.return_value = result2

        result = self.core.library.find_exact({'any': ['a']})

        self.assertIn(result1, result)
        self.assertIn(result2, result)
        self.library1.search.assert_called_once_with(query={'any': ['a']},
                                                     uris=None,
                                                     exact=True)
        self.library2.search.assert_called_once_with(query={'any': ['a']},
                                                     uris=None,
                                                     exact=True)
Exemplo n.º 8
0
 def search(self, query=None, limit=100, offset=0, uris=None, exact=False):
     limit = self._config["max_search_results"]
     q = []
     for field, values in query.items() if query else []:
         q.extend((field, value) for value in values)
     filters = [f for uri in uris or [] for f in self._filters(uri) if f]
     with self._connect() as c:
         tracks = schema.search_tracks(c, q, limit, offset, exact, filters)
     uri = uritools.uricompose("local", path="search", query=q)
     return SearchResult(uri=uri, tracks=tracks)
Exemplo n.º 9
0
    def test_search_combines_results_from_all_backends(self):
        track1 = Track(uri="dummy1:a")
        track2 = Track(uri="dummy2:a")
        result1 = SearchResult(tracks=[track1])
        result2 = SearchResult(tracks=[track2])

        self.library1.search.return_value.get.return_value = result1
        self.library2.search.return_value.get.return_value = result2

        result = self.core.library.search({"any": ["a"]})

        assert result1 in result
        assert result2 in result
        self.library1.search.assert_called_once_with(query={"any": ["a"]},
                                                     uris=None,
                                                     exact=False)
        self.library2.search.assert_called_once_with(query={"any": ["a"]},
                                                     uris=None,
                                                     exact=False)
Exemplo n.º 10
0
 def search(self, query=None, uris=None, exact=False):
     try:
         artists, albums, tracks = \
             tidal_search(self.backend._session,
                          query=query,
                          exact=exact)
         return SearchResult(artists=artists, albums=albums, tracks=tracks)
     except Exception as ex:
         logger.info("EX")
         logger.info("%r", ex)
Exemplo n.º 11
0
    def test_search_combines_results_from_all_backends(self):
        track1 = Track(uri='dummy1:a')
        track2 = Track(uri='dummy2:a')
        result1 = SearchResult(tracks=[track1])
        result2 = SearchResult(tracks=[track2])

        self.library1.search().get.return_value = result1
        self.library1.search.reset_mock()
        self.library2.search().get.return_value = result2
        self.library2.search.reset_mock()

        result = self.core.library.search(any=['a'])

        self.assertIn(result1, result)
        self.assertIn(result2, result)
        self.library1.search.assert_called_once_with(query=dict(any=['a']),
                                                     uris=None)
        self.library2.search.assert_called_once_with(query=dict(any=['a']),
                                                     uris=None)
Exemplo n.º 12
0
    def test_searchadd(self):
        self.backend.library.dummy_search_result = SearchResult(
            tracks=[Track(uri='dummy:a', name='A')])
        self.assertEqual(self.core.tracklist.length.get(), 0)

        self.sendRequest('searchadd "title" "a"')

        self.assertEqual(self.core.tracklist.length.get(), 1)
        self.assertEqual(self.core.tracklist.tracks.get()[0].uri, 'dummy:a')
        self.assertInResponse('OK')
Exemplo n.º 13
0
    def test_count_correct_length(self):
        # Count the lone track
        self.backend.library.dummy_find_exact_result = SearchResult(tracks=[
            Track(uri='dummy:a', name="foo", date="2001", length=4000),
        ])
        self.sendRequest('count "title" "foo"')
        self.assertInResponse('songs: 1')
        self.assertInResponse('playtime: 4')
        self.assertInResponse('OK')

        # Count multiple tracks
        self.backend.library.dummy_find_exact_result = SearchResult(tracks=[
            Track(uri='dummy:b', date="2001", length=50000),
            Track(uri='dummy:c', date="2001", length=600000),
        ])
        self.sendRequest('count "date" "2001"')
        self.assertInResponse('songs: 2')
        self.assertInResponse('playtime: 650')
        self.assertInResponse('OK')
Exemplo n.º 14
0
    def test_list_performer_should_not_return_artists_without_names(self):
        self.backend.library.dummy_find_exact_result = SearchResult(
            tracks=[Track(performers=[Artist(name='')])])

        self.sendRequest('list "performer"')
        self.assertNotInResponse('Artist: ')
        self.assertNotInResponse('Albumartist: ')
        self.assertNotInResponse('Composer: ')
        self.assertNotInResponse('Performer: ')
        self.assertInResponse('OK')
Exemplo n.º 15
0
    def search(self, query=None, uris=None):
        # TODO Only return results within URI roots given by ``uris``

        if query is None:
            query = {}
        self._validate_query(query)
        result_tracks = self._uri_mapping.values()

        for (field, values) in query.iteritems():
            if not hasattr(values, '__iter__'):
                values = [values]
            # FIXME this is bound to be slow for large libraries
            for value in values:
                if field == 'track_no':
                    q = value
                else:
                    q = value.strip().lower()

                uri_filter = lambda t: q in t.uri.lower()
                track_filter = lambda t: q in t.name.lower()
                album_filter = lambda t: q in getattr(t, 'album', Album()
                                                      ).name.lower()
                artist_filter = lambda t: filter(lambda a: q in a.name.lower(),
                                                 t.artists)
                albumartist_filter = lambda t: any([
                    q in a.name.lower()
                    for a in getattr(t.album, 'artists', [])
                ])
                track_no_filter = lambda t: q == t.track_no
                date_filter = lambda t: t.date and t.date.startswith(q)
                any_filter = lambda t: (uri_filter(t) or track_filter(
                    t) or album_filter(t) or artist_filter(
                        t) or albumartist_filter(t) or track_no_filter(t) or
                                        date_filter(t))

                if field == 'uri':
                    result_tracks = filter(uri_filter, result_tracks)
                elif field == 'track':
                    result_tracks = filter(track_filter, result_tracks)
                elif field == 'album':
                    result_tracks = filter(album_filter, result_tracks)
                elif field == 'artist':
                    result_tracks = filter(artist_filter, result_tracks)
                elif field == 'albumartist':
                    result_tracks = filter(albumartist_filter, result_tracks)
                elif field == 'track_no':
                    result_tracks = filter(track_no_filter, result_tracks)
                elif field == 'date':
                    result_tracks = filter(date_filter, result_tracks)
                elif field == 'any':
                    result_tracks = filter(any_filter, result_tracks)
                else:
                    raise LookupError('Invalid lookup field: %s' % field)
        # TODO: add local:search:<query>
        return SearchResult(uri='local:search', tracks=result_tracks)
Exemplo n.º 16
0
 def search(self, query=None, uris=None, exact=False):
     if "artist" in query and "album" in query and "track_name" in query:
         return self.search_by_artist_album_and_track(
             query.get("artist")[0],
             query.get("album")[0],
             query.get("track_name")[0],
         )
     if "artist" in query and "album" in query:
         return self.search_by_artist_and_album(
             query.get("artist")[0],
             query.get("album")[0])
     if "artist" in query:
         return self.search_by_artist(query.get("artist")[0], exact)
     if "comment" in query:
         if query.get("comment")[0] == "random":
             return SearchResult(
                 tracks=self.subsonic_api.get_random_songs_as_tracks())
     if "any" in query:
         return self.subsonic_api.find_as_search_result(query.get("any")[0])
     return SearchResult(artists=self.subsonic_api.get_artists_as_artists())
Exemplo n.º 17
0
 def search_by_artist_and_album(self, artist_name, album_name):
     artists = self.subsonic_api.find_raw(artist_name).get("artist")
     if artists is None:
         return None
     tracks = []
     for artist in artists:
         for album in self.subsonic_api.get_raw_albums(artist.get("id")):
             if album_name in album.get("name"):
                 tracks.extend(
                     self.subsonic_api.get_songs_as_tracks(album.get("id")))
     return SearchResult(tracks=tracks)
Exemplo n.º 18
0
    def test_list_composer_should_not_return_artists_without_names(self):
        self.backend.library.dummy_find_exact_result = SearchResult(
            tracks=[Track(composers=[Artist(name="")])]
        )

        self.send_request('list "composer"')
        self.assertNotInResponse("Artist: ")
        self.assertNotInResponse("Albumartist: ")
        self.assertNotInResponse("Composer: ")
        self.assertNotInResponse("Performer: ")
        self.assertInResponse("OK")
Exemplo n.º 19
0
    def test_searchadd(self):
        track = Track(uri="dummy:a", name="A")
        self.backend.library.dummy_library = [track]
        self.backend.library.dummy_search_result = SearchResult(tracks=[track])
        assert self.core.tracklist.get_length().get() == 0

        self.send_request('searchadd "title" "a"')

        assert self.core.tracklist.get_length().get() == 1
        assert self.core.tracklist.get_tracks().get()[0].uri == "dummy:a"
        self.assertInResponse("OK")
Exemplo n.º 20
0
    def _find_exact(self, query=None, uris=None):
        # Find exact can only be done on gmusic library,
        # since one can't filter all access searches
        lib_tracks, lib_artists, lib_albums = self._search_library(query, uris)

        return SearchResult(
            uri="gmusic:search",
            tracks=lib_tracks,
            artists=lib_artists,
            albums=lib_albums,
        )
Exemplo n.º 21
0
    def test_searchaddpl_creates_missing_playlist(self):
        self.backend.library.dummy_search_result = SearchResult(
            tracks=[Track(uri='dummy:a', name='A')])
        self.assertEqual(len(self.core.playlists.filter(name='my favs').get()),
                         0)

        self.sendRequest('searchaddpl "my favs" "title" "a"')

        playlists = self.core.playlists.filter(name='my favs').get()
        self.assertEqual(len(playlists), 1)
        self.assertEqual(playlists[0].tracks[0].uri, 'dummy:a')
        self.assertInResponse('OK')
Exemplo n.º 22
0
 def search(self, query=None, limit=100, offset=0, uris=None, exact=False):
     q = []
     for field, values in (query.items() if query else []):
         q.extend((field, value) for value in values)
     # temporary workaround until Mopidy core sets limit
     if self._config['search_limit'] is not None:
         limit = self._config['search_limit']
     filters = [f for uri in uris or [] for f in self._filters(uri) if f]
     with self._connect() as c:
         tracks = schema.search_tracks(c, q, limit, offset, exact, filters)
     uri = uritools.uricompose('local', path='search', query=q)
     return SearchResult(uri=uri, tracks=tracks)
Exemplo n.º 23
0
    def search(self, query=None, uris=None, exact=False):

        result = []

        self.backend.radionet.do_search(' '.join(query['any']))

        for station in self.backend.radionet.search_results:
            result.append(self.station_to_track(station))

        return SearchResult(
            tracks=result
        )
Exemplo n.º 24
0
    def test_count_correct_length(self):
        # Count the lone track
        self.backend.library.dummy_find_exact_result = SearchResult(
            tracks=[Track(uri="dummy:a", name="foo", date="2001", length=4000)]
        )
        self.send_request('count "title" "foo"')
        self.assertInResponse("songs: 1")
        self.assertInResponse("playtime: 4")
        self.assertInResponse("OK")

        # Count multiple tracks
        self.backend.library.dummy_find_exact_result = SearchResult(
            tracks=[
                Track(uri="dummy:b", date="2001", length=50000),
                Track(uri="dummy:c", date="2001", length=600000),
            ]
        )
        self.send_request('count "date" "2001"')
        self.assertInResponse("songs: 2")
        self.assertInResponse("playtime: 650")
        self.assertInResponse("OK")
Exemplo n.º 25
0
 def search(self, query=None, limit=100, offset=0, uris=None, exact=False):
     q = []
     for field, values in (query.items() if query else []):
         if isinstance(values, basestring):
             q.append((field, values))
         else:
             q.extend((field, value) for value in values)
     filters = [f for uri in uris or [] for f in self._filters(uri) if f]
     with self._connect() as c:
         tracks = schema.search_tracks(c, q, limit, offset, exact, filters)
     uri = uritools.uricompose('local', path='search', query=q)
     return SearchResult(uri=uri, tracks=tracks)
Exemplo n.º 26
0
    def search(self, query=None, uris=None, exact=False):
        # TODO Support exact search
        logger.info('youtube LibraryProvider.search "%s"', query)

        # handle only searching (queries with 'any') not browsing!
        if not (query and "any" in query):
            return None

        search_query = " ".join(query["any"])
        logger.info('Searching YouTube for query "%s"', search_query)

        try:
            entries = youtube.Entry.search(search_query)
        except Exception as e:
            logger.error('search error "%s"', e)
            return None

        # load playlist info (to get video_count) of all playlists together
        playlists = [entry for entry in entries if not entry.is_video]
        youtube.Playlist.load_info(playlists)

        tracks = []
        for entry in entries:
            if entry.is_video:
                uri_base = "youtube:video"
                album = "YouTube Video"
                length = int(entry.length.get()) * 1000
            else:
                uri_base = "youtube:playlist"
                album = "YouTube Playlist (%s videos)" % entry.video_count.get()
                length = 0

            name = entry.title.get()

            tracks.append(
                Track(
                    name=name.replace(";", ""),
                    comment=entry.id,
                    length=length,
                    artists=[Artist(name=entry.channel.get())],
                    album=Album(name=album),
                    uri="%s/%s.%s" % (uri_base, safe_url(name), entry.id),
                )
            )

        # load video info and playlist videos in the background. they should be
        # ready by the time the user adds search results to the playing queue

        for pl in playlists:
            pl.videos  # start loading

        return SearchResult(uri="youtube:search", tracks=tracks)
Exemplo n.º 27
0
    def search(self, query=None, uris=None):
        if query is None:
            return
        stations = []
        for (field, values) in query.iteritems():
            if field == 'any':
                if hasattr(values, '__iter__'):
                    values = ' '.join(values)

                stations += self.backend.api.search_stations_by_string(values)

        tracks = [self._station_to_track(station) for station in stations]
        return SearchResult(uri='radio-de:search', tracks=tracks)
Exemplo n.º 28
0
    def search(self, query=None, uris=None, exact=False):
        logger.debug('RadioBrowser: Start backend.RadioBrowserLibrary.search')

        if query is None or not query:
            return
        radiobrowser_query = translator.mopidy_to_radiobrowser_query(query)
        tracks = []
        stations = self.backend.radiobrowser.search(radiobrowser_query)
        for station in stations:
            self.backend.radiobrowser.addStation(station)
            track = translator.station_to_track(station)
            tracks.append(track)
        return SearchResult(uri='radiobrowser:search', tracks=tracks)
Exemplo n.º 29
0
    def search(self, query=None, uris=None, exact=False):
        # TODO Support exact search

        if not query:
            return

        if "uri" in query:
            search_query = "".join(query["uri"])
            url = urllib.parse.urlparse(search_query)
            if "soundcloud.com" in url.netloc:
                logger.info(f"Resolving SoundCloud for: {search_query}")
                return SearchResult(
                    uri="soundcloud:search",
                    tracks=self.backend.remote.resolve_url(search_query),
                )
        else:
            search_query = simplify_search_query(query)
            logger.info(f"Searching SoundCloud for: {search_query}")
            return SearchResult(
                uri="soundcloud:search",
                tracks=self.backend.remote.search(search_query),
            )
Exemplo n.º 30
0
    def search(self, query=None, uris=None):
        if not query:
            return

        if 'uri' in query:
            search_query = ''.join(query['uri'])
            url = urlparse(search_query)
            if 'youtube.com' in url.netloc:
                req = parse_qs(url.query)
                if 'list' in req:
                    return SearchResult(uri='youtube:search',
                                        tracks=resolve_playlist(
                                            req.get('list')[0]))
                else:
                    logger.info("Resolving Youtube for track '%s'",
                                search_query)
                    return SearchResult(uri='youtube:search',
                                        tracks=[resolve_url(search_query)])
        else:
            search_query = ' '.join(query.values()[0])
            logger.info("Searching Youtube for query '%s'", search_query)
            return SearchResult(uri='youtube:search',
                                tracks=search_youtube(search_query))