Skip to content
This repository has been archived by the owner on Jan 22, 2022. It is now read-only.

Commit

Permalink
Merge branch 'release-2.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-weber committed Aug 1, 2013
2 parents 72e86e8 + 77cc786 commit 325ab63
Show file tree
Hide file tree
Showing 39 changed files with 3,427 additions and 2,025 deletions.
8 changes: 6 additions & 2 deletions .travis.yml
Expand Up @@ -15,7 +15,11 @@ branches:
only:
- develop
- master
- mobileclient
env:
global:
- GM_N="Travis-CI (gmusicapi)"
matrix:
- secure: "UAXrAYzrYRVFWSRldd5o9NrreexCsXdBna/kcKLlAQ8ygRahpqP7qXX8qiNU\nVhz0kdgBxgS84AEE3H/30o9v2IDWqmJCI5OqMfH1o5Pm+CelBt+8FHu3SMjm\nNvNcm/Vmip7WCSx7P2FfOf8HboSH/kVXuF0iPlOdozrTR1wPUq8="
- secure: "ILJA2Vhh3BRav2xLIMxS7/mE65AF15OA7UmDNdqE22qUoeEBL+ZduBQY8oAz\n+pJwHndP8bdD23Y9PLdC99qm1yZRV1x3yY1JclKzYnuwbeI1zYFHfGXTjtM+\n+rxxwo3ygEzrDnzIqKqP1+xKpKAGNqqLj0Pro8quyLhtKNUImMc="
# first is AA, second is not
- secure: "De4nJrP5O5uL0kWPYCDmTdsiDTHv7Vuvkv02XdwPOFoGG6sOL1svrJhL3Z+G\n3eMFy3DE69mybFf1gZEb9XdDY3LoOX0oAgkHigh+memrvgw/QzaJYN553kmF\n31ose52SFNmtFZH95cwQg1qkSZZsMXlmPxRq510MVl6SA7j6Pi4="
- secure: "aK3s024vOcybRx+Wq7/9tSd9XGJn0LBAuejTWxIiUul0I8sgt/ry7Pc8r0Gv\nXU3a9P/0LOUAYu1hS3/hH3u2oVIgXoEotrm2wC6r8N2R8xE7ZhYVl1Nf0fOK\ns0jy1ebIU+s/yHQmuboe61FT3lfiFRxQm6yJu5/G/D77O4HGuQQ="
11 changes: 11 additions & 0 deletions HISTORY.rst
Expand Up @@ -5,6 +5,17 @@ History

As of 1.0.0, `semantic versioning <http://semver.org/>`__ is used.

2.0.0
+++++++++
released 2013-08-01

- remove broken Webclient.{create_playlist, change_playlist, copy_playlist, search, change_playlist_name}
- add Mobileclient; this will slowly replace most of the Webclient, so prefer it when possible
- add support for streaming All Access songs
- add Webclient.get_registered_devices
- add a toggle to turn off validation per client
- raise an exception when a song dictionary is passed instead of an id

1.2.0
+++++
released 2013-05-16
Expand Down
23 changes: 13 additions & 10 deletions README.rst
Expand Up @@ -4,20 +4,19 @@ gmusicapi: an unofficial API for Google Play Music
gmusicapi allows control of
`Google Music <http://music.google.com>`__ with Python.


.. code-block:: python
from gmusicapi import Webclient
from gmusicapi import Mobileclient
api = Webclient()
api = Mobileclient()
api.login('user@gmail.com', 'my-password')
# => True
library = api.get_all_songs()
sweet_tracks = [track for track in library if track['artist'] == 'The Cat Empire']
playlist_id = api.create_playlist('Rad muzak')
api.change_playlist(playlist_id, sweet_tracks)
api.add_songs_to_playlist(playlist_id, sweet_tracks)
**gmusicapi is not supported nor endorsed by Google.**

Expand All @@ -27,10 +26,12 @@ That said, it's actively maintained, and used in a bunch of cool projects:
(`screenshot <http://i.imgur.com/Mwl0k.png>`__)
- Ryan McGuire's `GMusicFS <https://github.com/EnigmaCurry/GMusicFS>`__ - a FUSE
filesystem linked to your music
- David Dooling's `sync scripts for Banshee <https://github.com/ddgenome/banshee-helper-scripts>`__
- Kilian Lackhove's `Google Music support <https://github.com/crabmanX/google-music-resolver>`__
for http://www.tomahawk-player.org
- `@thebigmunch <https://github.com/thebigmunch>`__'s `syncing scripts <https://github.com/thebigmunch/gmusicapi-scripts>`__
- David Dooling's `sync scripts for Banshee <https://github.com/ddgenome/banshee-helper-scripts>`__
- Tom Graham's `playlist syncing tool <https://github.com/Tyris/m3uGoogleMusicSync>`__
- Karl Stoney's `sync tool <https://github.com/Stono/GoogleMusicSync>`__


Getting started
Expand All @@ -47,9 +48,11 @@ Status and updates
.. image:: https://travis-ci.org/simon-weber/Unofficial-Google-Music-API.png?branch=develop
:target: https://travis-ci.org/simon-weber/Unofficial-Google-Music-API

