Skip to content

Commit

Permalink
#879 Add support to browse an artist's album by release type and cont…
Browse files Browse the repository at this point in the history
…ribution.
  • Loading branch information
mherger committed Oct 12, 2023
1 parent ba4e305 commit 5598745
Show file tree
Hide file tree
Showing 11 changed files with 282 additions and 26 deletions.
32 changes: 31 additions & 1 deletion HTML/EN/html/docs/cli-api.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ <h3 id="Changelog">Changelog</h3>

<h4 id="8.4">Changes starting from Squeezebox Server 8.4</h4>
<ul>
<li>Added support for release types to <a href="#albums">albums</a>, and <a href="#titles">titles</a> queries.</li>
<li>Added support for release types and roles to <a href="#albums">albums</a>, and <a href="#titles">titles</a> queries.</li>
</ul>

<h4 id="8.2">Changes starting from Squeezebox Server 8.2</h4>
Expand Down Expand Up @@ -4005,6 +4005,17 @@ <h3 id="DB">
The album's external ID, if it is eg. from an online music service.
</td>
</tr>
<tr>
<td>
R
</td>
<td>
&nbsp;&nbsp;role_ids
</td>
<td>
A comma separated list of role ids for the album.
</td>
</tr>
<tr>
<td>
X
Expand Down Expand Up @@ -5110,6 +5121,17 @@ <h3 id="DB">
1 if the album this track belongs to is a compilation
</td>
</tr>
<tr>
<td>
<b>K</b>
</td>
<td>
artwork_url
</td>
<td>
A full URL to remote artwork. Only available for certain online music services.
</td>
</tr>
<tr>
<td>
<b>W</b>
Expand Down Expand Up @@ -5640,6 +5662,14 @@ <h3 id="DB">
of role IDs, or a comma separated list of role tokens (eg. ALBUMARTIST, ARTIST)
</td>
</tr>
<tr>
<td>
release_type
</td>
<td>
The release type of the track's album, eg. "album", "ep", etc.
</td>
</tr>
<tr>
<td>
library_id
Expand Down
29 changes: 21 additions & 8 deletions HTML/EN/settings/server/behavior.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,32 @@
[% END %]

[% WRAPPER settingSection %]
[% WRAPPER settingGroup title="SETUP_RELEASE_TYPES" desc="SETUP_RELEASE_TYPES_DESC"%]
[% FOREACH releaseType IN release_types %]
<input type="checkbox" [% IF NOT releaseType.ignore %]checked="1"[% END %] class="stdedit" name="release_type_[% releaseType.id %]" id="release_type_[% releaseType.id %]" value="1" />
<label for="release_type_[% releaseType.id %]" class="stdlabel">[% releaseType.title %]</label>[% IF loop.last; ""; ELSE; "<br/>"; END %]
[% END %]
[% END %]

[% WRAPPER settingGroup title="" desc=""%]
[% WRAPPER settingGroup title="SETUP_RELEASE_TYPES" desc=""%]
<select class="stdedit" name="pref_ignoreReleaseTypes" id="ignoreReleaseTypes">
<option [% IF NOT prefs.pref_ignoreReleaseTypes %]selected [% END %]value="0">[% 'SETUP_IGNORE_RELEASE_TYPES_0' | string %]</option>
<option [% IF prefs.pref_ignoreReleaseTypes %]selected [% END %]value="1">[% 'SETUP_IGNORE_RELEASE_TYPES_1' | string %]</option>
</select>
[% END %]

[% IF !prefs.pref_ignoreReleaseTypes; WRAPPER settingGroup title="" desc="" %]
<select class="stdedit" name="pref_groupArtistAlbumsByReleaseType" id="groupArtistAlbumsByReleaseType">
<option [% IF prefs.pref_groupArtistAlbumsByReleaseType %]selected [% END %]value="1">[% 'SETUP_GROUP_BY_RELEASE_TYPES_1' | string %]</option>
<option [% IF NOT prefs.pref_groupArtistAlbumsByReleaseType %]selected [% END %]value="0">[% 'SETUP_GROUP_BY_RELEASE_TYPES_0' | string %]</option>
</select>
[% END; ELSE %]
<input type="hidden" name="pref_groupArtistAlbumsByReleaseType" value="[% IF prefs.pref_groupArtistAlbumsByReleaseType %]1[% END %]">
[% END %]
[% END %]

