Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#212 implemented repository of playlist #307

Merged
merged 3 commits into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,26 @@ public List<Playlist> getWritablePlaylists(Principal p) {
return playlistService.getWritablePlaylistsForUser(p.getName());
}

/**
* Creates a playlist and broadcasts it to all users that have access to it.
*
* @param playlist the playlist to create
* @return the id of the created playlist
*/
private Playlist createPlaylist(String name, boolean shared, String username) {
Playlist result = playlistService.createPlaylist(name, shared, username);
playlistService.broadcast(result);
return result;
}

@MessageMapping("/create/empty")
@SendToUser(broadcast = false)
public int createEmptyPlaylist(Principal p) {
Locale locale = localeResolver.resolveLocale(p.getName());
DateTimeFormatter dateFormat = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT).withLocale(locale);

Instant now = Instant.now();
Playlist playlist = new Playlist();
playlist.setUsername(p.getName());
playlist.setCreated(now);
playlist.setChanged(now);
playlist.setShared(false);
playlist.setName(dateFormat.format(now.atZone(ZoneId.systemDefault())));

playlistService.createPlaylist(playlist);

return playlist.getId();
Playlist result = createPlaylist(dateFormat.format(now.atZone(ZoneId.systemDefault())), false, p.getName());
return result.getId();
}

@MessageMapping("/create/starred")
Expand All @@ -83,22 +86,18 @@ public int createPlaylistForStarredSongs(Principal p) {
Locale locale = localeResolver.resolveLocale(p.getName());
DateTimeFormatter dateFormat = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT).withLocale(locale);

Instant now = Instant.now();
Playlist playlist = new Playlist();
playlist.setUsername(p.getName());
playlist.setCreated(now);
playlist.setChanged(now);
playlist.setShared(false);

ResourceBundle bundle = ResourceBundle.getBundle("org.airsonic.player.i18n.ResourceBundle", locale);
playlist.setName(bundle.getString("top.starred") + " " + dateFormat.format(now.atZone(ZoneId.systemDefault())));

playlistService.createPlaylist(playlist);
List<MusicFolder> musicFolders = mediaFolderService.getMusicFoldersForUser(p.getName());
List<MediaFile> songs = mediaFileDao.getStarredFiles(0, Integer.MAX_VALUE, p.getName(), musicFolders);
playlistService.setFilesInPlaylist(playlist.getId(), songs);

return playlist.getId();
Instant now = Instant.now();
String name = bundle.getString("top.starred") + " " + dateFormat.format(now.atZone(ZoneId.systemDefault()));
String username = p.getName();

Playlist result = createPlaylist(name, false, username);
List<MusicFolder> musicFolders = mediaFolderService.getMusicFoldersForUser(username);
List<MediaFile> songs = mediaFileDao.getStarredFiles(0, Integer.MAX_VALUE, username, musicFolders);
Integer playlistId = result.getId();
playlistService.setFilesInPlaylist(playlistId, songs);
playlistService.broadcastFileChange(playlistId, false, true);
return result.getId();
}

@MessageMapping("/create/playqueue")
Expand All @@ -111,29 +110,31 @@ public int createPlaylistForPlayQueue(Principal p, Integer playerId) throws Exce
Instant now = Instant.now();
Playlist playlist = new Playlist();
playlist.setUsername(p.getName());
playlist.setCreated(now);
playlist.setChanged(now);
playlist.setShared(false);
playlist.setName(dateFormat.format(now.atZone(ZoneId.systemDefault())));

playlistService.createPlaylist(playlist);
playlistService.setFilesInPlaylist(playlist.getId(), player.getPlayQueue().getFiles());
Playlist result = createPlaylist(dateFormat.format(now.atZone(ZoneId.systemDefault())), false, p.getName());
Integer playlistId = result.getId();
playlistService.setFilesInPlaylist(playlistId, player.getPlayQueue().getFiles());
playlistService.broadcastFileChange(playlistId, false, true);

return playlist.getId();
return playlistId;
}

@MessageMapping("/delete")
public void deletePlaylist(int id) {
playlistService.deletePlaylist(id);
playlistService.broadcastDeleted(id);
}

@MessageMapping("/update")
public void updatePlaylist(PlaylistUpdateRequest req) {
Playlist playlist = new Playlist(playlistService.getPlaylist(req.getId()));
playlist.setName(req.getName());
playlist.setComment(req.getComment());
playlist.setShared(req.getShared());
playlistService.updatePlaylist(playlist);
Playlist playlist = playlistService.getPlaylist(req.getId());
if (playlist == null) {
return;
}
playlistService.updatePlaylist(req.getId(), req.getName(), req.getComment(), req.getShared());
playlistService.broadcastFileChange(req.getId(), playlist.getShared(), false);
}

