Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
7 changes: 6 additions & 1 deletion HTML/Default/status_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@
[% IF item.includeAlbum && item.album.defined && item.album != noAlbum %]
<div class="playlistSongDetail">
[% IF item.album_id %]
<a href="[% webroot %]clixmlbrowser/clicmd=browselibrary+items&amp;mode=albums&amp;linktitle=[% stringALBUM %]%20([% item.album | uri %])&amp;album_id=[% item.album_id %]&amp;player=[% playerURI %]/index.html?index=0" target="browser" class="browseItemLink"><span>[% item.album | html %]</span></a>
[% IF item.version;
album_and_version = item.album _ ' [' _ item.version _ ']' ;
ELSE;
album_and_version = item.album;
END %]
<a href="[% webroot %]clixmlbrowser/clicmd=browselibrary+items&amp;mode=albums&amp;linktitle=[% stringALBUM %]%20([% item.album | uri %])&amp;album_id=[% item.album_id %]&amp;player=[% playerURI %]/index.html?index=0" target="browser" class="browseItemLink"><span>[% album_and_version | html %]</span></a>
[% ELSE %][% item.album | html %][% END %]
</div>
[% END %]
Expand Down
10 changes: 10 additions & 0 deletions HTML/EN/html/SqueezeJS/Base.js
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,16 @@ SqueezeJS.SonginfoParser = {
});
},

version : function(result, noLink){
var version;

if (result.playlist_tracks > 0 && result.playlist_loop[0].version) {
version = result.playlist_loop[0].version;
}

return version;
},

