Giter VIP home page Giter VIP logo

pydora's Introduction

Pandora API Client

This code is licensed under the MIT license. The code is maintained on GitHub.

This is a reasonably complete implementation of the Pandora API in pure Python that supports Python 3.5+. It contains a complete implementation of the core radio features but does not implement account management or Pandora Plus functionality; pull requests adding that functionality are welcomed from anyone needing those features.

Keys or passwords for Pandora are not provided in this repo, you'll have to go get those for yourself. Make something awesome with this library, don't abuse Pandora, that's not cool.

Project Complete

This project is actively maintained but the author considers it to be both stable and complete. There will be very few new changes initiated by the author outside of bug fixes and security updates.

If you run into a problem, file an issue and we'll respond. Pull requests for new features and fixes will be reviewed and accepted if they meet our criteria for stability, see below for contributing instructions.

Compatibility

This is the 2.x series which supports only Python 3.8+. For older versions of Python please use the 1.x series. The 1.x series is no longer maintained but pull requests to fix bugs are still welcomed.

This package uses semantic versioning. The API is guaranteed to be stable within a major version release. Please constrain your dependencies to major versions. For example, to depend on version 2.x use this line in your setup.py install_requires:

pydora>=2,<3

Installing

Installing is as simple as using pip and running the built-in configuration command to create a ~/.pydora.cfg file. If you already have a PianoBar config file Pydora will automatically use that.

$ pip install pydora
$ pydora-configure

On Ubuntu install vlc or vlc:

# apt-get install vlc

To install VLC on Mac OS X visit the VLC site to download VLC.app, then drag-and-drop the bundle into your /Applications folder. Pydora will auto-detect this.

Audio Output Back-end

The pydora player does not directly support audio output but instead relies upon external audio output back-ends. The two supported back-ends are VLC and mpg123. The main difference between the two back-ends is the supported file formats. VLC supports a vast array of codecs, including MP3 and AAC, the two formats that Pandora uses. mpg123 on the other hand supports only MP3. As of 2017 Pandora has started to prefer AAC files over MP3 which necessitates VLC. The pydora player will try to auto-detect whatever player exists on your system, preferring VLC, and will use that audio output back-end. If you notice a lot of skipping in a playlist consider installing VLC.

Remote VLC Back-end

It is also possible to remotely control a copy of VLC running on another machine if you're unable or unwilling to install Pydora on your playback machine. To do this start VLC on the remote machine with the rc-host option set. For example:

vlc -I rc --advanced --rc-host=0.0.0.0:1234

Once VLC is running start Pydora with the vlc-net option and specify the remote host and port that VLC is listening on. For example:

pydora --vlc-net 192.168.0.12:1234

Pydora will now send all audio playback requests to the remote VLC. It does this using a text control protocol; all audio data is streamed directly from the internet to VLC and is not passed over the Pydora control channel. Because of this it is possible for the control channel to run over a very low bandwidth connection.

Note: VLC doesn't provide any security so anyone on the network will be able to control VLC. It is generally safer to bind VLC to 127.0.0.1 and use something like SSH forwarding to securely forward the port to a remote host but that's outside of the scope of this README.

Simple Player

Included is pydora, a simple Pandora stream player that runs at the command line. It requires that mpg123 or VLC be installed with HTTP support as well as a settings file (example below) located in ~/.pydora.cfg. Alternatively an environment variable PYDORA_CFG can point to the path of the config file.

The player only supports basic functionality for now. It will display a station list, allow listening to any station, basic feedback and bookmarking are also supported. The player starts an mpg123 or VLC process in remote control mode and feeds commands to it. It does not download any music but rather streams them directly from Pandora.

When playing the following keys work (press enter afterwards):

  • n - next song
  • p - pause or resume song
  • s - station list (stops song)
  • d - thumbs down track
  • u - thumbs up track
  • b - bookmark song
  • a - bookmark artist
  • S - sleep song
  • Q - quit program
  • vu - volume up
  • vd - volume down
  • ? - display help

Note: volume control is currently only supported with the VLC back-end.

Sample Config File

The built-in pydora-configure script can be run to create a configuration file automatically if you don't already have one. This will download the keys from the link below and pick a suitable one when writing the config file. If you want to create the config file manually the format is:

[api]
api_host = hostname
encryption_key = key
decryption_key = key
username = partner username
password = partner password
device = key
default_audio_quality = mediumQuality

[user]
username = your username
password = your password
default_audio_quality
Default audio quality to request from the API; can be one of lowQuality, mediumQuality (default), or highQuality. If the preferred audio quality is not available for the device specified, then the next-highest bit-rate stream that Pandora supports for the chosen device will be used.

Programmatic Use

The Pydora distribution contains two python packages. The pandora package is the API for interacting with the Pandora service. The pydora package is a very small reference implementation of using the API to drive a command line player. If you're interested in the command line skip this section and read Installing below to get started.

The easiest way to get started is by using the pandora.clientbuilder package. This package contains a set of factories that can be used to build a Pandora client with some configuration. The classes in the package that end in Builder are the factories and the rest of the classes are implementation details. All of the builders will return an instance of pandora.client.APIClient that is completely configured and ready for use in your program.

If you have an existing program and would like to connect to Pandora the easiest way is to use the SettingsDictBuilder class like so:

client = SettingsDictBuilder({
    "DECRYPTION_KEY": "see_link_above",
    "ENCRYPTION_KEY": "see_link_above",
    "PARTNER_USER": "see_link_above",
    "PARTNER_PASSWORD": "see_link_above",
    "DEVICE": "see_link_above",
}).build()

client.login("username", "password")

At this point the client is ready for use, see pandora.client.APIClient for a list of methods that can be called. All responses from the API will return Python objects from the pandora.models.pandora package or raise exceptions from pandora.errors

For a more functional example look at the file pydora/player.py which shows how to use the API in a simple command line application.

Pandora API Spec and Partner Keys

If you're interested in the underlying API or need to download the keys yourself you can find more details at the links below. This documentation is community maintained and not official.

