Issue #164: Show link to MusicBrainz release on album pages
This commit is contained in:
@@ -134,6 +134,7 @@ public class MainController {
|
|||||||
map.put("sieblingAlbums", sieblingAlbums);
|
map.put("sieblingAlbums", sieblingAlbums);
|
||||||
map.put("artist", guessArtist(children));
|
map.put("artist", guessArtist(children));
|
||||||
map.put("album", guessAlbum(children));
|
map.put("album", guessAlbum(children));
|
||||||
|
map.put("musicBrainzReleaseId", guessMusicBrainzReleaseId(children));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -241,6 +242,15 @@ public class MainController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String guessMusicBrainzReleaseId(List<MediaFile> children) {
|
||||||
|
for (MediaFile child : children) {
|
||||||
|
if (child.isFile() && child.getMusicBrainzReleaseId() != null) {
|
||||||
|
return child.getMusicBrainzReleaseId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private List<MediaFile> getMultiFolderChildren(List<MediaFile> mediaFiles) throws IOException {
|
private List<MediaFile> getMultiFolderChildren(List<MediaFile> mediaFiles) throws IOException {
|
||||||
SortedSet<MediaFile> result = new TreeSet<>(new MediaFileComparator(settingsService.isSortAlbumsByYear()));
|
SortedSet<MediaFile> result = new TreeSet<>(new MediaFileComparator(settingsService.isSortAlbumsByYear()));
|
||||||
for (MediaFile mediaFile : mediaFiles) {
|
for (MediaFile mediaFile : mediaFiles) {
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ import java.util.*;
|
|||||||
@Repository
|
@Repository
|
||||||
public class AlbumDao extends AbstractDao {
|
public class AlbumDao extends AbstractDao {
|
||||||
private static final String INSERT_COLUMNS = "path, name, artist, song_count, duration_seconds, cover_art_path, " +
|
private static final String INSERT_COLUMNS = "path, name, artist, song_count, duration_seconds, cover_art_path, " +
|
||||||
"year, genre, play_count, last_played, comment, created, last_scanned, present, folder_id";
|
"year, genre, play_count, last_played, comment, created, last_scanned, present, " +
|
||||||
|
"folder_id, mb_release_id";
|
||||||
|
|
||||||
private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS;
|
private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS;
|
||||||
|
|
||||||
@@ -127,19 +128,20 @@ public class AlbumDao extends AbstractDao {
|
|||||||
"created=?," +
|
"created=?," +
|
||||||
"last_scanned=?," +
|
"last_scanned=?," +
|
||||||
"present=?, " +
|
"present=?, " +
|
||||||
"folder_id=? " +
|
"folder_id=?, " +
|
||||||
|
"mb_release_id=? " +
|
||||||
"where artist=? and name=?";
|
"where artist=? and name=?";
|
||||||
|
|
||||||
int n = update(sql, album.getPath(), album.getSongCount(), album.getDurationSeconds(), album.getCoverArtPath(), album.getYear(),
|
int n = update(sql, album.getPath(), album.getSongCount(), album.getDurationSeconds(), album.getCoverArtPath(), album.getYear(),
|
||||||
album.getGenre(), album.getPlayCount(), album.getLastPlayed(), album.getComment(), album.getCreated(),
|
album.getGenre(), album.getPlayCount(), album.getLastPlayed(), album.getComment(), album.getCreated(),
|
||||||
album.getLastScanned(), album.isPresent(), album.getFolderId(), album.getArtist(), album.getName());
|
album.getLastScanned(), album.isPresent(), album.getFolderId(), album.getMusicBrainzReleaseId(), album.getArtist(), album.getName());
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
|
||||||
update("insert into album (" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")", album.getPath(),
|
update("insert into album (" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")", album.getPath(),
|
||||||
album.getName(), album.getArtist(), album.getSongCount(), album.getDurationSeconds(),
|
album.getName(), album.getArtist(), album.getSongCount(), album.getDurationSeconds(),
|
||||||
album.getCoverArtPath(), album.getYear(), album.getGenre(), album.getPlayCount(), album.getLastPlayed(),
|
album.getCoverArtPath(), album.getYear(), album.getGenre(), album.getPlayCount(), album.getLastPlayed(),
|
||||||
album.getComment(), album.getCreated(), album.getLastScanned(), album.isPresent(), album.getFolderId());
|
album.getComment(), album.getCreated(), album.getLastScanned(), album.isPresent(), album.getFolderId(), album.getMusicBrainzReleaseId());
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = queryForInt("select id from album where artist=? and name=?", null, album.getArtist(), album.getName());
|
int id = queryForInt("select id from album where artist=? and name=?", null, album.getArtist(), album.getName());
|
||||||
@@ -404,7 +406,8 @@ public class AlbumDao extends AbstractDao {
|
|||||||
rs.getTimestamp(13),
|
rs.getTimestamp(13),
|
||||||
rs.getTimestamp(14),
|
rs.getTimestamp(14),
|
||||||
rs.getBoolean(15),
|
rs.getBoolean(15),
|
||||||
rs.getInt(16));
|
rs.getInt(16),
|
||||||
|
rs.getString(17));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ public class MediaFileDao extends AbstractDao {
|
|||||||
private static final Logger logger = LoggerFactory.getLogger(MediaFileDao.class);
|
private static final Logger logger = LoggerFactory.getLogger(MediaFileDao.class);
|
||||||
private static final String INSERT_COLUMNS = "path, folder, type, format, title, album, artist, album_artist, disc_number, " +
|
private static final String INSERT_COLUMNS = "path, folder, type, format, title, album, artist, album_artist, disc_number, " +
|
||||||
"track_number, year, genre, bit_rate, variable_bit_rate, duration_seconds, file_size, width, height, cover_art_path, " +
|
"track_number, year, genre, bit_rate, variable_bit_rate, duration_seconds, file_size, width, height, cover_art_path, " +
|
||||||
"parent_path, play_count, last_played, comment, created, changed, last_scanned, children_last_updated, present, version";
|
"parent_path, play_count, last_played, comment, created, changed, last_scanned, children_last_updated, present, " +
|
||||||
|
"version, mb_release_id";
|
||||||
|
|
||||||
private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS;
|
private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS;
|
||||||
private static final String GENRE_COLUMNS = "name, song_count, album_count";
|
private static final String GENRE_COLUMNS = "name, song_count, album_count";
|
||||||
@@ -162,7 +163,8 @@ public class MediaFileDao extends AbstractDao {
|
|||||||
"last_scanned=?," +
|
"last_scanned=?," +
|
||||||
"children_last_updated=?," +
|
"children_last_updated=?," +
|
||||||
"present=?, " +
|
"present=?, " +
|
||||||
"version=? " +
|
"version=?, " +
|
||||||
|
"mb_release_id=? " +
|
||||||
"where path=?";
|
"where path=?";
|
||||||
|
|
||||||
logger.trace("Updating media file {}", Util.debugObject(file));
|
logger.trace("Updating media file {}", Util.debugObject(file));
|
||||||
@@ -172,7 +174,8 @@ public class MediaFileDao extends AbstractDao {
|
|||||||
file.getAlbumArtist(), file.getDiscNumber(), file.getTrackNumber(), file.getYear(), file.getGenre(), file.getBitRate(),
|
file.getAlbumArtist(), file.getDiscNumber(), file.getTrackNumber(), file.getYear(), file.getGenre(), file.getBitRate(),
|
||||||
file.isVariableBitRate(), file.getDurationSeconds(), file.getFileSize(), file.getWidth(), file.getHeight(),
|
file.isVariableBitRate(), file.getDurationSeconds(), file.getFileSize(), file.getWidth(), file.getHeight(),
|
||||||
file.getCoverArtPath(), file.getParentPath(), file.getPlayCount(), file.getLastPlayed(), file.getComment(),
|
file.getCoverArtPath(), file.getParentPath(), file.getPlayCount(), file.getLastPlayed(), file.getComment(),
|
||||||
file.getChanged(), file.getLastScanned(), file.getChildrenLastUpdated(), file.isPresent(), VERSION, file.getPath());
|
file.getChanged(), file.getLastScanned(), file.getChildrenLastUpdated(), file.isPresent(), VERSION,
|
||||||
|
file.getMusicBrainzReleaseId(), file.getPath());
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
|
||||||
@@ -190,7 +193,7 @@ public class MediaFileDao extends AbstractDao {
|
|||||||
file.isVariableBitRate(), file.getDurationSeconds(), file.getFileSize(), file.getWidth(), file.getHeight(),
|
file.isVariableBitRate(), file.getDurationSeconds(), file.getFileSize(), file.getWidth(), file.getHeight(),
|
||||||
file.getCoverArtPath(), file.getParentPath(), file.getPlayCount(), file.getLastPlayed(), file.getComment(),
|
file.getCoverArtPath(), file.getParentPath(), file.getPlayCount(), file.getLastPlayed(), file.getComment(),
|
||||||
file.getCreated(), file.getChanged(), file.getLastScanned(),
|
file.getCreated(), file.getChanged(), file.getLastScanned(),
|
||||||
file.getChildrenLastUpdated(), file.isPresent(), VERSION);
|
file.getChildrenLastUpdated(), file.isPresent(), VERSION, file.getMusicBrainzReleaseId());
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = queryForInt("select id from media_file where path=?", null, file.getPath());
|
int id = queryForInt("select id from media_file where path=?", null, file.getPath());
|
||||||
@@ -717,7 +720,8 @@ public class MediaFileDao extends AbstractDao {
|
|||||||
rs.getTimestamp(27),
|
rs.getTimestamp(27),
|
||||||
rs.getTimestamp(28),
|
rs.getTimestamp(28),
|
||||||
rs.getBoolean(29),
|
rs.getBoolean(29),
|
||||||
rs.getInt(30));
|
rs.getInt(30),
|
||||||
|
rs.getString(31));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,13 +43,14 @@ public class Album {
|
|||||||
private Date lastScanned;
|
private Date lastScanned;
|
||||||
private boolean present;
|
private boolean present;
|
||||||
private Integer folderId;
|
private Integer folderId;
|
||||||
|
private String musicBrainzReleaseId;
|
||||||
|
|
||||||
public Album() {
|
public Album() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Album(int id, String path, String name, String artist, int songCount, int durationSeconds, String coverArtPath,
|
public Album(int id, String path, String name, String artist, int songCount, int durationSeconds, String coverArtPath,
|
||||||
Integer year, String genre, int playCount, Date lastPlayed, String comment, Date created, Date lastScanned,
|
Integer year, String genre, int playCount, Date lastPlayed, String comment, Date created, Date lastScanned,
|
||||||
boolean present, Integer folderId) {
|
boolean present, Integer folderId, String musicBrainzReleaseId) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -66,6 +67,7 @@ public class Album {
|
|||||||
this.lastScanned = lastScanned;
|
this.lastScanned = lastScanned;
|
||||||
this.folderId = folderId;
|
this.folderId = folderId;
|
||||||
this.present = present;
|
this.present = present;
|
||||||
|
this.musicBrainzReleaseId = musicBrainzReleaseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
@@ -195,4 +197,12 @@ public class Album {
|
|||||||
public Integer getFolderId() {
|
public Integer getFolderId() {
|
||||||
return folderId;
|
return folderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMusicBrainzReleaseId() {
|
||||||
|
return musicBrainzReleaseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMusicBrainzReleaseId(String musicBrainzReleaseId) {
|
||||||
|
this.musicBrainzReleaseId = musicBrainzReleaseId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,12 +67,13 @@ public class MediaFile {
|
|||||||
private Date childrenLastUpdated;
|
private Date childrenLastUpdated;
|
||||||
private boolean present;
|
private boolean present;
|
||||||
private int version;
|
private int version;
|
||||||
|
private String musicBrainzReleaseId;
|
||||||
|
|
||||||
public MediaFile(int id, String path, String folder, MediaType mediaType, String format, String title,
|
public MediaFile(int id, String path, String folder, MediaType mediaType, String format, String title,
|
||||||
String albumName, String artist, String albumArtist, Integer discNumber, Integer trackNumber, Integer year, String genre, Integer bitRate,
|
String albumName, String artist, String albumArtist, Integer discNumber, Integer trackNumber, Integer year, String genre, Integer bitRate,
|
||||||
boolean variableBitRate, Integer durationSeconds, Long fileSize, Integer width, Integer height, String coverArtPath,
|
boolean variableBitRate, Integer durationSeconds, Long fileSize, Integer width, Integer height, String coverArtPath,
|
||||||
String parentPath, int playCount, Date lastPlayed, String comment, Date created, Date changed, Date lastScanned,
|
String parentPath, int playCount, Date lastPlayed, String comment, Date created, Date changed, Date lastScanned,
|
||||||
Date childrenLastUpdated, boolean present, int version) {
|
Date childrenLastUpdated, boolean present, int version, String musicBrainzReleaseId) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.folder = folder;
|
this.folder = folder;
|
||||||
@@ -103,6 +104,7 @@ public class MediaFile {
|
|||||||
this.childrenLastUpdated = childrenLastUpdated;
|
this.childrenLastUpdated = childrenLastUpdated;
|
||||||
this.present = present;
|
this.present = present;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
this.musicBrainzReleaseId = musicBrainzReleaseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaFile() {
|
public MediaFile() {
|
||||||
@@ -405,6 +407,14 @@ public class MediaFile {
|
|||||||
this.starredDate = starredDate;
|
this.starredDate = starredDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMusicBrainzReleaseId() {
|
||||||
|
return musicBrainzReleaseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMusicBrainzReleaseId(String musicBrainzReleaseId) {
|
||||||
|
this.musicBrainzReleaseId = musicBrainzReleaseId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns when the children was last updated in the database.
|
* Returns when the children was last updated in the database.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -503,6 +503,7 @@ public class MediaFileService {
|
|||||||
mediaFile.setVariableBitRate(metaData.getVariableBitRate());
|
mediaFile.setVariableBitRate(metaData.getVariableBitRate());
|
||||||
mediaFile.setHeight(metaData.getHeight());
|
mediaFile.setHeight(metaData.getHeight());
|
||||||
mediaFile.setWidth(metaData.getWidth());
|
mediaFile.setWidth(metaData.getWidth());
|
||||||
|
mediaFile.setMusicBrainzReleaseId(metaData.getMusicBrainzReleaseId());
|
||||||
}
|
}
|
||||||
String format = StringUtils.trimToNull(StringUtils.lowerCase(FilenameUtils.getExtension(mediaFile.getPath())));
|
String format = StringUtils.trimToNull(StringUtils.lowerCase(FilenameUtils.getExtension(mediaFile.getPath())));
|
||||||
mediaFile.setFormat(format);
|
mediaFile.setFormat(format);
|
||||||
|
|||||||
@@ -298,6 +298,9 @@ public class MediaScannerService {
|
|||||||
album.setArtist(artist);
|
album.setArtist(artist);
|
||||||
album.setCreated(file.getChanged());
|
album.setCreated(file.getChanged());
|
||||||
}
|
}
|
||||||
|
if (file.getMusicBrainzReleaseId() != null) {
|
||||||
|
album.setMusicBrainzReleaseId(file.getMusicBrainzReleaseId());
|
||||||
|
}
|
||||||
if (file.getYear() != null) {
|
if (file.getYear() != null) {
|
||||||
album.setYear(file.getYear());
|
album.setYear(file.getYear());
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -92,6 +92,7 @@ public class JaudiotaggerParser extends MetaDataParser {
|
|||||||
metaData.setGenre(mapGenre(getTagField(tag, FieldKey.GENRE)));
|
metaData.setGenre(mapGenre(getTagField(tag, FieldKey.GENRE)));
|
||||||
metaData.setDiscNumber(parseInteger(getTagField(tag, FieldKey.DISC_NO)));
|
metaData.setDiscNumber(parseInteger(getTagField(tag, FieldKey.DISC_NO)));
|
||||||
metaData.setTrackNumber(parseTrackNumber(getTagField(tag, FieldKey.TRACK)));
|
metaData.setTrackNumber(parseTrackNumber(getTagField(tag, FieldKey.TRACK)));
|
||||||
|
metaData.setMusicBrainzReleaseId(getTagField(tag, FieldKey.MUSICBRAINZ_RELEASEID));
|
||||||
|
|
||||||
String songArtist = getTagField(tag, FieldKey.ARTIST);
|
String songArtist = getTagField(tag, FieldKey.ARTIST);
|
||||||
String albumArtist = getTagField(tag, FieldKey.ALBUM_ARTIST);
|
String albumArtist = getTagField(tag, FieldKey.ALBUM_ARTIST);
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class MetaData {
|
|||||||
private Integer durationSeconds;
|
private Integer durationSeconds;
|
||||||
private Integer width;
|
private Integer width;
|
||||||
private Integer height;
|
private Integer height;
|
||||||
|
private String musicBrainzReleaseId;
|
||||||
|
|
||||||
public Integer getDiscNumber() {
|
public Integer getDiscNumber() {
|
||||||
return discNumber;
|
return discNumber;
|
||||||
@@ -142,4 +143,12 @@ public class MetaData {
|
|||||||
public void setHeight(Integer height) {
|
public void setHeight(Integer height) {
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMusicBrainzReleaseId() {
|
||||||
|
return musicBrainzReleaseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMusicBrainzReleaseId(String musicBrainzReleaseId) {
|
||||||
|
this.musicBrainzReleaseId = musicBrainzReleaseId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||||
|
<changeSet id="add-album-mb-release-id" author="fxthomas">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<not>
|
||||||
|
<columnExists tableName="album" columnName="mb_release_id" />
|
||||||
|
</not>
|
||||||
|
</preConditions>
|
||||||
|
<addColumn tableName="album">
|
||||||
|
<column name="mb_release_id" type="${varchar_type}">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||||
|
<changeSet id="add-media-file-mb-release-id" author="fxthomas">
|
||||||
|
<preConditions onFail="MARK_RAN">
|
||||||
|
<not>
|
||||||
|
<columnExists tableName="media_file" columnName="mb_release_id" />
|
||||||
|
</not>
|
||||||
|
</preConditions>
|
||||||
|
<addColumn tableName="media_file">
|
||||||
|
<column name="mb_release_id" type="${varchar_type}">
|
||||||
|
<constraints nullable="true" />
|
||||||
|
</column>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<databaseChangeLog
|
||||||
|
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||||
|
<include file="add-media-file-mb-release-id.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="add-album-mb-release-id.xml" relativeToChangelogFile="true"/>
|
||||||
|
</databaseChangeLog>
|
||||||
@@ -10,4 +10,5 @@
|
|||||||
<include file="legacy/legacy-changelog.xml" relativeToChangelogFile="true"/>
|
<include file="legacy/legacy-changelog.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="6.2/changelog.xml" relativeToChangelogFile="true"/>
|
<include file="6.2/changelog.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="6.3/changelog.xml" relativeToChangelogFile="true"/>
|
<include file="6.3/changelog.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="6.4/changelog.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
@@ -262,6 +262,11 @@
|
|||||||
<span class="header"><a target="_blank" href="${wikipediaUrl}">Wikipedia</a></span> |
|
<span class="header"><a target="_blank" href="${wikipediaUrl}">Wikipedia</a></span> |
|
||||||
<span class="header"><a target="_blank" href="${allmusicUrl}">allmusic</a></span> |
|
<span class="header"><a target="_blank" href="${allmusicUrl}">allmusic</a></span> |
|
||||||
<span class="header"><a target="_blank" href="${lastFmUrl}">Last.fm</a></span> |
|
<span class="header"><a target="_blank" href="${lastFmUrl}">Last.fm</a></span> |
|
||||||
|
<c:if test="${not empty model.musicBrainzReleaseId}">
|
||||||
|
<sub:url value="https://musicbrainz.org/release/${model.musicBrainzReleaseId}" var="musicBrainzUrl" encoding="UTF-8">
|
||||||
|
</sub:url>
|
||||||
|
<span class="header"><a target="_blank" href="${musicBrainzUrl}">MusicBrainz</a></span> |
|
||||||
|
</c:if>
|
||||||
<span class="header">
|
<span class="header">
|
||||||
<fmt:message key="main.playcount"><fmt:param value="${model.dir.playCount}"/></fmt:message>
|
<fmt:message key="main.playcount"><fmt:param value="${model.dir.playCount}"/></fmt:message>
|
||||||
<c:if test="${not empty model.dir.lastPlayed}">
|
<c:if test="${not empty model.dir.lastPlayed}">
|
||||||
|
|||||||
Reference in New Issue
Block a user