diff options
Diffstat (limited to 'pydora')
-rw-r--r-- | pydora/audio_backend.py | 7 | ||||
-rw-r--r-- | pydora/configure.py | 15 | ||||
-rw-r--r-- | pydora/player.py | 56 | ||||
-rw-r--r-- | pydora/utils.py | 5 |
4 files changed, 55 insertions, 28 deletions
diff --git a/pydora/audio_backend.py b/pydora/audio_backend.py index bd778ad..aecd87e 100644 --- a/pydora/audio_backend.py +++ b/pydora/audio_backend.py | |||
@@ -15,18 +15,21 @@ log = logging.getLogger("pydora.audio_backend") | |||
15 | class PlayerException(Exception): | 15 | class PlayerException(Exception): |
16 | """Base class for all player exceptions | 16 | """Base class for all player exceptions |
17 | """ | 17 | """ |
18 | |||
18 | pass | 19 | pass |
19 | 20 | ||
20 | 21 | ||
21 | class UnsupportedEncoding(PlayerException): | 22 | class UnsupportedEncoding(PlayerException): |
22 | """Song encoding is not supported by player backend | 23 | """Song encoding is not supported by player backend |
23 | """ | 24 | """ |
25 | |||
24 | pass | 26 | pass |
25 | 27 | ||
26 | 28 | ||
27 | class PlayerUnusable(PlayerException): | 29 | class PlayerUnusable(PlayerException): |
28 | """Player can not be used on this system | 30 | """Player can not be used on this system |
29 | """ | 31 | """ |
32 | |||
30 | pass | 33 | pass |
31 | 34 | ||
32 | 35 | ||
@@ -172,7 +175,8 @@ class BasePlayer: | |||
172 | self._loop_hook() | 175 | self._loop_hook() |
173 | 176 | ||
174 | readers, _, _ = select.select( | 177 | readers, _, _ = select.select( |
175 | self._get_select_readers(), [], [], 1) | 178 | self._get_select_readers(), [], [], 1 |
179 | ) | ||
176 | 180 | ||
177 | for handle in readers: | 181 | for handle in readers: |
178 | if handle.fileno() == self._control_fd: | 182 | if handle.fileno() == self._control_fd: |
@@ -296,7 +300,6 @@ class VLCPlayer(BasePlayer): | |||
296 | 300 | ||
297 | 301 | ||
298 | class RemoteVLC(VLCPlayer): | 302 | class RemoteVLC(VLCPlayer): |
299 | |||
300 | def __init__(self, host, port, callbacks, control_channel): | 303 | def __init__(self, host, port, callbacks, control_channel): |
301 | self._connect_to = (host, int(port)) | 304 | self._connect_to = (host, int(port)) |
302 | self._control_sock = None | 305 | self._control_sock = None |
diff --git a/pydora/configure.py b/pydora/configure.py index d31c097..d58d445 100644 --- a/pydora/configure.py +++ b/pydora/configure.py | |||
@@ -32,11 +32,13 @@ class PandoraKeysConfigParser: | |||
32 | the pandora API docs keys source file. | 32 | the pandora API docs keys source file. |
33 | """ | 33 | """ |
34 | 34 | ||
35 | KEYS_URL = ("http://6xq.net/git/lars/pandora-apidoc.git/" | 35 | KEYS_URL = ( |
36 | "plain/json/partners.rst") | 36 | "http://6xq.net/git/lars/pandora-apidoc.git/plain/json/partners.rst" |
37 | ) | ||
37 | 38 | ||
38 | FIELD_RE = re.compile( | 39 | FIELD_RE = re.compile( |
39 | ":(?P<key>[^:]+): (?:`{2})?(?P<value>[^`\n]+)(?:`{2})?$") | 40 | ":(?P<key>[^:]+): (?:`{2})?(?P<value>[^`\n]+)(?:`{2})?$" |
41 | ) | ||
40 | 42 | ||
41 | def _fixup_key(self, key): | 43 | def _fixup_key(self, key): |
42 | key = key.lower() | 44 | key = key.lower() |
@@ -90,7 +92,7 @@ class PandoraKeysConfigParser: | |||
90 | key = self._clean_device_name(buffer.pop()) | 92 | key = self._clean_device_name(buffer.pop()) |
91 | current_partner = partners[key] = { | 93 | current_partner = partners[key] = { |
92 | "api_host": self._format_api_host(api_host) | 94 | "api_host": self._format_api_host(api_host) |
93 | } | 95 | } |
94 | 96 | ||
95 | buffer.append(line.strip().lower()) | 97 | buffer.append(line.strip().lower()) |
96 | 98 | ||
@@ -165,8 +167,9 @@ class Configurator: | |||
165 | self.add_partner_config(self.get_partner_config()) | 167 | self.add_partner_config(self.get_partner_config()) |
166 | self.get_value("user", "username", "Pandora Username: ") | 168 | self.get_value("user", "username", "Pandora Username: ") |
167 | self.get_password("user", "password", "Pandora Password: ") | 169 | self.get_password("user", "password", "Pandora Password: ") |
168 | self.set_static_value("api", "default_audio_quality", | 170 | self.set_static_value( |
169 | APIClient.HIGH_AUDIO_QUALITY) | 171 | "api", "default_audio_quality", APIClient.HIGH_AUDIO_QUALITY |
172 | ) | ||
170 | 173 | ||
171 | self.write_config() | 174 | self.write_config() |
172 | 175 | ||
diff --git a/pydora/player.py b/pydora/player.py index fdacc63..c4ce2e0 100644 --- a/pydora/player.py +++ b/pydora/player.py | |||
@@ -132,8 +132,12 @@ class PlayerApp: | |||
132 | if song.is_ad: | 132 | if song.is_ad: |
133 | print("{} ".format(Colors.cyan("Advertisement"))) | 133 | print("{} ".format(Colors.cyan("Advertisement"))) |
134 | else: | 134 | else: |
135 | print("{} by {}".format(Colors.cyan(song.song_name), | 135 | print( |
136 | Colors.yellow(song.artist_name))) | 136 | "{} by {}".format( |
137 | Colors.cyan(song.song_name), | ||
138 | Colors.yellow(song.artist_name), | ||
139 | ) | ||
140 | ) | ||
137 | 141 | ||
138 | def skip_song(self, song): | 142 | def skip_song(self, song): |
139 | if song.is_ad: | 143 | if song.is_ad: |
@@ -183,13 +187,15 @@ class PlayerApp: | |||
183 | self.screen.print_error("Failed to bookmark artis") | 187 | self.screen.print_error("Failed to bookmark artis") |
184 | except NotImplementedError: | 188 | except NotImplementedError: |
185 | self.screen.print_error( | 189 | self.screen.print_error( |
186 | "Cannot bookmark artist for this type of track") | 190 | "Cannot bookmark artist for this type of track" |
191 | ) | ||
187 | 192 | ||
188 | def sleep_song(self, song): | 193 | def sleep_song(self, song): |
189 | try: | 194 | try: |
190 | if song.sleep(): | 195 | if song.sleep(): |
191 | self.screen.print_success( | 196 | self.screen.print_success( |
192 | "Song will not be played for 30 days") | 197 | "Song will not be played for 30 days" |
198 | ) | ||
193 | self.player.stop() | 199 | self.player.stop() |
194 | else: | 200 | else: |
195 | self.screen.print_error("Failed to sleep song") | 201 | self.screen.print_error("Failed to sleep song") |
@@ -214,10 +220,14 @@ class PlayerApp: | |||
214 | 220 | ||
215 | def help(self, song): | 221 | def help(self, song): |
216 | print("") | 222 | print("") |
217 | print("\n".join([ | 223 | print( |
218 | "\t{:>2} - {}".format(k, v[0]) | 224 | "\n".join( |
219 | for k, v in sorted(self.CMD_MAP.items()) | 225 | [ |
220 | ])) | 226 | "\t{:>2} - {}".format(k, v[0]) |
227 | for k, v in sorted(self.CMD_MAP.items()) | ||
228 | ] | ||
229 | ) | ||
230 | ) | ||
221 | print("") | 231 | print("") |
222 | 232 | ||
223 | def input(self, input, song): | 233 | def input(self, input, song): |
@@ -227,7 +237,8 @@ class PlayerApp: | |||
227 | cmd = getattr(self, self.CMD_MAP[input][1]) | 237 | cmd = getattr(self, self.CMD_MAP[input][1]) |
228 | except (IndexError, KeyError): | 238 | except (IndexError, KeyError): |
229 | return self.screen.print_error( | 239 | return self.screen.print_error( |
230 | "Invalid command {!r}!".format(input)) | 240 | "Invalid command {!r}!".format(input) |
241 | ) | ||
231 | 242 | ||
232 | cmd(song) | 243 | cmd(song) |
233 | 244 | ||
@@ -240,21 +251,30 @@ class PlayerApp: | |||
240 | def pre_flight_checks(self): | 251 | def pre_flight_checks(self): |
241 | # See #52, this key no longer passes some server-side check | 252 | # See #52, this key no longer passes some server-side check |
242 | if self.client.partner_user == "iphone": | 253 | if self.client.partner_user == "iphone": |
243 | self.screen.print_error(( | 254 | self.screen.print_error( |
244 | "The `iphone` partner key set is no longer compatible with " | 255 | ( |
245 | "pydora. Please re-run pydora-configure to re-generate " | 256 | "The `iphone` partner key set is no longer compatible " |
246 | "your config file before continuing.")) | 257 | "with pydora. Please re-run pydora-configure to " |
258 | "re-generate your config file before continuing." | ||
259 | ) | ||
260 | ) | ||
247 | sys.exit(1) | 261 | sys.exit(1) |
248 | 262 | ||
249 | def _parse_args(self): | 263 | def _parse_args(self): |
250 | parser = argparse.ArgumentParser( | 264 | parser = argparse.ArgumentParser( |
251 | description="command line Pandora player") | 265 | description="command line Pandora player" |
266 | ) | ||
252 | parser.add_argument( | 267 | parser.add_argument( |
253 | "--vlc-net", dest="vlc_net", | 268 | "--vlc-net", |
254 | help="connect to VLC over the network (host:port)") | 269 | dest="vlc_net", |
270 | help="connect to VLC over the network (host:port)", | ||
271 | ) | ||
255 | parser.add_argument( | 272 | parser.add_argument( |
256 | "-v", dest="verbose", action="store_true", | 273 | "-v", |
257 | help="enable verbose logging") | 274 | dest="verbose", |
275 | action="store_true", | ||
276 | help="enable verbose logging", | ||
277 | ) | ||
258 | return parser.parse_args() | 278 | return parser.parse_args() |
259 | 279 | ||
260 | def run(self): | 280 | def run(self): |
diff --git a/pydora/utils.py b/pydora/utils.py index 6675773..5a96ff1 100644 --- a/pydora/utils.py +++ b/pydora/utils.py | |||
@@ -10,11 +10,11 @@ class TerminalPlatformUnsupported(Exception): | |||
10 | Raised by code that can not be used to interact with the terminal on this | 10 | Raised by code that can not be used to interact with the terminal on this |
11 | platform. | 11 | platform. |
12 | """ | 12 | """ |
13 | |||
13 | pass | 14 | pass |
14 | 15 | ||
15 | 16 | ||
16 | class Colors: | 17 | class Colors: |
17 | |||
18 | def __wrap_with(raw_code): | 18 | def __wrap_with(raw_code): |
19 | @staticmethod | 19 | @staticmethod |
20 | def inner(text, bold=False): | 20 | def inner(text, bold=False): |
@@ -22,6 +22,7 @@ class Colors: | |||
22 | if bold: | 22 | if bold: |
23 | code = "1;{}".format(code) | 23 | code = "1;{}".format(code) |
24 | return "\033[{}m{}\033[0m".format(code, text) | 24 | return "\033[{}m{}\033[0m".format(code, text) |
25 | |||
25 | return inner | 26 | return inner |
26 | 27 | ||
27 | red = __wrap_with("31") | 28 | red = __wrap_with("31") |
@@ -44,6 +45,7 @@ class PosixEchoControl: | |||
44 | def __init__(self): | 45 | def __init__(self): |
45 | try: | 46 | try: |
46 | import termios | 47 | import termios |
48 | |||
47 | self.termios = termios | 49 | self.termios = termios |
48 | except ImportError: | 50 | except ImportError: |
49 | raise TerminalPlatformUnsupported("POSIX not supported") | 51 | raise TerminalPlatformUnsupported("POSIX not supported") |
@@ -110,7 +112,6 @@ class Win32EchoControl: | |||
110 | 112 | ||
111 | 113 | ||
112 | class Screen: | 114 | class Screen: |
113 | |||
114 | def __init__(self): | 115 | def __init__(self): |
115 | try: | 116 | try: |
116 | self._echo_driver = PosixEchoControl() | 117 | self._echo_driver = PosixEchoControl() |