mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +03:00
[FEATURE] Реализована полоска загрузки при использовании WebSockets
This commit is contained in:
parent
e008c33aff
commit
d805fb7515
2 changed files with 80 additions and 8 deletions
|
@ -10,8 +10,10 @@
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -19,21 +21,42 @@
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ListDownloader {
|
public class ListDownloader {
|
||||||
public void download(String base, List<String> applies, Path dstDirFile) throws IOException, URISyntaxException {
|
@FunctionalInterface
|
||||||
|
public interface DownloadCallback
|
||||||
|
{
|
||||||
|
void stateChanged(String filename,long downloadedSize, long size);
|
||||||
|
}
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface DownloadTotalCallback
|
||||||
|
{
|
||||||
|
void addTotal(long size);
|
||||||
|
}
|
||||||
|
public static class DownloadTask
|
||||||
|
{
|
||||||
|
public String apply;
|
||||||
|
public long size;
|
||||||
|
|
||||||
|
public DownloadTask(String apply, long size) {
|
||||||
|
this.apply = apply;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void download(String base, List<DownloadTask> applies, Path dstDirFile, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException, URISyntaxException {
|
||||||
try (CloseableHttpClient httpclient = HttpClients.custom()
|
try (CloseableHttpClient httpclient = HttpClients.custom()
|
||||||
.setRedirectStrategy(new LaxRedirectStrategy())
|
.setRedirectStrategy(new LaxRedirectStrategy())
|
||||||
.build()) {
|
.build()) {
|
||||||
|
|
||||||
HttpGet get = null;
|
HttpGet get = null;
|
||||||
for (String apply : applies) {
|
for (DownloadTask apply : applies) {
|
||||||
URI u = new URL(base.concat(escapeURL(apply))).toURI();
|
URI u = new URL(base.concat(escapeURL(apply.apply))).toURI();
|
||||||
|
callback.stateChanged(apply.apply,0L, apply.size);
|
||||||
LogHelper.debug("Download URL: %s", u.toString());
|
LogHelper.debug("Download URL: %s", u.toString());
|
||||||
if (get == null) get = new HttpGet(u);
|
if (get == null) get = new HttpGet(u);
|
||||||
else {
|
else {
|
||||||
get.reset();
|
get.reset();
|
||||||
get.setURI(u);
|
get.setURI(u);
|
||||||
}
|
}
|
||||||
httpclient.execute(get, new FileDownloadResponseHandler(dstDirFile.resolve(apply)));
|
httpclient.execute(get, new FileDownloadResponseHandler(dstDirFile.resolve(apply.apply), apply, callback, totalCallback));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,16 +82,59 @@ public String escapeURL(String apply)
|
||||||
|
|
||||||
static class FileDownloadResponseHandler implements ResponseHandler<Path> {
|
static class FileDownloadResponseHandler implements ResponseHandler<Path> {
|
||||||
private final Path target;
|
private final Path target;
|
||||||
|
private final DownloadTask task;
|
||||||
|
private final DownloadCallback callback;
|
||||||
|
private final DownloadTotalCallback totalCallback;
|
||||||
|
|
||||||
public FileDownloadResponseHandler(Path target) {
|
public FileDownloadResponseHandler(Path target) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
this.task = null;
|
||||||
|
callback = null;
|
||||||
|
totalCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileDownloadResponseHandler(Path target, DownloadTask task, DownloadCallback callback, DownloadTotalCallback totalCallback) {
|
||||||
|
this.target = target;
|
||||||
|
this.task = task;
|
||||||
|
this.callback = callback;
|
||||||
|
this.totalCallback = totalCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
|
public Path handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
|
||||||
InputStream source = response.getEntity().getContent();
|
InputStream source = response.getEntity().getContent();
|
||||||
IOHelper.transfer(source, this.target);
|
if(callback != null && task != null)
|
||||||
|
{
|
||||||
|
callback.stateChanged(task.apply, 0, task.size);
|
||||||
|
transfer(source, this.target, task.apply, task.size, callback, totalCallback);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
IOHelper.transfer(source, this.target);
|
||||||
return this.target;
|
return this.target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static void transfer(InputStream input, Path file, String filename, long size, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException
|
||||||
|
{
|
||||||
|
try (OutputStream fileOutput = IOHelper.newOutput(file)) {
|
||||||
|
long downloaded = 0L;
|
||||||
|
|
||||||
|
// Download with digest update
|
||||||
|
byte[] bytes = IOHelper.newBuffer();
|
||||||
|
while (downloaded < size) {
|
||||||
|
int remaining = (int) Math.min(size - downloaded, bytes.length);
|
||||||
|
int length = input.read(bytes, 0, remaining);
|
||||||
|
if (length < 0)
|
||||||
|
throw new EOFException(String.format("%d bytes remaining", size - downloaded));
|
||||||
|
|
||||||
|
// Update file
|
||||||
|
fileOutput.write(bytes, 0, length);
|
||||||
|
|
||||||
|
// Update state
|
||||||
|
downloaded += length;
|
||||||
|
//totalDownloaded += length;
|
||||||
|
totalCallback.addTotal(length);
|
||||||
|
callback.stateChanged(filename, downloaded, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -206,15 +206,21 @@ public UpdateRequestEvent requestWebSockets() throws Exception {
|
||||||
LogHelper.debug("Start update");
|
LogHelper.debug("Start update");
|
||||||
Launcher.profile.pushOptionalFile(e.hdir, !Launcher.profile.isUpdateFastCheck());
|
Launcher.profile.pushOptionalFile(e.hdir, !Launcher.profile.isUpdateFastCheck());
|
||||||
HashedDir.Diff diff = e.hdir.diff(localDir, matcher);
|
HashedDir.Diff diff = e.hdir.diff(localDir, matcher);
|
||||||
final List<String> adds = new ArrayList<>();
|
final List<ListDownloader.DownloadTask> adds = new ArrayList<>();
|
||||||
diff.mismatch.walk(IOHelper.CROSS_SEPARATOR, (path, name, entry) -> {
|
diff.mismatch.walk(IOHelper.CROSS_SEPARATOR, (path, name, entry) -> {
|
||||||
if(entry.getType() == HashedEntry.Type.FILE) adds.add(path);
|
if(entry.getType() == HashedEntry.Type.FILE) {
|
||||||
|
HashedFile file = (HashedFile) entry;
|
||||||
|
totalSize += file.size;
|
||||||
|
adds.add(new ListDownloader.DownloadTask(path, file.size));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
totalSize = diff.mismatch.size();
|
totalSize = diff.mismatch.size();
|
||||||
startTime = Instant.now();
|
startTime = Instant.now();
|
||||||
updateState("UnknownFile", 0L, 100);
|
updateState("UnknownFile", 0L, 100);
|
||||||
ListDownloader listDownloader = new ListDownloader();
|
ListDownloader listDownloader = new ListDownloader();
|
||||||
listDownloader.download(e.url, adds, dir);
|
listDownloader.download(e.url, adds, dir, this::updateState, (add) -> {
|
||||||
|
totalDownloaded += add;
|
||||||
|
});
|
||||||
deleteExtraDir(dir, diff.extra, diff.extra.flag);
|
deleteExtraDir(dir, diff.extra, diff.extra.flag);
|
||||||
LogHelper.debug("Update success");
|
LogHelper.debug("Update success");
|
||||||
return e;
|
return e;
|
||||||
|
|
Loading…
Reference in a new issue