Contributing

See CONTRIBUTING

Contributors

Thanks to the contributors who make Pydora possible by adding features and fixing bugs. List is organized by date of first contribution.

pydora's People

Contributors

enzuru avatar hugovk avatar jcass77 avatar mcrute avatar skybound1 avatar t-8ch avatar theophileds avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pydora's Issues

Consider making 'Invalid Partner Login' message less ambiguous

Pandora produces an Invalid Partner Login (code 1002) error message for both partner authentication auth.partnerLogin as well as auth.userLogin related issues.

This can be confusing for users, as seen here: mopidy/mopidy-pandora#41 and here PromyLOPh/pianobar#263.

It may make it easier to troubleshoot and provide user support if some distinction was made between the two root causes for authentication. An example of how this was done in pianobar is available here: https://github.com/PromyLOPh/pianobar/blob/7235a62c183d3815a0fc3dd7e05c6a3492a23f1f/src/libpiano/response.c#L101-L108

ParameterMissing exception when requesting next track from iterator

I came across the following stack trace today:

ERROR Unhandled exception in PandoraBackend (urn:uuid:3cdfb222-12ef-42bf-bf8f-e3e6978caf66):
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 201, in _actor_loop
response = self._handle_receive(message)
File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 295, in _handle_receive
return callee(_message['args'], *_message['kwargs'])
File "/Users/jcass/PycharmProjects/Mopidy/mopidy/mopidy/core/listener.py", line 34, in on_event
getattr(self, event)(**kwargs)
File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/backend.py", line 60, in end_of_tracklist_reached
next_track = self.library.next_track()
File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 138, in next_track
pandora_track = self._station_iter.next()
File "/usr/local/lib/python2.7/site-packages/pydora/utils.py", line 121, in iterate_forever
yield next(output).prepare_playback()
File "/usr/local/lib/python2.7/site-packages/pandora/models/pandora.py", line 227, in prepare_playback
self.register_ad(self.station_id)
File "/usr/local/lib/python2.7/site-packages/pandora/models/pandora.py", line 224, in register_ad
self._api_client.register_ad(station_id, self.tracking_tokens)
File "/usr/local/lib/python2.7/site-packages/pandora/client.py", line 280, in register_ad
adTrackingTokens=tokens)
File "/usr/local/lib/python2.7/site-packages/pandora/client.py", line 104, in call
return self.transport(method, *_kwargs)
File "/usr/local/lib/python2.7/site-packages/pandora/transport.py", line 47, in function
return func(_args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/pandora/transport.py", line 234, in call
return self._parse_response(result)
File "/usr/local/lib/python2.7/site-packages/pandora/transport.py", line 220, in _parse_response
raise PandoraException.from_code(result["code"], result["message"])
ParameterMissing: Parameter Missing

As best I can tell, there seems to be a parameter missing in the register_ad call when the track is yielded from the iterator (either the token or the station id)?

Inquiry: How to use a library on project?

HI, I am trying to use your library and was hoping you can give me in the right direction.
The commands rely on stdin for stopping, skipping, etc.
I create a process to start the player but can't seem to get the callbacks to work for ending the player. I can do p.terminate() but I am hoping for a cleaner implementation.

import time
from multiprocessing import Process
from pydora.player import PlayerApp
from pydora.mpg123 import Player

client = py.get_client()
stations = client.get_station_list()
p = Process(target=py.player.play_station, args=(stations[0],))
p.start()

time.sleep(10)

py.player.stop()  # this works
py.player.end_station() # doesn't work 

Thanks in advance,
Diego

Issues with creating a new station

Hi,
I'm currently using the APIClient class, that is your high level Pandora API client to search for something, then choose the best result from the results. After choosing the best result, I'd get, say a chosen_station, which can then use the create_station() function. It all seems to work, though I get a status of fail, with the message An unexpected error occurred, with code 0. I am sure that the resulting chosen_station is either a SongSearchResultItem or an ArtistSearchResultItem.

Any ideas what could be going wrong? I don't have any issues with using the client to get my own playlists or anything, but I'm unable to create stations from the search results.

Player does not appear to work on OSX

I get the following stack trace as soon as a station is selected in the bundled player:

Traceback (most recent call last):
The Wishing Well File "/usr/local/bin/pydora", line 9, in
by load_entry_point('pydora==1.6', 'console_scripts', 'pydora')()
Sharon Shannon & Friends File "/Users/jcass/PycharmProjects/Mopidy/pydora/pydora/player.py", line 199, in main

PlayerApp().run()

File "/Users/jcass/PycharmProjects/Mopidy/pydora/pydora/player.py", line 193, in run
self.player.play_station(station)
File "/Users/jcass/PycharmProjects/Mopidy/pydora/pydora/mpg123.py", line 97, in play_station
self.play(song)
File "/Users/jcass/PycharmProjects/Mopidy/pydora/pydora/mpg123.py", line 82, in play
self._callbacks.post_poll()
File "/Users/jcass/PycharmProjects/Mopidy/pydora/pydora/player.py", line 184, in post_poll
Screen.set_echo(True)
File "/Users/jcass/PycharmProjects/Mopidy/pydora/pydora/utils.py", line 44, in set_echo
lflag, ispeed, ospeed, cc) = termios.tcgetattr(fd)
termios.error: (25, 'Inappropriate ioctl for device')

Typo in source code

I've found a typo resulting in a syntax error in the source code - fix contained in PR #3

Broken pipe on play station

I just installed pydora and may have missed something. I'm on a Raspberry Pi 2 under Debian Jessie using Python 3.4.2.

When I try to play a station, it fails immediately with this traceback. Is this maybe related to that warning in the Python docs about not eading/writing to subprocess pipes due to race conditions or something?

...
 29: electro-pop-dance-rock
