diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4c1dedd4..4d1634fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,17 @@
# Libresonic/libresonic
# -->
+v6.2
+----
+
+ * Small fixes
+ * Release only a month behind schedule! We're improving!
+
+v6.2.beta4
+---------
+
+ * Final fixes in Beta! Release soon
+
v6.2.beta3
----------
diff --git a/README.md b/README.md
index 85d58820..4c5b853d 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ The original [Subsonic](http://www.subsonic.org/) is developed by [Sindre Mehus]
Libresonic is maintained by [Eugene E. Kashpureff Jr](mailto:eugene@kashpureff.org). It originated as an unofficial("Kang") of Subsonic which did not contain the Licensing code checks present in the official builds. With the announcement of Subsonic's closed-source future, a decision was made to make a full fork and rebrand to Libresonic.
-Libresonic will strive to maintain compatibility and stability for Subsonic users, including a clean upgrade path. New features and refactoring are welcomed as a Pull Request on Github.
+Libresonic will strive to maintain compatibility and stability for Subsonic users, including a clean upgrade path. New features and refactoring are welcomed as a Pull Request on GitHub.
License
@@ -42,10 +42,10 @@ Usage
-----
Libresonic can be downloaded from
-[Github](https://github.com/Libresonic/libresonic/releases) for personal usage.
+[GitHub](https://github.com/Libresonic/libresonic/releases) for personal usage.
Packagers can also reference the [release repository](https://libresonic.org/release/).
-Please see the [INSTALL document](https://github.com/Libresonic/libresonic/blob/develop/INSTALL.md) for instructions on running Libresonic.
+Please see the [INSTALL document](https://github.com/Libresonic/libresonic/blob/stable/documentation/INSTALL.md) for instructions on running Libresonic.
Community
diff --git a/documentation/INSTALL.md b/documentation/INSTALL.md
index e4319e81..3a3ca08d 100644
--- a/documentation/INSTALL.md
+++ b/documentation/INSTALL.md
@@ -45,7 +45,7 @@ You will need a running [Tomcat](http://tomcat.apache.org/) server. If you're un
1. Download the latest war file:
- wget https://github.com/Libresonic/libresonic/releases/download/v6.2.beta1/libresonic-v6.2.beta1.war -O /var/lib/tomcat8/webapps/libresonic.war
+ wget https://github.com/Libresonic/libresonic/releases/download/v6.2/libresonic-v6.2.war -O /var/lib/tomcat8/webapps/libresonic.war
Note that this command copies the war file directly to the Tomcat webapps directory, and renames it to `libresonic.war`.
diff --git a/libresonic-main/pom.xml b/libresonic-main/pom.xml
index 752e1730..11c461e0 100644
--- a/libresonic-main/pom.xml
+++ b/libresonic-main/pom.xml
@@ -196,9 +196,9 @@
- org
+ net.jthink
jaudiotagger
- 2.0.3
+ 2.2.3
@@ -401,7 +401,6 @@
1.7.24
-
org.springframework.boot
@@ -425,6 +424,16 @@
provided
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.8.7
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.8.7
+
diff --git a/libresonic-main/src/main/java/org/libresonic/player/boot/Application.java b/libresonic-main/src/main/java/org/libresonic/player/boot/Application.java
index 4e82c11a..274c3595 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/boot/Application.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/boot/Application.java
@@ -11,6 +11,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
+import org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
@@ -32,6 +33,7 @@ import java.lang.reflect.Method;
JdbcTemplateAutoConfiguration.class,
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
+ MultipartAutoConfiguration.class, // TODO: update to use spring boot builtin multipart support
LiquibaseAutoConfiguration.class})
@Configuration
@ImportResource(value = {"classpath:/applicationContext-service.xml",
diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/AvatarUploadController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/AvatarUploadController.java
index 1ab390c6..d33a2bb5 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/controller/AvatarUploadController.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/controller/AvatarUploadController.java
@@ -24,7 +24,7 @@ import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.libresonic.player.Logger;
import org.libresonic.player.domain.Avatar;
import org.libresonic.player.service.SecurityService;
@@ -38,7 +38,6 @@ import org.springframework.web.servlet.ModelAndView;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
@@ -66,8 +65,8 @@ public class AvatarUploadController {
@Autowired
private SecurityService securityService;
- @RequestMapping(method = RequestMethod.GET)
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
+ @RequestMapping(method = RequestMethod.POST)
+ protected ModelAndView handleRequestInternal(HttpServletRequest request) throws Exception {
String username = securityService.getCurrentUsername(request);
diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/ImportPlaylistController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/ImportPlaylistController.java
index 95b7480b..29b8903b 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/controller/ImportPlaylistController.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/controller/ImportPlaylistController.java
@@ -32,10 +32,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
@@ -55,8 +54,10 @@ public class ImportPlaylistController {
@Autowired
private PlaylistService playlistService;
- @RequestMapping(method = RequestMethod.GET)
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
+ @RequestMapping(method = RequestMethod.POST)
+ protected String handlePost(RedirectAttributes redirectAttributes,
+ HttpServletRequest request
+ ) throws Exception {
Map map = new HashMap();
try {
@@ -85,7 +86,13 @@ public class ImportPlaylistController {
map.put("error", e.getMessage());
}
- return new ModelAndView("importPlaylist","model",map);
+ redirectAttributes.addFlashAttribute("model", map);
+ return "redirect:importPlaylist";
+ }
+
+ @RequestMapping(method = RequestMethod.GET)
+ public String handleGet() {
+ return "importPlaylist";
}
diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/SonosSettingsController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/SonosSettingsController.java
index a83bbc12..c52e399d 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/controller/SonosSettingsController.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/controller/SonosSettingsController.java
@@ -19,6 +19,7 @@
package org.libresonic.player.controller;
import org.apache.commons.lang.StringUtils;
+import org.libresonic.player.service.NetworkService;
import org.libresonic.player.service.SettingsService;
import org.libresonic.player.service.SonosService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -80,8 +81,8 @@ public class SonosSettingsController {
settingsService.setSonosServiceName(sonosServiceName);
settingsService.save();
- sonosService.setMusicServiceEnabled(false);
- sonosService.setMusicServiceEnabled(sonosEnabled);
+ sonosService.setMusicServiceEnabled(false, NetworkService.getBaseUrl(request));
+ sonosService.setMusicServiceEnabled(sonosEnabled, NetworkService.getBaseUrl(request));
}
public void setSettingsService(SettingsService settingsService) {
diff --git a/libresonic-main/src/main/java/org/libresonic/player/controller/UploadController.java b/libresonic-main/src/main/java/org/libresonic/player/controller/UploadController.java
index 924c7ad9..597e2abe 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/controller/UploadController.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/controller/UploadController.java
@@ -70,7 +70,7 @@ public class UploadController {
private SettingsService settingsService;
public static final String UPLOAD_STATUS = "uploadStatus";
- @RequestMapping(method = RequestMethod.GET)
+ @RequestMapping(method = { RequestMethod.POST })
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map map = new HashMap<>();
diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java
index 94c4045b..8759d007 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java
@@ -24,6 +24,7 @@ import org.libresonic.player.domain.Genre;
import org.libresonic.player.domain.MediaFile;
import org.libresonic.player.domain.MusicFolder;
import org.libresonic.player.domain.RandomSearchCriteria;
+import org.libresonic.player.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.RowMapper;
@@ -165,6 +166,8 @@ public class MediaFileDao extends AbstractDao {
"version=? " +
"where path=?";
+ logger.trace("Updating media file {}", Util.debugObject(file));
+
int n = update(sql,
file.getFolder(), file.getMediaType().name(), file.getFormat(), file.getTitle(), file.getAlbumName(), file.getArtist(),
file.getAlbumArtist(), file.getDiscNumber(), file.getTrackNumber(), file.getYear(), file.getGenre(), file.getBitRate(),
diff --git a/libresonic-main/src/main/java/org/libresonic/player/security/GlobalSecurityConfig.java b/libresonic-main/src/main/java/org/libresonic/player/security/GlobalSecurityConfig.java
index f1244967..4af3aae0 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/security/GlobalSecurityConfig.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/security/GlobalSecurityConfig.java
@@ -125,7 +125,7 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter
.frameOptions()
.sameOrigin()
.and().authorizeRequests()
- .antMatchers("recover.view", "accessDenied.view",
+ .antMatchers("/recover.view", "/accessDenied.view",
"/style/**", "/icons/**", "/flash/**", "/script/**",
"/sonos/**", "/crossdomain.xml", "/login", "/error")
.permitAll()
diff --git a/libresonic-main/src/main/java/org/libresonic/player/service/SonosService.java b/libresonic-main/src/main/java/org/libresonic/player/service/SonosService.java
index 314d330d..4c7aa623 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/service/SonosService.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/service/SonosService.java
@@ -106,7 +106,7 @@ public class SonosService implements SonosSoap {
@Resource
private WebServiceContext context;
- public void setMusicServiceEnabled(boolean enabled) {
+ public void setMusicServiceEnabled(boolean enabled, String baseUrl) {
List sonosControllers = upnpService.getSonosControllerHosts();
if (sonosControllers.isEmpty()) {
LOG.info("No Sonos controller found");
@@ -116,11 +116,10 @@ public class SonosService implements SonosSoap {
String sonosServiceName = settingsService.getSonosServiceName();
int sonosServiceId = settingsService.getSonosServiceId();
- String libresonicBaseUrl = NetworkService.getBaseUrl(getRequest());
for (String sonosController : sonosControllers) {
try {
- new SonosServiceRegistration().setEnabled(libresonicBaseUrl, sonosController, enabled,
+ new SonosServiceRegistration().setEnabled(baseUrl, sonosController, enabled,
sonosServiceName, sonosServiceId);
break;
} catch (IOException x) {
diff --git a/libresonic-main/src/main/java/org/libresonic/player/service/metadata/JaudiotaggerParser.java b/libresonic-main/src/main/java/org/libresonic/player/service/metadata/JaudiotaggerParser.java
index 903e42d9..59f475fb 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/service/metadata/JaudiotaggerParser.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/service/metadata/JaudiotaggerParser.java
@@ -26,7 +26,7 @@ import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.AudioHeader;
import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag;
-import org.jaudiotagger.tag.datatype.Artwork;
+import org.jaudiotagger.tag.images.Artwork;
import org.jaudiotagger.tag.reference.GenreTypes;
import org.libresonic.player.Logger;
import org.libresonic.player.domain.MediaFile;
diff --git a/libresonic-main/src/main/java/org/libresonic/player/util/Util.java b/libresonic-main/src/main/java/org/libresonic/player/util/Util.java
index 2f8ab6e5..88f58e68 100644
--- a/libresonic-main/src/main/java/org/libresonic/player/util/Util.java
+++ b/libresonic-main/src/main/java/org/libresonic/player/util/Util.java
@@ -19,12 +19,16 @@
*/
package org.libresonic.player.util;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.libresonic.player.Logger;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
/**
* Miscellaneous general utility methods.
@@ -102,4 +106,14 @@ public final class Util {
}
return result;
}
+
+ static ObjectMapper objectMapper = new ObjectMapper();
+ public static String debugObject(Object object) {
+ try {
+ return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
+ } catch (JsonProcessingException e) {
+ LOG.warn("Cant output debug object", e);
+ return "";
+ }
+ }
}
\ No newline at end of file
diff --git a/libresonic-main/src/main/resources/liquibase/legacy/schema52.xml b/libresonic-main/src/main/resources/liquibase/legacy/schema52.xml
index 13652962..16656d75 100644
--- a/libresonic-main/src/main/resources/liquibase/legacy/schema52.xml
+++ b/libresonic-main/src/main/resources/liquibase/legacy/schema52.xml
@@ -16,6 +16,7 @@
+ 7:8fde86035edbca443a54b1861ae70819
@@ -32,6 +33,13 @@
+
+ insert into music_folder_user select music_folder.id, u.username
+ from music_folder, ${userTableQuote}user${userTableQuote} u
+
+
+
+
diff --git a/libresonic-main/src/main/webapp/WEB-INF/jsp/importPlaylist.jsp b/libresonic-main/src/main/webapp/WEB-INF/jsp/importPlaylist.jsp
index 419f8bbe..ece723d8 100644
--- a/libresonic-main/src/main/webapp/WEB-INF/jsp/importPlaylist.jsp
+++ b/libresonic-main/src/main/webapp/WEB-INF/jsp/importPlaylist.jsp
@@ -29,8 +29,7 @@
-
diff --git a/libresonic-main/src/main/webapp/WEB-INF/jsp/more.jsp b/libresonic-main/src/main/webapp/WEB-INF/jsp/more.jsp
index 846378e4..489ccc88 100644
--- a/libresonic-main/src/main/webapp/WEB-INF/jsp/more.jsp
+++ b/libresonic-main/src/main/webapp/WEB-INF/jsp/more.jsp
@@ -290,8 +290,7 @@
-