diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java index 913c7ed7..e582d45b 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java @@ -153,7 +153,22 @@ public class AlbumDao extends AbstractDao { * @param musicFolders Only return albums from these folders. * @return Albums in alphabetical order. */ + @Deprecated public List getAlphabetialAlbums(final int offset, final int count, boolean byArtist, final List musicFolders) { + return getAlphabeticalAlbums(offset, count, byArtist, false, musicFolders); + } + + /** + * Returns albums in alphabetical order. + * + * @param offset Number of albums to skip. + * @param count Maximum number of albums to return. + * @param byArtist Whether to sort by artist name + * @param musicFolders Only return albums from these folders. + * @param ignoreCase Use case insensitive sorting + * @return Albums in alphabetical order. + */ + public List getAlphabeticalAlbums(final int offset, final int count, boolean byArtist, boolean ignoreCase, final List musicFolders) { if (musicFolders.isEmpty()) { return Collections.emptyList(); } @@ -162,11 +177,34 @@ public class AlbumDao extends AbstractDao { put("count", count); put("offset", offset); }}; - String orderBy = byArtist ? "artist, name" : "name"; + String orderBy; + if (ignoreCase) { + orderBy = byArtist ? "LOWER(artist), LOWER(name)" : "LOWER(name)"; + } else { + orderBy = byArtist ? "artist, name" : "name"; + } + return namedQuery("select " + QUERY_COLUMNS + " from album where present and folder_id in (:folders) " + "order by " + orderBy + " limit :count offset :offset", rowMapper, args); } + /** + * Returns the count of albums in the given folders + * + * @param musicFolders Only return albums from these folders. + * @return the count of present albums + */ + public int getAlbumCount(final List musicFolders) { + if (musicFolders.isEmpty()) { + return 0; + } + Map args = new HashMap(); + args.put("folders", MusicFolder.toIdList(musicFolders)); + + return getNamedParameterJdbcTemplate().queryForObject("select count(*) from album where present and folder_id in (:folders)", args, Integer.class); + + } + /** * Returns the most frequently played albums. * diff --git a/libresonic-main/src/main/java/org/libresonic/player/service/upnp/AlbumUpnpProcessor.java b/libresonic-main/src/main/java/org/libresonic/player/service/upnp/AlbumUpnpProcessor.java index 1a893e7c..62fb4e7c 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/service/upnp/AlbumUpnpProcessor.java +++ b/libresonic-main/src/main/java/org/libresonic/player/service/upnp/AlbumUpnpProcessor.java @@ -18,8 +18,10 @@ Based upon Subsonic, Copyright 2009 (C) Sindre Mehus */ package org.libresonic.player.service.upnp; +import org.fourthline.cling.support.model.BrowseResult; import org.fourthline.cling.support.model.DIDLContent; import org.fourthline.cling.support.model.PersonWithRole; +import org.fourthline.cling.support.model.SortCriterion; import org.fourthline.cling.support.model.container.Container; import org.fourthline.cling.support.model.container.MusicAlbum; import org.libresonic.player.dao.AlbumDao; @@ -53,6 +55,20 @@ public class AlbumUpnpProcessor extends UpnpContentProcessor setRootTitle("Albums"); } + /** + * Browses the top-level content of a type. + */ + public BrowseResult browseRoot(String filter, long firstResult, long maxResults, SortCriterion[] orderBy) throws Exception { + DIDLContent didl = new DIDLContent(); + + List allFolders = getDispatchingContentDirectory().getSettingsService().getAllMusicFolders(); + List selectedItems = getAlbumDao().getAlphabeticalAlbums((int) firstResult, (int) maxResults, false, true, allFolders); + for (Album item : selectedItems) { + addItem(didl, item); + } + + return createBrowseResult(didl, (int) didl.getCount(), getAllItemsSize()); + } public Container createContainer(Album album) throws Exception { MusicAlbum container = new MusicAlbum(); @@ -74,7 +90,7 @@ public class AlbumUpnpProcessor extends UpnpContentProcessor public List getAllItems() { List allFolders = getDispatchingContentDirectory().getSettingsService().getAllMusicFolders(); - return getAlbumDao().getAlphabetialAlbums(0, 0, false, allFolders); + return getAlbumDao().getAlphabeticalAlbums(0, Integer.MAX_VALUE, false, true, allFolders); } public Album getItemById(String id) throws Exception { @@ -110,6 +126,13 @@ public class AlbumUpnpProcessor extends UpnpContentProcessor return allFiles; } + @Override + public int getAllItemsSize() throws Exception { + List allFolders = getDispatchingContentDirectory().getSettingsService().getAllMusicFolders(); + return getAlbumDao().getAlbumCount(allFolders); + } + + public void addChild(DIDLContent didl, MediaFile child) throws Exception { didl.addItem(getDispatcher().getMediaFileProcessor().createItem(child)); }