Skip to content

Commit ef480c9

Browse files
committed
Aktualizowanie z linii poleceń
1 parent fe188c7 commit ef480c9

File tree

3 files changed

+216
-150
lines changed

3 files changed

+216
-150
lines changed

src/main/java/pl/koder95/eme/Main.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import javafx.scene.layout.VBox;
2828
import javafx.stage.Stage;
2929
import javafx.stage.StageStyle;
30+
import pl.koder95.eme.au.SelfUpdate;
3031
import pl.koder95.eme.au.SelfUpdateTask;
3132
import pl.koder95.eme.core.*;
3233
import pl.koder95.eme.core.spi.CabinetAnalyzer;
@@ -83,7 +84,8 @@ public static void main(String[] args) {
8384
System.exit(0);
8485
}
8586
else if (args[0].equals("-u")) {
86-
87+
SelfUpdate su = new SelfUpdate();
88+
new Thread(su).start();
8789
}
8890
}
8991
Main.launch(args);
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
package pl.koder95.eme.au;
2+
3+
import javafx.application.Platform;
4+
import pl.koder95.eme.git.RepositoryInfo;
5+
6+
import java.io.IOException;
7+
import java.io.InputStream;
8+
import java.io.OutputStream;
9+
import java.net.URL;
10+
import java.nio.channels.Channels;
11+
import java.nio.channels.FileChannel;
12+
import java.nio.channels.ReadableByteChannel;
13+
import java.nio.file.Files;
14+
import java.nio.file.Path;
15+
import java.nio.file.StandardOpenOption;
16+
import java.text.NumberFormat;
17+
import java.util.*;
18+
import java.util.function.BiConsumer;
19+
import java.util.function.Consumer;
20+
import java.util.stream.Stream;
21+
import java.util.zip.ZipEntry;
22+
import java.util.zip.ZipFile;
23+
24+
import static pl.koder95.eme.Files.*;
25+
import static pl.koder95.eme.Files.TEMP_DIR;
26+
27+
public class SelfUpdate implements Runnable {
28+
29+
private static final UpdateScriptGenerator US_GENERATOR = UpdateScriptGenerator.create(UPDATE_SCRIPT);
30+
31+
private final BiConsumer<Number, Number> updateProgress;
32+
private final Consumer<String> updateMessage;
33+
private final Consumer<String> updateTitle;
34+
private final UpdateScriptGenerator updateScriptGenerator;
35+
36+
SelfUpdate(BiConsumer<Number, Number> updateProgress, Consumer<String> updateMessage,
37+
Consumer<String> updateTitle, UpdateScriptGenerator updateScriptGenerator) {
38+
this.updateProgress = updateProgress;
39+
this.updateMessage = updateMessage;
40+
this.updateTitle = updateTitle;
41+
this.updateScriptGenerator = updateScriptGenerator;
42+
}
43+
44+
SelfUpdate(BiConsumer<Number, Number> updateProgress, Consumer<String> updateMessage,
45+
Consumer<String> updateTitle) {
46+
this(updateProgress, updateMessage, updateTitle, US_GENERATOR);
47+
}
48+
49+
public SelfUpdate() {
50+
this((workDone, max) -> {
51+
double percent = 100 * workDone.doubleValue()/max.doubleValue();
52+
System.out.println("Processing... " + (int) percent);
53+
}, msg -> System.out.println("INFO: " + msg), title -> System.out.println('\n' + title + '\n'));
54+
}
55+
56+
@Override
57+
public void run() {
58+
try {
59+
// usuwanie plików z katalogu tymczasowego:
60+
clear();
61+
// pobieranie zip'a i rozpakowywanie do folderu tymczasowego:
62+
prepare();
63+
} catch (IOException e) {
64+
throw new RuntimeException(e);
65+
}
66+
restart(); // restartowanie z wywołaniem skryptu
67+
}
68+
69+
private void clear() throws IOException {
70+
List<Exception> exceptions = new LinkedList<>();
71+
try (Stream<Path> paths = Files.walk(TEMP_DIR).sorted(Comparator.reverseOrder())) {
72+
paths.forEach(path -> {
73+
try {
74+
Files.deleteIfExists(path);
75+
} catch (IOException e) {
76+
exceptions.add(e);
77+
}
78+
});
79+
}
80+
if (!exceptions.isEmpty()) {
81+
IOException ex = new IOException();
82+
exceptions.forEach(ex::addSuppressed);
83+
exceptions.clear();
84+
throw ex;
85+
}
86+
}
87+
88+
private void restart() {
89+
Platform.exit();
90+
try {
91+
new ProcessBuilder(updateScriptGenerator.getPath().toString()).start();
92+
} catch (IOException e) {
93+
throw new RuntimeException(e);
94+
}
95+
System.exit(0);
96+
}
97+
98+
private void prepare() throws IOException {
99+
if (extractZip(downloadZip())) {
100+
Map<Path, Path> updateMap = new HashMap<>();
101+
try (Stream<Path> paths = Files.list(TEMP_DIR)) {
102+
paths.forEach(path -> updateMap.put(path, WORKDIR.resolve(path.getFileName().toString())));
103+
}
104+
updateScriptGenerator.generateUpdateScript(updateMap);
105+
}
106+
}
107+
108+
109+
private Path downloadZip() throws IOException {
110+
updateTitle.accept("Pobieranie " + RepositoryInfo.get().getLatestReleaseName());
111+
return tryTransfer(RepositoryInfo.get().getLatestReleaseBrowserURL());
112+
}
113+
114+
private Path tryTransfer(String urlSpec) throws IOException {
115+
Path forDownload = TEMP_DIR.resolve(RepositoryInfo.get().getLatestReleaseName());
116+
Files.deleteIfExists(forDownload);
117+
Files.createDirectories(forDownload.getParent());
118+
Files.createFile(forDownload);
119+
URL url = new URL(urlSpec);
120+
System.out.println("Downloading: " + forDownload);
121+
updateProgress.accept(0, 1L);
122+
try (ReadableByteChannel rbc = Channels.newChannel(url.openStream());
123+
FileChannel channel = FileChannel.open(forDownload, StandardOpenOption.WRITE)) {
124+
transfer(rbc, channel);
125+
}
126+
if (Files.isRegularFile(forDownload)) return forDownload;
127+
Files.deleteIfExists(forDownload);
128+
return null;
129+
}
130+
131+
private void transfer(ReadableByteChannel rbc, FileChannel channel) throws IOException {
132+
System.out.println("TRANSFERRING TO: " + channel);
133+
long size = RepositoryInfo.get().getLatestReleaseSize();
134+
channel.truncate(size);
135+
long count = size > 100? size / 100: 1;
136+
long workDone = 0;
137+
updateProgress.accept(workDone, size);
138+
while (workDone < size) {
139+
long transferred = channel.transferFrom(rbc, workDone, count);
140+
workDone += transferred;
141+
updateMessage.accept(NumberFormat.getPercentInstance().format((double) workDone / size));
142+
updateProgress.accept(workDone, size);
143+
}
144+
channel.force(true);
145+
}
146+
147+
private boolean extractZip(Path forExtract) throws IOException {
148+
updateTitle.accept("Rozpakowywanie " + forExtract.getFileName());
149+
updateProgress.accept(0, 1);
150+
updateMessage.accept("");
151+
try (ZipFile zip = new ZipFile(forExtract.toFile())) {
152+
updateProgress.accept(0, Files.size(forExtract));
153+
154+
Enumeration<? extends ZipEntry> entries = zip.entries();
155+
long total = getTotal(zip);
156+
long workDone = 0;
157+
while (entries.hasMoreElements()) {
158+
ZipEntry entry = entries.nextElement();
159+
Path outFile = TEMP_DIR.resolve(entry.getName());
160+
Files.deleteIfExists(outFile);
161+
162+
if (!entry.isDirectory()) {
163+
Files.createFile(outFile);
164+
165+
if (Files.isRegularFile(outFile)) {
166+
tryTransfer(zip, entry, outFile, workDone, total);
167+
}
168+
} else if (Files.notExists(outFile)) {
169+
Files.createDirectories(outFile);
170+
}
171+
}
172+
updateProgress.accept(1d, 1d);
173+
updateTitle.accept("Zakończono wypakowywanie archiwum");
174+
}
175+
updateProgress.accept(Double.NaN, 0);
176+
return Files.deleteIfExists(forExtract);
177+
}
178+
179+
private static long getTotal(ZipFile zip) throws IOException {
180+
long total = 0;
181+
Enumeration<? extends ZipEntry> entries = zip.entries();
182+
while (entries.hasMoreElements()) {
183+
ZipEntry entry = entries.nextElement();
184+
if (!entry.isDirectory()) {
185+
InputStream input = zip.getInputStream(entry);
186+
int available = input.available();
187+
total += available;
188+
}
189+
}
190+
return total;
191+
}
192+
193+
private void tryTransfer(ZipFile zip, ZipEntry entry, Path outFile, long workDone, long total) throws IOException {
194+
try (InputStream input = zip.getInputStream(entry);
195+
OutputStream output = Files.newOutputStream(outFile)) {
196+
transfer(input, output, workDone, total);
197+
}
198+
}
199+
200+
private void transfer(InputStream input, OutputStream output, long workDone, long total) throws IOException {
201+
while (input.available() > 0) {
202+
int b = input.read();
203+
output.write(b);
204+
output.flush();
205+
updateProgress.accept(++workDone, total);
206+
updateMessage.accept(NumberFormat.getPercentInstance().format((double) workDone / total));
207+
}
208+
}
209+
}

0 commit comments

Comments
 (0)