/* 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 . 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 org.springframework.stereotype.Service; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @author Allen Petersen * @version $Id$ */ @Service public class MediaFileUpnpProcessor extends UpnpContentProcessor { @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 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 getAllItems() throws Exception { List allFolders = getDispatcher().getSettingsService().getAllMusicFolders(); List returnValue = new ArrayList(); 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 getChildren(MediaFile item) { List 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; } }