bitrate : function(result){
var bitrate = '';

Expand Down
6 changes: 4 additions & 2 deletions HTML/EN/html/SqueezeJS/UI.js
Original file line number Diff line number Diff line change
Expand Up @@ -1559,14 +1559,16 @@ SqueezeJS.UI.CompoundTitle = Ext.extend(SqueezeJS.UI.Component, {
SqueezeJS.UI.Album = Ext.extend(SqueezeJS.UI.Component, {
onPlayerStateChange : function(result){
var year = SqueezeJS.SonginfoParser.year(result, this.noLink);
var version = SqueezeJS.SonginfoParser.version(result, this.noLink);
this.el.update(SqueezeJS.SonginfoParser.album(result, this.noLink)
+ (year ? '&nbsp;(' + year + ')' : ''));
+ (year ? '&nbsp;(' + year + ')' : '') + (version ? '&nbsp;[' + version + ']' : '') );
}
});

SqueezeJS.UI.AlbumTitle = Ext.extend(SqueezeJS.UI.Component, {
onPlayerStateChange : function(result){
this.el.update(SqueezeJS.SonginfoParser.album(result, this.noLink));
var version = SqueezeJS.SonginfoParser.version(result, this.noLink);
this.el.update(SqueezeJS.SonginfoParser.album(result, this.noLink) + (version ? '&nbsp;[' + version + ']' : ''));
}
});

Expand Down
Empty file added SQL/SQLite/schema_26_down.sql
Empty file.
24 changes: 24 additions & 0 deletions SQL/SQLite/schema_26_up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ALTER TABLE albums ADD version blob;
ALTER TABLE tracks ADD lms_persistent_id text;
DROP INDEX IF EXISTS albumsLabelIndex;
CREATE INDEX albumsLabelIndex ON albums (label);
DROP TABLE IF EXISTS labels;
CREATE TABLE labels (
id integer PRIMARY KEY AUTOINCREMENT,
name blob,
namesort text,
namesearch text
);
DROP TABLE IF EXISTS label_album;
CREATE TABLE label_album (
label int(10),
album int(10),
PRIMARY KEY (label,album),
FOREIGN KEY (`album`) REFERENCES `albums` (`id`) ON DELETE CASCADE,
FOREIGN KEY (`label`) REFERENCES `labels` (`id`) ON DELETE CASCADE
);
DROP INDEX IF EXISTS label_albumAlbumIndex;
CREATE INDEX label_albumAlbumIndex ON label_album (album);
DROP INDEX IF EXISTS label_albumLabelIndex;
CREATE INDEX label_albumLabelIndex ON label_album (label);

Empty file added SQL/mysql/schema_26_down.sql
Empty file.
24 changes: 24 additions & 0 deletions SQL/mysql/schema_26_up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ALTER TABLE albums ADD version blob;
ALTER TABLE tracks ADD lms_persistent_id text;
DROP INDEX IF EXISTS albumsLabelIndex;
CREATE INDEX albumsLabelIndex ON albums (label);
DROP TABLE IF EXISTS labels;
CREATE TABLE labels (
id integer PRIMARY KEY AUTOINCREMENT,
name blob,
namesort text,
namesearch text
);
DROP TABLE IF EXISTS label_album;
CREATE TABLE label_album (
label int(10),
album int(10),
PRIMARY KEY (label,album),
FOREIGN KEY (`album`) REFERENCES `albums` (`id`) ON DELETE CASCADE,
FOREIGN KEY (`label`) REFERENCES `labels` (`id`) ON DELETE CASCADE
);
DROP INDEX IF EXISTS label_albumAlbumIndex;
CREATE INDEX label_albumAlbumIndex ON label_album (album);
DROP INDEX IF EXISTS label_albumLabelIndex;
CREATE INDEX label_albumLabelIndex ON label_album (label);

1 change: 1 addition & 0 deletions Slim/Control/Commands.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3598,6 +3598,7 @@ sub _playlistXtracksCommand_parseDbItem {
my $lcClass = lc($class);
$classes{Album} = Slim::Schema->search('Album', {
titlesearch => $albumObj->titlesearch,
version => $albumObj->version,
"$lcClass.$key" => $value,
},{
prefetch => $lcClass
Expand Down
31 changes: 24 additions & 7 deletions Slim/Control/Queries.pm
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ sub albumsQuery {

if ( $tags =~ /l/ ) {
# title/disc/discc is needed to construct (N of M) title
map { $c->{$_} = 1 } qw(albums.title albums.disc albums.discc);
map { $c->{$_} = 1 } qw(albums.title albums.version albums.disc albums.discc);
}

if ( $tags =~ /y/ ) {
Expand Down Expand Up @@ -804,6 +804,7 @@ sub albumsQuery {
while ( $sth->fetch ) {

utf8::decode( $c->{'albums.title'} ) if exists $c->{'albums.title'};
utf8::decode( $c->{'albums.version'} ) if exists $c->{'albums.version'};
utf8::decode( $c->{'works.title'} ) if exists $c->{'works.title'};
utf8::decode( $c->{'composer.name'} ) if exists $c->{'composer.name'};
utf8::decode( $c->{'tracks.performance'} ) if exists $c->{'tracks.performance'};
Expand All @@ -814,23 +815,31 @@ sub albumsQuery {
$request->addResultLoopIfValueDefined($loopname, $chunkCount, 'composer', $c->{'composer.name'});
$request->addResultLoop($loopname, $chunkCount, 'performance', $c->{'tracks.performance'}||"");

my $favoritesUrl = $work
? sprintf('db:album.title=%s&contributor.name=%s&work.title=%s&composer.name=%s&track.performance=%s',
URI::Escape::uri_escape_utf8($c->{'albums.title'}), URI::Escape::uri_escape_utf8($c->{'contributors.name'}),
URI::Escape::uri_escape_utf8($c->{'works.title'}), URI::Escape::uri_escape_utf8($c->{'composer.name'}), URI::Escape::uri_escape_utf8($c->{'tracks.performance'}))
: sprintf('db:album.title=%s&contributor.name=%s', URI::Escape::uri_escape_utf8($c->{'albums.title'}), URI::Escape::uri_escape_utf8($c->{'contributors.name'}));
my $favoritesUrl = sprintf('db:album.title=%s', URI::Escape::uri_escape_utf8($c->{'albums.title'}));
if ( $c->{'albums.version'} ) {
$favoritesUrl .= sprintf('&album.version=%s', URI::Escape::uri_escape_utf8($c->{'albums.version'}));
}
$favoritesUrl .= $work
? sprintf('&contributor.name=%s&work.title=%s&composer.name=%s&track.performance=%s',
URI::Escape::uri_escape_utf8($c->{'contributors.name'}), URI::Escape::uri_escape_utf8($c->{'works.title'}),
URI::Escape::uri_escape_utf8($c->{'composer.name'}), URI::Escape::uri_escape_utf8($c->{'tracks.performance'}))
: sprintf('&contributor.name=%s', URI::Escape::uri_escape_utf8($c->{'contributors.name'}));
# even if we have an extid, it cannot be used when we're dealing here with a work, which is a subset of the album.
$request->addResultLoop($loopname, $chunkCount, 'favorites_url', $c->{'albums.extid'} && !$c->{'tracks.work'} ? $c->{'albums.extid'} : $favoritesUrl);
my $favoritesTitle = $c->{'albums.title'};
$favoritesTitle .= ' [' . $c->{'albums.version'} . ']' if $c->{'albums.version'};
if ( $work ) {
$favoritesTitle = $c->{'composer.name'} ? $c->{'composer.name'} . cstring($client, 'COLON') . ' ' : '';
$favoritesTitle .= $c->{'works.title'} . ' (';
$favoritesTitle .= "$c->{'tracks.performance'} " if $c->{'tracks.performance'};
$favoritesTitle .= cstring($client,'FROM') . ' ' . $c->{'albums.title'} . ')';
$favoritesTitle .= cstring($client,'FROM') . ' ' . $c->{'albums.title'};
$favoritesTitle .= ' [' . $c->{'albums.version'} . ']' if $c->{'albums.version'};
$favoritesTitle .= ')';
}
$request->addResultLoop($loopname, $chunkCount, 'favorites_title', $favoritesTitle);

$tags =~ /l/ && $request->addResultLoop($loopname, $chunkCount, 'album', $construct_title->());
$tags =~ /l/ && $request->addResultLoop($loopname, $chunkCount, 'version', $c->{'albums.version'});
$tags =~ /y/ && $request->addResultLoopIfValueDefined($loopname, $chunkCount, 'year', $c->{'albums.year'});
$tags =~ /j/ && $request->addResultLoopIfValueDefined($loopname, $chunkCount, 'artwork_track_id', $c->{'albums.artwork'}) if ($c->{'albums.artwork'} || '') !~ /^https?:/;;
$tags =~ /K/ && $request->addResultLoopIfValueDefined($loopname, $chunkCount, 'artwork_url', $c->{'albums.artwork'}) if ($c->{'albums.artwork'} || '') =~ /^https?:/;
Expand Down Expand Up @@ -5660,6 +5669,12 @@ sub _songDataFromHash {
}
}

# Special case for l (albums.title), return albums.version as well
elsif ( $tag eq 'l' ) {
$returnHash{'album'} = $res->{'albums.title'} if $res->{'albums.title'};
$returnHash{'version'} = $res->{'albums.version'} if $res->{'albums.version'};
}

# Special case for b (work), return work_id as well
elsif ( $tag eq 'b' ) {
$returnHash{'work'} = $res->{'works.title'} if $res->{'works.title'};
Expand Down Expand Up @@ -6391,6 +6406,7 @@ sub _getTagDataForTracks {
$tags =~ /l/ && do {
$join_albums->();
$c->{'albums.title'} = 1;
$c->{'albums.version'} = 1;
};

$tags =~ /q/ && do {
Expand Down Expand Up @@ -6517,6 +6533,7 @@ sub _getTagDataForTracks {
utf8::decode( $c->{'works.title'} ) if exists $c->{'works.title'};
utf8::decode( $c->{'tracks.lyrics'} ) if exists $c->{'tracks.lyrics'};
utf8::decode( $c->{'albums.title'} ) if exists $c->{'albums.title'};
utf8::decode( $c->{'albums.version'} ) if exists $c->{'albums.version'};
utf8::decode( $c->{'contributors.name'} ) if exists $c->{'contributors.name'};
utf8::decode( $c->{'genres.name'} ) if exists $c->{'genres.name'};
utf8::decode( $c->{'comments.value'} ) if exists $c->{'comments.value'};
Expand Down
1 change: 1 addition & 0 deletions Slim/Menu/AlbumInfo.pm
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ sub infoAlbum {
my $item;
my $library_id = $filter->{library_id} || Slim::Music::VirtualLibraries->getLibraryIdForClient($client);
my $albumName = $album->title;
$albumName .= ' [' . $album->version . ']' if $album->version;
my $totalAlbumTracks = $album->tracks->count;

if ( $albumName && $totalAlbumTracks > $filter->{track_count} ) {
Expand Down
5 changes: 3 additions & 2 deletions Slim/Menu/BrowseLibrary.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1534,8 +1534,9 @@ sub _albums {
$_->{'name'} .= "$_->{'performance'} " if $_->{'performance'};
$_->{'name'} .= cstring($client,'FROM') . ' ';
}
$_->{'name'} .= $_->{'album'};
$_->{'name'} .= ')' if $_->{'work_id'};
$_->{'name'} .= $_->{'album'};
$_->{'name'} .= ' [' . $_->{'version'} . ']' if $_->{'version'};
$_->{'name'} .= ')' if $_->{'work_id'};
$_->{'image'} = 'music/' . $_->{'artwork_track_id'} . '/cover' if $_->{'artwork_track_id'};
$_->{'image'} ||= $_->{'artwork_url'} if $_->{'artwork_url'};
$_->{'type'} = 'playlist';
Expand Down
15 changes: 14 additions & 1 deletion Slim/Schema.pm
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,7 @@ sub _objForDbUrl {
if ($term =~ /(.*)=(.*)/) {
my $key = $1;
my $value = Slim::Utils::Misc::unescape($2);
$key = 'me.version' if $key eq 'album.version';

if (utf8::is_utf8($value)) {
utf8::decode($value);
Expand Down Expand Up @@ -904,6 +905,7 @@ sub _createOrUpdateAlbum {

# Now handle Album creation
my $title = $attributes->{ALBUM};
my $version = $attributes->{VERSION};
my $disc = $attributes->{DISC};
my $discc = $attributes->{DISCC};
# Bug 10583 - Also check for MusicBrainz Album Id
Expand Down Expand Up @@ -1046,6 +1048,7 @@ sub _createOrUpdateAlbum {
( $lastAlbum->{_dirname}
&& $lastAlbum->{_dirname} eq $basename
&& $lastAlbum->{title} eq $title
&& $lastAlbum->{version} eq $version
&& (!$checkDisc || (($disc || '') eq ($lastAlbum->{disc} || 0)))
)
) {
Expand All @@ -1070,6 +1073,13 @@ sub _createOrUpdateAlbum {
push @{$search}, 'albums.title = ?';
push @{$values}, $title;

if ($version) {
push @{$search}, 'albums.version = ?';
push @{$values}, $version;
} else {
push @{$search}, 'albums.version IS NULL';
}

if (defined $brainzId) {
push @{$search}, 'albums.musicbrainz_id = ?';
push @{$values}, $brainzId;
Expand Down Expand Up @@ -1248,6 +1258,8 @@ sub _createOrUpdateAlbum {
$albumHash->{release_type} = Slim::Utils::Text::ignoreCase( $releaseType || 'album' );
Slim::Schema::Album->addReleaseTypeMap($releaseType, $albumHash->{release_type});

$albumHash->{version} = $attributes->{VERSION};

# Bug 3255 - add album contributor which is either VA or the primary artist, used for sort by artist
$vaObjId ||= $self->variousArtistsObject->id;

Expand Down Expand Up @@ -1514,7 +1526,6 @@ sub _createWork {

sub _createTrack {
my ($self, $columnValueHash, $persistentColumnValueHash, $source) = @_;

# Create the track
# Using native DBI here to improve performance during scanning
my $dbh = $self->dbh;
Expand Down Expand Up @@ -2814,6 +2825,8 @@ sub _preCheckAttributes {
# We also need these in _postCheckAttributes, but they should be set during create()
$deferredAttributes->{'DISC'} = $attributes->{'DISC'} if $attributes->{'DISC'};

$deferredAttributes->{'VERSION'} = $attributes->{'VERSION'} || undef;

# thumb has gone away, since we have GD resizing.
delete $attributes->{'THUMB'};

Expand Down
3 changes: 3 additions & 0 deletions Slim/Schema/Album.pm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ my $log = logger('database.info');
musicbrainz_id
release_type
extid
subtitle
label
version
), title => { accessor => undef() });

$class->set_primary_key('id');
Expand Down