|
|
|
/*
|
|
|
|
This file is part of Airsonic.
|
|
|
|
|
|
|
|
Airsonic 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.
|
|
|
|
|
|
|
|
Airsonic 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 Airsonic. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
Copyright 2017 (C) Airsonic Authors
|
|
|
|
Based upon Subsonic, Copyright 2009 (C) Sindre Mehus
|
|
|
|
*/
|
|
|
|
package org.airsonic.player.service.upnp;
|
|
|
|
|
|
|
|
import org.airsonic.player.dao.MediaFileDao;
|
|
|
|
import org.airsonic.player.domain.MediaFile;
|
|
|
|
import org.airsonic.player.domain.MusicFolder;
|
|
|
|
import org.airsonic.player.service.MediaFileService;
|
|
|
|
import org.fourthline.cling.support.model.BrowseResult;
|
|
|
|
import org.fourthline.cling.support.model.DIDLContent;
|
|
|
|
import org.fourthline.cling.support.model.DIDLObject;
|
|
|
|
import org.fourthline.cling.support.model.container.Container;
|
|
|
|
import org.fourthline.cling.support.model.container.MusicAlbum;
|
|
|
|
import org.fourthline.cling.support.model.item.Item;
|
|
|
|
import org.fourthline.cling.support.model.item.MusicTrack;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
|
|
import java.net.URI;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Allen Petersen
|
|
|
|
* @version $Id$
|
|
|
|
*/
|
|
|
|
public class MediaFileUpnpProcessor extends UpnpContentProcessor <MediaFile, MediaFile> {
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
MediaFileDao mediaFileDao;
|
|
|
|
|
|
|
|
public MediaFileUpnpProcessor() {
|
|
|
|
setRootId(DispatchingContentDirectory.CONTAINER_ID_FOLDER_PREFIX);
|
|
|
|
setRootTitle("Folders");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
// overriding for the case of browsing a file
|
|
|
|
public BrowseResult browseObjectMetadata(String id) throws Exception {
|
|
|
|
MediaFile item = getItemById(id);
|
|
|
|
DIDLContent didl = new DIDLContent();
|
|
|
|
addChild(didl, item);
|
|
|
|
return createBrowseResult(didl, 1, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Container createContainer(MediaFile item) throws Exception {
|
|
|
|
MusicAlbum container = new MusicAlbum();
|
|
|
|
if (item.isAlbum()) {
|
|
|
|
container.setAlbumArtURIs(new URI[] { getDispatcher().getAlbumProcessor().getAlbumArtURI(item.getId())});
|
|
|
|
|
|
|
|
if (item.getArtist() != null) {
|
|
|
|
container.setArtists(getDispatcher().getAlbumProcessor().getAlbumArtists(item.getArtist()));
|
|
|
|
}
|
|
|
|
container.setDescription(item.getComment());
|
|
|
|
}
|
|
|
|
container.setId(DispatchingContentDirectory.CONTAINER_ID_FOLDER_PREFIX + DispatchingContentDirectory.SEPARATOR + item.getId());
|
|
|
|
container.setTitle(item.getName());
|
|
|
|
List<MediaFile> children = getChildren(item);
|
|
|
|
container.setChildCount(children.size());
|
|
|
|
|
|
|
|
if (! getMediaFileService().isRoot(item)) {
|
|
|
|
MediaFile parent = getMediaFileService().getParentOf(item);
|
|
|
|
if (parent != null) {
|
|
|
|
container.setParentID(String.valueOf(parent.getId()));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
container.setParentID(DispatchingContentDirectory.CONTAINER_ID_FOLDER_PREFIX);
|
|
|
|
}
|
|
|
|
return container;
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<MediaFile> getAllItems() throws Exception {
|
|
|
|
List<MusicFolder> allFolders = getDispatcher().getSettingsService().getAllMusicFolders();
|
|
|
|
List<MediaFile> returnValue = new ArrayList<MediaFile>();
|
|
|
|
if (allFolders.size() == 1) {
|
|
|
|
// if there's only one root folder just return it
|
|
|
|
return getChildren(getMediaFileService().getMediaFile(allFolders.get(0).getPath()));
|
|
|
|
} else {
|
|
|
|
for (MusicFolder folder : allFolders) {
|
|
|
|
returnValue.add(getMediaFileService().getMediaFile(folder.getPath()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return returnValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
public MediaFile getItemById(String id) throws Exception {
|
|
|
|
return getMediaFileService().getMediaFile(Integer.parseInt(id));
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<MediaFile> getChildren(MediaFile item) {
|
|
|
|
List<MediaFile> children = getMediaFileService().getChildrenOf(item, true, true, true);
|
|
|
|
children.sort((MediaFile o1, MediaFile o2)->o1.getPath().replaceAll("\\W", "").compareToIgnoreCase(o2.getPath().replaceAll("\\W", "")));
|
|
|
|
return children;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addItem(DIDLContent didl, MediaFile item) throws Exception {
|
|
|
|
if (item.isFile()) {
|
|
|
|
didl.addItem(createItem(item));
|
|
|
|
} else {
|
|
|
|
didl.addContainer(createContainer(item));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addChild(DIDLContent didl, MediaFile child) throws Exception {
|
|
|
|
if (child.isFile()) {
|
|
|
|
didl.addItem(createItem(child));
|
|
|
|
} else {
|
|
|
|
didl.addContainer(createContainer(child));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Item createItem(MediaFile song) throws Exception {
|
|
|
|
MediaFile parent = getMediaFileService().getParentOf(song);
|
|
|
|
MusicTrack item = new MusicTrack();
|
|
|
|
item.setId(String.valueOf(song.getId()));
|
|
|
|
item.setParentID(String.valueOf(parent.getId()));
|
|
|
|
item.setTitle(song.getTitle());
|
|
|
|
item.setAlbum(song.getAlbumName());
|
|
|
|
if (song.getArtist() != null) {
|
|
|
|
item.setArtists(getDispatcher().getAlbumProcessor().getAlbumArtists(song.getArtist()));
|
|
|
|
}
|
|
|
|
Integer year = song.getYear();
|
|
|
|
if (year != null) {
|
|
|
|
item.setDate(year + "-01-01");
|
|
|
|
}
|
|
|
|
item.setOriginalTrackNumber(song.getTrackNumber());
|
|
|
|
if (song.getGenre() != null) {
|
|
|
|
item.setGenres(new String[]{song.getGenre()});
|
|
|
|
}
|
|
|
|
item.setResources(Arrays.asList(getDispatcher().createResourceForSong(song)));
|
|
|
|
item.setDescription(song.getComment());
|
|
|
|
item.addProperty(new DIDLObject.Property.UPNP.ALBUM_ART_URI(getDispatcher().getAlbumProcessor().getAlbumArtURI(parent.getId())));
|
|
|
|
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
public MediaFileService getMediaFileService() {
|
|
|
|
return getDispatchingContentDirectory().getMediaFileService();
|
|
|
|
}
|
|
|
|
|
|
|
|
public MediaFileDao getMediaFileDao() {
|
|
|
|
return mediaFileDao;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setMediaFileDao(MediaFileDao mediaFileDao) {
|
|
|
|
this.mediaFileDao = mediaFileDao;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|