Merge branch 'stable' into develop

Signed-off-by: Andrew DeMaria <lostonamountain@gmail.com>

Conflicts:
	libresonic-main/pom.xml
	libresonic-rest-api/pom.xml
	libresonic-sonos-api/pom.xml
	pom.xml
master
Andrew DeMaria 8 years ago
commit 7c19e9f4ab
No known key found for this signature in database
GPG Key ID: 0A3F5E91F8364EDF
  1. 11
      CHANGELOG.md
  2. 6
      README.md
  3. 2
      documentation/INSTALL.md
  4. 15
      libresonic-main/pom.xml
  5. 2
      libresonic-main/src/main/java/org/libresonic/player/boot/Application.java
  6. 7
      libresonic-main/src/main/java/org/libresonic/player/controller/AvatarUploadController.java
  7. 17
      libresonic-main/src/main/java/org/libresonic/player/controller/ImportPlaylistController.java
  8. 5
      libresonic-main/src/main/java/org/libresonic/player/controller/SonosSettingsController.java
  9. 2
      libresonic-main/src/main/java/org/libresonic/player/controller/UploadController.java
  10. 3
      libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java
  11. 2
      libresonic-main/src/main/java/org/libresonic/player/security/GlobalSecurityConfig.java
  12. 5
      libresonic-main/src/main/java/org/libresonic/player/service/SonosService.java
  13. 2
      libresonic-main/src/main/java/org/libresonic/player/service/metadata/JaudiotaggerParser.java
  14. 16
      libresonic-main/src/main/java/org/libresonic/player/util/Util.java
  15. 8
      libresonic-main/src/main/resources/liquibase/legacy/schema52.xml
  16. 3
      libresonic-main/src/main/webapp/WEB-INF/jsp/importPlaylist.jsp
  17. 3
      libresonic-main/src/main/webapp/WEB-INF/jsp/more.jsp
  18. 3
      libresonic-main/src/main/webapp/WEB-INF/jsp/personalSettings.jsp
  19. 4
      pom.xml

@ -3,6 +3,17 @@
# Libresonic/libresonic # 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 v6.2.beta3
---------- ----------

@ -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 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 License
@ -42,10 +42,10 @@ Usage
----- -----
Libresonic can be downloaded from 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/). 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 Community