[% IF !prefs.pref_ignoreReleaseTypes; WRAPPER setting title="SETUP_RELEASE_TYPES_INCLUDE" desc="SETUP_RELEASE_TYPES_DESC"%]
[% FOREACH releaseType IN release_types %]
<input type="checkbox" [% IF NOT releaseType.ignore %]checked="1"[% END %] class="stdedit" name="release_type_[% releaseType.id %]" id="release_type_[% releaseType.id %]" value="1" />
<label for="release_type_[% releaseType.id %]" class="stdlabel">[% releaseType.title %]</label>[% IF loop.last; ""; ELSE; "<br/>"; END %]
[% END %]
[% END; ELSE %]
[% FOREACH releaseType IN release_types %]
<input type="hidden" name="release_type_[% releaseType.id %]" value="[% IF NOT releaseType.ignore %]1[% END %]" />
[% END %]
[% END %]

[% WRAPPER setting title="SETUP_NOGENREFILTER" desc="SETUP_NOGENREFILTER_DESC"%]
Expand Down
21 changes: 20 additions & 1 deletion Slim/Control/Commands.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2062,6 +2062,10 @@ sub playlistcontrolCommand {
$info[0] = Slim::Schema->find('Contributor', $artist_id)->name;
}

if (defined(my $role_id = $request->getParam('role_id'))) {
$what->{'contributorTracks.role'} = $role_id;
}

