mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-29 00:23:23 -05:00
[spotify] Use db_file_ping_bypath() + refactor + fix small memleak
Align with other scanners to use 1-query db_file_ping_bypath(). Also refactor to reduce indent level and fix memleak of mfi->album + mfi->album_artist.
This commit is contained in:
parent
10bd30c036
commit
c8edd2ff64
178
src/spotify.c
178
src/spotify.c
@ -1,7 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Espen Jürgensen <espenjurgensen@gmail.com>
|
* Copyright (C) 2016-17 Espen Jürgensen <espenjurgensen@gmail.com>
|
||||||
*
|
|
||||||
* Stiched together from libspotify examples
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -58,7 +56,6 @@
|
|||||||
#include "listener.h"
|
#include "listener.h"
|
||||||
|
|
||||||
/* TODO for the web api:
|
/* TODO for the web api:
|
||||||
* - UI should be prettier
|
|
||||||
* - map "added_at" to time_added
|
* - map "added_at" to time_added
|
||||||
* - what to do about the lack of push?
|
* - what to do about the lack of push?
|
||||||
* - use the web api more, implement proper init
|
* - use the web api more, implement proper init
|
||||||
@ -1968,16 +1965,15 @@ spotify_login(char **arglist)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
map_track_to_mfi(const struct spotify_track *track, struct media_file_info* mfi)
|
map_track_to_mfi(struct media_file_info* mfi, const struct spotify_track *track, const struct spotify_album *album, const char *pl_name)
|
||||||
{
|
{
|
||||||
|
char virtual_path[PATH_MAX];
|
||||||
|
|
||||||
mfi->title = safe_strdup(track->name);
|
mfi->title = safe_strdup(track->name);
|
||||||
mfi->album = safe_strdup(track->album);
|
|
||||||
mfi->artist = safe_strdup(track->artist);
|
mfi->artist = safe_strdup(track->artist);
|
||||||
mfi->album_artist = safe_strdup(track->album_artist);
|
|
||||||
mfi->disc = track->disc_number;
|
mfi->disc = track->disc_number;
|
||||||
mfi->song_length = track->duration_ms;
|
mfi->song_length = track->duration_ms;
|
||||||
mfi->track = track->track_number;
|
mfi->track = track->track_number;
|
||||||
mfi->compilation = track->is_compilation;
|
|
||||||
|
|
||||||
mfi->artwork = ARTWORK_SPOTIFY;
|
mfi->artwork = ARTWORK_SPOTIFY;
|
||||||
mfi->type = strdup("spotify");
|
mfi->type = strdup("spotify");
|
||||||
@ -1986,33 +1982,74 @@ map_track_to_mfi(const struct spotify_track *track, struct media_file_info* mfi)
|
|||||||
|
|
||||||
mfi->path = strdup(track->uri);
|
mfi->path = strdup(track->uri);
|
||||||
mfi->fname = strdup(track->uri);
|
mfi->fname = strdup(track->uri);
|
||||||
|
|
||||||
|
if (album)
|
||||||
|
{
|
||||||
|
mfi->album_artist = safe_strdup(album->artist);
|
||||||
|
mfi->album = safe_strdup(album->name);
|
||||||
|
mfi->genre = safe_strdup(album->genre);
|
||||||
|
mfi->compilation = album->is_compilation;
|
||||||
|
mfi->year = album->release_year;
|
||||||
|
mfi->time_modified = album->mtime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mfi->album_artist = safe_strdup(track->album_artist);
|
||||||
|
mfi->album = cfg_getbool(cfg_getsec(cfg, "spotify"), "album_override") ? safe_strdup(pl_name) : safe_strdup(track->album);
|
||||||
|
mfi->compilation = cfg_getbool(cfg_getsec(cfg, "spotify"), "artist_override") ? true : track->is_compilation;
|
||||||
|
mfi->time_modified = time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(virtual_path, PATH_MAX, "/spotify:/%s/%s/%s", mfi->album_artist, mfi->album, mfi->title);
|
||||||
|
mfi->virtual_path = strdup(virtual_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
map_album_to_mfi(const struct spotify_album *album, struct media_file_info* mfi)
|
webapi_track_save(struct spotify_track *track, struct spotify_album *album, const char *pl_name, int dir_id)
|
||||||
{
|
{
|
||||||
mfi->album = safe_strdup(album->name);
|
struct media_file_info mfi;
|
||||||
mfi->album_artist = safe_strdup(album->artist);
|
int ret;
|
||||||
mfi->genre = safe_strdup(album->genre);
|
|
||||||
mfi->compilation = album->is_compilation;
|
if (track->linked_from_uri)
|
||||||
mfi->year = album->release_year;
|
DPRINTF(E_DBG, L_SPOTIFY, "Track '%s' (%s) linked from %s\n", track->name, track->uri, track->linked_from_uri);
|
||||||
mfi->time_modified = album->mtime;
|
|
||||||
|
ret = db_file_ping_bypath(track->uri, track->mtime);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_SPOTIFY, "Track '%s' (%s) is new or modified (mtime is %" PRIi64 ")\n", track->name, track->uri, (int64_t)track->mtime);
|
||||||
|
|
||||||
|
memset(&mfi, 0, sizeof(struct media_file_info));
|
||||||
|
|
||||||
|
mfi.data_kind = DATA_KIND_SPOTIFY;
|
||||||
|
mfi.id = db_file_id_bypath(track->uri);
|
||||||
|
mfi.directory_id = dir_id;
|
||||||
|
|
||||||
|
map_track_to_mfi(&mfi, track, album, pl_name);
|
||||||
|
|
||||||
|
library_add_media(&mfi);
|
||||||
|
|
||||||
|
free_mfi(&mfi, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
spotify_uri_register(track->uri);
|
||||||
|
|
||||||
|
if (album)
|
||||||
|
cache_artwork_ping(track->uri, album->mtime, 0);
|
||||||
|
else
|
||||||
|
cache_artwork_ping(track->uri, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Thread: library */
|
/* Thread: library */
|
||||||
static int
|
static int
|
||||||
scan_saved_albums()
|
scan_saved_albums()
|
||||||
{
|
{
|
||||||
struct spotify_request request;
|
struct spotify_request request;
|
||||||
json_object *jsontracks;
|
|
||||||
int track_count;
|
|
||||||
struct spotify_album album;
|
struct spotify_album album;
|
||||||
struct spotify_track track;
|
struct spotify_track track;
|
||||||
struct media_file_info mfi;
|
json_object *jsontracks;
|
||||||
char virtual_path[PATH_MAX];
|
int track_count;
|
||||||
int dir_id;
|
int dir_id;
|
||||||
time_t stamp;
|
|
||||||
int id;
|
|
||||||
int i;
|
int i;
|
||||||
int count;
|
int count;
|
||||||
int ret;
|
int ret;
|
||||||
@ -2034,39 +2071,12 @@ scan_saved_albums()
|
|||||||
for (i = 0; i < track_count && ret == 0; i++)
|
for (i = 0; i < track_count && ret == 0; i++)
|
||||||
{
|
{
|
||||||
ret = spotifywebapi_album_track_fetch(jsontracks, i, &track);
|
ret = spotifywebapi_album_track_fetch(jsontracks, i, &track);
|
||||||
if (ret == 0 && track.uri)
|
if (ret < 0 || !track.uri)
|
||||||
{
|
continue;
|
||||||
db_file_stamp_bypath(track.uri, &stamp, &id);
|
|
||||||
if (stamp && (stamp >= track.mtime))
|
|
||||||
{
|
|
||||||
db_file_ping(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(&mfi, 0, sizeof(struct media_file_info));
|
|
||||||
|
|
||||||
mfi.id = id;
|
webapi_track_save(&track, &album, NULL, dir_id);
|
||||||
|
if (spotify_saved_plid)
|
||||||
map_track_to_mfi(&track, &mfi);
|
db_pl_add_item_bypath(spotify_saved_plid, track.uri);
|
||||||
map_album_to_mfi(&album, &mfi);
|
|
||||||
|
|
||||||
mfi.data_kind = DATA_KIND_SPOTIFY;
|
|
||||||
snprintf(virtual_path, PATH_MAX, "/spotify:/%s/%s/%s", mfi.album_artist, mfi.album, mfi.title);
|
|
||||||
mfi.virtual_path = strdup(virtual_path);
|
|
||||||
mfi.directory_id = dir_id;
|
|
||||||
|
|
||||||
library_add_media(&mfi);
|
|
||||||
|
|
||||||
free_mfi(&mfi, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
spotify_uri_register(track.uri);
|
|
||||||
|
|
||||||
cache_artwork_ping(track.uri, album.mtime, 0);
|
|
||||||
|
|
||||||
if (spotify_saved_plid)
|
|
||||||
db_pl_add_item_bypath(spotify_saved_plid, track.uri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db_transaction_end();
|
db_transaction_end();
|
||||||
@ -2086,79 +2096,27 @@ scan_saved_albums()
|
|||||||
static int
|
static int
|
||||||
scan_playlisttracks(struct spotify_playlist *playlist, int plid)
|
scan_playlisttracks(struct spotify_playlist *playlist, int plid)
|
||||||
{
|
{
|
||||||
cfg_t *spotify_cfg;
|
|
||||||
bool artist_override;
|
|
||||||
bool album_override;
|
|
||||||
struct spotify_request request;
|
struct spotify_request request;
|
||||||
struct spotify_track track;
|
struct spotify_track track;
|
||||||
struct media_file_info mfi;
|
|
||||||
char virtual_path[PATH_MAX];
|
|
||||||
int dir_id;
|
int dir_id;
|
||||||
time_t stamp;
|
|
||||||
int id;
|
|
||||||
|
|
||||||
memset(&request, 0, sizeof(struct spotify_request));
|
memset(&request, 0, sizeof(struct spotify_request));
|
||||||
|
|
||||||
spotify_cfg = cfg_getsec(cfg, "spotify");
|
|
||||||
artist_override = cfg_getbool(spotify_cfg, "artist_override");
|
|
||||||
album_override = cfg_getbool(spotify_cfg, "album_override");
|
|
||||||
|
|
||||||
while (0 == spotifywebapi_request_next(&request, playlist->tracks_href, true))
|
while (0 == spotifywebapi_request_next(&request, playlist->tracks_href, true))
|
||||||
{
|
{
|
||||||
db_transaction_begin();
|
db_transaction_begin();
|
||||||
|
|
||||||
// DPRINTF(E_DBG, L_SPOTIFY, "Playlist tracks\n%s\n", request.response_body);
|
|
||||||
while (0 == spotifywebapi_playlisttracks_fetch(&request, &track))
|
while (0 == spotifywebapi_playlisttracks_fetch(&request, &track))
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_SPOTIFY, "Got playlist track: '%s' (%s) \n", track.name, track.uri);
|
if (!track.uri || !track.is_playable)
|
||||||
|
|
||||||
if (!track.is_playable)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SPOTIFY, "Track not available for playback: '%s' - '%s' (%s) (restrictions: %s)\n", track.artist, track.name, track.uri, track.restrictions);
|
DPRINTF(E_LOG, L_SPOTIFY, "Track not available for playback: '%s' - '%s' (%s) (restrictions: %s)\n", track.artist, track.name, track.uri, track.restrictions);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (track.uri)
|
dir_id = prepare_directories(track.album_artist, track.album);
|
||||||
{
|
webapi_track_save(&track, NULL, playlist->name, dir_id);
|
||||||
if (track.linked_from_uri)
|
db_pl_add_item_bypath(plid, track.uri);
|
||||||
DPRINTF(E_DBG, L_SPOTIFY, "Track '%s' (%s) linked from %s\n", track.name, track.uri, track.linked_from_uri);
|
|
||||||
|
|
||||||
db_file_stamp_bypath(track.uri, &stamp, &id);
|
|
||||||
if (stamp)
|
|
||||||
{
|
|
||||||
db_file_ping(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memset(&mfi, 0, sizeof(struct media_file_info));
|
|
||||||
|
|
||||||
mfi.id = id;
|
|
||||||
|
|
||||||
dir_id = prepare_directories(track.album_artist, track.album);
|
|
||||||
|
|
||||||
map_track_to_mfi(&track, &mfi);
|
|
||||||
|
|
||||||
mfi.compilation = (track.is_compilation || artist_override);
|
|
||||||
if (album_override)
|
|
||||||
{
|
|
||||||
free(mfi.album);
|
|
||||||
mfi.album = strdup(playlist->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
mfi.time_modified = time(NULL);
|
|
||||||
mfi.data_kind = DATA_KIND_SPOTIFY;
|
|
||||||
snprintf(virtual_path, PATH_MAX, "/spotify:/%s/%s/%s", mfi.album_artist, mfi.album, mfi.title);
|
|
||||||
mfi.virtual_path = strdup(virtual_path);
|
|
||||||
mfi.directory_id = dir_id;
|
|
||||||
|
|
||||||
library_add_media(&mfi);
|
|
||||||
free_mfi(&mfi, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
spotify_uri_register(track.uri);
|
|
||||||
cache_artwork_ping(track.uri, 1, 0);
|
|
||||||
db_pl_add_item_bypath(plid, track.uri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db_transaction_end();
|
db_transaction_end();
|
||||||
@ -2318,7 +2276,7 @@ initscan()
|
|||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SPOTIFY, "Spotify webapi token refresh failed. "
|
DPRINTF(E_LOG, L_SPOTIFY, "Spotify webapi token refresh failed. "
|
||||||
"In order to use the web api, authorize forked-daapd to access "
|
"In order to use the web api, authorize forked-daapd to access "
|
||||||
"your saved tracks by visiting http://forked-daapd.local:3689/oauth\n");
|
"your saved tracks by visiting http://forked-daapd.local:3689\n");
|
||||||
|
|
||||||
db_spotify_purge();
|
db_spotify_purge();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user