]> kaliko git repositories - mpd-sima.git/blob - sima/lib/player.py
721d9a67e017e2cae2ad040a795669609efeaac4
[mpd-sima.git] / sima / lib / player.py
1 # -*- coding: utf-8 -*-
2 # Copyright (c) 2009-2014 Jack Kaliko <jack@azylum.org>
3 #
4 #  This file is part of sima
5 #
6 #  sima is free software: you can redistribute it and/or modify
7 #  it under the terms of the GNU General Public License as published by
8 #  the Free Software Foundation, either version 3 of the License, or
9 #  (at your option) any later version.
10 #
11 #  sima is distributed in the hope that it will be useful,
12 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #  GNU General Public License for more details.
15 #
16 #  You should have received a copy of the GNU General Public License
17 #  along with sima.  If not, see <http://www.gnu.org/licenses/>.
18 #
19 #
20
21 # TODO:
22 # Add decorator to filter through history?
23
24 # standard library import
25 import logging
26 from itertools import dropwhile
27
28 # local import
29
30 def blacklist(artist=False, album=False, track=False):
31     #pylint: disable=C0111,W0212
32     field = (album, track)
33     def decorated(func):
34         def wrapper(*args, **kwargs):
35             if not args[0].database:
36                 return func(*args, **kwargs)
37             cls = args[0]
38             boolgen = (bl for bl in field)
39             bl_fun = (cls.database.get_bl_album,
40                       cls.database.get_bl_track,)
41             #bl_getter = next(fn for fn, bl in zip(bl_fun, boolgen) if bl is True)
42             bl_getter = next(dropwhile(lambda _: not next(boolgen), bl_fun))
43             #cls.log.debug('using {0} as bl filter'.format(bl_getter.__name__))
44             results = list()
45             for elem in func(*args, **kwargs):
46                 if bl_getter(elem, add_not=True):
47                     #cls.log.debug('Blacklisted "{0}"'.format(elem))
48                     continue
49                 if track and cls.database.get_bl_album(elem, add_not=True):
50                     # filter album as well in track mode
51                     # (artist have already been)
52                     cls.log.debug('Blacklisted alb. "{0.album}"'.format(elem))
53                     continue
54                 results.append(elem)
55             return results
56         return wrapper
57     return decorated
58
59
60 class Player(object):
61     """Player interface to inherit from.
62
63     When querying player music library for tracks, Player instance *must* return
64     Track objects (usually a list of them)
65
66     Player instance should expose the following immutable attributes:
67         * artists
68         * state
69         * current
70         * queue
71         * playlist
72     """
73
74     def __init__(self):
75         super().__init__()
76         self.log = logging.getLogger('sima')
77
78     def monitor(self):
79         """Monitor player for change
80         Returns :
81             * database  player media library has changed
82             * playlist  playlist modified
83             * options   player options changed: repeat mode, etc…
84             * player    player state changed: paused, stopped, skip track…
85         """
86         raise NotImplementedError
87
88     def clean(self):
89         """Any cleanup necessary"""
90         pass
91
92     def remove(self, position=0):
93         """Removes the oldest element of the playlist (index 0)
94         """
95         raise NotImplementedError
96
97     def find_track(self, artist, title=None):
98         """
99         Find tracks for a specific artist or filtering with a track title
100             >>> player.find_track(Artist('The Beatles'))
101             >>> player.find_track(Artist('Nirvana'), title='Smells Like Teen Spirit')
102
103         Returns a list of Track objects
104         """
105         raise NotImplementedError
106
107     def find_album(self, artist, album):
108         """
109         Find tracks by track's album name
110             >>> player.find_album('Nirvana', 'Nevermind')
111
112         Returns a list of Track objects
113         """
114         raise NotImplementedError
115
116     def search_albums(self, artist):
117         """
118         Find albums by artist's name
119             >>> art = Artist(name='Nirvana')
120             >>> player.search_albums(art)
121
122         Returns a list of string objects
123         """
124         raise NotImplementedError
125
126     def search_artist(self, artist):
127         """
128         Search artists based on a fuzzy search in the media library
129             >>> art = Artist(name='the beatles', mbid=<UUID4>) # mbid optional
130             >>> bea = player.search_artist(art)
131             >>> print(bea.names)
132             >>> ['The Beatles', 'Beatles', 'the beatles']
133
134         Returns an Artist object
135         """
136         raise NotImplementedError
137
138     def disconnect(self):
139         """Closing client connection with the Player
140         """
141         raise NotImplementedError
142
143     def connect(self):
144         """Connect client to the Player
145         """
146         raise NotImplementedError
147
148     @property
149     def artists(self):
150         #pylint: disable=C0111
151         raise NotImplementedError
152
153     @property
154     def state(self):
155         #pylint: disable=C0111
156         raise NotImplementedError
157
158     @property
159     def current(self):
160         #pylint: disable=C0111
161         raise NotImplementedError
162
163     @property
164     def queue(self):
165         #pylint: disable=C0111
166         raise NotImplementedError
167
168     @property
169     def playlist(self):
170         #pylint: disable=C0111
171         raise NotImplementedError
172
173 # VIM MODLINE
174 # vim: ai ts=4 sw=4 sts=4 expandtab