mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-26 21:09:18 -05:00
Merge branch 'spotify_logout1'
This commit is contained in:
commit
2f702ed3ef
@ -497,8 +497,9 @@ forked-daapd will not store your password, but will still be able to log you in
|
|||||||
automatically afterwards, because libspotify saves a login token. You can
|
automatically afterwards, because libspotify saves a login token. You can
|
||||||
configure the location of your Spotify user data in the configuration file.
|
configure the location of your Spotify user data in the configuration file.
|
||||||
|
|
||||||
To permanently logout and remove credentials, delete the contents of
|
To permanently logout and remove Spotify tracks + credentials make a request to
|
||||||
`/var/cache/forked-daapd/libspotify` (while forked-daapd is stopped).
|
[http://[your_server_address_here]:3689/api/spotify-logout](http://[your_server_address_here]:3689/api/spotify-logout)
|
||||||
|
and also delete the contents of `/var/cache/forked-daapd/libspotify`.
|
||||||
|
|
||||||
Limitations:
|
Limitations:
|
||||||
You will not be able to do any playlist management through forked-daapd - use
|
You will not be able to do any playlist management through forked-daapd - use
|
||||||
|
4
src/db.c
4
src/db.c
@ -4319,7 +4319,6 @@ db_pairing_fetch_byguid(struct pairing_info *pi)
|
|||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SPOTIFY_H
|
|
||||||
/* Spotify */
|
/* Spotify */
|
||||||
void
|
void
|
||||||
db_spotify_purge(void)
|
db_spotify_purge(void)
|
||||||
@ -4399,7 +4398,6 @@ db_spotify_files_delete(void)
|
|||||||
DPRINTF(E_DBG, L_DB, "Deleted %d rows\n", sqlite3_changes(hdl));
|
DPRINTF(E_DBG, L_DB, "Deleted %d rows\n", sqlite3_changes(hdl));
|
||||||
#undef Q_TMPL
|
#undef Q_TMPL
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Admin */
|
/* Admin */
|
||||||
int
|
int
|
||||||
@ -4540,7 +4538,7 @@ db_admin_getint64(int64_t *int64val, const char *key)
|
|||||||
int
|
int
|
||||||
db_admin_delete(const char *key)
|
db_admin_delete(const char *key)
|
||||||
{
|
{
|
||||||
#define Q_TMPL "DELETE FROM admin where key='%q';"
|
#define Q_TMPL "DELETE FROM admin WHERE key='%q';"
|
||||||
char *query;
|
char *query;
|
||||||
|
|
||||||
query = sqlite3_mprintf(Q_TMPL, key);
|
query = sqlite3_mprintf(Q_TMPL, key);
|
||||||
|
2
src/db.h
2
src/db.h
@ -762,7 +762,6 @@ db_pairing_add(struct pairing_info *pi);
|
|||||||
int
|
int
|
||||||
db_pairing_fetch_byguid(struct pairing_info *pi);
|
db_pairing_fetch_byguid(struct pairing_info *pi);
|
||||||
|
|
||||||
#ifdef HAVE_SPOTIFY_H
|
|
||||||
/* Spotify */
|
/* Spotify */
|
||||||
void
|
void
|
||||||
db_spotify_purge(void);
|
db_spotify_purge(void);
|
||||||
@ -772,7 +771,6 @@ db_spotify_pl_delete(int id);
|
|||||||
|
|
||||||
void
|
void
|
||||||
db_spotify_files_delete(void);
|
db_spotify_files_delete(void);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Admin */
|
/* Admin */
|
||||||
int
|
int
|
||||||
|
@ -1251,6 +1251,15 @@ jsonapi_reply_spotify_login(struct httpd_request *hreq)
|
|||||||
return HTTP_OK;
|
return HTTP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
jsonapi_reply_spotify_logout(struct httpd_request *hreq)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_SPOTIFY_H
|
||||||
|
spotify_logout();
|
||||||
|
#endif
|
||||||
|
return HTTP_NOCONTENT;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
jsonapi_reply_lastfm(struct httpd_request *hreq)
|
jsonapi_reply_lastfm(struct httpd_request *hreq)
|
||||||
{
|
{
|
||||||
@ -4217,6 +4226,7 @@ static struct httpd_uri_map adm_handlers[] =
|
|||||||
EVHTTP_REQ_PUT, "^/api/update$", jsonapi_reply_update },
|
EVHTTP_REQ_PUT, "^/api/update$", jsonapi_reply_update },
|
||||||
{ EVHTTP_REQ_PUT, "^/api/rescan$", jsonapi_reply_meta_rescan },
|
{ EVHTTP_REQ_PUT, "^/api/rescan$", jsonapi_reply_meta_rescan },
|
||||||
{ EVHTTP_REQ_POST, "^/api/spotify-login$", jsonapi_reply_spotify_login },
|
{ EVHTTP_REQ_POST, "^/api/spotify-login$", jsonapi_reply_spotify_login },
|
||||||
|
{ EVHTTP_REQ_GET, "^/api/spotify-logout$", jsonapi_reply_spotify_logout },
|
||||||
{ EVHTTP_REQ_GET, "^/api/spotify$", jsonapi_reply_spotify },
|
{ EVHTTP_REQ_GET, "^/api/spotify$", jsonapi_reply_spotify },
|
||||||
{ EVHTTP_REQ_GET, "^/api/pairing$", jsonapi_reply_pairing_get },
|
{ EVHTTP_REQ_GET, "^/api/pairing$", jsonapi_reply_pairing_get },
|
||||||
{ EVHTTP_REQ_POST, "^/api/pairing$", jsonapi_reply_pairing_pair },
|
{ EVHTTP_REQ_POST, "^/api/pairing$", jsonapi_reply_pairing_pair },
|
||||||
|
@ -1340,6 +1340,40 @@ spotify_status_info_get(struct spotify_status_info *info)
|
|||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&status_lck));
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&status_lck));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Thread: library, httpd */
|
||||||
|
static int
|
||||||
|
logout(char **errmsg)
|
||||||
|
{
|
||||||
|
sp_error err;
|
||||||
|
|
||||||
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&login_lck));
|
||||||
|
|
||||||
|
if (SP_CONNECTION_STATE_LOGGED_IN != fptr_sp_session_connectionstate(g_sess))
|
||||||
|
{
|
||||||
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&login_lck));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_LOG, L_SPOTIFY, "Logging out of Spotify (current state is %d)\n", g_state);
|
||||||
|
|
||||||
|
fptr_sp_session_player_unload(g_sess);
|
||||||
|
err = fptr_sp_session_logout(g_sess);
|
||||||
|
if (SP_ERROR_OK != err)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_SPOTIFY, "Could not logout of Spotify: %s\n", fptr_sp_error_message(err));
|
||||||
|
if (errmsg)
|
||||||
|
*errmsg = safe_asprintf("Could not logout of Spotify: %s", fptr_sp_error_message(err));
|
||||||
|
|
||||||
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&login_lck));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_ERR(L_SPOTIFY, pthread_cond_wait(&login_cond, &login_lck)); // Wait for logged_out()
|
||||||
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&login_lck));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Thread: library, httpd */
|
/* Thread: library, httpd */
|
||||||
static int
|
static int
|
||||||
login_user(const char *user, const char *password, char **errmsg)
|
login_user(const char *user, const char *password, char **errmsg)
|
||||||
@ -1365,28 +1399,9 @@ login_user(const char *user, const char *password, char **errmsg)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SP_CONNECTION_STATE_LOGGED_IN == fptr_sp_session_connectionstate(g_sess))
|
ret = logout(errmsg);
|
||||||
{
|
if (ret < 0)
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&login_lck));
|
return -1;
|
||||||
|
|
||||||
DPRINTF(E_LOG, L_SPOTIFY, "Logging out of Spotify (current state is %d)\n", g_state);
|
|
||||||
|
|
||||||
fptr_sp_session_player_unload(g_sess);
|
|
||||||
err = fptr_sp_session_logout(g_sess);
|
|
||||||
|
|
||||||
if (SP_ERROR_OK != err)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_SPOTIFY, "Could not logout of Spotify: %s\n", fptr_sp_error_message(err));
|
|
||||||
if (errmsg)
|
|
||||||
*errmsg = safe_asprintf("Could not logout of Spotify: %s", fptr_sp_error_message(err));
|
|
||||||
|
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&login_lck));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_cond_wait(&login_cond, &login_lck));
|
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&login_lck));
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&login_lck));
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&login_lck));
|
||||||
|
|
||||||
@ -1457,6 +1472,14 @@ spotify_login(char **arglist)
|
|||||||
spotify_login_user(NULL, NULL, NULL);
|
spotify_login_user(NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spotify_logout(void)
|
||||||
|
{
|
||||||
|
logout(NULL);
|
||||||
|
|
||||||
|
spotifywebapi_purge();
|
||||||
|
}
|
||||||
|
|
||||||
/* Thread: main */
|
/* Thread: main */
|
||||||
int
|
int
|
||||||
spotify_init(void)
|
spotify_init(void)
|
||||||
|
@ -50,6 +50,9 @@ spotify_login_user(const char *user, const char *password, char **errmsg);
|
|||||||
void
|
void
|
||||||
spotify_login(char **arglist);
|
spotify_login(char **arglist);
|
||||||
|
|
||||||
|
void
|
||||||
|
spotify_logout(void);
|
||||||
|
|
||||||
void
|
void
|
||||||
spotify_status_info_get(struct spotify_status_info *info);
|
spotify_status_info_get(struct spotify_status_info *info);
|
||||||
|
|
||||||
|
@ -94,14 +94,19 @@ struct spotify_playlist
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Credentials for the web api
|
// Credentials for the web api
|
||||||
static char *spotify_access_token;
|
struct spotify_credentials
|
||||||
static char *spotify_refresh_token;
|
{
|
||||||
static char *spotify_granted_scope;
|
char *access_token;
|
||||||
static char *spotify_user_country;
|
char *refresh_token;
|
||||||
static char *spotify_user;
|
char *granted_scope;
|
||||||
|
char *user_country;
|
||||||
|
char *user;
|
||||||
|
|
||||||
static int32_t expires_in = 3600;
|
int32_t token_expires_in;
|
||||||
static time_t token_requested = 0;
|
time_t token_time_requested;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct spotify_credentials spotify_credentials;
|
||||||
|
|
||||||
// Mutex to avoid conflicting requests for access tokens and protects accessing the credentials from different threads
|
// Mutex to avoid conflicting requests for access tokens and protects accessing the credentials from different threads
|
||||||
static pthread_mutex_t token_lck;
|
static pthread_mutex_t token_lck;
|
||||||
@ -135,6 +140,17 @@ static const char *spotify_playlist_tracks_uri = "https://api.spotify.com/v1/pla
|
|||||||
static const char *spotify_artist_albums_uri = "https://api.spotify.com/v1/artists/%s/albums?include_groups=album,single";
|
static const char *spotify_artist_albums_uri = "https://api.spotify.com/v1/artists/%s/albums?include_groups=album,single";
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_credentials(void)
|
||||||
|
{
|
||||||
|
free(spotify_credentials.access_token);
|
||||||
|
free(spotify_credentials.refresh_token);
|
||||||
|
free(spotify_credentials.granted_scope);
|
||||||
|
free(spotify_credentials.user_country);
|
||||||
|
free(spotify_credentials.user);
|
||||||
|
|
||||||
|
memset(&spotify_credentials, 0, sizeof(struct spotify_credentials));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_http_client_ctx(struct http_client_ctx *ctx)
|
free_http_client_ctx(struct http_client_ctx *ctx)
|
||||||
@ -155,7 +171,7 @@ free_http_client_ctx(struct http_client_ctx *ctx)
|
|||||||
static bool
|
static bool
|
||||||
token_valid(void)
|
token_valid(void)
|
||||||
{
|
{
|
||||||
return spotify_access_token != NULL;
|
return spotify_credentials.access_token != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -209,34 +225,34 @@ request_access_tokens(struct keyval *kv, const char **err)
|
|||||||
goto out_free_input_body;
|
goto out_free_input_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(spotify_access_token);
|
free(spotify_credentials.access_token);
|
||||||
spotify_access_token = NULL;
|
spotify_credentials.access_token = NULL;
|
||||||
|
|
||||||
tmp = jparse_str_from_obj(haystack, "access_token");
|
tmp = jparse_str_from_obj(haystack, "access_token");
|
||||||
if (tmp)
|
if (tmp)
|
||||||
spotify_access_token = strdup(tmp);
|
spotify_credentials.access_token = strdup(tmp);
|
||||||
|
|
||||||
tmp = jparse_str_from_obj(haystack, "refresh_token");
|
tmp = jparse_str_from_obj(haystack, "refresh_token");
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
free(spotify_refresh_token);
|
free(spotify_credentials.refresh_token);
|
||||||
spotify_refresh_token = strdup(tmp);
|
spotify_credentials.refresh_token = strdup(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = jparse_str_from_obj(haystack, "scope");
|
tmp = jparse_str_from_obj(haystack, "scope");
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
free(spotify_granted_scope);
|
free(spotify_credentials.granted_scope);
|
||||||
spotify_granted_scope = strdup(tmp);
|
spotify_credentials.granted_scope = strdup(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
expires_in = jparse_int_from_obj(haystack, "expires_in");
|
spotify_credentials.token_expires_in = jparse_int_from_obj(haystack, "expires_in");
|
||||||
if (expires_in == 0)
|
if (spotify_credentials.token_expires_in == 0)
|
||||||
expires_in = 3600;
|
spotify_credentials.token_expires_in = 3600;
|
||||||
|
|
||||||
jparse_free(haystack);
|
jparse_free(haystack);
|
||||||
|
|
||||||
if (!spotify_access_token)
|
if (!spotify_credentials.access_token)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SPOTIFY, "Could not find access token in reply: %s\n", body);
|
DPRINTF(E_LOG, L_SPOTIFY, "Could not find access token in reply: %s\n", body);
|
||||||
|
|
||||||
@ -245,10 +261,10 @@ request_access_tokens(struct keyval *kv, const char **err)
|
|||||||
goto out_free_input_body;
|
goto out_free_input_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
token_requested = time(NULL);
|
spotify_credentials.token_time_requested = time(NULL);
|
||||||
|
|
||||||
if (spotify_refresh_token)
|
if (spotify_credentials.refresh_token)
|
||||||
db_admin_set(DB_ADMIN_SPOTIFY_REFRESH_TOKEN, spotify_refresh_token);
|
db_admin_set(DB_ADMIN_SPOTIFY_REFRESH_TOKEN, spotify_credentials.refresh_token);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
@ -281,7 +297,7 @@ request_endpoint(const char *uri)
|
|||||||
ctx->input_body = evbuffer_new();
|
ctx->input_body = evbuffer_new();
|
||||||
ctx->url = uri;
|
ctx->url = uri;
|
||||||
|
|
||||||
snprintf(bearer_token, sizeof(bearer_token), "Bearer %s", spotify_access_token);
|
snprintf(bearer_token, sizeof(bearer_token), "Bearer %s", spotify_credentials.access_token);
|
||||||
if (keyval_add(ctx->output_headers, "Authorization", bearer_token) < 0)
|
if (keyval_add(ctx->output_headers, "Authorization", bearer_token) < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SPOTIFY, "Add bearer_token to keyval failed for request '%s'\n", uri);
|
DPRINTF(E_LOG, L_SPOTIFY, "Add bearer_token to keyval failed for request '%s'\n", uri);
|
||||||
@ -331,21 +347,21 @@ request_user_info(void)
|
|||||||
{
|
{
|
||||||
json_object *response;
|
json_object *response;
|
||||||
|
|
||||||
free(spotify_user_country);
|
free(spotify_credentials.user_country);
|
||||||
spotify_user_country = NULL;
|
spotify_credentials.user_country = NULL;
|
||||||
free(spotify_user);
|
free(spotify_credentials.user);
|
||||||
spotify_user = NULL;
|
spotify_credentials.user = NULL;
|
||||||
|
|
||||||
response = request_endpoint(spotify_me_uri);
|
response = request_endpoint(spotify_me_uri);
|
||||||
|
|
||||||
if (response)
|
if (response)
|
||||||
{
|
{
|
||||||
spotify_user = safe_strdup(jparse_str_from_obj(response, "id"));
|
spotify_credentials.user = safe_strdup(jparse_str_from_obj(response, "id"));
|
||||||
spotify_user_country = safe_strdup(jparse_str_from_obj(response, "country"));
|
spotify_credentials.user_country = safe_strdup(jparse_str_from_obj(response, "country"));
|
||||||
|
|
||||||
jparse_free(response);
|
jparse_free(response);
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_SPOTIFY, "User '%s', country '%s'\n", spotify_user, spotify_user_country);
|
DPRINTF(E_DBG, L_SPOTIFY, "User '%s', country '%s'\n", spotify_credentials.user, spotify_credentials.user_country);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -411,7 +427,7 @@ token_refresh(void)
|
|||||||
|
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&token_lck));
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&token_lck));
|
||||||
|
|
||||||
if (token_requested && difftime(time(NULL), token_requested) < expires_in)
|
if (spotify_credentials.token_time_requested && difftime(time(NULL), spotify_credentials.token_time_requested) < spotify_credentials.token_expires_in)
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_SPOTIFY, "Spotify token still valid\n");
|
DPRINTF(E_DBG, L_SPOTIFY, "Spotify token still valid\n");
|
||||||
|
|
||||||
@ -524,16 +540,16 @@ request_pagingobject_endpoint(const char *href, paging_item_cb item_cb, paging_r
|
|||||||
int total;
|
int total;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!with_market || !spotify_user_country)
|
if (!with_market || !spotify_credentials.user_country)
|
||||||
{
|
{
|
||||||
next_href = safe_strdup(href);
|
next_href = safe_strdup(href);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (strchr(href, '?'))
|
if (strchr(href, '?'))
|
||||||
next_href = safe_asprintf("%s&market=%s", href, spotify_user_country);
|
next_href = safe_asprintf("%s&market=%s", href, spotify_credentials.user_country);
|
||||||
else
|
else
|
||||||
next_href = safe_asprintf("%s?market=%s", href, spotify_user_country);
|
next_href = safe_asprintf("%s?market=%s", href, spotify_credentials.user_country);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (next_href)
|
while (next_href)
|
||||||
@ -1815,6 +1831,19 @@ webapi_rescan(void *arg, int *ret)
|
|||||||
return COMMAND_END;
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Thread: library */
|
||||||
|
static enum command_state
|
||||||
|
webapi_purge(void *arg, int *ret)
|
||||||
|
{
|
||||||
|
free_credentials();
|
||||||
|
|
||||||
|
db_spotify_purge();
|
||||||
|
db_admin_delete(DB_ADMIN_SPOTIFY_REFRESH_TOKEN);
|
||||||
|
|
||||||
|
*ret = 0;
|
||||||
|
return COMMAND_END;
|
||||||
|
}
|
||||||
|
|
||||||
/* Thread: library */
|
/* Thread: library */
|
||||||
static enum command_state
|
static enum command_state
|
||||||
webapi_pl_save(void *arg, int *ret)
|
webapi_pl_save(void *arg, int *ret)
|
||||||
@ -1887,6 +1916,12 @@ spotifywebapi_rescan(void)
|
|||||||
library_exec_async(webapi_rescan, NULL);
|
library_exec_async(webapi_rescan, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spotifywebapi_purge(void)
|
||||||
|
{
|
||||||
|
library_exec_async(webapi_purge, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spotifywebapi_pl_save(const char *uri)
|
spotifywebapi_pl_save(const char *uri)
|
||||||
{
|
{
|
||||||
@ -1942,17 +1977,17 @@ spotifywebapi_status_info_get(struct spotifywebapi_status_info *info)
|
|||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&token_lck));
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&token_lck));
|
||||||
|
|
||||||
info->token_valid = token_valid();
|
info->token_valid = token_valid();
|
||||||
if (spotify_user)
|
if (spotify_credentials.user)
|
||||||
{
|
{
|
||||||
strncpy(info->user, spotify_user, (sizeof(info->user) - 1));
|
strncpy(info->user, spotify_credentials.user, (sizeof(info->user) - 1));
|
||||||
}
|
}
|
||||||
if (spotify_user_country)
|
if (spotify_credentials.user_country)
|
||||||
{
|
{
|
||||||
strncpy(info->country, spotify_user_country, (sizeof(info->country) - 1));
|
strncpy(info->country, spotify_credentials.user_country, (sizeof(info->country) - 1));
|
||||||
}
|
}
|
||||||
if (spotify_granted_scope)
|
if (spotify_credentials.granted_scope)
|
||||||
{
|
{
|
||||||
strncpy(info->granted_scope, spotify_granted_scope, (sizeof(info->granted_scope) - 1));
|
strncpy(info->granted_scope, spotify_credentials.granted_scope, (sizeof(info->granted_scope) - 1));
|
||||||
}
|
}
|
||||||
if (spotify_scope)
|
if (spotify_scope)
|
||||||
{
|
{
|
||||||
@ -1971,12 +2006,12 @@ spotifywebapi_access_token_get(struct spotifywebapi_access_token *info)
|
|||||||
|
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&token_lck));
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_lock(&token_lck));
|
||||||
|
|
||||||
if (token_requested > 0)
|
if (spotify_credentials.token_time_requested > 0)
|
||||||
info->expires_in = expires_in - difftime(time(NULL), token_requested);
|
info->expires_in = spotify_credentials.token_expires_in - difftime(time(NULL), spotify_credentials.token_time_requested);
|
||||||
else
|
else
|
||||||
info->expires_in = 0;
|
info->expires_in = 0;
|
||||||
|
|
||||||
info->token = safe_strdup(spotify_access_token);
|
info->token = safe_strdup(spotify_credentials.access_token);
|
||||||
|
|
||||||
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&token_lck));
|
CHECK_ERR(L_SPOTIFY, pthread_mutex_unlock(&token_lck));
|
||||||
}
|
}
|
||||||
@ -1999,11 +2034,7 @@ spotifywebapi_deinit()
|
|||||||
|
|
||||||
spotify_deinit();
|
spotify_deinit();
|
||||||
|
|
||||||
free(spotify_access_token);
|
free_credentials();
|
||||||
free(spotify_refresh_token);
|
|
||||||
free(spotify_granted_scope);
|
|
||||||
free(spotify_user_country);
|
|
||||||
free(spotify_user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct library_source spotifyscanner =
|
struct library_source spotifyscanner =
|
||||||
|
@ -52,6 +52,8 @@ spotifywebapi_fullrescan(void);
|
|||||||
void
|
void
|
||||||
spotifywebapi_rescan(void);
|
spotifywebapi_rescan(void);
|
||||||
void
|
void
|
||||||
|
spotifywebapi_purge(void);
|
||||||
|
void
|
||||||
spotifywebapi_pl_save(const char *uri);
|
spotifywebapi_pl_save(const char *uri);
|
||||||
void
|
void
|
||||||
spotifywebapi_pl_remove(const char *uri);
|
spotifywebapi_pl_remove(const char *uri);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user