Skip to content

Commit

Permalink
google music: support logging in via cached auth token (closes #132).
Browse files Browse the repository at this point in the history
  • Loading branch information
juanrubio committed Nov 29, 2015
1 parent 756451c commit e9fc51f
Show file tree
Hide file tree
Showing 15 changed files with 48 additions and 85 deletions.
51 changes: 31 additions & 20 deletions clients/gmusic/gmusicproxy/tizgmusicproxy.py
Expand Up @@ -30,10 +30,12 @@
"""

import os
import sys
import logging
import random
import unicodedata
import pickle
from operator import itemgetter
from gmusicapi import Mobileclient
from gmusicapi.exceptions import CallFailure
Expand Down Expand Up @@ -125,7 +127,7 @@ class tizgmusicproxy(object):
all_songs_album_title = "All Songs"
thumbs_up_playlist_name = "Thumbs Up"

def __init__(self, email, password, device_id, auth_token=None):
def __init__(self, email, password, device_id):
self.__gmusic = Mobileclient()
self.__email = email
self.__device_id = device_id
Expand All @@ -137,32 +139,41 @@ def __init__(self, email, password, device_id, auth_token=None):
self.current_play_mode = self.play_modes.NORMAL
self.now_playing_song = None

if auth_token is None:
userdir = os.path.expanduser('~')
tizconfig = os.path.join(userdir, ".config/tizonia/." + email + ".auth_token")
auth_token = ""
if os.path.isfile(tizconfig):
with open(tizconfig, "r") as f:
auth_token = pickle.load(f)
if auth_token:
# 'Keep track of the auth token' workaround. See:
# https://github.com/diraimondo/gmusicproxy/issues/34#issuecomment-147359198
print_msg("[Google Play Music] [Authenticating] : " \
"'with cached auth token'")
self.__gmusic.android_id = device_id
self.__gmusic.session._authtoken = auth_token
self.__gmusic.session.is_authenticated = True
try:
self.__gmusic.get_registered_devices()
except CallFailure:
# The token has expired. Reset the client object
print_wrn("[Google Play Music] [Authenticating] : " \
"'auth token expired'")
self.__gmusic = Mobileclient()
auth_token = ""

if not auth_token:
attempts = 0
print_nfo("[Google Play Music] [Authenticating] : " \
"'with user credentials'")
while not self.logged_in and attempts < 3:
self.logged_in = self.__gmusic.login(email, password, device_id)
attempts += 1

if self.__gmusic.session.is_authenticated:
print_msg("[Google Play Music] [{0}]".format(self.__email))
print_msg("[Google Play Music] [To avoid server-side rate " \
"limit logouts on Android devices]")
print_msg("[Google Play Music] [please copy the " \
"authentication token into your Tizonia's " \
"config file]")
print_msg("[Google Play Music] [auth token] {0}"\
.format(self.__gmusic.session._authtoken))
else:
# Keep track of the auth token workaround. See:
# https://github.com/diraimondo/gmusicproxy/issues/34#issuecomment-147359198
print_msg("[Google Play Music] [Authenticating] : " \
"'with auth token'")
self.__gmusic.android_id = device_id
self.__gmusic.session._authtoken = auth_token
self.__gmusic.session.is_authenticated = True

with open(tizconfig, "a+") as f:
f.truncate()
pickle.dump(self.__gmusic.session._authtoken, f)

self.library = CaseInsensitiveDict()
self.song_map = CaseInsensitiveDict()
self.playlists = CaseInsensitiveDict()
Expand Down
12 changes: 5 additions & 7 deletions clients/gmusic/libtizgmusic/src/tizgmusic.cpp
Expand Up @@ -77,19 +77,17 @@ namespace
void start_gmusic (boost::python::object &py_global,
boost::python::object &py_gm_proxy,
const std::string &user, const std::string &pass,
const std::string &device_id,
const std::string &auth_token)
const std::string &device_id)
{
bp::object pygmusicproxy = py_global["tizgmusicproxy"];
py_gm_proxy
= pygmusicproxy (user.c_str (), pass.c_str (), device_id.c_str (),
auth_token.empty() ? NULL : auth_token.c_str ());
= pygmusicproxy (user.c_str (), pass.c_str (), device_id.c_str ());
}
}

tizgmusic::tizgmusic (const std::string &user, const std::string &pass,
const std::string &device_id, const std::string &auth_token)
: user_ (user), pass_ (pass), device_id_ (device_id), auth_token_ (auth_token)
const std::string &device_id)
: user_ (user), pass_ (pass), device_id_ (device_id)
{
}

Expand All @@ -108,7 +106,7 @@ int tizgmusic::start ()
{
int rc = 0;
try_catch_wrapper (start_gmusic (py_global_, py_gm_proxy_, user_, pass_,
device_id_, auth_token_));
device_id_));
return rc;
}

Expand Down
3 changes: 1 addition & 2 deletions clients/gmusic/libtizgmusic/src/tizgmusic.hpp
Expand Up @@ -48,7 +48,7 @@ class tizgmusic

public:
tizgmusic (const std::string &user, const std::string &pass,
const std::string &device_id, const std::string &auth_token);
const std::string &device_id);
~tizgmusic ();

int init ();
Expand Down Expand Up @@ -83,7 +83,6 @@ class tizgmusic
std::string user_;
std::string pass_;
std::string device_id_;
std::string auth_token_;
std::string current_url_;
std::string current_artist_;
std::string current_title_;
Expand Down
10 changes: 4 additions & 6 deletions clients/gmusic/libtizgmusic/src/tizgmusic_c.cpp
Expand Up @@ -50,14 +50,13 @@ static void gmusic_free_data (tiz_gmusic_t *ap_gmusic)
}

static int gmusic_alloc_data (tiz_gmusic_t *ap_gmusic, const char *ap_user,
const char *ap_pass, const char *ap_device_id,
const char *ap_auth_token)
const char *ap_pass, const char *ap_device_id)
{
int rc = 0;
assert (ap_gmusic);
try
{
ap_gmusic->p_proxy_ = new tizgmusic (ap_user, ap_pass, ap_device_id, ap_auth_token);
ap_gmusic->p_proxy_ = new tizgmusic (ap_user, ap_pass, ap_device_id);
}
catch (...)
{
Expand All @@ -69,8 +68,7 @@ static int gmusic_alloc_data (tiz_gmusic_t *ap_gmusic, const char *ap_user,

extern "C" int tiz_gmusic_init (tiz_gmusic_ptr_t *app_gmusic,
const char *ap_user, const char *ap_pass,
const char *ap_device_id,
const char *ap_auth_token)
const char *ap_device_id)
{
tiz_gmusic_t *p_gmusic = NULL;
int rc = 1;
Expand All @@ -82,7 +80,7 @@ extern "C" int tiz_gmusic_init (tiz_gmusic_ptr_t *app_gmusic,

if ((p_gmusic = (tiz_gmusic_t *)calloc (1, sizeof(tiz_gmusic_t))))
{
if (!gmusic_alloc_data (p_gmusic, ap_user, ap_pass, ap_device_id, ap_auth_token))
if (!gmusic_alloc_data (p_gmusic, ap_user, ap_pass, ap_device_id))
{
tizgmusic *p_gm = p_gmusic->p_proxy_;
assert (p_gm);
Expand Down
4 changes: 1 addition & 3 deletions clients/gmusic/libtizgmusic/src/tizgmusic_c.h
Expand Up @@ -71,15 +71,13 @@ typedef enum tiz_gmusic_playback_mode
* @param ap_user A Google email account.
* @param ap_pass The password associated to the Google account.
* @param ap_device_id A 16-character string containing a device id
* @param ap_auth_token A null-terminated string containing an auth token
* associated to the Google Play Music account.
*
* @return 0 on success.
*/
int tiz_gmusic_init (/*@null@ */ tiz_gmusic_ptr_t *app_gmusic,
const char *ap_user, const char *ap_pass,
const char *ap_device_id,
const char *ap_auth_token);
const char *ap_device_id);

/**
* Set the playback mode.
Expand Down
12 changes: 0 additions & 12 deletions config/src/tizonia.conf.in
Expand Up @@ -87,18 +87,6 @@ mpris-enabled = false
# gmusic.password = pass
# gmusic.device_id = deviceid

# Optional: Google Play Music authentication token
#
# To avoid the server-side rate limit triggering a log out in all of the user's
# Android devices, the Google Play Music authentication token can be provided
# in 'gmusic.auth_token'. Simply copy the token that gets displayed by Tizonia
# in the console right after connecting to Google Play Music. When
# 'gmusic.auth_token' is enabled and non-empty, it is used for authentication
# instead of the user's email and password, which may then be removed from this
# file.

# gmusic.auth_token = XXXXX....


# SoundCloud configuration
# -------------------------------------------------------------------------
Expand Down
1 change: 0 additions & 1 deletion include/omxil-1.2/OMX_TizoniaExt.h
Expand Up @@ -327,7 +327,6 @@ typedef struct OMX_TIZONIA_AUDIO_PARAM_GMUSICSESSIONTYPE {
OMX_U8 cUserName[OMX_MAX_STRINGNAME_SIZE];
OMX_U8 cUserPassword[OMX_MAX_STRINGNAME_SIZE];
OMX_U8 cDeviceId[OMX_MAX_STRINGNAME_SIZE];
OMX_U8 cUserAuthToken[500];
} OMX_TIZONIA_AUDIO_PARAM_GMUSICSESSIONTYPE;

typedef struct OMX_TIZONIA_AUDIO_PARAM_GMUSICPLAYLISTTYPE {
Expand Down
8 changes: 0 additions & 8 deletions player/src/services/googlemusic/tizgmusicconfig.hpp
Expand Up @@ -46,14 +46,12 @@ namespace tiz
public:
gmusicconfig (const tizplaylist_ptr_t &playlist, const std::string &user,
const std::string &pass, const std::string &device_id,
const std::string &auth_token,
const OMX_TIZONIA_AUDIO_GMUSICPLAYLISTTYPE playlist_type,
const bool is_unlimited_search = false)
: config (playlist),
user_ (user),
pass_ (pass),
device_id_ (device_id),
auth_token_ (auth_token),
playlist_type_ (playlist_type),
is_unlimited_search_ (is_unlimited_search)
{
Expand All @@ -78,11 +76,6 @@ namespace tiz
return device_id_;
}

std::string get_auth_token () const
{
return auth_token_;
}

OMX_TIZONIA_AUDIO_GMUSICPLAYLISTTYPE get_playlist_type () const
{
return playlist_type_;
Expand All @@ -97,7 +90,6 @@ namespace tiz
const std::string user_;
const std::string pass_;
const std::string device_id_;
const std::string auth_token_;
const OMX_TIZONIA_AUDIO_GMUSICPLAYLISTTYPE playlist_type_;
bool is_unlimited_search_;
};
Expand Down
7 changes: 2 additions & 5 deletions player/src/services/googlemusic/tizgmusicgraphops.cpp
Expand Up @@ -107,8 +107,7 @@ void graph::gmusicops::do_configure_source ()
G_OPS_BAIL_IF_ERROR (
set_gmusic_user_and_device_id (
handles_[0], gmusic_config->get_user_name (),
gmusic_config->get_user_pass (), gmusic_config->get_device_id (),
gmusic_config->get_auth_token ()),
gmusic_config->get_user_pass (), gmusic_config->get_device_id ()),
"Unable to set OMX_TizoniaIndexParamAudioGmusicSession");

G_OPS_BAIL_IF_ERROR (
Expand Down Expand Up @@ -408,8 +407,7 @@ OMX_ERRORTYPE
graph::gmusicops::set_gmusic_user_and_device_id (const OMX_HANDLETYPE handle,
const std::string &user,
const std::string &pass,
const std::string &device_id,
const std::string &auth_token)
const std::string &device_id)
{
// Set the Google Play Music user and pass
OMX_TIZONIA_AUDIO_PARAM_GMUSICSESSIONTYPE sessiontype;
Expand All @@ -421,7 +419,6 @@ graph::gmusicops::set_gmusic_user_and_device_id (const OMX_HANDLETYPE handle,
copy_omx_string (sessiontype.cUserName, user);
copy_omx_string (sessiontype.cUserPassword, pass);
copy_omx_string (sessiontype.cDeviceId, device_id);
copy_omx_string (sessiontype.cUserAuthToken, auth_token, 500);
return OMX_SetParameter (handle, static_cast< OMX_INDEXTYPE >(
OMX_TizoniaIndexParamAudioGmusicSession),
&sessiontype);
Expand Down
3 changes: 1 addition & 2 deletions player/src/services/googlemusic/tizgmusicgraphops.hpp
Expand Up @@ -65,8 +65,7 @@ namespace tiz
const int tunnel_id, const OMX_COMMANDTYPE to_disabled_or_enabled);
OMX_ERRORTYPE set_gmusic_user_and_device_id (
const OMX_HANDLETYPE handle, const std::string &user,
const std::string &pass, const std::string &device_id,
const std::string &auth_token);
const std::string &pass, const std::string &device_id);
OMX_ERRORTYPE set_gmusic_playlist (const OMX_HANDLETYPE handle,
const std::string &playlist);

Expand Down
3 changes: 1 addition & 2 deletions player/src/tizplayapp.cpp
Expand Up @@ -748,8 +748,7 @@ tiz::playapp::gmusic_stream ()
playlist->set_loop_playback (true);

tizgraphconfig_ptr_t config = boost::make_shared< tiz::graph::gmusicconfig >(
playlist, user, pass, device_id, popts_.gmusic_auth_token (),
playlist_type, is_unlimited_search);
playlist, user, pass, device_id, playlist_type, is_unlimited_search);

// Instantiate the streaming client manager
tiz::graphmgr::mgr_ptr_t p_mgr
Expand Down
13 changes: 1 addition & 12 deletions player/src/tizprogramopts.cpp
Expand Up @@ -265,7 +265,6 @@ tiz::programopts::programopts (int argc, char *argv[])
gmusic_user_ (),
gmusic_pass_ (),
gmusic_device_id_ (),
gmusic_auth_token_ (),
gmusic_artist_ (),
gmusic_album_ (),
gmusic_playlist_ (),
Expand Down Expand Up @@ -561,11 +560,6 @@ const std::string &tiz::programopts::gmusic_device_id () const
return gmusic_device_id_;
}

const std::string &tiz::programopts::gmusic_auth_token () const
{
return gmusic_auth_token_;
}

const std::vector< std::string > &
tiz::programopts::gmusic_playlist_container ()
{
Expand Down Expand Up @@ -1260,11 +1254,6 @@ int tiz::programopts::consume_gmusic_client_options (bool &done,
retrieve_config_from_rc_file ("tizonia", "gmusic.device_id",
gmusic_device_id_);
}
if (gmusic_auth_token_.empty ())
{
retrieve_config_from_rc_file ("tizonia", "gmusic.auth_token",
gmusic_auth_token_);
}

if (vm_.count ("gmusic-unlimited-promoted-tracks"))
{
Expand All @@ -1288,7 +1277,7 @@ int tiz::programopts::consume_gmusic_client_options (bool &done,
gmusic_is_unlimited_search_ = true;
}

if (gmusic_user_.empty () && gmusic_auth_token_.empty ())
if (gmusic_user_.empty ())
{
rc = EXIT_FAILURE;
std::ostringstream oss;
Expand Down
2 changes: 0 additions & 2 deletions player/src/tizprogramopts.hpp
Expand Up @@ -80,7 +80,6 @@ namespace tiz
const std::string &gmusic_user () const;
const std::string &gmusic_password () const;
const std::string &gmusic_device_id () const;
const std::string &gmusic_auth_token () const;
const std::vector< std::string > &gmusic_playlist_container ();
OMX_TIZONIA_AUDIO_GMUSICPLAYLISTTYPE gmusic_playlist_type ();
bool gmusic_is_unlimited_search () const;
Expand Down Expand Up @@ -175,7 +174,6 @@ namespace tiz
std::string gmusic_user_;
std::string gmusic_pass_;
std::string gmusic_device_id_;
std::string gmusic_auth_token_;
std::string gmusic_artist_;
std::string gmusic_album_;
std::string gmusic_playlist_;
Expand Down
1 change: 0 additions & 1 deletion plugins/http_source/src/gmusiccfgport.c
Expand Up @@ -143,7 +143,6 @@ gmusic_cfgport_SetParameter (const void *ap_obj,
p_obj->session_.cUserName[OMX_MAX_STRINGNAME_SIZE - 1] = '\000';
p_obj->session_.cUserPassword[OMX_MAX_STRINGNAME_SIZE - 1] = '\000';
p_obj->session_.cDeviceId[OMX_MAX_STRINGNAME_SIZE - 1] = '\000';
p_obj->session_.cUserAuthToken[500 - 1] = '\000';
TIZ_TRACE (ap_hdl, "Gmusic User Name [%s]...",
p_obj->session_.cUserName);
}
Expand Down
3 changes: 1 addition & 2 deletions plugins/http_source/src/gmusicprc.c
Expand Up @@ -652,8 +652,7 @@ static OMX_ERRORTYPE gmusic_prc_allocate_resources (void *ap_obj, OMX_U32 a_pid)
on_gmusic_error_ret_omx_oom (tiz_gmusic_init (
&(p_prc->p_gmusic_), (const char *)p_prc->session_.cUserName,
(const char *)p_prc->session_.cUserPassword,
(const char *)p_prc->session_.cDeviceId,
(const char *)p_prc->session_.cUserAuthToken));
(const char *)p_prc->session_.cDeviceId));

tiz_check_omx_err (enqueue_playlist_items (p_prc));
tiz_check_omx_err (obtain_next_url (p_prc, 1));
Expand Down

0 comments on commit e9fc51f

Please sign in to comment.