diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | LICENSE | 14 | ||||
-rw-r--r-- | Makefile | 153 | ||||
-rw-r--r-- | conf.py | 242 | ||||
-rw-r--r-- | index.rst | 24 | ||||
-rw-r--r-- | json/authentication.rst | 179 | ||||
-rw-r--r-- | json/bookmarks.rst | 157 | ||||
-rw-r--r-- | json/errorcodes.rst | 54 | ||||
-rw-r--r-- | json/index.rst | 79 | ||||
-rw-r--r-- | json/methods.rst | 42 | ||||
-rw-r--r-- | json/partners.rst | 71 | ||||
-rw-r--r-- | json/play.rst | 209 | ||||
-rw-r--r-- | json/stations.rst | 289 | ||||
-rw-r--r-- | make.bat | 190 |
14 files changed, 1705 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e81d4a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +_build +*.sw? @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+
+ Everyone is permitted to copy and distribute verbatim or modified
+ copies of this license document, and changing it is allowed as long
+ as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..16e1711 --- /dev/null +++ b/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PandoraAPIdocumentation.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PandoraAPIdocumentation.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/PandoraAPIdocumentation" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PandoraAPIdocumentation" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- +# +# Pandora API documentation documentation build configuration file, created by +# sphinx-quickstart on Mon Jun 30 21:53:24 2014. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Unofficial Pandora API' +copyright = u'' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '' +# The full version, including alpha/beta/rc tags. +release = '' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'PandoraAPIdocumentationdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'PandoraAPIdocumentation.tex', u'Pandora API documentation Documentation', + u'People', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'pandoraapidocumentation', u'Pandora API documentation Documentation', + [u'People'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'PandoraAPIdocumentation', u'Pandora API documentation Documentation', + u'People', 'PandoraAPIdocumentation', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' diff --git a/index.rst b/index.rst new file mode 100644 index 0000000..c7dcc78 --- /dev/null +++ b/index.rst @@ -0,0 +1,24 @@ +Unofficial Pandora API documentation +==================================== + +This documentation project replaces the Wiki_ hosted by wikia_, which got taken +down by Pandora_ (`read more`_). It aims to provide language-independent +documentation of Pandora’s `proprietary API`_. + +.. _Wiki: http://pan-do-ra-api.wikia.com/ +.. _wikia: http://www.wikia.com/ +.. _Pandora: http://www.pandora.com/ +.. _Read more: http://6xq.net/blog/2014/dmca/ +.. _proprietary API: http://developer.pandora.com/ + +The source code of this documentation is available at `github`_ or `here`_. +Suggestions and patches are welcome. + +.. _github: http://github.com/promyloph/pandora-apidoc/ +.. _here: http://6xq.net/git/pandora-apidoc.git + +.. toctree:: + :maxdepth: 2 + + json/index + diff --git a/json/authentication.rst b/json/authentication.rst new file mode 100644 index 0000000..67f5879 --- /dev/null +++ b/json/authentication.rst @@ -0,0 +1,179 @@ +.. _authentication: + +Authentication +============== + +Authentication is divided into two steps: Partner and user login. + +.. _auth-partnerLogin: + +Partner login +------------- + +:Method: auth.partnerLogin + +This request additionally serves as API version validation, time +synchronization and endpoint detection and *must* be sent over a TLS-encrypted +link. The POST body however is :ref:`not encrypted <bodyenc>`. + +.. csv-table:: + :header: Name,Type,Description + + username,string,See :ref:`partners` + password,string,See :ref:`partners` + deviceModel,string,See :ref:`partners` + version,string,"Current version number, “5”." + includeUrls,boolean, + returnDeviceType,boolean, + returnUpdatePromptVersions,boolean, + +.. code:: json + + { + "username": "pandora one", + "password": "TVCKIBGS9AO9TSYLNNFUML0743LH82D", + "deviceModel": "D01", + "version": "5" + } + +syncTime is used to calculate the server time, see :ref:`synctime`. partnerId +and authToken are required to procceed with user authentication. + +================ ======= =========== +Name Type Description +================ ======= =========== +syncTime string Hex-encoded, encrypted server time. Decrypt with password from :ref:`partners` and skip first four bytes of garbage. +partnerAuthToken string +partnerId string +================ ======= =========== + +.. code:: json + + { + "stat": "ok", + "result": { + "syncTime": "6923e263a8c3ac690646146b50065f43", + "deviceProperties": { + "videoAdRefreshInterval": 900, + "videoAdUniqueInterval": 0, + "adRefreshInterval": 5, + "videoAdStartInterval": 180 + }, + "partnerAuthToken": "VAzrFQTtsy3BQ3K+3iqFi0WF5HA63B1nFA", + "partnerId": "42", + "stationSkipUnit": "hour", + "urls": { + "autoComplete": "http://autocomplete.pandora.com/search" + }, + "stationSkipLimit": 6 + } + } + +==== ============ +Code Description +==== ============ +1002 INVALID_PARTNER_LOGIN. Invalid partner credentials. +==== ============ + +.. _auth-userLogin: + +User login +---------- + +:Method: auth.userLogin + +This request *must* be sent over a TLS-encrypted link. It authenticates the +Pandora user by sending his username, usually his email address, and password +as well as the partnerAuthToken obtained by :ref:`auth-partnerLogin`. + +.. TODO: Describe device login. + +Additional response data can be requested by setting flags listed below. + +.. csv-table:: + :header: Name,Type,Description + + loginType ,string ,“user” + username ,string ,Username + password ,string ,User’s password + partnerAuthToken ,string ,Partner token obtained by :ref:`auth-partnerLogin` + returnGenreStations ,boolean ,(optional) + returnCapped ,boolean ,return isCapped parameter (optional) + includePandoraOneInfo,boolean,(optional) + includeDemographics,boolean,(optional) + includeAdAttributes,boolean,(optional) + returnStationList,boolean,"Return station list, see :ref:`user-getStationList` (optional)" + includeStationArtUrl,boolean,(optional) + includeStationSeeds,boolean,(optional) + includeShuffleInsteadOfQuickMix,boolean,(optional) + stationArtSize,string,W130H130(optional) + returnCollectTrackLifetimeStats,boolean,(optional) + returnIsSubscriber,boolean,(optional) + xplatformAdCapable,boolean,(optional) + complimentarySponsorSupported,boolean,(optional) + includeSubscriptionExpiration,boolean,(optional) + returnHasUsedTrial,boolean,(optional) + returnUserstate,boolean,(optional) + includeAccountMessage,boolean,(optional) + includeUserWebname,boolean,(optional) + includeListeningHours,boolean,(optional) + includeFacebook,boolean,(optional) + includeTwitter,boolean,(optional) + includeDailySkipLimit,boolean,(optional) + includeSkipDelay,boolean,(optional) + includeGoogleplay,boolean,(optional) + includeShowUserRecommendations,boolean,(optional) + includeAdvertiserAttributes,boolean,(optional) + + +.. code:: json + + { + "loginType": "user", + "username": "user@example.com", + "password": "example", + "partnerAuthToken": "VAzrFQTtsy3BQ3K+3iqFi0WF5HA63B1nFA", + "includePandoraOneInfo":true, + "includeAdAttributes":true, + "includeSubscriptionExpiration":true, + "includeStationArtUrl":true, + "returnStationList":true, + "returnGenreStations":true, + "syncTime": 1335777573 + } + +The returned userAuthToken is used to authenticate access to other API methods. + +.. csv-table:: + :header: Name ,Type ,Description + + isCapped ,boolean , + userAuthToken,string, + +.. code:: json + + { + "stat": "ok", + "result": { + "stationCreationAdUrl": "http://ad.doubleclick.net/adx/pand.android/prod.createstation;ag=112;gnd=1;zip=23950;genre=0;model=;app=;OS=;dma=560;clean=0;logon=__LOGON__;tile=1;msa=115;st=VA;co=51117;et=0;mc=0;aa=0;hisp=0;hhi=0;u=l*2jedvn446s7ce!ag*112!gnd*1!zip*23950!dma*560!clean*0!logon*__LOGON__!msa*115!st*VA!co*51117!et*0!mc*0!aa*0!hisp*0!hhi*0!genre*0;sz=320x50;ord=__CACHEBUST__", + "hasAudioAds": true, + "splashScreenAdUrl": "http://ad.doubleclick.net/pfadx/pand.android/prod.welcome;ag=112;gnd=1;zip=23950;model=;app=;OS=;dma=560;clean=0;hours=1;msa=115;st=VA;co=51117;et=0;mc=0;aa=0;hisp=0;hhi=0;u=l*op4jfgdxmddjk!ag*112!gnd*1!zip*23950!dma*560!clean*0!msa*115!st*VA!co*51117!et*0!mc*0!aa*0!hisp*0!hhi*0!hours*1;sz=320x50;ord=__CACHEBUST__", + "videoAdUrl": "http://ad.doubleclick.net/pfadx/pand.android/prod.nowplaying;ag=112;gnd=1;zip=23950;dma=560;clean=0;hours=1;app=;index=__INDEX__;msa=115;st=VA;co=51117;et=0;mc=0;aa=0;hisp=0;hhi=0;u=l*2jedvn446s7ce!ag*112!gnd*1!zip*23950!dma*560!clean*0!index*__INDEX__!msa*115!st*VA!co*51117!et*0!mc*0!aa*0!hisp*0!hhi*0!hours*1;sz=442x188;ord=__CACHEBUST__", + "username": "user@example.com", + "canListen": true, + "nowPlayingAdUrl": "http://ad.doubleclick.net/pfadx/pand.android/prod.nowplaying;ag=112;gnd=1;zip=23950;genre=0;station={4};model=;app=;OS=;dma=560;clean=0;hours=1;artist=;interaction=__INTERACTION__;index=__INDEX__;newUser=__AFTERREG__;logon=__LOGON__;msa=115;st=VA;co=51117;et=0;mc=0;aa=0;hisp=0;hhi=0;u=l*op4jfgdxmddjk!ag*112!gnd*1!zip*23950!station*{4}!dma*560!clean*0!index*__INDEX__!newUser*__AFTERREG__!logon*__LOGON__!msa*115!st*VA!co*51117!et*0!mc*0!aa*0!hisp*0!hhi*0!genre*0!interaction*__INTERACTION__!hours*1;sz=320x50;ord=__CACHEBUST__", + "userId": "272772589", + "listeningTimeoutMinutes": "180", + "maxStationsAllowed": 100, + "listeningTimeoutAlertMsgUri": "/mobile/still_listening.vm", + "userProfileUrl": "https://www.pandora.com/login?auth_token=XXX&target=%2Fpeople%2FXXX", + "minimumAdRefreshInterval": 5, + "userAuthToken": "XXX" + } + } + +.. csv-table:: + :header: Code ,Description + + 1002,Wrong user credentials. + diff --git a/json/bookmarks.rst b/json/bookmarks.rst new file mode 100644 index 0000000..1d826bb --- /dev/null +++ b/json/bookmarks.rst @@ -0,0 +1,157 @@ +Bookmarks +========= + +Users can bookmark artists or songs. + +.. _user.getBookmarks: + +Retrieve bookmarks +------------------ + +:Method: user.getBookmarks + +The request has no parameters. + +.. code:: json + + { + "stat":"ok", + "result": { + "artists": [ + { + "musicToken": "R130360", + "artistName": "Cannabich, Christian", + "artUrl": "http://cont-sv5-2.pandora.com/images/public/amz/5/2/9/7/095115137925_500W_488H.jpg", + "bookmarkToken": "80982345262345234", + "dateCreated": { + "nanos": 300000000, + "seconds": 22, + "year": 112, + "month": 4, + "hours": 11, + "time": 1350566223422, + "date": 23, + "minutes": 01, + "day": 2, + "timezoneOffset": 720 + } + } + ], + "songs": [ + { + "sampleUrl": "http://www.pandora.com/favorites/getSample.jsp?token=32458973245b90287345d0234fc34f8b&allowExplicit=true", + "sampleGain": "-7.87", + "albumName": "Symphony In G Major", + "artistName": "Cannabich, Christian", + "musicToken": "S2894329", + "dateCreated": { + "nanos": 300000000, + "seconds": 22, + "year": 112, + "month": 4, + "hours": 11, + "time": 1350566223422, + "date": 23, + "minutes": 01, + "day": 2, + "timezoneOffset": 720 + }, + "artUrl": "http://cont-sv5-2.pandora.com/images/public/amz/5/2/9/7/095115137925_500W_488H.jpg", + "bookmarkToken": "290832123432459854", + "songName": "London Mozart Players, Christian Cannabich: Symphonies" + } + ] + } + + } + +.. _bookmark.addArtistBookmark: + +Add artist bookmark +------------------- + +:Method: bookmark.addArtistBookmark + +.. csv-table:: + :header: Name ,Type ,Description + + trackToken,string, + +.. code:: json + + { + "trackToken": "f17ff6c86c11743fc890808e1a1dd6ff5b1dca1a2e260f7d998ba6e7786dd9941c5dd4b345a1008e86862353da1e6cdc78172b4199240c76", + "userAuthToken": "XXX", + "syncTime": 1338210690 + } + +.. code:: json + + { + "stat": "ok", + "result": { + "artistName": "Wallis Bird", + "dateCreated": { + "date": 2, + "day": 3, + "hours": 7, + "minutes": 6, + "month": 6, + "seconds": 13, + "time": 1404309973468, + "timezoneOffset": 420, + "year": 114 + }, + "bookmarkToken": "49854851068341741", + "artUrl": "http://cont-dc6-2.pandora.com/images/public/amg/portrait/pic200/drP900/P998/P99805K1QKS.jpg", + "musicToken": "R278544" + } + } + +.. _bookmark.addSongBookmark: + +Add song bookmark +----------------- + +:Method: bookmark.addSongBookmark + +.. csv-table:: + :header: Name ,Type ,Description + + trackToken ,string , + +.. code:: json + + { + "trackToken": "f17ff6c86c11743fc890808e1a1dd6ff5b1dca1a2e260f7d998ba6e7786dd9941c5dd4b345a1008e86862353da1e6cdc78172b4199240c76", + "userAuthToken": "XXX", + "syncTime": 1338210690 + } + +.. code:: json + + { + "stat": "ok", + "result": { + "sampleGain": "1.96", + "musicToken": "S1143982", + "bookmarkToken": "200207779061968365", + "sampleUrl": "http://www.pandora.com/favorites/getSample.jsp?token=a74b4f7551e3e174425ba2910f7abf8b&allowExplicit=true", + "albumName": "The 5th Exotic", + "songName": "The 5th Exotic", + "artUrl": "http://cont-sjl-1.pandora.com/images/public/amz/9/4/5/2/800002549_500W_500H.jpg", + "dateCreated": { + "date": 28, + "day": 1, + "hours": 6, + "minutes": 11, + "month": 4, + "seconds": 31, + "time": 1338210691404, + "timezoneOffset": 420, + "year": 112 + }, + "artistName": "Quantic" + } + } + diff --git a/json/errorcodes.rst b/json/errorcodes.rst new file mode 100644 index 0000000..edd14bd --- /dev/null +++ b/json/errorcodes.rst @@ -0,0 +1,54 @@ +List of error codes +=================== + +These error codes can be returned by all methods: + +==== ============ +Code Description +==== ============ +0 Internal error. It can denote that your account has been temporarily blocked due to having too frequent station.getPlaylist calls. +1 MAINTENANCE_MODE +2 URL_PARAM_MISSING_METHOD +3 URL_PARAM_MISSING_AUTH_TOKEN +4 URL_PARAM_MISSING_PARTNER_ID +5 URL_PARAM_MISSING_USER_ID +6 SECURE_PROTOCOL_REQUIRED +7 CERTIFICATE_REQUIRED +8 PARAMETER_TYPE_MISMATCH +9 PARAMETER_MISSING +10 PARAMETER_VALUE_INVALID +11 API_VERSION_NOT_SUPPORTED +12 LICENSING_RESTRICTIONS. Pandora not available in this country. +13 INSUFFICIENT_CONNECTIVITY. Bad sync time? +14 Unknown method name? +15 Wrong protocol (http/https)? +1000 READ_ONLY_MODE +1001 INVALID_AUTH_TOKEN. Occurs once a user auth token expires. +1002 INVALID_PARTNER_LOGIN. auth.partnerLogin auth.userLogin. Can also occur for a user login. +1003 LISTENER_NOT_AUTHORIZED station.getPlaylist Pandora One Subscription or Trial Expired. Possibly account suspended? +1004 USER_NOT_AUTHORIZED User not authorized to perform action +1005 MAX_STATIONS_REACHED Station limit reached +1006 STATION_DOES_NOT_EXIST Station does not exist +1007 COMPLIMENTARY_PERIOD_ALREADY_IN_USE +1008 CALL_NOT_ALLOWED station.addFeedback Returned when attempting to add feedback to shared station +1009 DEVICE_NOT_FOUND +1010 PARTNER_NOT_AUTHORIZED +1011 INVALID_USERNAME +1012 INVALID_PASSWORD +1013 USERNAME_ALREADY_EXISTS +1014 DEVICE_ALREADY_ASSOCIATED_TO_ACCOUNT +1015 UPGRADE_DEVICE_MODEL_INVALID +1018 EXPLICIT_PIN_INCORRECT +1020 EXPLICIT_PIN_MALFORMED +1023 DEVICE_MODEL_INVALID +1024 ZIP_CODE_INVALID +1025 BIRTH_YEAR_INVALID +1026 BIRTH_YEAR_TOO_YOUNG +1027 INVALID_COUNTRY_CODE +1027 INVALID_GENDER +1034 DEVICE_DISABLED +1035 DAILY_TRIAL_LIMIT_REACHED +1036 INVALID_SPONSOR +1037 USER_ALREADY_USED_TRIAL +==== ============ + diff --git a/json/index.rst b/json/index.rst new file mode 100644 index 0000000..48edc1e --- /dev/null +++ b/json/index.rst @@ -0,0 +1,79 @@ +JSON API v5 +=========== + +The current JSON API version is 5. Two different endpoints are available: + +- http://tuner.pandora.com/services/json/ +- https://tuner.pandora.com/services/json/ + +- http://internal-tuner.pandora.com/services/json/ +- https://internal-tuner.pandora.com/services/json/ + +.. _bodyenc: + +Unless noted otherwise JSON-encoded requests sent by the client within the HTTP +POST body are encrypted using Blowfish ECB and converted to hexadecimal +notation. + +These URL parameters must be appended to the endpoint above if available: + +========== =========== +Name Description +========== =========== +method Method name +auth_token User auth token if available, partner auth token or empty if neither is known yet. +partner_id Partner id obtained by :ref:`auth-partnerLogin` or empty +user_id User id as obtained by :ref:`auth-userLogin` or empty +========== =========== + +For instance when calling :ref:`auth-userLogin` two parameters are known: +method and partner_id. The URL in this case would be +``http://tuner.pandora.com/services/json/?method=auth.userLogin&partner_id=123``. +Make sure you URL encode the parameter’s values. + +The following values must be present in every JSON request object (if available): + +.. _synctime: + +============= ====== =========== +Name Type Description +============= ====== =========== +userAuthToken string User auth token, see :ref:`auth-userLogin` +syncTime int Synchonized time. Calculation: current time + (time of :ref:`auth-partnerLogin` request – syncTime from :ref:`auth-partnerLogin` response). This is a protection against replay-attacks. +============= ====== =========== + +Every response includes the key ``stat`` which indicates success (``ok``) or +failure (``fail``) of the resquest. Failed requests contain an error code and +message whereas successful requests carry actual response data in the key +``result``: + +.. code:: json + + { + "stat": "ok", + "result": { + } + } + +.. code:: json + + { + "stat": "fail", + "message": "An unexpected error occurred", + "code": 1008 + } + +.. toctree:: + + authentication + stations + play + bookmarks + methods + errorcodes + +.. toctree:: + :hidden: + + partners + diff --git a/json/methods.rst b/json/methods.rst new file mode 100644 index 0000000..f5b7cf5 --- /dev/null +++ b/json/methods.rst @@ -0,0 +1,42 @@ +.. _methods: + +List of methods +=============== + +- :ref:`auth.getAdMetadata <auth-getAdMetadata>` +- :ref:`auth.partnerLogin <auth-partnerLogin>` +- :ref:`auth.userLogin <auth-userLogin>` +- :ref:`bookmark.addArtistBookmark <bookmark-addArtistBookmark>` +- :ref:`bookmark.addSongBookmark <bookmark-addSongBookmark>` +- :ref:`bookmark.deleteArtistBookmark <bookmark-deleteArtistBookmark>` +- :ref:`bookmark.deleteSongBookmark <bookmark-deleteSongBookmark>` +- :ref:`music.search <music-search>` +- :ref:`music.shareMusic <music-shareMusic>` +- :ref:`station.addFeedback <station-addFeedback>` +- :ref:`station.addMusic <station-addMusic>` +- :ref:`station.createStation <station-createStation>` +- :ref:`station.deleteFeedback <station-deleteFeedback>` +- :ref:`station.deleteMusic <station-deleteMusic>` +- :ref:`station.deleteStation <station-deleteStation>` +- :ref:`station.getGenreStations <station-getGenreStations>` +- :ref:`station.getGenreStationsChecksum <station-getGenreStationsChecksum>` +- :ref:`station.getPlaylist <station-getPlaylist>` +- :ref:`station.getStation <station-getStation>` +- :ref:`station.shareStation <station-shareStation>` +- :ref:`station.renameStation <station-renameStation>` +- :ref:`station.transformSharedStation <station-transformSharedStation>` +- :ref:`test.echo <test-echo>` +- :ref:`track.explainTrack <track-explainTrack>` +- :ref:`user.acknowledgeSubscriptionExpiration <user-acknowledgeSubscriptionExpiration>` +- :ref:`user.associateDevice <user-associateDevice>` +- :ref:`user.canSubscribe <user-canSubscribe>` +- :ref:`user.createUser <user-createUser>` +- :ref:`user.emailPassword <user-emailPassword>` +- :ref:`user.getBookmarks <user-getBookmarks>` +- :ref:`user.getStationList <user-getStationList>` +- :ref:`user.getStationListChecksum <user-getStationListChecksum>` +- :ref:`user.purchaseItunesSubscription <user-purchaseItunesSubscription>` +- :ref:`user.setQuickMix <user-setQuickMix>` +- :ref:`user.sleepSong <user-sleepSong>` +- :ref:`user.startComplimentaryTrial <user-startComplimentaryTrial>` + diff --git a/json/partners.rst b/json/partners.rst new file mode 100644 index 0000000..a759d41 --- /dev/null +++ b/json/partners.rst @@ -0,0 +1,71 @@ +.. _partners: + +Partner passwords +================= + +Passwords depend on the API entry point used. + +tuner.pandora.com +----------------- + +Android +^^^^^^^ + +:username: android +:password: ``AC7IBG09A3DTSYM4R41UJWL07VLN8JI7`` +:deviceId: android-generic +:decrpyt password: ``R=U!LH$O2B#`` +:encrypt password: ``6#26FRL$ZWD`` + +iOS +^^^ + +:username: iphone +:password: ``P2E4FC0EAD3*878N92B2CDp34I0B1@388137C`` +:deviceId: IP01 +:Decrypt password: ``20zE1E47BE57$51`` +:Encrypt password: ``721^26xE22776`` + +Palm +^^^^ + +:Username: palm +:Password: ``IUC7IBG09A3JTSYM4N11UJWL07VLH8JP0`` +:deviceId: pre +:decrypt password: ``E#U$MY$O2B=`` +:encrypt password: ``%526CBL$ZU3`` + +Windows Mobile +^^^^^^^^^^^^^^ + +:Username: winmo +:Password: ``ED227E10a628EB0E8Pm825Dw7114AC39`` +:deviceId: VERIZON_MOTOQ9C +:decrypt password: ``7D671jt0C5E5d251`` +:Encrypt password: ``v93C8C2s12E0EBD`` + +internal-tuner.pandora.com +-------------------------- + +Desktop (AIR) Client +^^^^^^^^^^^^^^^^^^^^ + +:Username: pandora one +:Password: ``TVCKIBGS9AO9TSYLNNFUML0743LH82D`` +:deviceId: D01 +:Decrypt password: ``U#IO$RZPAB%VX2`` +:Encrypt password: ``2%3WCL*JU$MP]4`` + +.. note:: + + Requires a Pandora One account. Fails at station.getPlaylist without one. + +Vista Widget +^^^^^^^^^^^^ + +:Username: windowsgadget +:Password: ``EVCCIBGS9AOJTSYMNNFUML07VLH8JYP0`` +:deviceId: WG01 +:Decrypt password: ``E#IO$MYZOAB%FVR2`` +:Encrypt password: ``%22CML*ZU$8YXP[1`` + diff --git a/json/play.rst b/json/play.rst new file mode 100644 index 0000000..4766f2f --- /dev/null +++ b/json/play.rst @@ -0,0 +1,209 @@ +.. _play: + +Play +==== + +.. _station-getPlaylist: + +Retrieve playlist +----------------- + +:Method: station.getPlaylist + +This method *must* be sent over a TLS-encrypted connection. + +.. csv-table:: + :header: Name ,Type ,Description + + stationToken ,string ,station token from :ref:`user-getStationList` + additionalAudioUrl,string,Comma separated list of additional audio formats to return. (optional) + stationIsStarting,boolean,(optional) + includeTrackLength,boolean,(optional) + includeAudioToken,boolean,(optional) + xplatformAdCapable,boolean,(optional) + includeAudioReceiptUrl,boolean,(optional) + includeBackstageAdUrl,boolean,(optional) + includeSharingAdUrl,boolean,(optional) + includeSocialAdUrl,boolean,(optional) + includeCompetitiveSepIndicator,boolean,(optional) + includeCompletePlaylist,boolean,(optional) + includeTrackOptions,boolean,(optional) + audioAdPodCapable,boolean,(optional) + +Valid values for additionalAudioUrl are: + +- HTTP_40_AAC_MONO +- HTTP_64_AAC +- HTTP_32_AACPLUS +- HTTP_64_AACPLUS +- HTTP_24_AACPLUS_ADTS +- HTTP_32_AACPLUS_ADTS +- HTTP_64_AACPLUS_ADTS +- HTTP_128_MP3 +- HTTP_32_WMA + +Usually a playlist contains four tracks. + +.. code:: json + + { + "userAuthToken": "XXX", + "additionalAudioUrl": "HTTP_32_AACPLUS_ADTS,HTTP_64_AACPLUS_ADTS", + "syncTime": 1335841463, + "stationToken": "121193154444133035" + } + +.. csv-table:: + :header: Name ,Type ,Description + + items.additionalAudioUrl ,array/string ,List of additional audio urls in the requested order or single string if only one format was requested + items.songRating ,int , "1 if song was given a thumbs up, 0 if song was not rated yet" + items.audioUrlMap ,object ,Song audio format and bitrates returned differ based on what partner credentials are used. + +.. code:: json + + { + "stat": "ok", + "result": { + "items": [{ + "trackToken": "40b892bc5376e695c2e5c2b347227b85af2761b6aa417f736d9a79319b8f4cb97c9695a5f9a9a32aa2abaed43571235c", + "artistName": "Cannabich, Christian", + "albumName": "London Mozart Players, Christian Cannabich: Symphonies", + "amazonAlbumUrl": "http://www.amazon.com/dp/B000GW8ATU/?tag=wwwpandoracom-20", + "songExplorerUrl": "http://www.pandora.com/xml/music/song/london-mozart-players/christian-cannabich-symphonies/2-andantino?explicit=false", + "albumArtUrl": "http://cont-sv5-2.pandora.com/images/public/amz/5/2/9/7/095115137925_500W_488H.jpg", + "artistDetailUrl": "http://www.pandora.com/christian-cannabich?...", + "audioUrlMap": { + "highQuality": { + "bitrate": "64", + "encoding": "aacplus", + "audioUrl": "http://audio-sjl-t1-2.pandora.com/access/166132182435087962.mp4?...", + "protocol": "http" + }, + "mediumQuality": { + "bitrate": "64", + "encoding": "aacplus", + "audioUrl": "http://t1-2.cdn.pandora.com/access/4127124196771074419.mp4?...", + "protocol": "http" + }, + "lowQuality": { + "bitrate": "32", + "encoding": "aacplus", + "audioUrl": "http://audio-sv5-t1-1.pandora.com/access/3464788359714661029.mp4?...", + "protocol": "http" + } + }, + "itunesSongUrl": "http://click.linksynergy.com/fs-bin/stat?...", + "additionalAudioUrl": [ + "http://t1-2.cdn.pandora.com/access/6705986462049243054.mp4?...", + "http://audio-sjl-t1-1.pandora.com/access/2473529637452270302.mp4?..." + ], + "amazonAlbumAsin": "B000GW8ATU", + "amazonAlbumDigitalAsin": "B003H37NN4", + "artistExplorerUrl": "http://www.pandora.com/xml/music/composer/christian-cannabich?explicit=false", + "songName": "Symphony In G Major", + "albumDetailUrl": "http://www.pandora.com/london-mozart-players/christian-cannabich-symphonies?...", + "songDetailUrl": "http://www.pandora.com/london-mozart-players/christian-cannabich-symphonies/2-andantino?...", + "stationId": "121193154444133035", + "songRating": 0, + "trackGain": "10.09", + "albumExplorerUrl": "http://www.pandora.com/xml/music/album/london-mozart-players/christian-cannabich-symphonies?explicit=false", + "allowFeedback": true, + "amazonSongDigitalAsin": "B003H39AGW", + "nowPlayingStationAdUrl": "http://ad.doubleclick.net/pfadx/pand.android/prod.nowplaying..." + }, { + "adToken": "121193154444133035-none" + }, + ] + } + } + +.. _station-addFeedback: + +Rate track +---------- + +:Method: station.addFeedback + +Songs can be “loved” or “banned”. Both influence the music played on the +station. Banned songs are never played again on this particular station. + +.. csv-table:: + :header: Name,Type,Description + + stationToken,string, + trackToken,string, + isPositive,boolean, + + +.. _user-sleepSong: + +Temporarily ban track +--------------------- + +:Method: user.sleepSong + +A song can be banned *from all stations* temporarily (one month). + +.. csv-table:: + :header: Name ,Type ,Description + + trackToken ,string ,See :ref:`station-getPlaylist` + +.. code:: json + + { + "trackToken": "d6aa37c60833f12150c4e2ba172c46f24590ebc49df948b6fb7117314c41c8e7d4faee3568884468d9509db2ab998dafdbc4093baf8c38ef", + "userAuthToken": "XXX", + "syncTime": 1336386838 + } + +Nothing is returned in the response. + +.. _track-explainTrack: + +Explain track choice +-------------------- + +:Method: track.explainTrack + +Get (incomplete) list of attributes assigned to song by Music Genome Project. + +.. csv-table:: + :header: Name ,Type ,Description + + trackToken ,string ,See :ref:`station-getPlaylist` + +.. code:: json + + { + "trackToken": "94f36e09e341780c2ee7ebbb3581a55c4f2066dbaa60f2ee253ede5bc407fbd3c4f6db7ed00f92312437e020e0bf0e05d2924742c2ccece2", + "userAuthToken": "XXX", + "syncTime": 1336675993 + } + +The request returns a list of attributes. Note that the last item is not an +actual attribute. + +.. csv-table:: + :header: Name ,Type ,Description + + explanations ,array , + +.. code:: json + + { + "stat": "ok", + "result": { + "explanations": [{ + "focusTraitName": "trance roots", + "focusTraitId": "F7524" + }, + { + "focusTraitName": "many other similarities identified in the Music Genome Project", + "focusTraitId": "F4797" + }] + } + } + + diff --git a/json/stations.rst b/json/stations.rst new file mode 100644 index 0000000..b8e7821 --- /dev/null +++ b/json/stations.rst @@ -0,0 +1,289 @@ +.. _stations: + +Stations +======== + +A *station* is a collection of one or more user-supplied *seeds*. Artists or +tracks can be used as seed. Based on the seeds Pandora decides which music to +play. + +.. _user-getStationList: + +Retrieve station list +--------------------- + +:Method: user.getStationList + +.. csv-table:: + :header: Name ,Type ,Description + + includeStationArtUrl ,boolean ,Includes "artUrl" field in result (optional) + stationArtSize,string,“W130H130” + includeAdAttributes,boolean,(optional) + includeStationSeeds,boolean,(optional) + includeShuffleInsteadOfQuickMix,boolean,(optional) + includeRecommendations,boolean,(optional) + includeExplanations,boolean,(optional) + +.. code:: json + + { + "userAuthToken": "XXX", + "syncTime": XXX + } + +Currently stationId and stationToken are the same. + +QuickMix stations additionally include a list of station ids +(quickMixStationIds) that are currently selected for the mix. + +.. csv-table:: + :header: Name ,Type ,Description + + stations.stationId,string, + stations.stationName,string, + checksum,string, + +.. code:: json + + { + "stat":"ok", + "result":{ + "stations":[ + { + "suppressVideoAds":true, + "isQuickMix":true, + "stationId":"3914377363925265", + "stationDetailUrl":"https://www.pandora.com/login?target=%2Fstations%2Fa61985110ea3d6c6c8d8a9c038588b26425ba2910f7abf8b", + "isShared":false, + "dateCreated":{ + "date":8, + "day":4, + "hours":22, + "minutes":44, + "month":10, + "nanos":241000000, + "seconds":46, + "time":1194590686241, + "timezoneOffset":480, + "year":107 + }, + "stationToken":"3914377363925265", + "stationName":"QuickMix", + "stationSharingUrl":"https://www.pandora.com/login?target=%2Fshare%2Fstation%2Fa61985110ea3d6c6c8d8a9c038588b26425ba2910f7abf8b", + "requiresCleanAds":true, + "allowRename":false, + "allowAddMusic":false, + "quickMixStationIds":[ + "339646069607180561", + "339644480469281041" + ], + "allowDelete":false + } + ], + "checksum":"99776ddd31ad798895578593e78e3691" + } + } + +.. _user-getStationListChecksum: + +Check station list for modifications +------------------------------------ + +:Method: user.getStationListChecksum + +To check if the station list was modified by another client the checksum can be +fetched. No parameters are required for this request. + +The response contains the new checksum. + +.. csv-table:: + :header: Name,Type,Description + + checksum,string, + +.. code:: json + + { + "stat":"ok", + "result":{ + "checksum":"99776ddd31ad798895578593e78e3691" + } + } + +Add new station +--------------- + +New stations can be created by searching for an artist/song or using a track +from a playlist. + +.. _music-search: + +Search +^^^^^^ + +:Method: music.search + +This is a free text search that matches artist and track names. + +.. csv-table:: + :header: Name ,Type ,Description + + searchText ,string ,Artist name or track title + +.. code:: json + + { + "searchText": "encore", + "userAuthToken": "XXX", + "syncTime": 1335869287 + } + +Matching songs and artists are returned in two separate list. + +.. csv-table:: + :header: Name ,Type ,Description + + songs.musicToken and artists.musicToken ,string , + +.. code:: json + + { + "stat": "ok", + "result": { + "nearMatchesAvailable": true, + "explanation": "", + "songs": [{ + "artistName": "Jason DeRulo", + "musicToken": "S1508963", + "songName": "Encore", + "score": 100 + }], + "artists": [{ + "artistName": "Encore", + "musicToken": "R175304", + "likelyMatch": false, + "score": 100 + }] + } + } + +.. _station-createStation: + +Create +^^^^^^ + +:Method: station.createStation + +Stations can either be created with a musicToken obtained by +:ref:`music-search` or trackToken from playlists (:ref:`station-getPlaylist`). +The latter needs a musicType to specify whether the track itself or its artist +should be used as seed. + +.. csv-table:: + :header: Name,Type,Description + + trackToken,string,See :ref:`station-getPlaylist` + musicType,string,“song” or “artist” + musicToken,string,See :ref:`music-search` + +.. _station-addMusic: + +Add seed +-------- + +:Method: station.addMusic + +:ref:`music-search` results can be used to add new seeds to an existing +station. + +.. csv-table:: + :header: Name,Type,Description + + stationToken,string,"Existing station, see :ref:`user-getStationList`" + musicToken,string,"See :ref:`music-search`" + +.. _station-renameStation: + +Rename station +-------------- + +:Method: station.renameStation + +.. csv-table:: + :header: Name,Type,Description + + stationToken,string,"Existing station, see :ref:`user-getStationList`" + stationName,string,New station name + +.. _station-deleteStation: + +Delete station +-------------- + +:Method: station.deleteStation + +.. csv-table:: + :header: Name,Type,Description + + stationToken,string,"Existing station, see :ref:`user-getStationList`" + +.. _station-getGenreStations: + +Predefined stations +------------------- + +:Method: station.getGenreStations + +Pandora provides a list of predefined stations (“genre stations”). The request +has no parameters. + +Each station belongs to one category, usually a genre name. stationToken can be +used as musicToken to create a new station with :ref:`station-createStation`. + +.. csv-table:: + :header: Name ,Type ,Description + + categories ,array ,List of categories + categories.stations ,array ,List of stations in category + categories.stations.stationToken,string,"Actually a musicToken, see :ref:`station-createStation`" + catogories.categoryName,string,Category name + +.. code:: json + + { + "stat": "ok", + "result": { + "categories": [{ + "stations": [{ + "stationToken": "G165", + "stationName": "90s Alternative ", + "stationId": "G165" + }], + "categoryName": "Alternative" + }] + } + } + +.. _user-setQuickMix: + +Modify QuickMix +--------------- + +:Method: user.setQuickMix + +.. csv-table:: + :header: Name ,Type ,Description + + quickMixStationIds ,array ,List of station id’s (strings) + +.. code:: json + + { + "quickMixStationIds": ["404958383414849005", "403387202773593581"], + "userAuthToken": "XXX", + "syncTime": 1338211186 + } + +The response contains no data. + diff --git a/make.bat b/make.bat new file mode 100644 index 0000000..95f36f4 --- /dev/null +++ b/make.bat @@ -0,0 +1,190 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^<target^>` where ^<target^> is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PandoraAPIdocumentation.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PandoraAPIdocumentation.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end |