예제 #1
0
    def test_build_queries_with_sorts(self):
        spl = SmartPlaylistPlugin()
        config['smartplaylist']['playlists'].set([
            {'name': 'no_sort', 'query': 'foo'},
            {'name': 'one_sort', 'query': 'foo year+'},
            {'name': 'only_empty_sorts', 'query': ['foo', 'bar']},
            {'name': 'one_non_empty_sort', 'query': ['foo year+', 'bar']},
            {'name': 'multiple_sorts', 'query': ['foo year+', 'bar genre-']},
            {'name': 'mixed', 'query': ['foo year+', 'bar', 'baz genre+ id-']}
        ])

        spl.build_queries()
        sorts = dict((name, sort)
                     for name, (_, sort), _ in spl._unmatched_playlists)

        asseq = self.assertEqual  # less cluttered code
        S = FixedFieldSort  # short cut since we're only dealing with this
        asseq(sorts["no_sort"], NullSort())
        asseq(sorts["one_sort"], S('year'))
        asseq(sorts["only_empty_sorts"], None)
        asseq(sorts["one_non_empty_sort"], S('year'))
        asseq(sorts["multiple_sorts"],
              MultipleSort([S('year'), S('genre', False)]))
        asseq(sorts["mixed"],
              MultipleSort([S('year'), S('genre'), S('id', False)]))
예제 #2
0
    def build_queries(self):
        """
        Instanciate queries for the playlists.

        Each playlist has 2 queries: one or items one for albums, each with a
        sort. We must also remember its name. _unmatched_playlists is a set of
        tuples (name, (q, q_sort), (album_q, album_q_sort)).

        sort may be any sort, or NullSort, or None. None and NullSort are
        equivalent and both eval to False.
        More precisely
        - it will be NullSort when a playlist query ('query' or 'album_query')
          is a single item or a list with 1 element
        - it will be None when there are multiple items i a query
        """
        self._unmatched_playlists = set()
        self._matched_playlists = set()

        for playlist in self.config['playlists'].get(list):
            playlist_data = (playlist['name'], )
            for key, Model in (('query', Item), ('album_query', Album)):
                qs = playlist.get(key)
                if qs is None:
                    query_and_sort = None, None
                elif isinstance(qs, basestring):
                    query_and_sort = parse_query_string(qs, Model)
                elif len(qs) == 1:
                    query_and_sort = parse_query_string(qs[0], Model)
                else:
                    # multiple queries and sorts
                    queries, sorts = zip(*(parse_query_string(q, Model)
                                           for q in qs))
                    query = OrQuery(queries)
                    final_sorts = []
                    for s in sorts:
                        if s:
                            if isinstance(s, MultipleSort):
                                final_sorts += s.sorts
                            else:
                                final_sorts.append(s)
                    if not final_sorts:
                        sort = None
                    elif len(final_sorts) == 1:
                        sort, = final_sorts
                    else:
                        sort = MultipleSort(final_sorts)
                    query_and_sort = query, sort

                playlist_data += (query_and_sort, )

            self._unmatched_playlists.add(playlist_data)
예제 #3
0
    def setupModelData(self, query):
        sort = FixedFieldSort
        msort = MultipleSort([
            sort(u'albumartist'),
            sort('year', False),
            sort('month', False),
            sort('day', False),
            sort(u'album'),
            sort('disc'),
            sort('track')
        ])

        try:
            items = self.library.items(query, msort)
        except:
            return False

        self.rootItem.reset()

        for item in items:
            self.rootItem.appendChild(item)

        return True
예제 #4
0
    def translate_sorts(self, sort_arg):
        """Translate an AURA sort parameter into a beets Sort.

        Args:
            sort_arg: The value of the 'sort' query parameter; a comma
                separated list of fields to sort by, in order.
                E.g. "-year,title".
        """
        # Change HTTP query parameter to a list
        aura_sorts = sort_arg.strip(",").split(",")
        sorts = []
        for aura_attr in aura_sorts:
            if aura_attr[0] == "-":
                ascending = False
                # Remove leading "-"
                aura_attr = aura_attr[1:]
            else:
                # JSON:API default
                ascending = True
            # Get the beets version of the attribute name
            beets_attr = self.attribute_map.get(aura_attr, aura_attr)
            # Use slow sort so it works with all fields (inc. computed)
            sorts.append(SlowFieldSort(beets_attr, ascending=ascending))
        return MultipleSort(sorts)
예제 #5
0
    def build_queries(self):
        """
        Instantiate queries for the playlists.

        Each playlist has 2 queries: one or items one for albums, each with a
        sort. We must also remember its name. _unmatched_playlists is a set of
        tuples (name, (q, q_sort), (album_q, album_q_sort)).

        sort may be any sort, or NullSort, or None. None and NullSort are
        equivalent and both eval to False.
        More precisely
        - it will be NullSort when a playlist query ('query' or 'album_query')
          is a single item or a list with 1 element
        - it will be None when there are multiple items i a query
        """
        self._unmatched_playlists = set()
        self._matched_playlists = set()

        for playlist in self.config['playlists'].get(list):
            if 'name' not in playlist:
                self._log.warning(u"playlist configuration is missing name")
                continue

            playlist_data = (playlist['name'], )
            try:
                for key, model_cls in (('query', Item), ('album_query',
                                                         Album)):
                    qs = playlist.get(key)
                    if qs is None:
                        query_and_sort = None, None
                    elif isinstance(qs, six.string_types):
                        query_and_sort = parse_query_string(qs, model_cls)
                    elif len(qs) == 1:
                        query_and_sort = parse_query_string(qs[0], model_cls)
                    else:
                        # multiple queries and sorts
                        queries, sorts = zip(
                            *(parse_query_string(q, model_cls) for q in qs))
                        query = OrQuery(queries)
                        final_sorts = []
                        for s in sorts:
                            if s:
                                if isinstance(s, MultipleSort):
                                    final_sorts += s.sorts
                                else:
                                    final_sorts.append(s)
                        if not final_sorts:
                            sort = None
                        elif len(final_sorts) == 1:
                            sort, = final_sorts
                        else:
                            sort = MultipleSort(final_sorts)
                        query_and_sort = query, sort

                    playlist_data += (query_and_sort, )

            except ParsingError as exc:
                self._log.warning(u"invalid query in playlist {}: {}",
                                  playlist['name'], exc)
                continue

            self._unmatched_playlists.add(playlist_data)