Skip to content

Commit ac5be26

Browse files
committed
Content validation is added to get rid of Retry errors.
1 parent 7f86ecc commit ac5be26

File tree

2 files changed

+116
-12
lines changed

2 files changed

+116
-12
lines changed

app/src/main/java/com/tasomaniac/muzei/comiccovers/ComicVineArtSource.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,22 @@
88
import com.google.android.apps.muzei.api.Artwork;
99
import com.google.android.apps.muzei.api.RemoteMuzeiArtSource;
1010
import com.tasomaniac.muzei.comiccovers.model.Comic;
11+
import com.tasomaniac.muzei.comiccovers.util.IOUtil;
1112

1213
import java.util.Random;
1314

1415
import retrofit.ErrorHandler;
1516
import retrofit.RequestInterceptor;
1617
import retrofit.RestAdapter;
1718
import retrofit.RetrofitError;
19+
import timber.log.Timber;
1820

1921
public class ComicVineArtSource extends RemoteMuzeiArtSource {
2022
private static final String SOURCE_NAME = "ComicVineArtSource";
2123
public static final String NUM_OF_TOTAL_RESULTS = "number_of_total_results";
2224

23-
private static final int ROTATE_TIME_MILLIS = 24 * 60 * 60 * 1000; // rotate every 3 hours
25+
private static final int ROTATE_TIME_MILLIS = 24 * 60 * 60 * 1000; // rotate every 24 hours
26+
private static final int NEXT_ON_ERROR_TIME_MILLIS = 60 * 60 * 1000; // rotate every 24 hours
2427

2528
Random random;
2629

@@ -60,14 +63,15 @@ public Throwable handleError(RetrofitError retrofitError) {
6063
|| (500 <= statusCode && statusCode < 600)) {
6164
return new RetryException();
6265
}
63-
scheduleUpdate(System.currentTimeMillis() + ROTATE_TIME_MILLIS);
66+
scheduleUpdate(System.currentTimeMillis() + NEXT_ON_ERROR_TIME_MILLIS);
67+
68+
Timber.d(retrofitError, "Error getting the image %s", retrofitError.getUrl());
69+
6470
return retrofitError;
6571
}
6672
})
6773
.build();
6874

