1 /*
2  * aTunes
3  * Copyright (C) Alex Aranda, Sylvain Gaudard and contributors
4  *
5  * See http://www.atunes.org/wiki/index.php?title=Contributing for information about contributors
6  *
7  * http://www.atunes.org
8  * http://sourceforge.net/projects/atunes
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  */
20 
21 package net.sourceforge.atunes.kernel.modules.webservices.lastfm;
22 
23 import java.awt.Image;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.List;
28 
29 import javax.swing.ImageIcon;
30 
31 import net.sourceforge.atunes.Constants;
32 import net.sourceforge.atunes.kernel.modules.webservices.lastfm.data.LastFmAlbum;
33 import net.sourceforge.atunes.kernel.modules.webservices.lastfm.data.LastFmAlbumList;
34 import net.sourceforge.atunes.model.IAlbumInfo;
35 import net.sourceforge.atunes.model.IAlbumListInfo;
36 import net.sourceforge.atunes.model.INetworkHandler;
37 import net.sourceforge.atunes.utils.ImageUtils;
38 import net.sourceforge.atunes.utils.Logger;
39 import net.sourceforge.atunes.utils.StringUtils;
40 import de.umass.lastfm.Album;
41 import de.umass.lastfm.Artist;
42 import de.umass.lastfm.Playlist;
43 
44 /**
45  * Services to retrieve information about albums
46  *
47  * @author alex
48  *
49  */
50 public class LastFmAlbumServices {
51 
52 	private LastFmCache lastFmCache;
53 
54 	private LastFmAPIKey lastFmAPIKey;
55 
56 	private INetworkHandler networkHandler;
57 
58 	/**
59 	 * @param lastFmAPIKey
60 	 */
setLastFmAPIKey(final LastFmAPIKey lastFmAPIKey)61 	public void setLastFmAPIKey(final LastFmAPIKey lastFmAPIKey) {
62 		this.lastFmAPIKey = lastFmAPIKey;
63 	}
64 
65 	/**
66 	 * @param lastFmCache
67 	 */
setLastFmCache(final LastFmCache lastFmCache)68 	public void setLastFmCache(final LastFmCache lastFmCache) {
69 		this.lastFmCache = lastFmCache;
70 	}
71 
72 	/**
73 	 * @param networkHandler
74 	 */
setNetworkHandler(final INetworkHandler networkHandler)75 	public void setNetworkHandler(final INetworkHandler networkHandler) {
76 		this.networkHandler = networkHandler;
77 	}
78 
79 	/**
80 	 * Gets the album.
81 	 *
82 	 * @param artist
83 	 *            the artist
84 	 * @param album
85 	 *            the album
86 	 *
87 	 * @return the album
88 	 */
getAlbum(final String artist, final String album)89 	IAlbumInfo getAlbum(final String artist, final String album) {
90 		try {
91 			// Try to get from cache
92 			IAlbumInfo albumObject = lastFmCache.retrieveAlbumInfo(artist,
93 					album);
94 			if (albumObject == null) {
95 				Album a = Album
96 						.getInfo(artist, album, lastFmAPIKey.getApiKey());
97 				if (a != null) {
98 					Playlist pl = Playlist.fetchAlbumPlaylist(a.getId(),
99 							lastFmAPIKey.getApiKey());
100 					albumObject = LastFmAlbum.getAlbum(a, pl);
101 					lastFmCache.storeAlbumInfo(artist, album, albumObject);
102 				}
103 			}
104 			return albumObject;
105 		} catch (Exception e) {
106 			Logger.error(e.getMessage());
107 		}
108 		return null;
109 	}
110 
111 	/**
112 	 * Gets the image of the album
113 	 *
114 	 * @param artist
115 	 * @param album
116 	 * @return
117 	 */
getAlbumImage(final String artist, final String album)118 	ImageIcon getAlbumImage(final String artist, final String album) {
119 		ImageIcon image = null;
120 		IAlbumInfo a = getAlbum(artist, album);
121 		if (a != null) {
122 			image = getAlbumImage(a);
123 		}
124 		return image;
125 	}
126 
127 	/**
128 	 * Gets the album list.
129 	 *
130 	 * @param artist
131 	 *            the artist
132 	 *
133 	 * @return the album list
134 	 */
getAlbumList(final String artist)135 	IAlbumListInfo getAlbumList(final String artist) {
136 		// Try to get from cache
137 		IAlbumListInfo albumList = lastFmCache.retrieveAbumList(artist);
138 		if (albumList == null) {
139 			Collection<Album> as = Artist.getTopAlbums(artist,
140 					lastFmAPIKey.getApiKey());
141 			if (as != null) {
142 				IAlbumListInfo albums = LastFmAlbumList
143 						.getAlbumList(as, artist);
144 
145 				List<IAlbumInfo> result = filterAlbumsFromSource(artist, albums);
146 
147 				albumList = new LastFmAlbumList();
148 				albumList.setArtist(artist);
149 				albumList.setAlbums(result);
150 				lastFmCache.storeAlbumList(artist, albumList);
151 			}
152 		}
153 
154 		return albumList;
155 	}
156 
157 	/**
158 	 * Removes albums with no image or no mbid and with correct artist
159 	 *
160 	 * @param artist
161 	 * @param albums
162 	 * @return
163 	 */
filterAlbumsFromSource(final String artist, final IAlbumListInfo albums)164 	private List<IAlbumInfo> filterAlbumsFromSource(final String artist,
165 			final IAlbumListInfo albums) {
166 		List<IAlbumInfo> result = new ArrayList<IAlbumInfo>();
167 		for (IAlbumInfo a : albums.getAlbums()) {
168 			if (hasMbid(a) && artistMatches(artist, a) && hasImage(a)) {
169 				result.add(a);
170 			}
171 		}
172 		return result;
173 	}
174 
175 	/**
176 	 * Returns if album has mbid
177 	 *
178 	 * @param a
179 	 * @return
180 	 */
hasMbid(final IAlbumInfo a)181 	private boolean hasMbid(final IAlbumInfo a) {
182 		return !StringUtils.isEmpty(a.getMbid());
183 	}
184 
185 	/**
186 	 * Returns if album has image
187 	 *
188 	 * @param a
189 	 * @return
190 	 */
hasImage(final IAlbumInfo a)191 	private boolean hasImage(final IAlbumInfo a) {
192 		return !StringUtils.isEmpty(a.getThumbCoverURL())
193 				&& !a.getThumbCoverURL().contains("noimage");
194 	}
195 
196 	/**
197 	 * Checks if artist of album is equal to given artist
198 	 *
199 	 * @param artist
200 	 * @param album
201 	 * @return
202 	 */
artistMatches(final String artist, final IAlbumInfo album)203 	private boolean artistMatches(final String artist, final IAlbumInfo album) {
204 		return album.getArtist().equalsIgnoreCase(artist);
205 	}
206 
207 	/**
208 	 * Gets the image.
209 	 *
210 	 * @param album
211 	 *            the album
212 	 *
213 	 * @return the image
214 	 */
getAlbumImage(final IAlbumInfo album)215 	ImageIcon getAlbumImage(final IAlbumInfo album) {
216 		try {
217 			ImageIcon img = null;
218 			// Try to retrieve from cache
219 			img = lastFmCache.retrieveAlbumCover(album);
220 			if (img == null && !StringUtils.isEmpty(album.getBigCoverURL())) {
221 				Image tmp = networkHandler.getImage(networkHandler
222 						.getConnection(album.getBigCoverURL()));
223 				if (tmp != null) {
224 					img = new ImageIcon(tmp);
225 					lastFmCache.storeAlbumCover(album, img);
226 				}
227 			}
228 
229 			return img;
230 		} catch (IOException e) {
231 			// Sometimes urls given by last.fm are forbidden, so avoid show full
232 			// error stack traces
233 			Logger.error(e.getMessage());
234 			Logger.debug(e);
235 		}
236 		return null;
237 	}
238 
239 	/**
240 	 * Gets the thumbnail image of album
241 	 *
242 	 * @param album
243 	 *            the album
244 	 *
245 	 * @return the image
246 	 */
getAlbumThumbImage(final IAlbumInfo album)247 	ImageIcon getAlbumThumbImage(final IAlbumInfo album) {
248 		try {
249 			ImageIcon img = null;
250 			// Try to retrieve from cache
251 			img = lastFmCache.retrieveAlbumCoverThumb(album);
252 			if (img == null && !StringUtils.isEmpty(album.getThumbCoverURL())) {
253 				Image tmp = networkHandler.getImage(networkHandler
254 						.getConnection(album.getThumbCoverURL()));
255 				if (tmp != null) {
256 					// Resize image for thumb images
257 					img = new ImageIcon(ImageUtils.scaleBufferedImageBicubic(
258 							tmp, Constants.THUMB_IMAGE_WIDTH,
259 							Constants.THUMB_IMAGE_HEIGHT));
260 					lastFmCache.storeAlbumCoverThumb(album, img);
261 				}
262 			}
263 
264 			return img;
265 		} catch (IOException e) {
266 			// Sometimes urls given by last.fm are forbidden, so avoid show full
267 			// error stack traces
268 			Logger.error(e.getMessage());
269 			Logger.debug(e);
270 		}
271 		return null;
272 	}
273 
274 }
275