Create CacheFileTask

This commit is contained in:
Glavo 2025-08-01 22:39:55 +08:00
parent bcd73e6d15
commit b7705df2a4
4 changed files with 119 additions and 4 deletions

View File

@ -35,6 +35,7 @@ import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
@ -44,6 +45,7 @@ import org.jackhuang.hmcl.mod.RemoteMod;
import org.jackhuang.hmcl.mod.RemoteModRepository;
import org.jackhuang.hmcl.mod.modrinth.ModrinthRemoteModRepository;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.task.GetTask;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.Controllers;
@ -61,6 +63,8 @@ import org.jackhuang.hmcl.util.i18n.I18n;
import org.jackhuang.hmcl.util.javafx.BindingMapping;
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import java.util.stream.Collectors;
@ -68,6 +72,7 @@ import static org.jackhuang.hmcl.ui.FXUtils.ignoreEvent;
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public class DownloadListPage extends Control implements DecoratorPage, VersionPage.VersionLoadable {
protected final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>();
@ -540,6 +545,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
.collect(Collectors.toList()));
if (StringUtils.isNotBlank(dataItem.getIconUrl())) {
LOG.debug("Icon: " + dataItem.getIconUrl());
imageView.setImage(FXUtils.newRemoteImage(dataItem.getIconUrl(), 40, 40, true, true, true));
}
}

View File

@ -0,0 +1,107 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.task;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
/**
* Download a file to cache repository.
*
* @author Glavo
*/
public class CacheFileTask extends FetchTask<Path> {
public CacheFileTask(@NotNull URI uri, int retry) {
super(List.of(uri), retry);
}
@Override
protected EnumCheckETag shouldCheckETag() {
// Check cache
for (URI uri : uris) {
try {
setResult(repository.getCachedRemoteFile(uri));
return EnumCheckETag.CACHED;
} catch (IOException ignored) {
}
}
return EnumCheckETag.CHECK_E_TAG;
}
@Override
protected void useCachedResult(Path cache) {
setResult(cache);
}
@Override
protected Context getContext(URLConnection connection, boolean checkETag) throws IOException {
assert checkETag;
Path temp = Files.createTempFile("hmcl-download-", null);
OutputStream fileOutput = Files.newOutputStream(temp);
return new Context() {
@Override
public void write(byte[] buffer, int offset, int len) throws IOException {
fileOutput.write(buffer, offset, len);
}
@Override
public void close() throws IOException {
try {
fileOutput.close();
} catch (IOException e) {
LOG.warning("Failed to close file: " + temp, e);
}
if (!isSuccess()) {
try {
Files.deleteIfExists(temp);
} catch (IOException e) {
LOG.warning("Failed to delete file: " + temp, e);
}
return;
}
try {
repository.cacheRemoteFile(connection, temp);
setResult(repository.getCachedRemoteFile(connection.getURL().toURI()));
} catch (URISyntaxException e) {
throw new IOException(e);
} finally {
try {
Files.deleteIfExists(temp);
} catch (IOException e) {
LOG.warning("Failed to delete file: " + temp, e);
}
}
}
};
}
}

View File

@ -46,7 +46,6 @@ import static org.jackhuang.hmcl.util.logging.Logger.LOG;
public abstract class FetchTask<T> extends Task<T> {
protected final List<URI> uris;
protected final int retry;
protected boolean caching;
protected CacheRepository repository = CacheRepository.getInstance();
public FetchTask(@NotNull List<@NotNull URI> uris, int retry) {
@ -61,9 +60,7 @@ public abstract class FetchTask<T> extends Task<T> {
setExecutor(download());
}
public void setCaching(boolean caching) {
this.caching = caching;
}
public void setCacheRepository(CacheRepository repository) {
this.repository = repository;

View File

@ -84,6 +84,7 @@ public class FileDownloadTask extends FetchTask<Void> {
private final Path file;
private final IntegrityCheck integrityCheck;
private boolean caching;
private Path candidate;
private final ArrayList<IntegrityCheckHandler> integrityCheckHandlers = new ArrayList<>();
@ -155,6 +156,10 @@ public class FileDownloadTask extends FetchTask<Void> {
return file;
}
public void setCaching(boolean caching) {
this.caching = caching;
}
public FileDownloadTask setCandidate(Path candidate) {
this.candidate = candidate;
return this;