Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 98 additions & 18 deletions Slim/Control/Queries.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4740,6 +4740,8 @@ sub titlesQuery {
my $ignoreWorkTracks = $request->getParam('ignore_work_tracks');
my $performance = $request->getParam('performance');
my $onlyAlbumYears = $request->getParam('only_album_years');
my $remoteAlbumId = $request->getParam('remote_album_id');
my $onlineService = $request->getParam('service');

# did we have override on the defaults?
# note that this is not equivalent to
Expand Down Expand Up @@ -4795,6 +4797,8 @@ sub titlesQuery {
workId => $workID,
libraryId => $libraryID,
onlyAlbumYears=> $onlyAlbumYears,
remoteAlbumId => $remoteAlbumId,
onlineService => $onlineService,
limit => sub {
$count = shift;

Expand All @@ -4813,26 +4817,67 @@ sub titlesQuery {

$count += 0;

my $loopname = 'titles_loop';
# this is the count of items in this part of the request (e.g., menu 100 200)
# not to be confused with $count, which is the count of the entire list
my $chunkCount = 0;
# is it a remote album that's not in the database?
my $handler;
if ( !scalar @{$itemOrder} && $remoteAlbumId && $onlineService ) {
my $url = $onlineService . ':album:' . $remoteAlbumId;
$handler = Slim::Player::ProtocolHandlers->handlerForURL($url);
}
#---
# this change gets rendered by git diff in a very confusing way. All we're doing is adding this "if" and indenting
# the existing code in an "else".
if ( $handler && $handler->can('getAlbumTracks') ) {
# we have an online service handler that can return album tracks in the expected format

$request->setStatusProcessing();
$handler->getAlbumTracks(sub{
($items, $itemOrder, $totalCount) = @_;

if ( scalar @{$itemOrder} ) {
my $loopname = 'titles_loop';
my $chunkCount = 0;

for my $trackId ( @{$itemOrder} ) {
my $item = $items->{$trackId};
if ( scalar @{$itemOrder} ) {

_addSong($request, $loopname, $chunkCount, $item, $tags);
for my $trackId ( @{$itemOrder} ) {
my $item = $items->{$trackId};

$chunkCount++;
}
_addSong($request, $loopname, $chunkCount, $item, $tags);

$chunkCount++;
}

}

$request->addResult('count', $totalCount);

$request->setStatusDone();
}, $request->client, $remoteAlbumId);

}
#---
else {

$request->addResult('count', $totalCount);
my $loopname = 'titles_loop';
# this is the count of items in this part of the request (e.g., menu 100 200)
# not to be confused with $count, which is the count of the entire list
my $chunkCount = 0;

$request->setStatusDone();
if ( scalar @{$itemOrder} ) {

for my $trackId ( @{$itemOrder} ) {
my $item = $items->{$trackId};

_addSong($request, $loopname, $chunkCount, $item, $tags);

$chunkCount++;
}

}

$request->addResult('count', $totalCount);

$request->setStatusDone();
}
}


Expand Down Expand Up @@ -5823,17 +5868,33 @@ sub _songData {
$song = $client->currentSongForUrl($url);
}

my $service;
if ( $isRemote ) {
my $handler = Slim::Player::ProtocolHandlers->handlerForURL($url);

if ( $handler && $handler->can('getMetadataFor') ) {
$service = (split(/:/, $url))[0];
# Don't modify source data
$remoteMeta = Storable::dclone(
$handler->getMetadataFor( $request->client, $url )
);

# if the artist is in the database, use their local id. If not, use the remote service id multiplied by -1
# so clients can distinguish between the two possibilities.
#-------------------------------------------------------------------------------------
### !!! Needs extra thought here: what if the remote service artist id is not numeric?
#-------------------------------------------------------------------------------------
my @extArtistIds = split /,/, $remoteMeta->{artistId};
my @artistIds;
foreach (@extArtistIds) {
my $artistObj = Slim::Schema->rs("Contributor")->search( extid => "$service:artist:$_" )->single;
push @artistIds, $artistObj ? $artistObj->id : $_ * -1;
}
$remoteMeta->{artistId} = join ',', @artistIds;

$remoteMeta->{a} = $remoteMeta->{artist};
$remoteMeta->{A} = $remoteMeta->{artist};
$remoteMeta->{e} = $remoteMeta->{albumId};
$remoteMeta->{E} = $remoteMeta->{extid};
$remoteMeta->{l} = $remoteMeta->{album};
$remoteMeta->{i} = $remoteMeta->{disc};
Expand Down Expand Up @@ -5877,6 +5938,7 @@ sub _songData {

$returnHash{'id'} = $track->id;
$returnHash{'title'} = $remoteMeta->{title} || $track->title;
$returnHash{'service_id'} = $service if $service;
my %seen;

# loop so that stuff is returned in the order given...
Expand Down Expand Up @@ -5906,6 +5968,15 @@ sub _songData {
elsif ($tag eq 'b') {
$returnHash{work} = $remoteMeta->{$tag};
$returnHash{composer} = $remoteMeta->{composer} if $remoteMeta->{composer};
# if the composer is in the database, use their local id. If not, use the remote service id multiplied by -1
# so clients can distinguish between the two possibilities.
#-------------------------------------------------------------------------------------
### !!! Needs extra thought here: what if the remote service composer id is not numeric?
#-------------------------------------------------------------------------------------
if ( $remoteMeta->{composerId} ) {
my $composerObj = Slim::Schema->rs("Contributor")->search( extid => "$service:artist:" . $remoteMeta->{composerId} )->single;
$returnHash{composer_ids} = $composerObj ? $composerObj->id . "" : $remoteMeta->{composerId} * -1 . "";
}
}

# Special case for 2: at track level, triggers addition of the play queue context $addedFromWork
Expand All @@ -5917,6 +5988,7 @@ sub _songData {
elsif ($tag eq 'A' || $tag eq 'S') {
if ( my $meta = $remoteMeta->{$tag} ) {
$returnHash{artist} = $meta;
$returnHash{artist_ids} = $remoteMeta->{artistId} if $remoteMeta->{artistId};
next;
}
elsif ( $track->isa('Slim::Schema::RemoteTrack')) {
Expand Down Expand Up @@ -6005,6 +6077,7 @@ sub _songData {
}
# we might need to proxy the image request to resize it
elsif ($tag eq 'K' && $value) {
$returnHash{baseImage} = URI::Escape::uri_escape_utf8($value);
$value = proxiedImage($value);
}

Expand Down Expand Up @@ -6289,12 +6362,6 @@ sub _getTagDataForTracks {
}
}

if ( my $libraryId = Slim::Music::VirtualLibraries->getRealId($args->{libraryId}) ) {
$sql .= 'JOIN library_track ON library_track.track = tracks.id ';
push @{$w}, 'library_track.library = ?';
push @{$p}, $libraryId;
}

# Some helper functions to setup joins with less code
my $join_genre_track = sub {
if ( $sql !~ /JOIN genre_track/ ) {
Expand Down Expand Up @@ -6336,6 +6403,19 @@ sub _getTagDataForTracks {
}
};

if ( $args->{remoteAlbumId} && $args->{onlineService} ) {
# allow retrieval of track by remote album id.
my $remoteAlbumId = $args->{remoteAlbumId};
my $onlineService = $args->{onlineService};
$join_albums->();
push @{$w}, 'albums.extid = ?';
push @{$p}, $onlineService . ':album:' . $remoteAlbumId;
} elsif ( my $libraryId = Slim::Music::VirtualLibraries->getRealId($args->{libraryId}) ) {
$sql .= 'JOIN library_track ON library_track.track = tracks.id ';
push @{$w}, 'library_track.library = ?';
push @{$p}, $libraryId;
}

if ( my $year = $args->{year} ) {
push @{$w}, 'tracks.year = ?';
push @{$p}, $year;
Expand Down
8 changes: 5 additions & 3 deletions Slim/Control/XMLBrowser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ my %colMap = (
G => 'genres',
i => 'discnum',
k => 'description',
l => ['album','version'],
l => ['album','version','remoteAlbumId'],
q => 'disccount',
t => ['tracknum','title','titleFlags'],
# "date" is being used in Podcast episodes
y => ['year','date'],
'y' => ['year','date'],
);

sub cliQuery {
Expand Down Expand Up @@ -695,7 +695,7 @@ sub _cliQuery_done {
&& (defined $subFeed->{'name'} || defined $subFeed->{'title'})
&& ($method !~ /all/)) {

my $title = $subFeed->{'name'} || $subFeed->{'title'};
my $title = $subFeed->{'album'} && $subFeed->{'artist'} ? $subFeed->{'title'} : $subFeed->{'name'};
my $url = $subFeed->{'url'};

# Podcast enclosures
Expand All @@ -721,6 +721,8 @@ sub _cliQuery_done {
bitrate => $subFeed->{'bitrate'},
cover => $subFeed->{'cover'} || $subFeed->{'image'} || $subFeed->{'icon'} || $request->getParam('icon'),
year => $subFeed->{'year'},
album => $subFeed->{'album'},
artist => $subFeed->{'artist'},
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about these _cliQuery_done changes: may be left over from my branch which included changes for Default and Classic skins?

} );

$client->execute([ 'playlist', $method, $url ]);
Expand Down
10 changes: 6 additions & 4 deletions Slim/Schema.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2824,13 +2824,15 @@ sub _preCheckAttributes {
# since the tag may need to be split. See bugs #295 and #4584.
#
# Push these back until we have a Track object.
for my $tag (Slim::Schema::Contributor->contributorRoles, (map { $_ . 'SORT' } Slim::Schema::Contributor->contributorRoles()),
for my $tag (Slim::Schema::Contributor->contributorRoles,
(map { $_ . 'SORT' } Slim::Schema::Contributor->contributorRoles()),
(map { $_ . '_EXTID' } Slim::Schema::Contributor->contributorRoles()),
qw(
COMMENT GENRE PIC APIC ALBUM ALBUMSORT DISCC
COMPILATION REPLAYGAIN_ALBUM_PEAK REPLAYGAIN_ALBUM_GAIN
MUSICBRAINZ_ARTIST_ID MUSICBRAINZ_ALBUMARTIST_ID MUSICBRAINZ_ALBUM_ID
MUSICBRAINZ_ALBUM_TYPE MUSICBRAINZ_ALBUM_STATUS RELEASETYPE
ALBUM_EXTID ARTIST_EXTID WORK WORKSORT
ALBUM_EXTID WORK WORKSORT
))
{

Expand Down Expand Up @@ -3114,6 +3116,7 @@ sub _mergeAndCreateContributors {
# Bug: 6507 - use any ARTISTSORT tag for this contributor
$attributes->{'TRACKARTISTSORT'} = delete $attributes->{'ARTISTSORT'};
$attributes->{'MUSICBRAINZ_TRACKARTIST_ID'} = delete $attributes->{'MUSICBRAINZ_ARTIST_ID'} if $attributes->{'MUSICBRAINZ_ARTIST_ID'};
$attributes->{'TRACKARTIST_EXTID'} = delete $attributes->{'ARTIST_EXTID'};

main::DEBUGLOG && $isDebug && $log->debug(sprintf("-- Contributor '%s' of role 'ARTIST' transformed to role 'TRACKARTIST'",
$attributes->{'TRACKARTIST'},
Expand All @@ -3138,8 +3141,7 @@ sub _mergeAndCreateContributors {
'artist' => $contributor,
'brainzID' => $attributes->{"MUSICBRAINZ_${tag}_ID"},
'sortBy' => $attributes->{$tag.'SORT'},
# only store EXTID for track artist, as we don't have it for other roles
'extid' => $tag eq 'ARTIST' && $attributes->{'ARTIST_EXTID'},
'extid' => $attributes->{"${tag}_EXTID"},
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These Slim::Schema changes just ensure we populate *_EXTID for all roles for which we have it, certainly the Qobuz plugin provides extid for Composers, at least.

Could be made into a separate PR, hopefully uncontroversial?

});

main::DEBUGLOG && $isDebug && $log->is_debug && $log->debug(sprintf("-- Track has contributor '$contributor' of role '$tag'"));
Expand Down
21 changes: 19 additions & 2 deletions Slim/Schema/RemoteTrack.pm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use strict;
use base qw(Slim::Utils::Accessor);

use Scalar::Util qw(blessed);
use Digest::MD5 qw(md5_hex);
use Tie::Cache::LRU;

use Slim::Utils::Cache;
Expand Down Expand Up @@ -63,6 +64,7 @@ my @allAttributes = (qw(
performance
discsubtitle
added_from_work
artistid
));

{
Expand Down Expand Up @@ -110,7 +112,7 @@ sub init {

# Emulate absent methods - hopefully these can be retired at some time
sub artists {return ();}
sub artistid {}
#sub artistid {}
sub genres {return ();}
sub genrename {}
sub genreid {}
Expand Down Expand Up @@ -349,6 +351,21 @@ my $separator;
sub setAttributes {
my ($self, $attributes) = @_;

#--------------
# leaving this here as a reminder, commented out for now, because something like this is required to make sure that the play queue
# is formatted correctly after a restart in default/classic skins. But it needs amendment because it causes problems
# for plugins (eg BBC Sounds) where getMetadataFor fails without a client.
#--------------
# my $url = $self->_url;
# if ( $url !~ "^http" && Slim::Music::Info::isRemoteURL($url) ) {
# my $handler = Slim::Player::ProtocolHandlers->handlerForURL( $url );
# if ( $handler && $handler->can('getMetadataFor') ) {
# if ( my $meta = $handler->getMetadataFor( undef, $url ) ) {;
# $attributes = $meta;
# }
# }
# }

%availableTags = map { $_ => 1 } @allAttributes unless keys %availableTags;

main::DEBUGLOG && $log->is_debug && $log->debug($self->url . " => ", Data::Dump::dump($attributes));
Expand All @@ -375,7 +392,7 @@ sub setAttributes {
main::DEBUGLOG && $log->is_debug && defined $self->$key() && $self->$key() ne $value &&
$log->debug("$key: ", $self->$key(), "=>$value");

$self->$key($value);
$self->$key($value) if !$self->$key || $value;
}
}

Expand Down