/*
This file is part of Libresonic.
Libresonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Libresonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Libresonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2016 (C) Libresonic Authors
Based upon Subsonic, Copyright 2009 (C) Sindre Mehus
*/
package org.libresonic.player.controller;
import org.apache.commons.lang.StringUtils;
import org.libresonic.player.domain.*;
import org.libresonic.player.service.MediaFileService;
import org.libresonic.player.service.PlayerService;
import org.libresonic.player.service.SecurityService;
import org.libresonic.player.service.SettingsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* Controller for the creating a random play queue.
*
* @author Sindre Mehus
*/
@Controller
@RequestMapping("/randomPlayQueue.view")
public class RandomPlayQueueController {
@Autowired
private PlayerService playerService;
@Autowired
private MediaFileService mediaFileService;
@Autowired
private SecurityService securityService;
@Autowired
private SettingsService settingsService;
@RequestMapping(method = RequestMethod.POST)
protected String handleRandomPlayQueue(
ModelMap model,
HttpServletRequest request,
HttpServletResponse response,
@RequestParam(value = "size") int size,
@RequestParam(value = "genre", required = false) String genre,
@RequestParam(value = "year", required = false) String year,
@RequestParam(value = "songRating", required = false) String songRating,
@RequestParam(value = "lastPlayedValue", required = false) String lastPlayedValue,
@RequestParam(value = "lastPlayedComp", required = false) String lastPlayedComp,
@RequestParam(value = "albumRatingValue", required = false) Integer albumRatingValue,
@RequestParam(value = "albumRatingComp", required = false) String albumRatingComp,
@RequestParam(value = "playCountValue", required = false) Integer playCountValue,
@RequestParam(value = "playCountComp", required = false) String playCountComp,
@RequestParam(value = "format", required = false) String format,
@RequestParam(value = "autoRandom", required = false) String autoRandom
) throws Exception {
Integer fromYear = null;
Integer toYear = null;
Integer minAlbumRating = null;
Integer maxAlbumRating = null;
Integer minPlayCount = null;
Integer maxPlayCount = null;
Date minLastPlayedDate = null;
Date maxLastPlayedDate = null;
boolean doesShowStarredSongs = false;
boolean doesShowUnstarredSongs = false;
// Handle the genre filter
if (StringUtils.equalsIgnoreCase("any", genre)) {
genre = null;
}
// Handle the release year filter
if (!StringUtils.equalsIgnoreCase("any", year)) {
String[] tmp = StringUtils.split(year);
fromYear = Integer.parseInt(tmp[0]);
toYear = Integer.parseInt(tmp[1]);
}
// Handle the song rating filter
if (StringUtils.equalsIgnoreCase("any", songRating)) {
doesShowStarredSongs = true;
doesShowUnstarredSongs = true;
} else if (StringUtils.equalsIgnoreCase("starred", songRating)) {
doesShowStarredSongs = true;
doesShowUnstarredSongs = false;
} else if (StringUtils.equalsIgnoreCase("unstarred", songRating)) {
doesShowStarredSongs = false;
doesShowUnstarredSongs = true;
}
// Handle the last played date filter
Calendar lastPlayed = Calendar.getInstance();
lastPlayed.setTime(new Date());
switch (lastPlayedValue) {
case "any":
lastPlayed = null;
break;
case "1day":
lastPlayed.add(Calendar.DAY_OF_YEAR, -1);
break;
case "1week":
lastPlayed.add(Calendar.WEEK_OF_YEAR, -1);
break;
case "1month":
lastPlayed.add(Calendar.MONTH, -1);
break;
case "3months":
lastPlayed.add(Calendar.MONTH, -3);
break;
case "6months":
lastPlayed.add(Calendar.MONTH, -6);
break;
case "1year":
lastPlayed.add(Calendar.YEAR, -1);
break;
}
if (lastPlayed != null) {
switch (lastPlayedComp) {
case "lt":
minLastPlayedDate = null;
maxLastPlayedDate = lastPlayed.getTime();
break;
case "gt":
minLastPlayedDate = lastPlayed.getTime();
maxLastPlayedDate = null;
break;
}
}
// Handle the album rating filter
if (albumRatingValue != null) {
switch (albumRatingComp) {
case "lt":
minAlbumRating = null;
maxAlbumRating = albumRatingValue - 1;
break;
case "gt":
minAlbumRating = albumRatingValue + 1;
maxAlbumRating = null;
break;
case "le":
minAlbumRating = null;
maxAlbumRating = albumRatingValue;
break;
case "ge":
minAlbumRating = albumRatingValue;
maxAlbumRating = null;
break;
case "eq":
minAlbumRating = albumRatingValue;
maxAlbumRating = albumRatingValue;
break;
}
}
// Handle the play count filter
if (playCountValue != null) {
switch (playCountComp) {
case "lt":
minPlayCount = null;
maxPlayCount = playCountValue - 1;
break;
case "gt":
minPlayCount = playCountValue + 1;
maxPlayCount = null;
break;
case "le":
minPlayCount = null;
maxPlayCount = playCountValue;
break;
case "ge":
minPlayCount = playCountValue;
maxPlayCount = null;
break;
case "eq":
minPlayCount = playCountValue;
maxPlayCount = playCountValue;
break;
}
}
// Handle the format filter
if (StringUtils.equalsIgnoreCase(format, "any")) format = null;
// Handle the music folder filter
List<MusicFolder> musicFolders = getMusicFolders(request);
// Do we add to the current playlist or do we replace it?
boolean shouldAddToPlayList = request.getParameter("addToPlaylist") != null;
// Search the database using these criteria
RandomSearchCriteria criteria = new RandomSearchCriteria(
size,
genre,
fromYear,
toYear,
musicFolders,
minLastPlayedDate,
maxLastPlayedDate,
minAlbumRating,
maxAlbumRating,
minPlayCount,
maxPlayCount,
doesShowStarredSongs,
doesShowUnstarredSongs,
format
);
User user = securityService.getCurrentUser(request);
Player player = playerService.getPlayer(request, response);
PlayQueue playQueue = player.getPlayQueue();
playQueue.addFiles(shouldAddToPlayList, mediaFileService.getRandomSongs(criteria, user.getUsername()));
if (autoRandom != null) {
playQueue.setRandomSearchCriteria(criteria);
}
// Render the 'reload' view to reload the play queue and the main page
List<ReloadFrame> reloadFrames = new ArrayList<>();
reloadFrames.add(new ReloadFrame("playQueue", "playQueue.view?"));
reloadFrames.add(new ReloadFrame("main", "more.view"));
Map<String, Object> map = new HashMap<>();
map.put("reloadFrames", reloadFrames);
model.addAttribute("model", map);
return "reload";
}
private List<MusicFolder> getMusicFolders(HttpServletRequest request) throws ServletRequestBindingException {
String username = securityService.getCurrentUsername(request);
Integer selectedMusicFolderId = ServletRequestUtils.getRequiredIntParameter(request, "musicFolderId");
if (selectedMusicFolderId == -1) {
selectedMusicFolderId = null;
}
return settingsService.getMusicFoldersForUser(username, selectedMusicFolderId);
}
}