|  |  |  | @ -19,62 +19,45 @@ | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | package org.libresonic.player.controller; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | import java.awt.Color; | 
			
		
	
		
			
				
					|  |  |  |  | import java.awt.Font; | 
			
		
	
		
			
				
					|  |  |  |  | import java.awt.GradientPaint; | 
			
		
	
		
			
				
					|  |  |  |  | import java.awt.Graphics2D; | 
			
		
	
		
			
				
					|  |  |  |  | import java.awt.RenderingHints; | 
			
		
	
		
			
				
					|  |  |  |  | import java.awt.image.BufferedImage; | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.ByteArrayInputStream; | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.File; | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.FileInputStream; | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.FileOutputStream; | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.IOException; | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.InputStream; | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.OutputStream; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.ArrayList; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.LinkedHashSet; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.List; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.Set; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.concurrent.Semaphore; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | import javax.imageio.ImageIO; | 
			
		
	
		
			
				
					|  |  |  |  | import javax.servlet.http.HttpServletRequest; | 
			
		
	
		
			
				
					|  |  |  |  | import javax.servlet.http.HttpServletResponse; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | import org.apache.commons.codec.digest.DigestUtils; | 
			
		
	
		
			
				
					|  |  |  |  | import org.apache.commons.io.FilenameUtils; | 
			
		
	
		
			
				
					|  |  |  |  | import org.apache.commons.io.IOUtils; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.bind.ServletRequestUtils; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.servlet.ModelAndView; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.servlet.mvc.Controller; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.servlet.mvc.LastModified; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.Logger; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.dao.AlbumDao; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.dao.ArtistDao; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.Album; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.Artist; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.CoverArtScheme; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.MediaFile; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.Playlist; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.PodcastChannel; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.Transcoding; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.VideoTranscodingSettings; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.service.MediaFileService; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.service.PlaylistService; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.service.PodcastService; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.service.SettingsService; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.service.TranscodingService; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.domain.*; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.service.*; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.service.metadata.JaudiotaggerParser; | 
			
		
	
		
			
				
					|  |  |  |  | import org.libresonic.player.util.StringUtil; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.stereotype.Controller; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.bind.ServletRequestUtils; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.bind.annotation.RequestMapping; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.bind.annotation.RequestMethod; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.servlet.ModelAndView; | 
			
		
	
		
			
				
					|  |  |  |  | import org.springframework.web.servlet.mvc.LastModified; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | import javax.annotation.PostConstruct; | 
			
		
	
		
			
				
					|  |  |  |  | import javax.imageio.ImageIO; | 
			
		
	
		
			
				
					|  |  |  |  | import javax.servlet.http.HttpServletRequest; | 
			
		
	
		
			
				
					|  |  |  |  | import javax.servlet.http.HttpServletResponse; | 
			
		
	
		
			
				
					|  |  |  |  | import java.awt.*; | 
			
		
	
		
			
				
					|  |  |  |  | import java.awt.image.BufferedImage; | 
			
		
	
		
			
				
					|  |  |  |  | import java.io.*; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.ArrayList; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.LinkedHashSet; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.List; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.Set; | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.concurrent.Semaphore; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /** | 
			
		
	
		
			
				
					|  |  |  |  |  * Controller which produces cover art images. | 
			
		
	
		
			
				
					|  |  |  |  |  * | 
			
		
	
		
			
				
					|  |  |  |  |  * @author Sindre Mehus | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | public class CoverArtController implements Controller, LastModified { | 
			
		
	
		
			
				
					|  |  |  |  | @Controller | 
			
		
	
		
			
				
					|  |  |  |  | @RequestMapping("/coverArt") | 
			
		
	
		
			
				
					|  |  |  |  | public class CoverArtController implements LastModified { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public static final String ALBUM_COVERART_PREFIX = "al-"; | 
			
		
	
		
			
				
					|  |  |  |  |     public static final String ARTIST_COVERART_PREFIX = "ar-"; | 
			
		
	
	
		
			
				
					|  |  |  | @ -83,26 +66,34 @@ public class CoverArtController implements Controller, LastModified { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private static final Logger LOG = Logger.getLogger(CoverArtController.class); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @Autowired | 
			
		
	
		
			
				
					|  |  |  |  |     private MediaFileService mediaFileService; | 
			
		
	
		
			
				
					|  |  |  |  |     @Autowired | 
			
		
	
		
			
				
					|  |  |  |  |     private TranscodingService transcodingService; | 
			
		
	
		
			
				
					|  |  |  |  |     @Autowired | 
			
		
	
		
			
				
					|  |  |  |  |     private SettingsService settingsService; | 
			
		
	
		
			
				
					|  |  |  |  |     @Autowired | 
			
		
	
		
			
				
					|  |  |  |  |     private PlaylistService playlistService; | 
			
		
	
		
			
				
					|  |  |  |  |     @Autowired | 
			
		
	
		
			
				
					|  |  |  |  |     private PodcastService podcastService; | 
			
		
	
		
			
				
					|  |  |  |  |     @Autowired | 
			
		
	
		
			
				
					|  |  |  |  |     private ArtistDao artistDao; | 
			
		
	
		
			
				
					|  |  |  |  |     @Autowired | 
			
		
	
		
			
				
					|  |  |  |  |     private AlbumDao albumDao; | 
			
		
	
		
			
				
					|  |  |  |  |     private Semaphore semaphore; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @PostConstruct | 
			
		
	
		
			
				
					|  |  |  |  |     public void init() { | 
			
		
	
		
			
				
					|  |  |  |  |         semaphore = new Semaphore(settingsService.getCoverArtConcurrency()); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public long getLastModified(HttpServletRequest request) { | 
			
		
	
		
			
				
					|  |  |  |  |         CoverArtRequest coverArtRequest = createCoverArtRequest(request); | 
			
		
	
		
			
				
					|  |  |  |  |         long result = coverArtRequest.lastModified(); | 
			
		
	
		
			
				
					|  |  |  |  | //        LOG.info("getLastModified - " + coverArtRequest + ": " + new Date(result));
 | 
			
		
	
		
			
				
					|  |  |  |  |         return result; | 
			
		
	
		
			
				
					|  |  |  |  |         //        LOG.info("getLastModified - " + coverArtRequest + ": " + new Date(result));
 | 
			
		
	
		
			
				
					|  |  |  |  |         return coverArtRequest.lastModified(); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     @RequestMapping(method = RequestMethod.GET) | 
			
		
	
		
			
				
					|  |  |  |  |     public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         CoverArtRequest coverArtRequest = createCoverArtRequest(request); | 
			
		
	
	
		
			
				
					|  |  |  | @ -341,33 +332,6 @@ public class CoverArtController implements Controller, LastModified { | 
			
		
	
		
			
				
					|  |  |  |  |         return thumb; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public void setMediaFileService(MediaFileService mediaFileService) { | 
			
		
	
		
			
				
					|  |  |  |  |         this.mediaFileService = mediaFileService; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public void setArtistDao(ArtistDao artistDao) { | 
			
		
	
		
			
				
					|  |  |  |  |         this.artistDao = artistDao; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public void setAlbumDao(AlbumDao albumDao) { | 
			
		
	
		
			
				
					|  |  |  |  |         this.albumDao = albumDao; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public void setTranscodingService(TranscodingService transcodingService) { | 
			
		
	
		
			
				
					|  |  |  |  |         this.transcodingService = transcodingService; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public void setSettingsService(SettingsService settingsService) { | 
			
		
	
		
			
				
					|  |  |  |  |         this.settingsService = settingsService; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public void setPlaylistService(PlaylistService playlistService) { | 
			
		
	
		
			
				
					|  |  |  |  |         this.playlistService = playlistService; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     public void setPodcastService(PodcastService podcastService) { | 
			
		
	
		
			
				
					|  |  |  |  |         this.podcastService = podcastService; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private abstract class CoverArtRequest { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -551,7 +515,7 @@ public class CoverArtController implements Controller, LastModified { | 
			
		
	
		
			
				
					|  |  |  |  |                     albums.add(album); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             return new ArrayList<MediaFile>(albums); | 
			
		
	
		
			
				
					|  |  |  |  |             return new ArrayList<>(albums); | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -559,7 +523,7 @@ public class CoverArtController implements Controller, LastModified { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         private final PodcastChannel channel; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         public PodcastCoverArtRequest(PodcastChannel channel) { | 
			
		
	
		
			
				
					|  |  |  |  |         PodcastCoverArtRequest(PodcastChannel channel) { | 
			
		
	
		
			
				
					|  |  |  |  |             this.channel = channel; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -633,7 +597,8 @@ public class CoverArtController implements Controller, LastModified { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         @Override | 
			
		
	
		
			
				
					|  |  |  |  |         public BufferedImage createImage(int size) { | 
			
		
	
		
			
				
					|  |  |  |  |             int height = size; | 
			
		
	
		
			
				
					|  |  |  |  |             int height; | 
			
		
	
		
			
				
					|  |  |  |  |             height = size; | 
			
		
	
		
			
				
					|  |  |  |  |             int width = height * 16 / 9; | 
			
		
	
		
			
				
					|  |  |  |  |             InputStream in = null; | 
			
		
	
		
			
				
					|  |  |  |  |             try { | 
			
		
	
	
		
			
				
					|  |  |  | @ -687,7 +652,7 @@ public class CoverArtController implements Controller, LastModified { | 
			
		
	
		
			
				
					|  |  |  |  |         private final int height; | 
			
		
	
		
			
				
					|  |  |  |  |         private final Color color; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         public AutoCover(Graphics2D graphics, String key, String artist, String album, int width, int height) { | 
			
		
	
		
			
				
					|  |  |  |  |         AutoCover(Graphics2D graphics, String key, String artist, String album, int width, int height) { | 
			
		
	
		
			
				
					|  |  |  |  |             this.graphics = graphics; | 
			
		
	
		
			
				
					|  |  |  |  |             this.artist = artist; | 
			
		
	
		
			
				
					|  |  |  |  |             this.album = album; | 
			
		
	
	
		
			
				
					|  |  |  | 
 |