Version 1.2.0 fixes a bug that fixes uploader_id formatting from a mac address.
This change may cause another machine to be registered - you can safely remove the
old machine (it's the one without the version in the name).
The project is in the middle of a major change at the moment: the Webclient interface has
gotten horrible to maintain, so I'm working on
switching the the Android app api. This will provide easy All Access support and easier
maintainability going forward. At this point, prefer the Mobileclient to the Webclient
whenever possible.

For development updates, follow me on Twitter:
`@simonmweber <https://twitter.com/simonmweber>`__.
Expand Down
23 changes: 14 additions & 9 deletions docs/source/index.rst
Expand Up @@ -6,17 +6,17 @@ This library allows control of

.. code-block:: python
from gmusicapi import Webclient
api = Webclient()
from gmusicapi import Mobileclient
api = Mobileclient()
api.login('user@gmail.com', 'my-password')
# => True
library = api.get_all_songs()
sweet_tracks = [track for track in library if track['artist'] == 'The Cat Empire']
playlist_id = api.create_playlist('Rad muzak')
api.change_playlist(playlist_id, sweet_tracks)
api.add_songs_to_playlist(playlist_id, sweet_tracks)
**This project is not supported nor endorsed by Google.**
Expand All @@ -30,11 +30,16 @@ All major functionality is supported:

- Library management: list, create, delete, and modify songs and playlists

- Webclient streaming and single-song downloading
- Streaming and single-song downloading

- Music Manager uploading/scan-and-match and library downloading

Support for Google Play Music All Access features is currently under consideration.
Some features may be temporarily unavailable while the project
transitions from the Webclient interface to the Mobileclient.
New code should prefer the Mobileclient when possible, as Webclient
calls may break unexpectedly.

All Access support is in progress.

See `the changelog
<https://github.com/simon-weber/Unofficial-Google-Music-API/blob/develop/HISTORY.rst>`__
Expand All @@ -52,7 +57,7 @@ Using gmusicapi

Getting started
+++++++++++++++
The :ref:`usage section <usage>` has information on installing
The :ref:`usage section <usage>` has installation instructions
and some simple examples.

Api and data reference
Expand Down
14 changes: 10 additions & 4 deletions docs/source/reference/api.rst
Expand Up @@ -4,17 +4,23 @@
Client Interfaces
=================

gmusicapi has two main interfaces: one for the music.google.com webclient, and
gmusicapi currently has three main interfaces:
one for the music.google.com webclient,
one for the Android App, and
one for the Music Manager. The big differences are:

* :py:class:`Musicmanager` is used only for uploading, while :py:class:`Webclient`
supports everything but uploading.
* :py:class:`Webclient` requires a plaintext email and password to login, while
* :py:class:`Webclient` development has ceased, and the :py:class:`Mobileclient`
will take its place
* :py:class:`Musicmanager` is used only for uploading, while
:py:class:`Webclient`/:py:class:`Mobileclient`
support everything but uploading.
* :py:class:`Webclient`/:py:class:`Mobileclient` require a plaintext email and password to login, while
:py:class:`Musicmanager` uses `OAuth2
<https://developers.google.com/accounts/docs/OAuth2#installed>`__.

.. toctree::
:maxdepth: 2

webclient
mobileclient
musicmanager
55 changes: 55 additions & 0 deletions docs/source/reference/mobileclient.rst
@@ -0,0 +1,55 @@
.. _mobileclient:
.. currentmodule:: gmusicapi.clients

Mobileclient Interface
======================

.. autoclass:: Mobileclient

Setup and login
---------------
.. automethod:: Mobileclient.__init__
.. automethod:: Mobileclient.login
.. automethod:: Mobileclient.logout

Songs
-----
Songs are uniquely referred to within a library
with a 'song id' or 'track id' uuid.

.. automethod:: Mobileclient.get_all_songs
.. automethod:: Mobileclient.get_stream_url
.. automethod:: Mobileclient.delete_songs

Playlists
---------
Like songs, playlists have unique ids within a library.
However, their names do not need to be unique.

The tracks making up a playlist are referred to as
'playlist entries', and have unique entry ids within the
entire library (not just their containing playlist).

.. automethod:: Mobileclient.get_all_playlists
.. automethod:: Mobileclient.get_all_playlist_contents
.. automethod:: Mobileclient.create_playlist
.. automethod:: Mobileclient.delete_playlist
.. automethod:: Mobileclient.add_songs_to_playlist
.. automethod:: Mobileclient.remove_entries_from_playlist

All Access features
-------------------
All Access/store tracks also have track ids, but they are in a different
form from normal track ids.
``store_id.beginswith('T')`` always holds for these ids (and will not
for library track ids).

Adding a store track to a library will yield a normal song id.

All Access track ids can be used in most places that normal song ids can
(e.g. when for playlist addition or streaming).

.. automethod:: Mobileclient.search_all_access
.. automethod:: Mobileclient.add_aa_track
.. automethod:: Mobileclient.get_all_stations
.. automethod:: Mobileclient.get_artist_info
12 changes: 6 additions & 6 deletions docs/source/reference/webclient.rst
Expand Up @@ -17,12 +17,12 @@ Getting songs and playlists
.. automethod:: Webclient.get_all_songs
.. automethod:: Webclient.get_all_playlist_ids
.. automethod:: Webclient.get_playlist_songs
.. automethod:: Webclient.search

Song downloading and streaming
------------------------------
.. automethod:: Webclient.get_song_download_info
.. automethod:: Webclient.get_stream_url
.. automethod:: Webclient.get_stream_audio
.. automethod:: Webclient.get_stream_urls
.. automethod:: Webclient.report_incorrect_match

Song manipulation
Expand All @@ -33,13 +33,13 @@ Song manipulation

Playlist manipulation
---------------------
.. automethod:: Webclient.create_playlist
.. automethod:: Webclient.change_playlist_name
.. automethod:: Webclient.copy_playlist
.. automethod:: Webclient.delete_playlist

Playlist content manipulation
-----------------------------
.. automethod:: Webclient.change_playlist
.. automethod:: Webclient.add_songs_to_playlist
.. automethod:: Webclient.remove_songs_from_playlist

Other
-----
.. automethod:: Webclient.get_registered_devices
10 changes: 5 additions & 5 deletions docs/source/usage.rst
Expand Up @@ -30,14 +30,14 @@ If you need to install avconv from source, be sure to use
Quickstart
----------

If you're not going to be uploading music, use the :py:class:`Webclient`.
If you're not going to be uploading music, use the :py:class:`Mobileclient`.
This requires plaintext auth, so your code might look something like:

.. code-block:: python
from gmusicapi import Webclient
from gmusicapi import Mobileclient
api = Webclient()
api = Mobileclient()
logged_in = api.login('user@gmail.com', 'my-password')
# logged_in is True if login was successful
Expand All @@ -49,7 +49,7 @@ It uses `OAuth2
does not require plaintext credentials.

Instead, you'll need to authorize your account *once* before logging in.
The easiest way is to follow the prompts from:
The easiest way is to run:

.. code-block:: python
Expand All @@ -59,7 +59,7 @@ The easiest way is to follow the prompts from:
mm.perform_oauth()
If successful, this will save your credentials to disk.
Then, future runs will start with:
Then, future runs can start with:

.. code-block:: python
Expand Down
36 changes: 18 additions & 18 deletions example.py
Expand Up @@ -3,22 +3,22 @@

from getpass import getpass

from gmusicapi import Webclient
from gmusicapi import Mobileclient


def ask_for_credentials():
"""Make an instance of the api and attempts to login with it.
Return the authenticated api.
"""

# We're not going to upload anything, so the webclient is what we want.
api = Webclient()
# We're not going to upload anything, so the Mobileclient is what we want.
api = Mobileclient()

logged_in = False
attempts = 0

while not logged_in and attempts < 3:
email = raw_input("Email: ")
email = raw_input('Email: ')
password = getpass()

logged_in = api.login(email, password)
Expand All @@ -36,56 +36,56 @@ def demonstrate():
print "Sorry, those credentials weren't accepted."
return

print "Successfully logged in."
print 'Successfully logged in.'
print

# Get all of the users songs.
# library is a big list of dictionaries, each of which contains a single song.
print "Loading library...",
print 'Loading library...',
library = api.get_all_songs()
print "done."
print 'done.'

print len(library), "tracks detected."
print len(library), 'tracks detected.'
print

# Show some info about a song. There is no guaranteed order;
# this is essentially a random song.
first_song = library[0]
print "The first song I see is '{}' by '{}'.".format(
first_song["name"],
first_song["artist"])
first_song['title'].encode('utf-8'),
first_song['artist'].encode('utf-8'))

# We're going to create a new playlist and add a song to it.
# Songs are uniquely identified by 'song ids', so let's get the id:
song_id = first_song["id"]
song_id = first_song['id']

print "I'm going to make a new playlist and add that song to it."
print "I'll delete it when we're finished."
print
playlist_name = raw_input("Enter a name for the playlist: ")
playlist_name = raw_input('Enter a name for the playlist: ')

# Like songs, playlists have unique ids.
# Google Music allows more than one playlist of the same name;
# these ids are necessary.
playlist_id = api.create_playlist(playlist_name)
print "Made the playlist."
print 'Made the playlist.'
print

# Now let's add the song to the playlist, using their ids:
api.add_songs_to_playlist(playlist_id, song_id)
print "Added the song to the playlist."
print 'Added the song to the playlist.'
print

# We're all done! The user can now go and see that the playlist is there.
# The web client syncs our changes in real time.
raw_input("You can now check on Google Music that the playlist exists.\n"
"When done, press enter to delete the playlist:")
raw_input('You can now check on Google Music that the playlist exists.\n'
'When done, press enter to delete the playlist:')
api.delete_playlist(playlist_id)
print "Deleted the playlist."
print 'Deleted the playlist.'

# It's good practice to logout when finished.
api.logout()
print "All done!"
print 'All done!'

if __name__ == '__main__':
demonstrate()

0 comments on commit 325ab63

Please sign in to comment.