Skip to content

Commit c2df62d

Browse files
committed
add function to request image url of track, version 1.1.6
1 parent c1bd5b4 commit c2df62d

File tree

3 files changed

+76
-30
lines changed

3 files changed

+76
-30
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ repositories {
2323
}
2424
2525
dependencies {
26-
implementation 'com.github.LabyStudio:java-spotify-api:1.1.5:all'
26+
implementation 'com.github.LabyStudio:java-spotify-api:1.1.6:all'
2727
}
2828
```
2929

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
}
55

66
group 'de.labystudio'
7-
version '1.1.5'
7+
version '1.1.6'
88

99
compileJava {
1010
sourceCompatibility = '1.8'
@@ -23,7 +23,7 @@ repositories {
2323
dependencies {
2424
implementation group: 'net.java.dev.jna', name: 'jna', version: '4.5.0'
2525
implementation group: 'net.java.dev.jna', name: 'jna-platform', version: '4.5.0'
26-
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
26+
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.9'
2727
}
2828

2929
java {

src/main/java/de/labystudio/spotifyapi/open/OpenSpotifyAPI.java

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ public class OpenSpotifyAPI {
3535

3636
private final Executor executor = Executors.newSingleThreadExecutor();
3737

38-
private final Map<Track, BufferedImage> imageCache = new ConcurrentHashMap<>();
39-
private final List<Track> cacheQueue = new ArrayList<>();
38+
private final Map<Track, String> urlCache = new ConcurrentHashMap<>();
39+
private final Map<String, BufferedImage> imageCache = new ConcurrentHashMap<>();
40+
private final List<String> cacheQueue = new ArrayList<>();
4041
private int cacheSize = 10;
4142

4243
private AccessTokenResponse accessTokenResponse;
@@ -94,6 +95,26 @@ public void requestImageAsync(Track track, Consumer<BufferedImage> callback) {
9495
});
9596
}
9697

98+
/**
99+
* Request the cover image url of the given track asynchronously.
100+
* If the track is already in the cache, it will be returned.
101+
*
102+
* @param track The track to lookup
103+
* @param callback Response with the image url of the track. It won't be called on an error.
104+
*/
105+
public void requestImageUrlAsync(Track track, Consumer<String> callback) {
106+
this.executor.execute(() -> {
107+
try {
108+
String imageUrl = this.requestImageUrl(track);
109+
if (imageUrl != null) {
110+
callback.accept(imageUrl);
111+
}
112+
} catch (Exception error) {
113+
error.printStackTrace();
114+
}
115+
});
116+
}
117+
97118
/**
98119
* Request the cover image of the given track synchronously.
99120
* If the track is already in the cache, it will be returned.
@@ -103,22 +124,61 @@ public void requestImageAsync(Track track, Consumer<BufferedImage> callback) {
103124
* @throws IOException if the request failed
104125
*/
105126
public BufferedImage requestImage(Track track) throws IOException {
106-
return this.requestImage(track, true);
127+
String url = this.requestImageUrl(track);
128+
if (url == null) {
129+
return null;
130+
}
131+
132+
// Try to get image from cache by url
133+
BufferedImage cachedImage = this.imageCache.get(url);
134+
if (cachedImage != null) {
135+
return cachedImage;
136+
}
137+
138+
// Download the image
139+
BufferedImage image = ImageIO.read(new URL(url));
140+
if (image == null) {
141+
throw new IOException("Could not load image: " + url);
142+
}
143+
144+
// Remove image from cache if cache is full
145+
if (this.cacheQueue.size() > this.cacheSize) {
146+
String urlToRemove = this.cacheQueue.remove(0);
147+
this.imageCache.remove(urlToRemove);
148+
}
149+
150+
// Add new image to cache
151+
this.imageCache.put(url, image);
152+
this.cacheQueue.add(url);
153+
154+
return image;
155+
}
156+
157+
/**
158+
* Request the cover image url of the given track.
159+
* If the track is already in the cache, it will be returned.
160+
*
161+
* @param track The track to lookup
162+
* @return The url of the track or null if it failed
163+
* @throws IOException if the request failed
164+
*/
165+
public String requestImageUrl(Track track) throws IOException {
166+
return this.requestImageUrl(track, true);
107167
}
108168

109169
/**
110-
* Request the cover image of the given track.
170+
* Request the cover image url of the given track.
111171
* If the track is already in the cache, it will be returned.
112172
*
113173
* @param track The track to lookup
114174
* @param canGenerateNewAccessToken It will try again once if it fails
115-
* @return Buffered image track.
175+
* @return The url of the track or null if it failed
116176
* @throws IOException if the request failed
117177
*/
118-
private BufferedImage requestImage(Track track, boolean canGenerateNewAccessToken) throws IOException {
119-
BufferedImage cachedImage = this.imageCache.get(track);
120-
if (cachedImage != null) {
121-
return cachedImage;
178+
private String requestImageUrl(Track track, boolean canGenerateNewAccessToken) throws IOException {
179+
String cachedUrl = this.urlCache.get(track);
180+
if (cachedUrl != null) {
181+
return cachedUrl;
122182
}
123183

124184
// Create REST API url
@@ -140,7 +200,7 @@ private BufferedImage requestImage(Track track, boolean canGenerateNewAccessToke
140200
this.accessTokenResponse = this.generateAccessToken();
141201

142202
// Try again
143-
return this.requestImage(track, false);
203+
return this.requestImageUrl(track, false);
144204
} else {
145205
// Request failed twice
146206
return null;
@@ -154,24 +214,10 @@ private BufferedImage requestImage(Track track, boolean canGenerateNewAccessToke
154214
// Get largest image url
155215
String imageUrl = openTrack.album.images.get(0).url;
156216

157-
// Download cover image
217+
// Cache url and return it
158218
if (imageUrl != null) {
159-
BufferedImage image = ImageIO.read(new URL(imageUrl));
160-
if (image == null) {
161-
throw new IOException("Could not load image: " + imageUrl);
162-
}
163-
164-
// Remove image from cache if cache is full
165-
if (this.cacheQueue.size() > this.cacheSize) {
166-
Track element = this.cacheQueue.remove(0);
167-
this.imageCache.remove(element);
168-
}
169-
170-
// Add new image to cache
171-
this.imageCache.put(track, image);
172-
this.cacheQueue.add(track);
173-
174-
return image;
219+
this.urlCache.put(track, imageUrl);
220+
return imageUrl;
175221
}
176222

177223
return null;

0 commit comments

Comments
 (0)