Station: 1
Judge Me by Sia
Traceback (most recent call last):
  File "/usr/local/bin/pydora", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.4/dist-packages/pydora/player.py", line 199, in main
    PlayerApp().run()
  File "/usr/local/lib/python3.4/dist-packages/pydora/player.py", line 193, in run
    self.player.play_station(station)
  File "/usr/local/lib/python3.4/dist-packages/pydora/mpg123.py", line 97, in play_station
    self.play(song)
  File "/usr/local/lib/python3.4/dist-packages/pydora/mpg123.py", line 63, in play
    self._send_cmd("load {}".format(song.audio_url))
  File "/usr/local/lib/python3.4/dist-packages/pydora/mpg123.py", line 39, in _send_cmd
    self._process.stdin.flush()
BrokenPipeError: [Errno 32] Broken pipe

Pydora player is not tolerant of proxies that rewrite the mime type

When there is an HTTP proxy between mpg123 and Pandora the rewrites the mime type to something silly like application/octet-stream mpg123 will fail to load songs with a mimetype error and will cycle through an entire playlist. mpg123 has a --ignore-mime flag that should prevent this.

Dropping Python 2.x - 3.4 Support

Dropping Python 2.x support

This is an announcement that, in 2019, this project will be dropping support for Python 2.x all the way through Python 3.4. Python 2.7 will be end-of-life on January 1, 2020 and Python 3.4 just reached end-of-life on March 16, 2019.

Because this is a backwards incompatible change Pydora will release a new major version 2.0 that supports only Python 3.5+. We will leave the 1.x series published to PyPi but no additional releases will be made. Consumers that have a hard dependency on the 1.x series and can not migrate will need to update their requirements to select the older version. For example:

pydora>=1.13,<2

Schedule

Semantic versioning has not historically been a standard in Python code-bases and many Python projects have open-ended dependency selectors (e.g. >=1). Because of this, and to avoid breaking existing consumers the Pydora project will provide 4 months of migration time before releasing 2.0 to allow consumers to update their dependency selectors.

IF YOU HAVE A HARD DEPENDENCY ON PYTHON 2 THAT YOU CAN NOT BREAK PLEASE UPDATE YOUR DEPENDENCY SELECTORS NOW!

  • April 2019 - a 1.x branch will be introduced for historical tracking of the 1.x series and master will become the development branch for the python3 transition
  • May 2019 - all proposed changes will be available to consumers in the master branch for testing but will not yet be released to PyPi.
  • June 2019 - the 2.xseries will be pushed to PyPi as pydora-2.0.0. The 1.x series will continue to be published as well but no new releases will be made. At this point all development on the 1.x series will cease and new development will proceed on the 2.x series.

Other backwards incompatible changes

We will also be removing some deprecated legacy APIs in concert with this change. Specifically the following will be removed:

  • Factory methods on BaseAPIClient - The ClientBuilder API was introduced in 2015 and is the preferred way to construct an APIClient. Constructing APIClient manually is still supported in the public API but consumers will need to adjust their imports.
  • __init__.py imports - these imports were originally provided for compatibility with an older file structure and will be removed. Consumers relying on building an APIClient directly will need to modify their imports to use the correct packages instead of relying on the high-level imports.
  • models breakdown - this package will be broken down to files per functional area (e.g. playlist, station, ads) and the top level __init__.py content will be moved to a differently named file. Although models are part of the public API for Pydora, most consumers should not be importing them directly so this should have limited impact. Consumers who are importing models directly will need to adjust their imports.
  • py2compat - this file will be completely removed and all uses re-written to their python3 versions
  • util - this file will be removed

Request for comments

If you will be affected by these changes and can not migrate or have other needs related to this migration please comment on this issue before May 2019. Other constructive comments are welcome as well.

Add docs and examples

What would you like to be added:
Easy to understand documentation and code examples

Why is this needed:
Because I and 2 pepole I asked cant understand this docs.
We can't even understand how to connect to API.

Goog docs examle PyTelegramBotApi

Config parsing should use raw mode

Some credentials have % characters in them which triggers ConfigParser's interpolation mode. Config settings should be read in raw mode instead.

Python3 syntax issues

The pydora player has a few python 3 syntax issues when using unicode strings with the u prefix. This is happening in python 3.2 and I haven't had a chance to test it on newer versions of 3. I would guess that this works fine in newer versions due to the re-introduced support for u prefixed unicode strings. This should be made to work with all versions of python 2.7-3.5.

Pydora player issues cause playlist cycling

When there is an issue with the underlying mpg123 player in Pydora it will continue to skip songs until the Pandora API rate limits the application. There should be better error checking around the mpg123 integration as well as some sort of internal rate limiting to try to detect errors before the Pandora API rate limiter does.

Help understand ads in Pandora and Login timeout (refresh)

Great library and pretty simple to implement. Keep up the good work!

I don't fully understand Ads. I notice in the Player, it refers to the add and play the URL, which can be something like:

https://delivery-cdn-cf.adswizz.com/pandora_newEnco/ad_[REDACTED].mp4?t=1

I don't see how just playing that URL counts as 'viewing' the ad.

Consider the following code:

from pandora.clientbuilder import SettingsDictBuilder
import subprocess
import time
from urllib.request import urlretrieve

client = SettingsDictBuilder({
    "DECRYPTION_KEY": "[REDACTED]",
    "ENCRYPTION_KEY": "[REDACTED]",
    "PARTNER_USER": "[REDACTED]",
    "PARTNER_PASSWORD": "[REDACTED]",
    "DEVICE": "[REDACTED]",
}).build()

client.login(userName, passWord)
stations = client.get_station_list()
for station in stations:
    for play in station.get_playlist():
        if play.is_ad:
            urlretrieve(play.audio_url, 'file.mp3')
            #AdItem(audio_url='https://delivery-cdn-cf.adswizz.com/pandora_newEnco/ad_[REDACTED].mp4?t=1', click_through_url='', company_name='', image_url='https://cont-1.p-cdn.us/images/public/devicead/e/l/i/t/daarv2audioprogtile_500W_500H.jpg', title='', tracking_tokens=['[REDACTED]', '[REDACTED]', '[REDACTED]', '[REDACTED]'])
        else:
           urlretrieve(play.audio_url, 'file.mp3')

        runCommand = str('cvlc --play-and-exit file.mp3').split()
        playSongProcess = subprocess.Popen(runCommand, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, encoding="utf-8")
        while playSongProcess.poll() == None:
            time.sleep(1)  # still running 

