diff --git a/HTML/Default/status_list.html b/HTML/Default/status_list.html
index bd06841c14..66531cf347 100644
--- a/HTML/Default/status_list.html
+++ b/HTML/Default/status_list.html
@@ -50,7 +50,12 @@
[% IF item.includeAlbum && item.album.defined && item.album != noAlbum %]
[% END %]
diff --git a/HTML/EN/html/SqueezeJS/Base.js b/HTML/EN/html/SqueezeJS/Base.js
index 67e2ed21f6..a75b821b88 100644
--- a/HTML/EN/html/SqueezeJS/Base.js
+++ b/HTML/EN/html/SqueezeJS/Base.js
@@ -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 = '';
diff --git a/HTML/EN/html/SqueezeJS/UI.js b/HTML/EN/html/SqueezeJS/UI.js
index 51772638fa..dd4c723490 100644
--- a/HTML/EN/html/SqueezeJS/UI.js
+++ b/HTML/EN/html/SqueezeJS/UI.js
@@ -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 ? ' (' + year + ')' : ''));
+ + (year ? ' (' + year + ')' : '') + (version ? ' [' + 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 ? ' [' + version + ']' : ''));
}
});
diff --git a/SQL/SQLite/schema_27_down.sql b/SQL/SQLite/schema_27_down.sql
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/SQL/SQLite/schema_27_up.sql b/SQL/SQLite/schema_27_up.sql
new file mode 100644
index 0000000000..3e3cd9d3d2
--- /dev/null
+++ b/SQL/SQLite/schema_27_up.sql
@@ -0,0 +1,23 @@
+ALTER TABLE albums ADD version blob;
+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);
+
diff --git a/SQL/mysql/schema_27_down.sql b/SQL/mysql/schema_27_down.sql
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/SQL/mysql/schema_27_up.sql b/SQL/mysql/schema_27_up.sql
new file mode 100644
index 0000000000..3e3cd9d3d2
--- /dev/null
+++ b/SQL/mysql/schema_27_up.sql
@@ -0,0 +1,23 @@
+ALTER TABLE albums ADD version blob;
+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);
+
diff --git a/Slim/Control/Commands.pm b/Slim/Control/Commands.pm
index a3fbb74837..42efac8ccf 100644
--- a/Slim/Control/Commands.pm
+++ b/Slim/Control/Commands.pm
@@ -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
diff --git a/Slim/Control/Queries.pm b/Slim/Control/Queries.pm
index 6ce452bf1a..64c9dfd6b9 100644
--- a/Slim/Control/Queries.pm
+++ b/Slim/Control/Queries.pm
@@ -582,7 +582,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/ ) {
@@ -806,6 +806,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'};
@@ -816,23 +817,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'});
if ($tags =~ /j/) {
my $albumCover = $c->{'tracks.coverid'} ? $c->{'tracks.coverid'} : $c->{'albums.artwork'};
@@ -5723,6 +5732,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'};
@@ -6454,6 +6469,7 @@ sub _getTagDataForTracks {
$tags =~ /l/ && do {
$join_albums->();
$c->{'albums.title'} = 1;
+ $c->{'albums.version'} = 1;
};
$tags =~ /q/ && do {
@@ -6580,6 +6596,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'};
diff --git a/Slim/Menu/AlbumInfo.pm b/Slim/Menu/AlbumInfo.pm
index 38a5776a50..b0469f7b60 100644
--- a/Slim/Menu/AlbumInfo.pm
+++ b/Slim/Menu/AlbumInfo.pm
@@ -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} ) {
diff --git a/Slim/Menu/BrowseLibrary.pm b/Slim/Menu/BrowseLibrary.pm
index 95286a0e94..97a138a2e1 100644
--- a/Slim/Menu/BrowseLibrary.pm
+++ b/Slim/Menu/BrowseLibrary.pm
@@ -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';
diff --git a/Slim/Schema.pm b/Slim/Schema.pm
index 9b7774b544..a5c4b87d48 100644
--- a/Slim/Schema.pm
+++ b/Slim/Schema.pm
@@ -901,6 +901,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);
@@ -937,6 +938,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
@@ -1079,6 +1081,7 @@ sub _createOrUpdateAlbum {
( $lastAlbum->{_dirname}
&& $lastAlbum->{_dirname} eq $basename
&& $lastAlbum->{title} eq $title
+ && $lastAlbum->{version} eq $version
&& (!$checkDisc || (($disc || '') eq ($lastAlbum->{disc} || 0)))
)
) {
@@ -1103,6 +1106,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;
@@ -1281,6 +1291,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;
@@ -1547,7 +1559,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;
@@ -2847,6 +2858,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'};
diff --git a/Slim/Schema/Album.pm b/Slim/Schema/Album.pm
index 2ee7f52ba5..68600c3de4 100644
--- a/Slim/Schema/Album.pm
+++ b/Slim/Schema/Album.pm
@@ -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');