if (defined(my $album_id = $request->getParam('album_id'))) {
$what->{'album.id'} = $album_id;
my $album = Slim::Schema->find('Album', $album_id);
Expand All @@ -2074,6 +2078,10 @@ sub playlistcontrolCommand {
$info[0] = $year;
}

if (defined(my $releaseType = $request->getParam('release_type'))) {
$what->{'album.release_type'} = uc($releaseType);
}

if (defined(my $library_id = $request->getParam('library_id'))) {
$what->{'libraryTracks.library'} = $library_id;
}
Expand Down Expand Up @@ -3345,6 +3353,13 @@ sub _playlistXtracksCommand_parseSearchTerms {
next;
}

elsif ($key eq 'contributorTracks.role') {
my @roles = split(/,\s*/, $value);
push @roles, 'ARTIST' if $value =~ /^(?:ALBUMARTIST|5)$/ && !$prefs->get('useUnifiedArtistsList');
$find{$key} = [ { 'in' => [ map { Slim::Schema::Contributor->typeToRole($_) || $_ } @roles ] } ];
next;
}

elsif (lc($key) eq 'librarytracks.library') {
$library_id = $value;
next;
Expand All @@ -3356,6 +3371,11 @@ sub _playlistXtracksCommand_parseSearchTerms {
$find{$key} = [ { 'is' => undef }, { '=' => 0 } ];
}

elsif ($key eq 'album.release_type') {
$find{$key} = [ {'=' => uc($value) } ];
$joinMap{'contributorTracks'} = { }
}

# Do some mapping from the player browse mode. This is
# already done in the web ui.
elsif ($key =~ /^(playlist|age|album|contributor|genre|year)$/) {
Expand Down Expand Up @@ -3434,7 +3454,6 @@ sub _playlistXtracksCommand_parseSearchTerms {
}
}

#
if ($find{'playlist.id'} && !$find{'me.id'}) {

# Treat playlists specially - they are containers.
Expand Down
26 changes: 22 additions & 4 deletions Slim/Control/Queries.pm
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ sub albumsQuery {
}

if (defined $releaseType) {
my @releaseTypes = split(',', $releaseType);
my @releaseTypes = map { uc($_) } split(',', $releaseType);
push @{$w}, 'albums.release_type IN (' . join(', ', map {'?'} @releaseTypes) . ')';
push @{$p}, @releaseTypes;
}
Expand Down Expand Up @@ -547,7 +547,7 @@ sub albumsQuery {
$c->{'albums.replay_gain'} = 1;
}

if ( $tags =~ /S/ ) {
if ( $tags =~ /R|S/ ) {
$c->{'albums.contributor'} = 1;
}

Expand Down Expand Up @@ -689,7 +689,7 @@ sub albumsQuery {
);
};

my ($contributorSql, $contributorSth, $contributorNameSth);
my ($contributorSql, $contributorSth, $contributorNameSth, $contributorRoleSth);
if ( $tags =~ /(?:aa|SS)/ ) {
my @roles = ( 'ARTIST', 'ALBUMARTIST' );

Expand Down Expand Up @@ -801,6 +801,16 @@ sub albumsQuery {
}
}

if ( $tags =~ /R/ ) {
$contributorRoleSth ||= $dbh->prepare_cached("SELECT role FROM contributor_album WHERE album = ? AND contributor = ?");
my $rolesRef = $dbh->selectall_arrayref($contributorRoleSth, , undef, $c->{'albums.id'}, $contributorID || $c->{'albums.contributor'});

if ($rolesRef) {
my $roles = join(',', map { $_->[0] } @$rolesRef);
$request->addResultLoopIfValueDefined($loopname, $chunkCount, 'role_ids', $roles);
}
}

$chunkCount++;

main::idleStreams() if !($chunkCount % 5);
Expand Down Expand Up @@ -4206,7 +4216,7 @@ sub titlesQuery {
my $libraryID = Slim::Music::VirtualLibraries->getRealId($request->getParam('library_id'));
my $year = $request->getParam('year');
my $menuStyle = $request->getParam('menuStyle') || 'item';

my $releaseType = $request->getParam('release_type');

# did we have override on the defaults?
# note that this is not equivalent to
Expand Down Expand Up @@ -4252,6 +4262,7 @@ sub titlesQuery {
contributorId => $contributorID,
trackId => $trackID,
roleId => $roleID,
releaseType => $releaseType,
libraryId => $libraryID,
limit => sub {
$count = shift;
Expand Down Expand Up @@ -5427,6 +5438,13 @@ sub _getTagDataForTracks {
}
};

if ( my $releaseType = $args->{releaseType} ) {
$join_albums->();
my @releaseTypes = map { uc($_) } split(',', $releaseType);
push @{$w}, 'albums.release_type IN (' . join(', ', map {'?'} @releaseTypes) . ')';
push @{$p}, @releaseTypes;
}

my $join_tracks_persistent = sub {
if ( main::STATISTICS && $sql !~ /JOIN tracks_persistent/ ) {
$sql .= 'LEFT JOIN tracks_persistent ON tracks_persistent.urlmd5 = tracks.urlmd5 ';
Expand Down
19 changes: 16 additions & 3 deletions Slim/Menu/BrowseLibrary.pm
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ should be passed a reference to a real sub (not an anonymous one).
use strict;
use JSON::XS::VersionOneAndTwo;

use Slim::Menu::BrowseLibrary::Releases;
use Slim::Music::VirtualLibraries;
use Slim::Utils::Cache;
use Slim::Utils::Log;
Expand Down Expand Up @@ -540,7 +541,7 @@ sub _registerBaseNodes {
type => 'link',
name => 'BROWSE_BY_ALBUM',
params => {mode => 'albums'},
feed => \&_albums,
feed => \&_albumsOrReleases,
icon => 'html/images/albums.png',
homeMenuText => 'BROWSE_ALBUMS',
condition => \&isEnabledNode,
Expand Down Expand Up @@ -578,7 +579,7 @@ sub _registerBaseNodes {
icon => 'html/images/newmusic.png',
params => {mode => 'albums', sort => 'new', wantMetadata => 1},
# including wantMetadata is a hack for ip3k
feed => \&_albums,
feed => \&_albumsOrReleases,
homeMenuText => 'BROWSE_NEW_MUSIC',
condition => \&isEnabledNode,
id => 'myMusicNewMusic',
Expand Down Expand Up @@ -1108,7 +1109,7 @@ sub _artists {
$_->{'name'} = $_->{'artist'};
$_->{'type'} = 'playlist';
$_->{'playlist'} = \&_tracks;
$_->{'url'} = \&_albums;
$_->{'url'} = \&_albumsOrReleases;
$_->{'passthrough'} = [ { searchTags => [@ptSearchTags, "artist_id:" . $_->{'id'}], remote_library => $remote_library } ];
$_->{'favorites_url'} = 'db:contributor.name=' .
URI::Escape::uri_escape_utf8( $_->{'name'} );
Expand Down Expand Up @@ -1384,6 +1385,18 @@ my %mapArtistOrders = (
artflow => 'yearalbum'
);

sub _albumsOrReleases {
my ($client, $callback, $args, $pt) = @_;
my @searchTags = $pt->{'searchTags'} ? @{$pt->{'searchTags'}} : ();

if ($prefs->get('groupArtistAlbumsByReleaseType') && grep /^artist_id:/, @searchTags) {
_releases(@_);
}
else {
_albums(@_);
}
}

sub _albums {
my ($client, $callback, $args, $pt) = @_;
my @searchTags = $pt->{'searchTags'} ? @{$pt->{'searchTags'}} : ();
Expand Down

0 comments on commit 5598745

Please sign in to comment.