Any insight on ads?

Also, I think Pandora times out the login. Should I client.login() periodically or how can I trap a need to login again?

I Need Help

I don't actually use this product, I have a question about the Unofficial Pandora API. Before you click away, it's super quick, I promise.

Alright, to the issue. I am able to get the partner login stuff fine (ex. the token, syncTime (before decode), etc). Then, I'm also able to decode the syncTime stuff aswell, getting the synccode number. But, this is where my issue comes in. I put everything together (username, pass, auth token, sync time, and putting partner_id into the url), using the method auth.userLogin, and ALWAYS; EVERY SINGLE DAMN TIME, I get a 1010 error (PARTNER_NOT_AUTHORIZED). Please, PLEASE help, I really want to get this working but it's just not workin' out.

By the way, I'm using Postman to send my requests before I get into any library, so it's simple stuff.

... and I don't have Pandora One, so internal-tuner won't be working out.

Example of my failures:

Retrieving audio URL does not work for all types of Pandora clients

The audioUrl field in pandora.py does not map correctly for all partner device types.

class PlaylistItem(PandoraModel):

    artist_name = Field('artistName')
    album_name = Field('albumName')
    song_name = Field('songName')
    song_rating = Field('songRating')
    track_gain = Field('trackGain')
    track_token = Field('trackToken')
    audio_url = Field('audioUrl')
    album_art_url = Field('albumArtUrl')
    allow_feedback = Field('allowFeedback', True)
    station_id = Field('stationId')

For example, for android-generic the actual URL is stored in a dictionary with structure:

[audioUrlMap][xQuality][audioUrl] where x is either 'low', 'medium', or 'high'.

This error can be reproduced by setting partner_device = android-generic in ~/.pydora.cfg and updating the related configuration entries for encryption etc. as per the unofficial Pandora API

I'm not sure whether it would be better to make PlayListItem partner-type aware based on some user-specified preferred bitrate in the configuration files, or if the loop in 'from_json' should just fall back to trying to retrieve the highest available stream:

https://github.com/mcrute/pydora/blob/1e8502b1eabb8e595f1f23d26e62d7763097b2a0/pandora/models/__init__.py#L51-63

Search for station, select it, and get station

How would I go about getting a station after searching for it?
I currently have the code:
search = pandora_client.search("Today's Hits", include_near_matches=True, include_genre_stations=True)
station = search[0]
station.create_station()

After creating the station; how do I select it to get a Station and get its tracks using get_playlist()?

Continuous skipping of tracks

Recently pydora stopped working, for some reason it keeps skipping tracks, I believe the tracks are not playable (python exception)j. Do you know why this might be happening? I have a premium account with pandora and all.

Here is my config:

[user]
username =
password =

[api]
username = android
api_host = tuner.pandora.com/services/json/
encryption_key = ...
decryption_key = ...
device = android-generic
password = ...
default_audio_quality = highQuality

Here is sample output

:
50: Mariah Carey (Holiday) Radio
51: Christmas Radio
52: Pink Radio
53: Pink Martini Radio
54: Alternative and Relaxation
55: Easy Listening Radio
56: Luis Fonsi Radio
57: Rainbows In The Dark Radio
58: Music For Brainwave Massage Radio
59: Krishna Radio
60: Carol Of The Bells (Instrumental) Radio
61: Lisa Shaw Radio
62: Nicki Minaj Radio
63: Yanni Radio
64: Trance
65: Deep Beat
66: Drum & Bass
67: Trip Hop
68: Liquid Drum & Bass
69: Deep House
70: Progressive/Electro House
71: Armin Van Buuren Radio
72: Milo Radio
73: Jungle Of Mirror (Scumfrog Remix) Radio
74: Silversun Pickups Radio
75: The Best Deceptions Radio
76: Thievery Corporation Radio
77: Alternative Pop/Rock
78: Alternative / Indie Rock
79: Drum'n'Bass
80: Dashboard Confessional Radio
Station: 1
The Prey by Ashes Divide
Find You There by We The Kings
Prescription Mixed Up by Snakes & Music
(This Is How I Look) When I Laugh At Death by Johnny Action Figure
Read My Mind by The Killers
Conservation Of Two by Sweet Trip
Damn Silence by Sunrise Avenue
Swinging Swords by Ben + Vesper
Radio Silence by Attention System
New Frontier by Counting Crows
Eighty-Eights by Farewell
Closer To The Edge (American Idol Performance) by James Durbin
(keeps skipping)

Error: pandora.errors.InvalidAuthToken: Invalid Auth Token

What happened:
As of yesterday, I am getting the error:
pandora.errors.InvalidAuthToken: Invalid Auth Token

What you expected to happen:
As has worked for years, I expect it to login

How to reproduce it (as minimally and precisely as possible):

  1. on Python 3.8 (on Linux or Windows), install the pydora

  2. using a new or old pandora account (not pandora one) run the following python script, adding the partner key and your username and password:

     from pandora.clientbuilder import SettingsDictBuilder
     from pandora import client
     
     userName="k******g"
     passWord="M******1"
     
     client = SettingsDictBuilder({
         "DECRYPTION_KEY": "R****B#",    
         "ENCRYPTION_KEY": "6****D",    
         "PARTNER_USER": "android", 
         "PARTNER_PASSWORD": "A******7",    
         "DEVICE": "android-generic",
     }).build()
     
     client.login(userName, passWord)
    

You should get the following error:

