Skip to content

Commit

Permalink
Merge pull request #537 from kagemomiji/issue526-podcast-episode-pagi…
Browse files Browse the repository at this point in the history
…nation

#526 feat: Add pagination of Podcast episodes
  • Loading branch information
kagemomiji authored Jul 13, 2024
2 parents abc9274 + 7da792a commit 5d4891a
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/trivy_scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
uses: actions/checkout@v4

- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.23.0
uses: aquasecurity/trivy-action@0.24.0
with:
scan-type: 'fs'
format: 'sarif'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import org.airsonic.player.command.PodcastChannelCommand;
import org.airsonic.player.command.PodcastEpisodeCommand;
import org.airsonic.player.domain.PodcastEpisode;
import org.airsonic.player.domain.PodcastStatus;
import org.airsonic.player.domain.User;
import org.airsonic.player.domain.UserSettings;
Expand All @@ -30,6 +31,8 @@
import org.airsonic.player.service.SecurityService;
import org.airsonic.player.service.podcast.PodcastDownloadClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down Expand Up @@ -73,23 +76,29 @@ public User getUser(HttpServletRequest request) {

@GetMapping
protected ModelAndView get(@ModelAttribute User user,
@RequestParam(name = "id", required = true) Integer channelId) throws Exception {
@RequestParam(name = "id", required = true) Integer channelId,
@RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
@RequestParam(name = "size", required = false, defaultValue = "10") Integer size) throws Exception {

PodcastChannelCommand command = new PodcastChannelCommand();
UserSettings settings = personalSettingsService.getUserSettings(user.getUsername());
command.setUser(user);
command.setChannel(podcastService.getChannel(channelId));
command.setEpisodesByDAO(podcastService.getEpisodes(channelId));
Page<PodcastEpisode> episodes = podcastService.getEpisodes(channelId, PageRequest.of(page, size));
command.setEpisodesByDAO(episodes.getContent());
command.setPartyModeEnabled(settings.getPartyModeEnabled());

ModelAndView result = new ModelAndView();
result.addObject("command", command);
result.addObject("pages", episodes);
return result;
}

@PostMapping(params = "delete")
protected String deleteEpisodes(@ModelAttribute User user,
@ModelAttribute(name = "channelId") Integer channelId,
@RequestParam(name = "page", defaultValue = "0") Integer page,
@RequestParam(name = "size", defaultValue = "10") Integer size,
@ModelAttribute("command") PodcastChannelCommand command) throws Exception {

if (!user.isPodcastRole()) {
Expand All @@ -105,13 +114,15 @@ protected String deleteEpisodes(@ModelAttribute User user,
.map(PodcastEpisodeCommand::getId)
.forEach(id -> podcastService.deleteEpisode(id, true));

return "redirect:/podcastChannel.view?id=" + channelId;
return String.format("redirect:/podcastChannel.view?id=%d&page=%d&size=%d", channelId, page, size);

}

@PostMapping(params = "download")
protected String downloadEpisodes(@ModelAttribute User user,
@ModelAttribute(name = "channelId") Integer channelId,
@RequestParam(name = "page", defaultValue = "0") Integer page,
@RequestParam(name = "size", defaultValue = "10") Integer size,
@ModelAttribute("command") PodcastChannelCommand command) throws Exception {

if (!user.isPodcastRole()) {
Expand All @@ -127,13 +138,15 @@ protected String downloadEpisodes(@ModelAttribute User user,
.map(PodcastEpisodeCommand::getId)
.forEach(podcastDownloadClient::downloadEpisode);

return "redirect:/podcastChannel.view?id=" + channelId;
return String.format("redirect:/podcastChannel.view?id=%d&page=%d&size=%d", channelId, page, size);

}

@PostMapping(params = "lock")
protected String lockEpisodes(@ModelAttribute User user,
@ModelAttribute(name = "channelId") Integer channelId,
@RequestParam(name = "page", defaultValue = "0") Integer page,
@RequestParam(name = "size", defaultValue = "10") Integer size,
@ModelAttribute("command") PodcastChannelCommand command) throws Exception {

if (!user.isPodcastRole()) {
Expand All @@ -149,13 +162,15 @@ protected String lockEpisodes(@ModelAttribute User user,
.map(PodcastEpisodeCommand::getId)
.forEach(podcastService::lockEpisode);

return "redirect:/podcastChannel.view?id=" + channelId;
return String.format("redirect:/podcastChannel.view?id=%d&page=%d&size=%d", channelId, page, size);

}

@PostMapping(params = "unlock")
protected String unlockEpisodes(@ModelAttribute User user,
@ModelAttribute(name = "channelId") Integer channelId,
@RequestParam(name = "page", defaultValue = "0") Integer page,
@RequestParam(name = "size", defaultValue = "10") Integer size,
@ModelAttribute("command") PodcastChannelCommand command) throws Exception {

if (!user.isPodcastRole()) {
Expand All @@ -171,7 +186,7 @@ protected String unlockEpisodes(@ModelAttribute User user,
.map(PodcastEpisodeCommand::getId)
.forEach(podcastService::unlockEpisode);

return "redirect:/podcastChannel.view?id=" + channelId;
return String.format("redirect:/podcastChannel.view?id=%d&page=%d&size=%d", channelId, page, size);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ public class PodcastEpisodesControler {

@PostMapping(params = "download")
public String downloadEpisode(
@RequestParam(name = "episodeId", required = true) Integer episodeId) throws Exception {
@RequestParam(name = "episodeId", required = true) Integer episodeId,
@RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
@RequestParam(name = "size", required = false, defaultValue = "10") Integer size) throws Exception {

PodcastEpisode episode = podcastService.getEpisode(episodeId, false);
if (episode == null) {
Expand All @@ -63,7 +65,7 @@ public String downloadEpisode(
Integer channelId = episode.getChannel().getId();
podcastDownloadClient.downloadEpisode(episodeId);

return "redirect:/podcastChannel?id=" + channelId;
return String.format("redirect:/podcastChannel.view?id=%d&page=%d&size=%d", channelId, page, size);
}

/**
Expand All @@ -75,7 +77,9 @@ public String downloadEpisode(
*/
@PostMapping(params = "init")
public String initializeEpisode(
@RequestParam(name = "episodeId", required = true) Integer episodeId) throws Exception {
@RequestParam(name = "episodeId", required = true) Integer episodeId,
@RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
@RequestParam(name = "size", required = false, defaultValue = "10") Integer size) throws Exception {

PodcastEpisode episode = podcastService.getEpisode(episodeId, true);
if (episode == null) {
Expand All @@ -87,7 +91,7 @@ public String initializeEpisode(
Integer channelId = episode.getChannel().getId();
podcastService.resetEpisode(episodeId);

return "redirect:/podcastChannel?id=" + channelId;
return String.format("redirect:/podcastChannel.view?id=%d&page=%d&size=%d", channelId, page, size);
}

/**
Expand All @@ -99,7 +103,9 @@ public String initializeEpisode(
*/
@PostMapping(params = "lock")
public String lockEpisode(
@RequestParam(name = "episodeId", required = true) Integer episodeId) throws Exception {
@RequestParam(name = "episodeId", required = true) Integer episodeId,
@RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
@RequestParam(name = "size", required = false, defaultValue = "10") Integer size) throws Exception {

PodcastEpisode episode = podcastService.getEpisode(episodeId, true);
if (episode == null) {
Expand All @@ -111,7 +117,7 @@ public String lockEpisode(
Integer channelId = episode.getChannel().getId();
podcastService.lockEpisode(episodeId);

return "redirect:/podcastChannel?id=" + channelId;
return String.format("redirect:/podcastChannel.view?id=%d&page=%d&size=%d", channelId, page, size);
}

/**
Expand All @@ -123,7 +129,9 @@ public String lockEpisode(
*/
@PostMapping(params = "unlock")
public String unlockEpisode(
@RequestParam(name = "episodeId", required = true) Integer episodeId) throws Exception {
@RequestParam(name = "episodeId", required = true) Integer episodeId,
@RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
@RequestParam(name = "size", required = false, defaultValue = "10") Integer size) throws Exception {

PodcastEpisode episode = podcastService.getEpisode(episodeId, true);
if (episode == null) {
Expand All @@ -135,7 +143,7 @@ public String unlockEpisode(
Integer channelId = episode.getChannel().getId();
podcastService.unlockEpisode(episodeId);

return "redirect:/podcastChannel?id=" + channelId;
return String.format("redirect:/podcastChannel.view?id=%d&page=%d&size=%d", channelId, page, size);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
import org.jdom2.Namespace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -384,7 +387,7 @@ public List<PodcastEpisode> getEpisodes(Integer channelId) {
if (mediaFile != null) {
// Refresh media file to check if it still exists
mediaFileService.refreshMediaFile(mediaFile);
if (!mediaFile.isPresent() && ep.getStatus() != PodcastStatus.DELETED) {
if (!mediaFile.isPresent() && ep.getStatus() != PodcastStatus.DELETED && !ep.isLocked()) {
LOG.info("Media file '{}' for episode '{}' is not present anymore. Setting episode status to deleted.", mediaFile.getId(), ep.getTitle());
// If media file is not present anymore, set episode status to deleted
ep.setStatus(PodcastStatus.DELETED);
Expand All @@ -402,6 +405,18 @@ public List<PodcastEpisode> getEpisodes(Integer channelId) {
});
}

@Transactional
public Page<PodcastEpisode> getEpisodes(Integer channelId, Pageable pageable) {
List<PodcastEpisode> episodes = getEpisodes(channelId);

int start = (int) pageable.getOffset();
int end = Math.min((start + pageable.getPageSize()), episodes.size());

List<PodcastEpisode> result = episodes.size() > start ? episodes.subList(start, end) : Collections.emptyList();

return new PageImpl<>(result, pageable, episodes.size());
}

/**
* Returns the N newest episodes.
*
Expand Down Expand Up @@ -432,7 +447,7 @@ public PodcastEpisode getEpisode(int episodeId, boolean includeDeleted) {
if (mediaFile != null) {
// Refresh media file to check if it still exists
mediaFileService.refreshMediaFile(mediaFile);
if (!mediaFile.isPresent() && ep.getStatus() != PodcastStatus.DELETED) {
if (!mediaFile.isPresent() && ep.getStatus() != PodcastStatus.DELETED && !ep.isLocked()) {
deleteEpisode(ep, true);
}
}
Expand Down

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion airsonic-main/src/main/resources/templates/bookmarks.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
order: [],
orderMulti: true,
pageLength: /*[[${model.initialPaginationSize}]]*/ 10,
//<c:set var="paginationaddition" value="${fn:contains(' 10 20 50 100 -1', ' '.concat(model.initialPaginationSize)) ? '' : ', '.concat(model.initialPaginationSize)}" />
lengthMenu: [ [10, 20, 50, 100, -1 ], [10, 20, 50, 100, "All" ] ],
processing: true,
autoWidth: true,
Expand Down
Loading

0 comments on commit 5d4891a

Please sign in to comment.