@ -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: 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`. Note that this command copies the war file directly to the Tomcat webapps directory, and renames it to `libresonic.war`.

@ -196,9 +196,9 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org</groupId> <groupId>net.jthink</groupId>
<artifactId>jaudiotagger</artifactId> <artifactId>jaudiotagger</artifactId>
<version>2.0.3</version> <version>2.2.3</version>
</dependency> </dependency>
<dependency> <dependency>
@ -401,7 +401,6 @@
<version>1.7.24</version> <version>1.7.24</version>
</dependency> </dependency>
<!-- Embedded tomcat --> <!-- Embedded tomcat -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -425,6 +424,16 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.7</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -11,6 +11,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
@ -32,6 +33,7 @@ import java.lang.reflect.Method;
JdbcTemplateAutoConfiguration.class, JdbcTemplateAutoConfiguration.class,
DataSourceAutoConfiguration.class, DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,
MultipartAutoConfiguration.class, // TODO: update to use spring boot builtin multipart support
LiquibaseAutoConfiguration.class}) LiquibaseAutoConfiguration.class})
@Configuration @Configuration
@ImportResource(value = {"classpath:/applicationContext-service.xml", @ImportResource(value = {"classpath:/applicationContext-service.xml",

@ -24,7 +24,7 @@ import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils; 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.Logger;
import org.libresonic.player.domain.Avatar; import org.libresonic.player.domain.Avatar;
import org.libresonic.player.service.SecurityService; import org.libresonic.player.service.SecurityService;
@ -38,7 +38,6 @@ import org.springframework.web.servlet.ModelAndView;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -66,8 +65,8 @@ public class AvatarUploadController {
@Autowired @Autowired
private SecurityService securityService; private SecurityService securityService;
@RequestMapping(method = RequestMethod.GET) @RequestMapping(method = RequestMethod.POST)
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { protected ModelAndView handleRequestInternal(HttpServletRequest request) throws Exception {
String username = securityService.getCurrentUsername(request); String username = securityService.getCurrentUsername(request);

@ -32,10 +32,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; 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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -55,8 +54,10 @@ public class ImportPlaylistController {
@Autowired @Autowired
private PlaylistService playlistService; private PlaylistService playlistService;
@RequestMapping(method = RequestMethod.GET) @RequestMapping(method = RequestMethod.POST)
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { protected String handlePost(RedirectAttributes redirectAttributes,
HttpServletRequest request
) throws Exception {
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = new HashMap<String, Object>();
try { try {
@ -85,7 +86,13 @@ public class ImportPlaylistController {
map.put("error", e.getMessage()); 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";
} }

@ -19,6 +19,7 @@
package org.libresonic.player.controller; package org.libresonic.player.controller;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.libresonic.player.service.NetworkService;
import org.libresonic.player.service.SettingsService; import org.libresonic.player.service.SettingsService;
import org.libresonic.player.service.SonosService; import org.libresonic.player.service.SonosService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -80,8 +81,8 @@ public class SonosSettingsController {
settingsService.setSonosServiceName(sonosServiceName); settingsService.setSonosServiceName(sonosServiceName);
settingsService.save(); settingsService.save();
sonosService.setMusicServiceEnabled(false); sonosService.setMusicServiceEnabled(false, NetworkService.getBaseUrl(request));
sonosService.setMusicServiceEnabled(sonosEnabled); sonosService.setMusicServiceEnabled(sonosEnabled, NetworkService.getBaseUrl(request));
} }
public void setSettingsService(SettingsService settingsService) { public void setSettingsService(SettingsService settingsService) {

@ -70,7 +70,7 @@ public class UploadController {
private SettingsService settingsService; private SettingsService settingsService;
public static final String UPLOAD_STATUS = "uploadStatus"; public static final String UPLOAD_STATUS = "uploadStatus";
@RequestMapping(method = RequestMethod.GET) @RequestMapping(method = { RequestMethod.POST })
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();

@ -24,6 +24,7 @@ import org.libresonic.player.domain.Genre;
import org.libresonic.player.domain.MediaFile; import org.libresonic.player.domain.MediaFile;
import org.libresonic.player.domain.MusicFolder; import org.libresonic.player.domain.MusicFolder;
import org.libresonic.player.domain.RandomSearchCriteria; import org.libresonic.player.domain.RandomSearchCriteria;
import org.libresonic.player.util.Util;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
@ -165,6 +166,8 @@ public class MediaFileDao extends AbstractDao {
"version=? " + "version=? " +
"where path=?"; "where path=?";
logger.trace("Updating media file {}", Util.debugObject(file));
int n = update(sql, int n = update(sql,
file.getFolder(), file.getMediaType().name(), file.getFormat(), file.getTitle(), file.getAlbumName(), file.getArtist(), 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(), file.getAlbumArtist(), file.getDiscNumber(), file.getTrackNumber(), file.getYear(), file.getGenre(), file.getBitRate(),

@ -125,7 +125,7 @@ public class GlobalSecurityConfig extends GlobalAuthenticationConfigurerAdapter
.frameOptions() .frameOptions()
.sameOrigin() .sameOrigin()
.and().authorizeRequests() .and().authorizeRequests()
.antMatchers("recover.view", "accessDenied.view", .antMatchers("/recover.view", "/accessDenied.view",
"/style/**", "/icons/**", "/flash/**", "/script/**", "/style/**", "/icons/**", "/flash/**", "/script/**",
"/sonos/**", "/crossdomain.xml", "/login", "/error") "/sonos/**", "/crossdomain.xml", "/login", "/error")
.permitAll() .permitAll()

@ -106,7 +106,7 @@ public class SonosService implements SonosSoap {
@Resource @Resource
private WebServiceContext context; private WebServiceContext context;
public void setMusicServiceEnabled(boolean enabled) { public void setMusicServiceEnabled(boolean enabled, String baseUrl) {
List<String> sonosControllers = upnpService.getSonosControllerHosts(); List<String> sonosControllers = upnpService.getSonosControllerHosts();
if (sonosControllers.isEmpty()) { if (sonosControllers.isEmpty()) {
LOG.info("No Sonos controller found"); LOG.info("No Sonos controller found");
@ -116,11 +116,10 @@ public class SonosService implements SonosSoap {
String sonosServiceName = settingsService.getSonosServiceName(); String sonosServiceName = settingsService.getSonosServiceName();
int sonosServiceId = settingsService.getSonosServiceId(); int sonosServiceId = settingsService.getSonosServiceId();
String libresonicBaseUrl = NetworkService.getBaseUrl(getRequest());
for (String sonosController : sonosControllers) { for (String sonosController : sonosControllers) {
try { try {
new SonosServiceRegistration().setEnabled(libresonicBaseUrl, sonosController, enabled, new SonosServiceRegistration().setEnabled(baseUrl, sonosController, enabled,
sonosServiceName, sonosServiceId); sonosServiceName, sonosServiceId);
break; break;
} catch (IOException x) { } catch (IOException x) {

@ -26,7 +26,7 @@ import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.AudioHeader; import org.jaudiotagger.audio.AudioHeader;
import org.jaudiotagger.tag.FieldKey; import org.jaudiotagger.tag.FieldKey;
import org.jaudiotagger.tag.Tag; 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.jaudiotagger.tag.reference.GenreTypes;
import org.libresonic.player.Logger; import org.libresonic.player.Logger;
import org.libresonic.player.domain.MediaFile; import org.libresonic.player.domain.MediaFile;

@ -19,12 +19,16 @@
*/ */
package org.libresonic.player.util; package org.libresonic.player.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.libresonic.player.Logger; import org.libresonic.player.Logger;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/** /**
* Miscellaneous general utility methods. * Miscellaneous general utility methods.
@ -102,4 +106,14 @@ public final class Util {
} }
return result; 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 "";
}
}
} }

@ -16,6 +16,7 @@
</rollback> </rollback>
</changeSet> </changeSet>
<changeSet id="schema52_002" author="muff1nman"> <changeSet id="schema52_002" author="muff1nman">
<validCheckSum>7:8fde86035edbca443a54b1861ae70819</validCheckSum>
<preConditions onFail="MARK_RAN"> <preConditions onFail="MARK_RAN">
<not> <not>
<tableExists tableName="music_folder_user" /> <tableExists tableName="music_folder_user" />
@ -32,6 +33,13 @@
<createIndex tableName="music_folder_user" indexName="idx_music_folder_user_username"> <createIndex tableName="music_folder_user" indexName="idx_music_folder_user_username">
<column name="username"/> <column name="username"/>
</createIndex> </createIndex>
<sql>
insert into music_folder_user select music_folder.id, u.username
from music_folder, ${userTableQuote}user${userTableQuote} u
</sql>
<rollback>
<dropTable tableName="music_folder_user" />
</rollback>
</changeSet> </changeSet>
<changeSet id="schema52_003" author="muff1nman"> <changeSet id="schema52_003" author="muff1nman">
<preConditions onFail="MARK_RAN"> <preConditions onFail="MARK_RAN">

@ -29,8 +29,7 @@
<div style="padding-bottom: 0.25em"> <div style="padding-bottom: 0.25em">
<fmt:message key="importPlaylist.text"/> <fmt:message key="importPlaylist.text"/>
</div> </div>
<form method="post" enctype="multipart/form-data" action="importPlaylist.view"> <form method="post" enctype="multipart/form-data" action="importPlaylist.view?${_csrf.parameterName}=${_csrf.token}">
<sec:csrfInput />
<input type="file" id="file" name="file" size="40"/> <input type="file" id="file" name="file" size="40"/>
<input type="submit" value="<fmt:message key="common.ok"/>"/> <input type="submit" value="<fmt:message key="common.ok"/>"/>
</form> </form>

@ -290,8 +290,7 @@
<span style="vertical-align: middle"><fmt:message key="more.upload.title"/></span> <span style="vertical-align: middle"><fmt:message key="more.upload.title"/></span>
</h2> </h2>
<form method="post" enctype="multipart/form-data" action="upload.view"> <form method="post" enctype="multipart/form-data" action="upload.view?${_csrf.parameterName}=${_csrf.token}">
<sec:csrfInput />
<table> <table>
<tr> <tr>
<td><fmt:message key="more.upload.source"/></td> <td><fmt:message key="more.upload.source"/></td>

@ -242,8 +242,7 @@
</p> </p>
</form:form> </form:form>
<form method="post" enctype="multipart/form-data" action="avatarUpload.view"> <form method="post" enctype="multipart/form-data" action="avatarUpload.view?${_csrf.parameterName}=${_csrf.token}">
<sec:csrfInput />
<table> <table>
<tr> <tr>
<td style="padding-right:1em"><fmt:message key="personalsettings.avatar.changecustom"/></td> <td style="padding-right:1em"><fmt:message key="personalsettings.avatar.changecustom"/></td>

@ -35,6 +35,10 @@
<name>teleal</name> <name>teleal</name>
<url>http://teleal.org/m2</url> <url>http://teleal.org/m2</url>
</repository> </repository>
<repository>
<id>jaudiotagger-repository</id>
<url>https://dl.bintray.com/ijabz/maven</url>
</repository>
</repositories> </repositories>
<pluginRepositories> <pluginRepositories>

Loading…
Cancel
Save