From e9fc51f96d7c65a94136cffdad4a2d5118fba21a Mon Sep 17 00:00:00 2001 From: "Juan A. Rubio" Date: Sun, 29 Nov 2015 02:27:25 +0000 Subject: [PATCH] google music: support logging in via cached auth token (closes #132). --- clients/gmusic/gmusicproxy/tizgmusicproxy.py | 51 +++++++++++-------- clients/gmusic/libtizgmusic/src/tizgmusic.cpp | 12 ++--- clients/gmusic/libtizgmusic/src/tizgmusic.hpp | 3 +- .../gmusic/libtizgmusic/src/tizgmusic_c.cpp | 10 ++-- clients/gmusic/libtizgmusic/src/tizgmusic_c.h | 4 +- config/src/tizonia.conf.in | 12 ----- include/omxil-1.2/OMX_TizoniaExt.h | 1 - .../services/googlemusic/tizgmusicconfig.hpp | 8 --- .../googlemusic/tizgmusicgraphops.cpp | 7 +-- .../googlemusic/tizgmusicgraphops.hpp | 3 +- player/src/tizplayapp.cpp | 3 +- player/src/tizprogramopts.cpp | 13 +---- player/src/tizprogramopts.hpp | 2 - plugins/http_source/src/gmusiccfgport.c | 1 - plugins/http_source/src/gmusicprc.c | 3 +- 15 files changed, 48 insertions(+), 85 deletions(-) diff --git a/clients/gmusic/gmusicproxy/tizgmusicproxy.py b/clients/gmusic/gmusicproxy/tizgmusicproxy.py index b693f9087..03451d630 100644 --- a/clients/gmusic/gmusicproxy/tizgmusicproxy.py +++ b/clients/gmusic/gmusicproxy/tizgmusicproxy.py @@ -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 @@ -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 @@ -137,7 +139,30 @@ 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'") @@ -145,24 +170,10 @@ def __init__(self, email, password, device_id, auth_token=None): 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() diff --git a/clients/gmusic/libtizgmusic/src/tizgmusic.cpp b/clients/gmusic/libtizgmusic/src/tizgmusic.cpp index b48273190..34c860297 100644 --- a/clients/gmusic/libtizgmusic/src/tizgmusic.cpp +++ b/clients/gmusic/libtizgmusic/src/tizgmusic.cpp @@ -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) { } @@ -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; } diff --git a/clients/gmusic/libtizgmusic/src/tizgmusic.hpp b/clients/gmusic/libtizgmusic/src/tizgmusic.hpp index 9c571f2c0..f1c86341d 100644 --- a/clients/gmusic/libtizgmusic/src/tizgmusic.hpp +++ b/clients/gmusic/libtizgmusic/src/tizgmusic.hpp @@ -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 (); @@ -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_; diff --git a/clients/gmusic/libtizgmusic/src/tizgmusic_c.cpp b/clients/gmusic/libtizgmusic/src/tizgmusic_c.cpp index caba9af3e..8f802fbe6 100644 --- a/clients/gmusic/libtizgmusic/src/tizgmusic_c.cpp +++ b/clients/gmusic/libtizgmusic/src/tizgmusic_c.cpp @@ -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 (...) { @@ -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; @@ -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); diff --git a/clients/gmusic/libtizgmusic/src/tizgmusic_c.h b/clients/gmusic/libtizgmusic/src/tizgmusic_c.h index 84d22cdf6..9235701ce 100644 --- a/clients/gmusic/libtizgmusic/src/tizgmusic_c.h +++ b/clients/gmusic/libtizgmusic/src/tizgmusic_c.h @@ -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. diff --git a/config/src/tizonia.conf.in b/config/src/tizonia.conf.in index 7c87249ad..68edca289 100644 --- a/config/src/tizonia.conf.in +++ b/config/src/tizonia.conf.in @@ -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 # ------------------------------------------------------------------------- diff --git a/include/omxil-1.2/OMX_TizoniaExt.h b/include/omxil-1.2/OMX_TizoniaExt.h index 331bd2d50..0b263bcee 100644 --- a/include/omxil-1.2/OMX_TizoniaExt.h +++ b/include/omxil-1.2/OMX_TizoniaExt.h @@ -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 { diff --git a/player/src/services/googlemusic/tizgmusicconfig.hpp b/player/src/services/googlemusic/tizgmusicconfig.hpp index eda279656..79313bf18 100644 --- a/player/src/services/googlemusic/tizgmusicconfig.hpp +++ b/player/src/services/googlemusic/tizgmusicconfig.hpp @@ -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) { @@ -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_; @@ -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_; }; diff --git a/player/src/services/googlemusic/tizgmusicgraphops.cpp b/player/src/services/googlemusic/tizgmusicgraphops.cpp index 4901ab103..f226c1e25 100644 --- a/player/src/services/googlemusic/tizgmusicgraphops.cpp +++ b/player/src/services/googlemusic/tizgmusicgraphops.cpp @@ -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 ( @@ -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; @@ -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); diff --git a/player/src/services/googlemusic/tizgmusicgraphops.hpp b/player/src/services/googlemusic/tizgmusicgraphops.hpp index a57bfe78d..27c4de7d3 100644 --- a/player/src/services/googlemusic/tizgmusicgraphops.hpp +++ b/player/src/services/googlemusic/tizgmusicgraphops.hpp @@ -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); diff --git a/player/src/tizplayapp.cpp b/player/src/tizplayapp.cpp index 9485db9bd..f8136268f 100644 --- a/player/src/tizplayapp.cpp +++ b/player/src/tizplayapp.cpp @@ -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 diff --git a/player/src/tizprogramopts.cpp b/player/src/tizprogramopts.cpp index 0d880adb2..f1d29bef1 100644 --- a/player/src/tizprogramopts.cpp +++ b/player/src/tizprogramopts.cpp @@ -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_ (), @@ -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 () { @@ -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")) { @@ -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; diff --git a/player/src/tizprogramopts.hpp b/player/src/tizprogramopts.hpp index 286527144..512d49590 100644 --- a/player/src/tizprogramopts.hpp +++ b/player/src/tizprogramopts.hpp @@ -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; @@ -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_; diff --git a/plugins/http_source/src/gmusiccfgport.c b/plugins/http_source/src/gmusiccfgport.c index f11cf8993..d8488a942 100644 --- a/plugins/http_source/src/gmusiccfgport.c +++ b/plugins/http_source/src/gmusiccfgport.c @@ -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); } diff --git a/plugins/http_source/src/gmusicprc.c b/plugins/http_source/src/gmusicprc.c index 546efc57a..366417a71 100644 --- a/plugins/http_source/src/gmusicprc.c +++ b/plugins/http_source/src/gmusicprc.c @@ -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));