@MessageMapping("/files/append")
Expand All @@ -146,6 +147,7 @@ public int appendToPlaylist(PlaylistFilesModificationRequest req) {
.collect(Collectors.toList());

playlistService.setFilesInPlaylist(req.getId(), files);
playlistService.broadcastFileChange(req.getId(), false, true);

return req.getId();
}
Expand All @@ -154,15 +156,10 @@ public int appendToPlaylist(PlaylistFilesModificationRequest req) {
@SendToUser(broadcast = false)
public int remove(PlaylistFilesModificationRequest req) {
// in this context, modifierIds are indices
List<MediaFile> files = playlistService.getFilesInPlaylist(req.getId(), true);
List<Integer> indices = req.getModifierIds();
Collections.sort(indices);
for (int i = 0; i < indices.size(); i++) {
// factor in previous indices we've deleted so far
files.remove(indices.get(i) - i);
}
playlistService.setFilesInPlaylist(req.getId(), files);

playlistService.removeFilesInPlaylistByIndices(req.getId(), indices);
playlistService.broadcastFileChange(req.getId(), false, true);
return req.getId();
}

Expand All @@ -174,6 +171,7 @@ public int up(PlaylistFilesModificationRequest req) {
if (req.getModifierIds().size() == 1 && req.getModifierIds().get(0) > 0) {
Collections.swap(files, req.getModifierIds().get(0), req.getModifierIds().get(0) - 1);
playlistService.setFilesInPlaylist(req.getId(), files);
playlistService.broadcastFileChange(req.getId(), false, true);
}

return req.getId();
Expand All @@ -187,6 +185,7 @@ public int down(PlaylistFilesModificationRequest req) {
if (req.getModifierIds().size() == 1 && req.getModifierIds().get(0) < files.size() - 1) {
Collections.swap(files, req.getModifierIds().get(0), req.getModifierIds().get(0) + 1);
playlistService.setFilesInPlaylist(req.getId(), files);
playlistService.broadcastFileChange(req.getId(), false, true);
}

return req.getId();
Expand All @@ -202,6 +201,7 @@ public int rearrange(PlaylistFilesModificationRequest req) {
newFiles[i] = files.get(req.getModifierIds().get(i));
}
playlistService.setFilesInPlaylist(req.getId(), Arrays.asList(newFiles));
playlistService.broadcastFileChange(req.getId(), false, true);

return req.getId();
}
Expand All @@ -217,26 +217,6 @@ public List<MediaFileEntry> getPlaylistEntries(Principal p, @DestinationVariable
return mediaFileService.toMediaFileEntryList(playlistService.getFilesInPlaylist(id, true), p.getName(), true, true, null, null, null);
}

public void setPlaylistService(PlaylistService playlistService) {
this.playlistService = playlistService;
}

public void setMediaFileService(MediaFileService mediaFileService) {
this.mediaFileService = mediaFileService;
}

public void setMediaFileDao(MediaFileDao mediaFileDao) {
this.mediaFileDao = mediaFileDao;
}

public void setPlayerService(PlayerService playerService) {
this.playerService = playerService;
}

public void setLocaleResolver(LocaleResolver localeResolver) {
this.localeResolver = localeResolver;
}

public static class PlaylistFilesModificationRequest {
private int id;
private List<Integer> modifierIds;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.airsonic.player.controller;

import org.airsonic.player.domain.Playlist;
import org.airsonic.player.service.PlaylistFileService;
import org.airsonic.player.service.PlaylistService;
import org.airsonic.player.service.SecurityService;
import org.airsonic.player.util.StringUtil;
Expand All @@ -26,6 +27,9 @@ public class ExportPlayListController {
@Autowired
private SecurityService securityService;

@Autowired
private PlaylistFileService playlistFileService;

@GetMapping
public ModelAndView exportPlaylist(HttpServletRequest request, HttpServletResponse response) throws Exception {

Expand All @@ -39,7 +43,7 @@ public ModelAndView exportPlaylist(HttpServletRequest request, HttpServletRespon
response.setContentType("application/x-download");
response.setHeader("Content-Disposition", "attachment; filename=\"" + StringUtil.fileSystemSafe(playlist.getName()) + ".m3u8\"");

playlistService.exportPlaylist(id, response.getOutputStream());
playlistFileService.exportPlaylist(id, response.getOutputStream());
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import org.airsonic.player.command.GeneralSettingsCommand;
import org.airsonic.player.domain.Theme;
import org.airsonic.player.service.PlaylistService;
import org.airsonic.player.service.PlaylistFileService;
import org.airsonic.player.service.SettingsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
Expand All @@ -47,7 +47,7 @@ public class GeneralSettingsController {
private SettingsService settingsService;

@Autowired
private PlaylistService playlistService;
private PlaylistFileService playlistFileService;

@GetMapping
protected String displayForm() {
Expand Down Expand Up @@ -123,8 +123,8 @@ protected String doSubmitAction(@ModelAttribute("command") GeneralSettingsComman
settingsService.setGenreSeparators(command.getGenreSeparators());
settingsService.setShortcuts(command.getShortcuts());
settingsService.setPlaylistFolder(command.getPlaylistFolder());
playlistService.addPlaylistFolderWatcher();
playlistService.importPlaylists();
playlistFileService.addPlaylistFolderWatcher();
playlistFileService.importPlaylists();
settingsService.setMusicFileTypes(command.getMusicFileTypes());
settingsService.setVideoFileTypes(command.getVideoFileTypes());
settingsService.setCoverArtFileTypes(command.getCoverArtFileTypes());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
package org.airsonic.player.controller;

import org.airsonic.player.domain.Playlist;
import org.airsonic.player.service.PlaylistService;
import org.airsonic.player.domain.User;
import org.airsonic.player.service.PlaylistFileService;
import org.airsonic.player.service.SecurityService;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
Expand Down Expand Up @@ -51,7 +52,7 @@ public class ImportPlaylistController {
@Autowired
private SecurityService securityService;
@Autowired
private PlaylistService playlistService;
private PlaylistFileService playlistFileService;

@PostMapping
protected String handlePost(@RequestParam("file") MultipartFile file,
Expand All @@ -67,8 +68,8 @@ protected String handlePost(@RequestParam("file") MultipartFile file,
}
String playlistName = FilenameUtils.getBaseName(file.getOriginalFilename());
String fileName = FilenameUtils.getName(file.getOriginalFilename());
String username = securityService.getCurrentUsername(request);
Playlist playlist = playlistService.importPlaylist(username, playlistName, fileName, null, file.getInputStream(), null);
User user = securityService.getCurrentUser(request);
Playlist playlist = playlistFileService.importPlaylist(user, playlistName, fileName, null, file.getInputStream(), null);
map.put("playlist", playlist);
} else {
throw new Exception("No file specified.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.airsonic.player.domain.MediaLibraryStatistics;
import org.airsonic.player.domain.MusicFolder;
import org.airsonic.player.domain.MusicFolder.Type;
import org.airsonic.player.domain.Playlist;
import org.airsonic.player.service.AlbumService;
import org.airsonic.player.service.ArtistService;
import org.airsonic.player.service.CoverArtService;
Expand Down Expand Up @@ -145,7 +146,10 @@ private void expunge() {
LOG.debug("Deleting non-present media folders...");
mediaFolderService.expunge();
LOG.debug("Refreshing playlist stats...");
playlistService.refreshPlaylistsStats();
List<Playlist> playlists = playlistService.refreshPlaylistsStats();
playlists.forEach(p -> {
playlistService.broadcastFileChange(p.getId(), false, false);
});
LOG.debug("Database cleanup complete.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -974,14 +974,8 @@ public void createPlaylist(HttpServletRequest request, HttpServletResponse respo
return;
}
} else {
playlist = new org.airsonic.player.domain.Playlist();
Instant now = Instant.now();
playlist.setName(name);
playlist.setCreated(now);
playlist.setChanged(now);
playlist.setShared(false);
playlist.setUsername(username);
playlistService.createPlaylist(playlist);
playlist = playlistService.createPlaylist(name, false, username);
playlistService.broadcast(playlist);
}

List<MediaFile> songs = new ArrayList<MediaFile>();
Expand All @@ -992,6 +986,7 @@ public void createPlaylist(HttpServletRequest request, HttpServletResponse respo
}
}
playlistService.setFilesInPlaylist(playlist.getId(), songs);
playlistService.broadcastFileChange(playlist.getId(), false, true);

writeEmptyResponse(request, response);
}
Expand All @@ -1013,21 +1008,10 @@ public void updatePlaylist(HttpServletRequest request, HttpServletResponse respo
}

// create new object to not mutate the cache
playlist = new org.airsonic.player.domain.Playlist(playlist);

String name = request.getParameter("name");
if (name != null) {
playlist.setName(name);
}
String comment = request.getParameter("comment");
if (comment != null) {
playlist.setComment(comment);
}
Boolean shared = getBooleanParameter(request, "public");
if (shared != null) {
playlist.setShared(shared);
}
playlistService.updatePlaylist(playlist);
playlistService.updatePlaylist(id, name, comment, shared);

// TODO: Add later
// for (String usernameToAdd : ServletRequestUtils.getStringParameters(request, "usernameToAdd")) {
Expand Down Expand Up @@ -1063,6 +1047,7 @@ public void updatePlaylist(HttpServletRequest request, HttpServletResponse respo
if (songsChanged) {
playlistService.setFilesInPlaylist(id, songs);
}
playlistService.broadcastFileChange(id, playlist.getShared(), songsChanged);

writeEmptyResponse(request, response);
}
Expand All @@ -1073,16 +1058,16 @@ public void deletePlaylist(HttpServletRequest request, HttpServletResponse respo
String username = securityService.getCurrentUsername(request);

int id = getRequiredIntParameter(request, "id");
org.airsonic.player.domain.Playlist playlist = playlistService.getPlaylist(id);
if (playlist == null) {
if (!playlistService.isExist(id)) {
error(request, response, ErrorCode.NOT_FOUND, "Playlist not found: " + id);
return;
}
if (!playlistService.isWriteAllowed(playlist, username)) {
if (!playlistService.isWriteAllowed(id, username)) {
error(request, response, ErrorCode.NOT_AUTHORIZED, "Permission denied for playlist " + id);
return;
}
playlistService.deletePlaylist(id);
playlistService.broadcastDeleted(id);

writeEmptyResponse(request, response);
}
Expand Down
Loading