C:/Python38-64/python.exe d:/Git/PandoraPlayer/getMusic.py
Traceback (most recent call last):
  File "d:/Git/PandoraPlayer/getMusic.py", line 19, in <module>
    client.login(userName, passWord)
  File "C:\Python38-64\lib\site-packages\pandora\client.py", line 64, in login
    return self._authenticate()
  File "C:\Python38-64\lib\site-packages\pandora\client.py", line 70, in _authenticate
    user = self.transport(
  File "C:\Python38-64\lib\site-packages\pandora\transport.py", line 51, in function
    return func(*args, **kwargs)
  File "C:\Python38-64\lib\site-packages\pandora\transport.py", line 243, in __call__
    return self._parse_response(result)
  File "C:\Python38-64\lib\site-packages\pandora\transport.py", line 232, in _parse_response
    raise PandoraException.from_code(result["code"], result["message"])
pandora.errors.InvalidAuthToken: Invalid Auth Token

Anything else we need to know?:
I have tried this with the iphone partner id, with 2 known good pandora login accounts and with a new pandora login account, all the same result.

Yesterday it was working fine so, I am confused.

Environment:

  • Pydora version: 2.0.1
  • Python version: 3.8.5 - x64
  • OS: Windows 10
  • Shell (if applicable):
  • Others:

Unable to login

What happened:
TypeError: Cannot mix str and non-str arguments

What you expected to happen:
Normal login

How to reproduce it (as minimally and precisely as possible):
I thing use this code:

from pandora.clientbuilder import SettingsDictBuilder


def play_music(url):
    # You'll need to implement this to do something like call VLC with the track to play it
    pass


# You will need to read the README, it has a link to a page that contains the values
# required for the below dictionary. You can copy/paste them to replace see_link_above
client = SettingsDictBuilder({
    "DECRYPTION_KEY": "[REDACTED]", "ENCRYPTION_KEY": "[REDACTED]",
    "PARTNER_USER": "[REDACTED]", "PARTNER_PASSWORD": "[REDACTED]",
    "DEVICE": "[REDACTED]",
    "PROXY": {'http': "http://89.187.177.96:80", 'https': "https://51.81.82.175:80"},
    "AUDIO_QUALITY": "highQuality"}).build()

client.login("My login", "my pass")

stations = client.get_station_list()

# A playlist has a fixed number of songs (3 IIRC) so you have to call get_playlist over and
# over to keep playing songs. Be careful here though, the Pandora server expects you to
# actually listen to the songs you get from it, if you call this API too often then Pandora will
# start to rate-limit you and fail your requests. The best idea is to call this no more than every
# (play_list_item_count * 3 minutes) minutes to avoid being rate limited.
first_station_playlist = stations[0].get_playlist()

first_track = first_station_playlist[0]

print(f"Now playing {first_track.song_name} by {first_track.artist_name} on album {first_track.album_name}\n"
      f"{len(first_station_playlist)=}")

play_music(first_track.audio_url)

You wil get this error:

TypeError: Cannot mix str and non-str arguments
Traceback (most recent call last):
  File "/run/media/dannkunt/01D67E9E24F55A00/Programing/Python/bef_music_bot/pandora_mus.py", line 17, in 
    client.login("my account", "strong pass")
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/pandora/client.py", line 64, in login
    return self._authenticate()
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/pandora/client.py", line 67, in _authenticate
    self._partner_login()
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/pandora/client.py", line 49, in _partner_login
    partner = self.transport(
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/pandora/transport.py", line 51, in function
    return func(*args, **kwargs)
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/pandora/transport.py", line 241, in __call__
    result = self._make_http_request(url, data, params)
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/pandora/transport.py", line 192, in _make_http_request
    result = self._http.post(url, data=data, params=params)
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/requests/sessions.py", line 590, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/requests/adapters.py", line 412, in send
    conn = self.get_connection(request.url, proxies)
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/requests/adapters.py", line 304, in get_connection
    proxy = prepend_scheme_if_needed(proxy, 'http')
  File "/home/dannkunt/.venvs/bef_music_bot39_venv/lib/python3.9/site-packages/requests/utils.py", line 910, in prepend_scheme_if_needed
    scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme)
  File "/usr/lib/python3.9/urllib/parse.py", line 389, in urlparse
    url, scheme, _coerce_result = _coerce_args(url, scheme)
  File "/usr/lib/python3.9/urllib/parse.py", line 122, in _coerce_args
    raise TypeError("Cannot mix str and non-str arguments")
TypeError: Cannot mix str and non-str arguments

Anything else we need to know?:

Environment:

  • Pydora version: 2.1.0
  • Python version: 3.9.0
  • OS: Manjaro Linux KDE
  • Shell (if applicable):
  • Others: Pycharm 2020.3

Continuous Song Cycling

When playing any station Pydora will continuously print song names out to the screen, 4 at a time, over and over. No music plays. I've only tried this on one computer: Mac running 10.12.3 and the latest version of Pydora.

Break pycrypto dependency

The only native C dependency in the project is pycrypto which is exclusively used for Blowfish. Even so this still means that to install the code you need to have a functioning C compiler and python headers on the system which is not always the case. We should instead swap in one of the many pure python implementations of blowfish either by vendoring the file or by using a third-party version.

Unhandled StopIteration exception

A StopIteration exception can occur on rare occasions when retrieving the next Pandora track.

Stack track details below:

  Received WebSocket message from 127.0.0.1: u'{"method":"core.library.browse","params":["pandora:station:2932455179979957924:2932455179979957924"],"jsonrpc":"2.0","id":1479}'
DEBUG    2015-12-10 10:17:04,778 [31248:PandoraBackend-14] pykka
  Exception returned from PandoraBackend (urn:uuid:e53806cb-71bd-4cf8-b1b8-6f97bc64c7fe) to caller:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 201, in _actor_loop
    response = self._handle_receive(message)
  File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 295, in _handle_receive
    return callee(*message['args'], **message['kwargs'])
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 46, in browse
    return self._browse_tracks(uri)
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 109, in _browse_tracks
    return [self.get_next_pandora_track()]
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 138, in get_next_pandora_track
    pandora_track = self._station_iter.next()
StopIteration
ERROR    2015-12-10 10:17:04,783 [31248:Core-16] mopidy.core.library
  PandoraBackend backend caused an exception.
Traceback (most recent call last):
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy/mopidy/core/library.py", line 19, in _backend_error_handling
    yield
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy/mopidy/core/library.py", line 112, in _browse
    result = backend.library.browse(uri).get()
  File "/usr/local/lib/python2.7/site-packages/pykka/threading.py", line 52, in get
    compat.reraise(*self._data['exc_info'])
  File "/usr/local/lib/python2.7/site-packages/pykka/compat.py", line 12, in reraise
    exec('raise tp, value, tb')
  File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 201, in _actor_loop
    response = self._handle_receive(message)
  File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 295, in _handle_receive
    return callee(*message['args'], **message['kwargs'])
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 46, in browse
    return self._browse_tracks(uri)
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 109, in _browse_tracks
    return [self.get_next_pandora_track()]
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 138, in get_next_pandora_track
    pandora_track = self._station_iter.next()
StopIteration
DEBUG    2015-12-10 10:17:10,338 [31248:HttpServer] mopidy.http.handlers
  Sent WebSocket message to 127.0.0.1: '{"jsonrpc": "2.0", "id": 1479, "result": []}'

This is supposed to be handled by stop_iteration, so not sure what the root cause is.

Remote VLC Backend

I have VLC installed on my system but don't want to install Pydora. Instead I want to run VLC in RC mode listening on the network and allow Pydora on a remote machine to play music to this listening VLC instance.

I have a working version of this that I've been using for a few weeks now that just needs cleaned up and documented. Opening this issue to track inclusion in 1.10.0

Unicode Encode Error

Pydora stops playing when it runs into special characters. In this instance it's an 'é'.

Traceback (most recent call last):
  File "./pydora/bin/pydora", line 11, in <module>
    sys.exit(main())
  File "/Users/kcrute/pydora/lib/python2.7/site-packages/pydora/player.py", line 199, in main
    PlayerApp().run()
  File "/Users/kcrute/pydora/lib/python2.7/site-packages/pydora/player.py", line 193, in run
    self.player.play_station(station)
  File "/Users/kcrute/pydora/lib/python2.7/site-packages/pydora/mpg123.py", line 97, in play_station
    self.play(song)
  File "/Users/kcrute/pydora/lib/python2.7/site-packages/pydora/mpg123.py", line 62, in play
    self._callbacks.play(song)
  File "/Users/kcrute/pydora/lib/python2.7/site-packages/pydora/player.py", line 97, in play
    print("{} by {}".format(Colors.cyan(song.song_name),
  File "/Users/kcrute/pydora/lib/python2.7/site-packages/pydora/utils.py", line 26, in inner
    return "\033[{}m{}\033[0m".format(code, text)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xc9' in position 11: ordinal not in range(128)

Recover from connection resets when iterating through playlist

iterate_forever should probably be able to recover gracefully from exceptions raised due to the Pandora server closing the connection for some reason:

File "/var/lib/git/pydora/pydora/utils.py", line 120, in iterate_forever
output = func(_args, *_kwargs)
File "/var/lib/git/pydora/pandora/models/pandora.py", line 24, in get_playlist
return iter(self._api_client.get_playlist(self.token))
File "/var/lib/git/pydora/pandora/client.py", line 117, in get_playlist
includeTrackLength=True))
File "/var/lib/git/pydora/pandora/client.py", line 88, in call
return self.transport(method, *_kwargs)
File "/var/lib/git/pydora/pandora/transport.py", line 170, in call
result = self._make_http_request(url, data, params)
File "/var/lib/git/pydora/pandora/transport.py", line 122, in _make_http_request
r = self._http.post(url, data=data, params=params)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 511, in post
return self.request('POST', url, data=data, json=json, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 468, in request
resp = self.send(prep, *_send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 576, in send
r = adapter.send(request, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 370, in send
timeout=timeout
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py", line 559, in urlopen
body=body, headers=headers)
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py", line 376, in _make_request
httplib_response = conn.getresponse(buffering=True)
File "/usr/lib/python2.7/httplib.py", line 1034, in getresponse
response.begin()
File "/usr/lib/python2.7/httplib.py", line 407, in begin
version, status, reason = self._read_status()
File "/usr/lib/python2.7/httplib.py", line 365, in _read_status
line = self.fp.readline()
File "/usr/lib/python2.7/socket.py", line 447, in readline
data = self._sock.recv(self._rbufsize)
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 179, in recv
data = self.connection.recv(_args, *_kwargs)
File "/usr/local/lib/python2.7/dist-packages/OpenSSL/SSL.py", line 1320, in recv
self._raise_ssl_error(self._ssl, result)
File "/usr/local/lib/python2.7/dist-packages/OpenSSL/SSL.py", line 1178, in _raise_ssl_error
raise SysCallError(errno, errorcode.get(errno))
SysCallError: (104, 'ECONNRESET')

Perhaps simply retrying the API call up to n times with a short delay in between as suggested in https://github.com/kennethreitz/requests/issues/2543 might be an option?

Token refresh doesn't work correctly

If the pydora player is left paused overnight when trying to resume playing the track the player silently fails. Navigating back to the main menu and selecting another station causes an InvalidAuthToken exception.

Using requests causes pydora connection reset exceptions

I noticed this three times so far today. It looks like it happens at the end of a playlist.

Traceback (most recent call last):
  File "/.../pydora/bin/pydora", line 9, in <module>
    load_entry_point('pydora==1.3.0', 'console_scripts', 'pydora')()
  File "/.../pydora/lib/python3.2/site-packages/pydora/player.py", line 140, in main
    PlayerApp().run()
  File "/.../pydora/lib/python3.2/site-packages/pydora/player.py", line 134, in run
    self.player.play_station(station)
  File "/.../pydora/lib/python3.2/site-packages/pydora/mpg123.py", line 149, in play_station
    for song in iterate_forever(station.get_playlist):
  File "/.../pydora/lib/python3.2/site-packages/pydora/mpg123.py", line 18, in iterate_forever
    output = func(*args, **kwargs)
  File "/.../pydora/lib/python3.2/site-packages/pandora/models/pandora.py", line 24, in get_playlist
    return iter(self._api_client.get_playlist(self.token))
  File "/.../pydora/lib/python3.2/site-packages/pandora/__init__.py", line 299, in get_playlist
    includeTrackLength=True))
  File "/.../pydora/lib/python3.2/site-packages/pandora/__init__.py", line 266, in __call__
    return self.transport(method, **kwargs)
  File "/.../lib/python3.2/site-packages/pandora/__init__.py", line 145, in __call__
    result = self._make_http_request(url, data, params)
  File "/.../pydora/lib/python3.2/site-packages/pandora/__init__.py", line 97, in _make_http_request
    r = self._http.post(url, data=data, params=params)
  File "/.../pydora/lib/python3.2/site-packages/requests/sessions.py", line 508, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/.../pydora/lib/python3.2/site-packages/requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "/.../pydora/lib/python3.2/site-packages/requests/sessions.py", line 573, in send
    r = adapter.send(request, **kwargs)
  File "/.../pydora/lib/python3.2/site-packages/requests/adapters.py", line 415, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', error(104, 'Connection reset by peer'))

API lacks support for retrieving station list checksum

At the moment, get_station_list() discards the checksum field when retrieving the list of stations from Pandora.

This, combined with the fact that user.getStationListChecksum has not been implemented yet means that it is not possible to cache a local copy of the station list without risking it becoming stale.

I'm not sure how to fix this and ensure backward compatibility, apart from adding the checksum to the Station model which would result in the same checksum field being duplicated for every station.

I know that the pydora API does not aim to implement every available Pandora function, but the ability to cache the station list does seem like a worthwhile optimisation to consider.

Pydora fails to start

What happened:
pydora fails to start

What you expected to happen:
the main menu

How to reproduce it (as minimally and precisely as possible):

  1. install pydora 2.0.1

  2. run pydora-config and put in a known userid and password

  3. run pydora

  4. you should get the error below:

     $ pydora
     Using VLC
     Traceback (most recent call last):
       File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 159, in _new_conn
         (self._dns_host, self.port), self.timeout, **extra_kw)
       File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 57, in create_connection
         for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
       File "/usr/lib/python3.7/socket.py", line 748, in getaddrinfo
         for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
     socket.gaierror: [Errno -2] Name or service not known
     
     During handling of the above exception, another exception occurred:
     
     Traceback (most recent call last):
       File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
         chunked=chunked)
       File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 343, in _make_request
         self._validate_conn(conn)
       File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 841, in _validate_conn
         conn.connect()
       File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 301, in connect
         conn = self._new_conn()
       File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 168, in _new_conn
         self, "Failed to establish a new connection: %s" % e)
     urllib3.exceptions.NewConnectionError: <urllib3.connection.VerifiedHTTPSConnection object at 0xb5e04a50>: Failed to establish a new connection: [Errno -2] Name or service not known
     
     During handling of the above exception, another exception occurred:
     
     Traceback (most recent call last):
       File "/usr/lib/python3/dist-packages/requests/adapters.py", line 449, in send
         timeout=timeout
       File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 667, in urlopen
         **response_kw)
       File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 667, in urlopen
         **response_kw)
       File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 667, in urlopen
         **response_kw)
       File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 638, in urlopen
         _stacktrace=sys.exc_info()[2])
       File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 398, in increment
         raise MaxRetryError(_pool, url, error or ResponseError(cause))
     urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='none', port=443): Max retries exceeded with url: /services/json/?method=auth.partnerLogin (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0xb5e04a50>: Failed to establish a new connection: [Errno -2] Name or service not known'))
     
     During handling of the above exception, another exception occurred:
     
     Traceback (most recent call last):
       File "/usr/local/bin/pydora", line 10, in <module>
         sys.exit(main())
       File "/usr/local/lib/python3.7/dist-packages/pydora/player.py", line 319, in main
         PlayerApp().run()
       File "/usr/local/lib/python3.7/dist-packages/pydora/player.py", line 292, in run
         self.client = self.get_client()
       File "/usr/local/lib/python3.7/dist-packages/pydora/player.py", line 105, in get_client
         return builder.build()
       File "/usr/local/lib/python3.7/dist-packages/pandora/clientbuilder.py", line 194, in build
         config["USER"]["USERNAME"], config["USER"]["PASSWORD"]
       File "/usr/local/lib/python3.7/dist-packages/pandora/client.py", line 64, in login
         return self._authenticate()
       File "/usr/local/lib/python3.7/dist-packages/pandora/client.py", line 67, in _authenticate
         self._partner_login()
       File "/usr/local/lib/python3.7/dist-packages/pandora/client.py", line 54, in _partner_login
         version=self.transport.API_VERSION,
       File "/usr/local/lib/python3.7/dist-packages/pandora/transport.py", line 51, in function
         return func(*args, **kwargs)
       File "/usr/local/lib/python3.7/dist-packages/pandora/transport.py", line 241, in __call__
         result = self._make_http_request(url, data, params)
       File "/usr/local/lib/python3.7/dist-packages/pandora/transport.py", line 192, in _make_http_request
         result = self._http.post(url, data=data, params=params)
       File "/usr/lib/python3/dist-packages/requests/sessions.py", line 581, in post
         return self.request('POST', url, data=data, json=json, **kwargs)
       File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
         resp = self.send(prep, **send_kwargs)
       File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
         r = adapter.send(request, **kwargs)
       File "/usr/lib/python3/dist-packages/requests/adapters.py", line 516, in send
         raise ConnectionError(e, request=request)
     requests.exceptions.ConnectionError: HTTPSConnectionPool(host='none', port=443): Max retries exceeded with url: /services/json/?method=auth.partnerLogin (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0xb5e04a50>: Failed to establish a new connection: [Errno -2] Name or service not known'))
    

Anything else we need to know?:

Environment: Raspbian buster

  • Pydora version: 2.0.1
  • Python version: 3.7.3
  • OS: Linux raspberrypi 5.10.63+ #1457 Tue Sep 28 11:24:51 BST 2021 armv6l GNU/Linux
  • Shell (if applicable):
  • Others:

Remove `py_release_tools` from `setup_requires` or provide wheels

Currently installing pydora from PyPI fails because py_release_tools pulls in mock which has a broken setup.cfg.
OTOH my music machine does not need the dev-dependencies. There are two (non-exclusive) ways out of this:

  • Provide wheels on PyPI. I won't ever have to evaluate setup.py
  • Make the dependency on py_release_tools optional by looking at sys.argv and decide based on that.

Thanks for considering.

PyDora pydora-configure configuration script error

What happened: I installed pydora and ran the pydora-configure function, but it gave me this error: Error loading config file. Unable to continue.
Screenshot 2021-09-01 175545

Environment:

  • Pydora version: 2.1.0
  • Python version: 3.7.8 64-bit
  • OS: Windows 10 64 bit

CERTIFICATE_VERIFY_FAILED error on login

Pandora changed the certificates for the Pandora One api_host (internal-tuner.pandora.com/services/json/) about a week ago:

ERROR    2015-11-12 12:00:40,096 [77037:PandoraBackend-8] mopidy_pandora.uri
  Error logging in to Pandora: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)
INFO     2015-11-12 12:00:40,096 [77037:MainThread] mopidy.commands

This issue has popped up on all of the other Pandora players as well (pithos/pithos#251, PromyLOPh/pianobar#555). Various workarounds have been suggested, from ignoring certificates to reverting to using curl.

PIP reports that I have certifi (2015.4.28) installed, if that is relevant. In the interim, relying on tuner.pandora.com/services/json/ still works but obviously won't have the high-quality Pandora One stream available.

Not sure how to address this in pydora at this stage...any ideas?

Instructions

So I followed the instructions. The app ran showed it was finding songs, but for some odd reason in VLC I don't know how to get it to play.

Error: pandora.errors.InvalidAuthToken: Invalid Auth Token

What happened:
Starting yesterday, I appear to be getting the Invalid Auth Token.

What you expected to happen:
No Error message

How to reproduce it (as minimally and precisely as possible):

  ksaye@home:~$ pip3 install pydora
  Collecting pydora
    Downloading pydora-2.2.0-py3-none-any.whl (33 kB)
  Collecting blowfish<1.0,>=0.6.1
    Downloading blowfish-0.6.1.tar.bz2 (27 kB)
  Requirement already satisfied: requests<3,>=2 in /usr/local/lib/python3.8/dist-packages (from pydora) (2.28.1)
  Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.8/dist-packages (from requests<3,>=2->pydora) (3.3)
  Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.8/dist-packages (from requests<3,>=2->pydora) (1.26.10)
  Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.8/dist-packages (from requests<3,>=2->pydora) (2022.6.15)
  Requirement already satisfied: charset-normalizer<3,>=2 in /usr/local/lib/python3.8/dist-packages (from requests<3,>=2->pydora) (2.1.0)
  Building wheels for collected packages: blowfish
    Building wheel for blowfish (setup.py) ... done
    Created wheel for blowfish: filename=blowfish-0.6.1-py3-none-any.whl size=28133 sha256=6510d404c9d6927a67d570f967a665e56510977198ea5c761def312d48fe8ff5
    Stored in directory: /mnt/disk2/home/ksaye/.cache/pip/wheels/67/5b/0b/b3129ff17820dc866bdf31db2dfdeede2cdf3395aa6627d105
  Successfully built blowfish
  Installing collected packages: blowfish, pydora
  Successfully installed blowfish-0.6.1 pydora-2.2.0
  ksaye@home:~$ pydora-configure
  Welcome to Pydora, let's configure a few things
  Pandora Username: [email protected]
  Pandora Password:
  ksaye@home:~$ pydora
  Using VLC
  Traceback (most recent call last):
    File "/home/ksaye/.local/bin/pydora", line 8, in <module>
      sys.exit(main())
    File "/home/ksaye/.local/lib/python3.8/site-packages/pydora/player.py", line 310, in main
      PlayerApp().run()
    File "/home/ksaye/.local/lib/python3.8/site-packages/pydora/player.py", line 283, in run
      self.client = self.get_client()
    File "/home/ksaye/.local/lib/python3.8/site-packages/pydora/player.py", line 100, in get_client
      return builder.build()
    File "/home/ksaye/.local/lib/python3.8/site-packages/pandora/clientbuilder.py", line 193, in build
      client.login(
    File "/home/ksaye/.local/lib/python3.8/site-packages/pandora/client.py", line 64, in login
      return self._authenticate()
    File "/home/ksaye/.local/lib/python3.8/site-packages/pandora/client.py", line 70, in _authenticate
      user = self.transport(
    File "/home/ksaye/.local/lib/python3.8/site-packages/pandora/transport.py", line 50, in function
      return func(*args, **kwargs)
    File "/home/ksaye/.local/lib/python3.8/site-packages/pandora/transport.py", line 245, in __call__
      return self._parse_response(result)
    File "/home/ksaye/.local/lib/python3.8/site-packages/pandora/transport.py", line 234, in _parse_response
      raise PandoraException.from_code(result["code"], result["message"])
  pandora.errors.InvalidAuthToken: Invalid Auth Token

Anything else we need to know?:

Environment:

  • Pydora version: 2.2.0
  • Python version: 3.8
  • OS: Ubuntu
  • Shell (if applicable): bash
  • Others:

Also reported here: pithos/pithos#701

Ads fail to register if tracking_tokens are missing

I've been encountering random issues with some advertisements not registering properly (see #37 at the Mopidy-Pandora project for stack trace details).

As best as I can tell, this happens if the advertisement does not contain any add tracking tokens (maybe one in every five ads being served up), causing APIClient.register_ad(station_id, tokens) to raise a ParameterMissing exception.

Pausing in pydora causes track skip on resume

When you pause a song in the pydora player and then resume it a few minutes later mplayer will play whatever is left in it's buffer and then skip to the next song. The fix for this may require implementing our own track buffering.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.