Fix thumbnail caching
This commit is contained in:
parent
cc9a2c640e
commit
959b41e3b9
|
@ -3,6 +3,7 @@
|
|||
* Added menu entry to force recording of models without changing the prio
|
||||
* Added blacklist and whitelist settings to automatically filter out models
|
||||
* Added setting to delete orphaned recording metadata (switched off by default)
|
||||
* Fixed thumbnail caching
|
||||
|
||||
5.2.3
|
||||
========================
|
||||
|
|
|
@ -14,10 +14,7 @@ import ctbrec.event.EventHandlerConfiguration;
|
|||
import ctbrec.image.LocalPortraitStore;
|
||||
import ctbrec.image.PortraitStore;
|
||||
import ctbrec.image.RemotePortraitStore;
|
||||
import ctbrec.io.BandwidthMeter;
|
||||
import ctbrec.io.ByteUnitFormatter;
|
||||
import ctbrec.io.HttpClient;
|
||||
import ctbrec.io.HttpException;
|
||||
import ctbrec.io.*;
|
||||
import ctbrec.io.json.ObjectMapperFactory;
|
||||
import ctbrec.notes.LocalModelNotesService;
|
||||
import ctbrec.notes.ModelNotesService;
|
||||
|
@ -434,6 +431,9 @@ public class CamrecApplication extends Application {
|
|||
}
|
||||
try {
|
||||
ExternalBrowser.getInstance().close();
|
||||
HttpClientCacheProvider.getCache(config).evictAll();
|
||||
HttpClientCacheProvider.getCache(config).close();
|
||||
IoUtils.deleteDirectory(new File(config.getConfigDir(), "cache"));
|
||||
} catch (IOException e12) {
|
||||
// noop
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
|||
Setting.of("Update overview interval (seconds)", overviewUpdateIntervalInSecs, "Update the thumbnail overviews every x seconds").needsRestart(),
|
||||
Setting.of("Update thumbnails", updateThumbnails,
|
||||
"The overviews will still be updated, but the thumbnails won't be changed. This is useful for less powerful systems."),
|
||||
Setting.of("Cache size", new CacheSettingsPane(this, config)).needsRestart(),
|
||||
Setting.of("Thumbnails cache size", new CacheSettingsPane(this, config)).needsRestart(),
|
||||
Setting.of("Manually select stream quality", chooseStreamQuality, "Opens a dialog to select the video resolution before recording"),
|
||||
Setting.of("Enable live previews (experimental)", livePreviews),
|
||||
Setting.of("Enable recently watched tab", recentlyWatched).needsRestart(),
|
||||
|
|
|
@ -170,19 +170,20 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
|
|||
}
|
||||
listPageId = content.optString("listPageId");
|
||||
JSONArray performers = content.getJSONArray("performers");
|
||||
for (var i = 0; i < performers.length(); i++) {
|
||||
var m = performers.getJSONObject(i);
|
||||
var name = m.optString("pid");
|
||||
if (name.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
LiveJasminModel model = (LiveJasminModel) liveJasmin.createModel(name);
|
||||
model.setId(m.getString("id"));
|
||||
model.setPreview(m.optString("profilePictureUrl"));
|
||||
for (var i = 0; i < performers.length(); i++) {
|
||||
var m = performers.getJSONObject(i);
|
||||
var name = m.optString("pid");
|
||||
if (name.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
LiveJasminModel model = (LiveJasminModel) liveJasmin.createModel(name);
|
||||
model.setId(m.getString("id"));
|
||||
model.setPreview(m.optString("profilePictureUrl"));
|
||||
model.setOnlineState(LiveJasminModel.mapStatus(m.optInt("status")));
|
||||
model.setDisplayName(m.optString("display_name", null));
|
||||
models.add(model);
|
||||
}} // if content
|
||||
models.add(model);
|
||||
}
|
||||
} // if content
|
||||
} // if data
|
||||
}
|
||||
}
|
||||
|
|
|
@ -429,7 +429,7 @@ public class ThumbCell extends StackPane {
|
|||
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||
.header(REFERER, getModel().getSite().getBaseUrl())
|
||||
.build();
|
||||
try (Response resp = model.getSite().getHttpClient().execute(req)) {
|
||||
try (Response resp = model.getSite().getHttpClient().executeWithCache(req)) {
|
||||
if (resp.isSuccessful()) {
|
||||
double width = 480;
|
||||
double height = width * imgAspectRatio;
|
||||
|
@ -500,9 +500,9 @@ public class ThumbCell extends StackPane {
|
|||
} else {
|
||||
modelRecordingState = ModelRecordingState.RECORDING;
|
||||
if (model.isForcePriority()) {
|
||||
recordingIndicator.setImage(imgForceRecordIndicator);
|
||||
recordingIndicator.setImage(imgForceRecordIndicator);
|
||||
} else {
|
||||
recordingIndicator.setImage(imgRecordIndicator);
|
||||
recordingIndicator.setImage(imgRecordIndicator);
|
||||
}
|
||||
recordingIndicatorTooltip.setText("Pause Recording");
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import ctbrec.io.json.ObjectMapperFactory;
|
|||
import ctbrec.io.json.dto.CookieDto;
|
||||
import ctbrec.io.json.mapper.CookieMapper;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.*;
|
||||
import okhttp3.OkHttpClient.Builder;
|
||||
|
@ -38,11 +39,14 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
|||
public abstract class HttpClient {
|
||||
private static final ConnectionPool GLOBAL_HTTP_CONN_POOL = new ConnectionPool(10, 2, TimeUnit.MINUTES);
|
||||
|
||||
@Getter
|
||||
protected CookieJarImpl cookieJar;
|
||||
protected OkHttpClient client;
|
||||
protected Cache cache;
|
||||
protected CookieJarImpl cookieJar;
|
||||
protected Config config;
|
||||
protected boolean loggedIn = false;
|
||||
protected long cacheSize;
|
||||
protected int cacheLifeTime = 600;
|
||||
private final String name;
|
||||
|
||||
protected HttpClient(String name, Config config) {
|
||||
|
@ -60,26 +64,26 @@ public abstract class HttpClient {
|
|||
ProxyType proxyType = config.getSettings().proxyType;
|
||||
switch (proxyType) {
|
||||
case HTTP:
|
||||
System.setProperty("http.proxyHost", config.getSettings().proxyHost);
|
||||
System.setProperty("http.proxyPort", config.getSettings().proxyPort);
|
||||
System.setProperty("https.proxyHost", config.getSettings().proxyHost);
|
||||
System.setProperty("https.proxyPort", config.getSettings().proxyPort);
|
||||
System.setProperty(ProxyConstants.HTTP_PROXY_HOST, config.getSettings().proxyHost);
|
||||
System.setProperty(ProxyConstants.HTTP_PROXY_PORT, config.getSettings().proxyPort);
|
||||
System.setProperty(ProxyConstants.HTTPS_PROXY_HOST, config.getSettings().proxyHost);
|
||||
System.setProperty(ProxyConstants.HTTPS_PROXY_PORT, config.getSettings().proxyPort);
|
||||
if (config.getSettings().proxyUser != null && !config.getSettings().proxyUser.isEmpty()) {
|
||||
String username = config.getSettings().proxyUser;
|
||||
String password = config.getSettings().proxyPassword;
|
||||
System.setProperty("http.proxyUser", username);
|
||||
System.setProperty("http.proxyPassword", password);
|
||||
System.setProperty(ProxyConstants.HTTP_PROXY_USER, username);
|
||||
System.setProperty(ProxyConstants.HTTP_PROXY_PASSWORD, password);
|
||||
}
|
||||
break;
|
||||
case SOCKS4:
|
||||
System.setProperty("socksProxyVersion", "4");
|
||||
System.setProperty("socksProxyHost", config.getSettings().proxyHost);
|
||||
System.setProperty("socksProxyPort", config.getSettings().proxyPort);
|
||||
System.setProperty(ProxyConstants.SOCKS_PROXY_VERSION, "4");
|
||||
System.setProperty(ProxyConstants.SOCKS_PROXY_HOST, config.getSettings().proxyHost);
|
||||
System.setProperty(ProxyConstants.SOCKS_PROXY_PORT, config.getSettings().proxyPort);
|
||||
break;
|
||||
case SOCKS5:
|
||||
System.setProperty("socksProxyVersion", "5");
|
||||
System.setProperty("socksProxyHost", config.getSettings().proxyHost);
|
||||
System.setProperty("socksProxyPort", config.getSettings().proxyPort);
|
||||
System.setProperty(ProxyConstants.SOCKS_PROXY_VERSION, "5");
|
||||
System.setProperty(ProxyConstants.SOCKS_PROXY_HOST, config.getSettings().proxyHost);
|
||||
System.setProperty(ProxyConstants.SOCKS_PROXY_PORT, config.getSettings().proxyPort);
|
||||
if (config.getSettings().proxyUser != null && !config.getSettings().proxyUser.isEmpty()) {
|
||||
String username = config.getSettings().proxyUser;
|
||||
String password = config.getSettings().proxyPassword;
|
||||
|
@ -88,44 +92,55 @@ public abstract class HttpClient {
|
|||
break;
|
||||
case DIRECT:
|
||||
default:
|
||||
System.clearProperty("http.proxyHost");
|
||||
System.clearProperty("http.proxyPort");
|
||||
System.clearProperty("https.proxyHost");
|
||||
System.clearProperty("https.proxyPort");
|
||||
System.clearProperty("socksProxyVersion");
|
||||
System.clearProperty("socksProxyHost");
|
||||
System.clearProperty("socksProxyPort");
|
||||
System.clearProperty("java.net.socks.username");
|
||||
System.clearProperty("java.net.socks.password");
|
||||
System.clearProperty("http.proxyUser");
|
||||
System.clearProperty("http.proxyPassword");
|
||||
System.clearProperty(ProxyConstants.HTTP_PROXY_HOST);
|
||||
System.clearProperty(ProxyConstants.HTTP_PROXY_PORT);
|
||||
System.clearProperty(ProxyConstants.HTTPS_PROXY_HOST);
|
||||
System.clearProperty(ProxyConstants.HTTPS_PROXY_PORT);
|
||||
System.clearProperty(ProxyConstants.SOCKS_PROXY_VERSION);
|
||||
System.clearProperty(ProxyConstants.SOCKS_PROXY_HOST);
|
||||
System.clearProperty(ProxyConstants.SOCKS_PROXY_PORT);
|
||||
System.clearProperty(ProxyConstants.JAVA_NET_SOCKS_USERNAME);
|
||||
System.clearProperty(ProxyConstants.JAVA_NET_SOCKS_PASSWORD);
|
||||
System.clearProperty(ProxyConstants.HTTP_PROXY_USER);
|
||||
System.clearProperty(ProxyConstants.HTTP_PROXY_PASSWORD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public Response execute(Request req) throws IOException {
|
||||
if (cache != null) {
|
||||
log.trace("Cache hit ratio {}/{} = {}", cache.hitCount(), cache.requestCount(), NumberFormat.getPercentInstance().format(cache.hitCount() / (double) cache.requestCount()));
|
||||
}
|
||||
Response resp = client.newCall(req).execute();
|
||||
return resp;
|
||||
}
|
||||
|
||||
public Response execute(Request request, int timeoutInMillis) throws IOException {
|
||||
if (cache != null) {
|
||||
log.trace("Cache hit ratio {}/{} = {}", cache.hitCount(), cache.requestCount(), NumberFormat.getPercentInstance().format(cache.hitCount() / (double) cache.requestCount()));
|
||||
}
|
||||
return client.newBuilder() //
|
||||
.connectTimeout(timeoutInMillis, TimeUnit.MILLISECONDS) //
|
||||
.readTimeout(timeoutInMillis, TimeUnit.MILLISECONDS).build() //
|
||||
.newCall(request).execute();
|
||||
}
|
||||
|
||||
public Response executeWithCache(Request req) throws IOException {
|
||||
log.trace("Cached request for {}", req.url());
|
||||
if (Objects.nonNull(cache)) {
|
||||
log.trace("Cache hit ratio {}/{} = {}", cache.hitCount(), cache.requestCount(), NumberFormat.getPercentInstance().format(cache.hitCount() / (double) cache.requestCount()));
|
||||
}
|
||||
if (cacheSize > 0 && Objects.nonNull(cache)) {
|
||||
Request r = req.newBuilder()
|
||||
.cacheControl(new CacheControl.Builder().maxAge(cacheLifeTime, TimeUnit.SECONDS).build())
|
||||
.build();
|
||||
return execute(r);
|
||||
} else {
|
||||
return execute(req);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean login() throws IOException;
|
||||
|
||||
public void reconfigure() {
|
||||
loadProxySettings();
|
||||
loadCookies();
|
||||
cacheSize = (long) config.getSettings().thumbCacheSize * 1024 * 1024;
|
||||
|
||||
Builder builder = new OkHttpClient.Builder()
|
||||
.cookieJar(cookieJar)
|
||||
.connectionPool(GLOBAL_HTTP_CONN_POOL)
|
||||
|
@ -133,12 +148,11 @@ public abstract class HttpClient {
|
|||
.readTimeout(config.getSettings().httpTimeout, TimeUnit.MILLISECONDS)
|
||||
.addNetworkInterceptor(new LoggingInterceptor());
|
||||
|
||||
long cacheSize = (long) config.getSettings().thumbCacheSize * 1024 * 1024;
|
||||
if (cacheSize > 0) {
|
||||
File configDir = config.getConfigDir();
|
||||
File cacheDir = new File(configDir, "cache");
|
||||
cache = new Cache(cacheDir, cacheSize);
|
||||
builder.cache(cache);
|
||||
cache = HttpClientCacheProvider.getCache(config);
|
||||
if (cache != null) {
|
||||
builder.cache(cache);
|
||||
}
|
||||
}
|
||||
|
||||
ProxyType proxyType = config.getSettings().proxyType;
|
||||
|
@ -265,10 +279,6 @@ public abstract class HttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
public CookieJarImpl getCookieJar() {
|
||||
return cookieJar;
|
||||
}
|
||||
|
||||
public void logout() {
|
||||
getCookieJar().clear();
|
||||
loggedIn = false;
|
||||
|
@ -332,4 +342,19 @@ public abstract class HttpClient {
|
|||
public void clearCookies() {
|
||||
logout();
|
||||
}
|
||||
|
||||
private static class ProxyConstants {
|
||||
public static final String HTTP_PROXY_HOST = "http.proxyHost";
|
||||
public static final String HTTP_PROXY_PORT = "http.proxyPort";
|
||||
public static final String HTTPS_PROXY_HOST = "https.proxyHost";
|
||||
public static final String HTTPS_PROXY_PORT = "https.proxyPort";
|
||||
public static final String HTTP_PROXY_USER = "https.proxyUser";
|
||||
public static final String HTTP_PROXY_PASSWORD = "https.proxyPassword";
|
||||
|
||||
public static final String SOCKS_PROXY_HOST = "socksProxyHost";
|
||||
public static final String SOCKS_PROXY_PORT = "socksProxyPort";
|
||||
public static final String SOCKS_PROXY_VERSION = "socksProxyVersion";
|
||||
public static final String JAVA_NET_SOCKS_USERNAME = "java.net.socks.username";
|
||||
public static final String JAVA_NET_SOCKS_PASSWORD = "java.net.socks.password";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package ctbrec.io;
|
||||
|
||||
import ctbrec.Config;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.Cache;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Slf4j
|
||||
public class HttpClientCacheProvider {
|
||||
|
||||
private static final Lock lock = new ReentrantLock();
|
||||
private static HttpClientCacheProvider provider;
|
||||
|
||||
private Cache cache;
|
||||
|
||||
private HttpClientCacheProvider(Config config) {
|
||||
File configDir = config.getConfigDir();
|
||||
File cacheDir = new File(configDir, "cache");
|
||||
long cacheSize = (long) config.getSettings().thumbCacheSize * 1024 * 1024;
|
||||
try {
|
||||
cache = new Cache(cacheDir, cacheSize);
|
||||
} catch (Exception ex) {
|
||||
log.error("Could not create HTTP client cache", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Cache getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
public static Cache getCache(Config config) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (provider == null) {
|
||||
provider = new HttpClientCacheProvider(config);
|
||||
}
|
||||
return provider.getCache();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue