diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java index 8e1e0d6579..a7124b0346 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.java @@ -84,7 +84,7 @@ public class DownloadManager { if (finished) { DownloadService.stop(context); } - }, e -> Timber.e(e.getCause(), e.getMessage())); + }, e -> DownloadService.stop(context)); if (!isRunning) { isRunning = true; diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/mangasync/services/MyAnimeList.java b/app/src/main/java/eu/kanade/tachiyomi/data/mangasync/services/MyAnimeList.java index 1e2103ba1a..add73acc9c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/mangasync/services/MyAnimeList.java +++ b/app/src/main/java/eu/kanade/tachiyomi/data/mangasync/services/MyAnimeList.java @@ -83,7 +83,7 @@ public class MyAnimeList extends MangaSyncService { public Observable login(String username, String password) { createHeaders(username, password); - return networkService.getResponse(getLoginUrl(), headers, null) + return networkService.getResponse(getLoginUrl(), headers, false) .map(response -> response.code() == 200); } @@ -101,7 +101,7 @@ public class MyAnimeList extends MangaSyncService { } public Observable> search(String query) { - return networkService.getStringResponse(getSearchUrl(query), headers, null) + return networkService.getStringResponse(getSearchUrl(query), headers, true) .map(Jsoup::parse) .flatMap(doc -> Observable.from(doc.select("entry"))) .filter(entry -> !entry.select("type").text().equals("Novel")) @@ -126,7 +126,7 @@ public class MyAnimeList extends MangaSyncService { public Observable> getList() { // TODO cache this list for a few minutes - return networkService.getStringResponse(getListUrl(username), headers, null) + return networkService.getStringResponse(getListUrl(username), headers, true) .map(Jsoup::parse) .flatMap(doc -> Observable.from(doc.select("manga"))) .map(entry -> { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/network/NetworkHelper.java b/app/src/main/java/eu/kanade/tachiyomi/data/network/NetworkHelper.java index 48ca958c64..4ecbbaae62 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/network/NetworkHelper.java +++ b/app/src/main/java/eu/kanade/tachiyomi/data/network/NetworkHelper.java @@ -7,11 +7,13 @@ import java.io.File; import java.net.CookieManager; import java.net.CookiePolicy; import java.net.CookieStore; +import java.util.concurrent.TimeUnit; import okhttp3.Cache; import okhttp3.CacheControl; import okhttp3.FormBody; import okhttp3.Headers; +import okhttp3.Interceptor; import okhttp3.JavaNetCookieJar; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -22,12 +24,23 @@ import rx.Observable; public final class NetworkHelper { private OkHttpClient client; + private OkHttpClient forceCacheClient; private CookieManager cookieManager; - public final CacheControl NULL_CACHE_CONTROL = new CacheControl.Builder().noCache().build(); public final Headers NULL_HEADERS = new Headers.Builder().build(); public final RequestBody NULL_REQUEST_BODY = new FormBody.Builder().build(); + public final CacheControl CACHE_CONTROL = new CacheControl.Builder() + .maxAge(10, TimeUnit.MINUTES) + .build(); + + private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = chain -> { + Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .removeHeader("Pragma") + .header("Cache-Control", "max-age=" + 600) + .build(); + }; private static final int CACHE_SIZE = 5 * 1024 * 1024; // 5 MiB private static final String CACHE_DIR_NAME = "network_cache"; @@ -42,18 +55,24 @@ public final class NetworkHelper { .cookieJar(new JavaNetCookieJar(cookieManager)) .cache(new Cache(cacheDir, CACHE_SIZE)) .build(); + + forceCacheClient = client.newBuilder() + .addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR) + .build(); } - public Observable getResponse(final String url, final Headers headers, final CacheControl cacheControl) { + public Observable getResponse(final String url, final Headers headers, boolean forceCache) { return Observable.defer(() -> { try { + OkHttpClient c = forceCache ? forceCacheClient : client; + Request request = new Request.Builder() .url(url) - .cacheControl(cacheControl != null ? cacheControl : NULL_CACHE_CONTROL) .headers(headers != null ? headers : NULL_HEADERS) + .cacheControl(CACHE_CONTROL) .build(); - return Observable.just(client.newCall(request).execute()); + return Observable.just(c.newCall(request).execute()); } catch (Throwable e) { return Observable.error(e); } @@ -70,8 +89,8 @@ public final class NetworkHelper { }); } - public Observable getStringResponse(final String url, final Headers headers, final CacheControl cacheControl) { - return getResponse(url, headers, cacheControl) + public Observable getStringResponse(final String url, final Headers headers, boolean forceCache) { + return getResponse(url, headers, forceCache) .flatMap(this::mapResponseToString); } @@ -95,7 +114,7 @@ public final class NetworkHelper { try { Request request = new Request.Builder() .url(url) - .cacheControl(NULL_CACHE_CONTROL) + .cacheControl(CacheControl.FORCE_NETWORK) .headers(headers != null ? headers : NULL_HEADERS) .build(); diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/source/base/Source.java b/app/src/main/java/eu/kanade/tachiyomi/data/source/base/Source.java index 0b47590bc6..417d60bd13 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/source/base/Source.java +++ b/app/src/main/java/eu/kanade/tachiyomi/data/source/base/Source.java @@ -53,7 +53,7 @@ public abstract class Source extends BaseSource { page.url = getInitialPopularMangasUrl(); return networkService - .getStringResponse(page.url, requestHeaders, null) + .getStringResponse(page.url, requestHeaders, true) .map(Jsoup::parse) .doOnNext(doc -> page.mangas = parsePopularMangasFromHtml(doc)) .doOnNext(doc -> page.nextPageUrl = parseNextPopularMangasUrl(doc, page)) @@ -66,7 +66,7 @@ public abstract class Source extends BaseSource { page.url = getInitialSearchUrl(query); return networkService - .getStringResponse(page.url, requestHeaders, null) + .getStringResponse(page.url, requestHeaders, true) .map(Jsoup::parse) .doOnNext(doc -> page.mangas = parseSearchFromHtml(doc)) .doOnNext(doc -> page.nextPageUrl = parseNextSearchUrl(doc, page, query)) @@ -76,14 +76,14 @@ public abstract class Source extends BaseSource { // Get manga details from the source public Observable pullMangaFromNetwork(final String mangaUrl) { return networkService - .getStringResponse(getBaseUrl() + overrideMangaUrl(mangaUrl), requestHeaders, null) + .getStringResponse(getBaseUrl() + overrideMangaUrl(mangaUrl), requestHeaders, true) .flatMap(unparsedHtml -> Observable.just(parseHtmlToManga(mangaUrl, unparsedHtml))); } // Get chapter list of a manga from the source public Observable> pullChaptersFromNetwork(final String mangaUrl) { return networkService - .getStringResponse(getBaseUrl() + mangaUrl, requestHeaders, null) + .getStringResponse(getBaseUrl() + mangaUrl, requestHeaders, false) .flatMap(unparsedHtml -> { List chapters = parseHtmlToChapters(unparsedHtml); return !chapters.isEmpty() ? @@ -102,7 +102,7 @@ public abstract class Source extends BaseSource { public Observable> pullPageListFromNetwork(final String chapterUrl) { return networkService - .getStringResponse(getBaseUrl() + overrideChapterUrl(chapterUrl), requestHeaders, null) + .getStringResponse(getBaseUrl() + overrideChapterUrl(chapterUrl), requestHeaders, false) .flatMap(unparsedHtml -> { List pages = convertToPages(parseHtmlToPageUrls(unparsedHtml)); return !pages.isEmpty() ? @@ -127,7 +127,7 @@ public abstract class Source extends BaseSource { public Observable getImageUrlFromPage(final Page page) { page.setStatus(Page.LOAD_PAGE); return networkService - .getStringResponse(overridePageUrl(page.getUrl()), requestHeaders, null) + .getStringResponse(overridePageUrl(page.getUrl()), requestHeaders, false) .flatMap(unparsedHtml -> Observable.just(parseHtmlToImageUrl(unparsedHtml))) .onErrorResumeNext(e -> { page.setStatus(Page.ERROR); diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/source/online/english/Batoto.java b/app/src/main/java/eu/kanade/tachiyomi/data/source/online/english/Batoto.java index d30cddd827..5d96d361ae 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/source/online/english/Batoto.java +++ b/app/src/main/java/eu/kanade/tachiyomi/data/source/online/english/Batoto.java @@ -309,7 +309,7 @@ public class Batoto extends LoginSource { @Override public Observable login(String username, String password) { - return networkService.getStringResponse(LOGIN_URL, requestHeaders, null) + return networkService.getStringResponse(LOGIN_URL, requestHeaders, false) .flatMap(response -> doLogin(response, username, password)) .map(this::isAuthenticationSuccessful); }