69-
70-
7175
final ComicVineService service = restAdapter.create(ComicVineService.class);
7276
Comic comic = getNextComic(service);
7377
if (comic != null) {
@@ -76,8 +80,10 @@ public Throwable handleError(RetrofitError retrofitError) {
7680
name.append(comic.getVolume().getName());
7781
}
7882
if (comic.getName() != null) {
79-
name.append(" | ")
80-
.append(comic.getName());
83+
if (name.length() > 0) {
84+
name.append(" | ");
85+
}
86+
name.append(comic.getName());
8187
}
8288

8389
publishArtwork(new Artwork.Builder()
@@ -96,26 +102,36 @@ public Throwable handleError(RetrofitError retrofitError) {
96102
private Comic getNextComic(final ComicVineService service) throws RetryException {
97103
String currentToken = (getCurrentArtwork() != null) ? getCurrentArtwork().getToken() : null;
98104

105+
String offset = String.valueOf(random.nextInt(max_size));
99106
ComicVineService.ComicVineResponse response =
100-
service.getIssues(String.valueOf(random.nextInt(max_size)));
107+
service.getIssues(offset);
101108

102109
if (response == null || response.getResults() == null) {
110+
Timber.d("Error getting the image %s", offset);
103111
throw new RetryException();
104112
}
105113

106114
max_size = response.getNumberOfTotalResult();
107115
prefs.edit().putInt(NUM_OF_TOTAL_RESULTS, max_size).apply();
108116

109117
if (response.getResults().size() < 1) {
110-
scheduleUpdate(System.currentTimeMillis() + ROTATE_TIME_MILLIS);
118+
scheduleUpdate(System.currentTimeMillis() + NEXT_ON_ERROR_TIME_MILLIS);
111119
return null;
112120
}
113121
Comic comic = response.getResults().get(0);
114122
String newToken = String.valueOf(comic.getId());
115-
if (currentToken == null || !currentToken.equals(newToken)) {
116-
return comic;
117-
} else {
118-
return getNextComic(service);
123+
try {
124+
boolean isContentValid = IOUtil.checkContentType(getApplicationContext(),
125+
Uri.parse(comic.getImage().getSuperUrl()), "image/");
126+
if ((currentToken == null || !currentToken.equals(newToken)) && isContentValid) {
127+
return comic;
128+
} else {
129+
return getNextComic(service);
130+
}
131+
} catch (IOUtil.OpenUriException e) {
132+
Timber.e(e, "Error on the image. Will try in an hour.");
133+
scheduleUpdate(System.currentTimeMillis() + NEXT_ON_ERROR_TIME_MILLIS);
134+
return null;
119135
}
120136
}
121137
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.tasomaniac.muzei.comiccovers.util;
2+
3+
import android.net.Uri;
4+
5+
import com.squareup.okhttp.OkHttpClient;
6+
import com.squareup.okhttp.OkUrlFactory;
7+
8+
import java.io.IOException;
9+
import java.net.HttpURLConnection;
10+
import java.net.MalformedURLException;
11+
import java.net.URL;
12+
13+
import timber.log.Timber;
14+
15+
public class IOUtil {
16+
private static final int DEFAULT_READ_TIMEOUT = 30 * 1000; // 30s
17+
private static final int DEFAULT_CONNECT_TIMEOUT = 15 * 1000; // 15s
18+
19+
public static boolean checkContentType(Uri uri, String reqContentTypeSubstring)
20+
throws OpenUriException {
21+
22+
if (uri == null) {
23+
throw new IllegalArgumentException("Uri cannot be empty");
24+
}
25+
26+
String scheme = uri.getScheme();
27+
if (scheme == null) {
28+
throw new OpenUriException(false, new IOException("Uri had no scheme"));
29+
}
30+
31+
OkHttpClient client = new OkHttpClient();
32+
HttpURLConnection conn;
33+
int responseCode = 0;
34+
String responseMessage = null;
35+
try {
36+
conn = new OkUrlFactory(client).open(new URL(uri.toString()));
37+
} catch (MalformedURLException e) {
38+
throw new OpenUriException(false, e);
39+
}
40+
41+
try {
42+
conn.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
43+
conn.setReadTimeout(DEFAULT_READ_TIMEOUT);
44+
responseCode = conn.getResponseCode();
45+
responseMessage = conn.getResponseMessage();
46+
if (!(responseCode >= 200 && responseCode < 300)) {
47+
throw new IOException("HTTP error response.");
48+
}
49+
if (reqContentTypeSubstring != null) {
50+
String contentType = conn.getContentType();
51+
if (contentType == null || !contentType.contains(reqContentTypeSubstring)) {
52+
53+
Timber.e("Wrong content type. Will retry in an hour. ");
54+
return false;
55+
}
56+
}
57+
58+
} catch (IOException e) {
59+
if (responseCode > 0) {
60+
throw new OpenUriException(
61+
500 <= responseCode && responseCode < 600,
62+
responseMessage, e);
63+
} else {
64+
throw new OpenUriException(false, e);
65+
}
66+
}
67+
68+
return true;
69+
}
70+
71+
public static class OpenUriException extends Exception {
72+
private boolean mRetryable;
73+
74+
public OpenUriException(boolean retryable, String message, Throwable cause) {
75+
super(message, cause);
76+
mRetryable = retryable;
77+
}
78+
79+
public OpenUriException(boolean retryable, Throwable cause) {
80+
super(cause);
81+
mRetryable = retryable;
82+
}
83+
84+
public boolean isRetryable() {
85+
return mRetryable;
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)