|
2 | 2 |
|
3 | 3 | import javafx.application.Platform;
|
4 | 4 | import javafx.concurrent.Task;
|
5 |
| -import pl.koder95.eme.Main; |
| 5 | +import javafx.scene.control.Alert; |
| 6 | +import org.kohsuke.github.GHAsset; |
| 7 | +import org.kohsuke.github.GHRelease; |
| 8 | +import pl.koder95.eme.Files; |
6 | 9 |
|
7 | 10 | import java.io.*;
|
8 |
| -import java.net.URISyntaxException; |
| 11 | +import java.net.URL; |
| 12 | +import java.net.URLConnection; |
| 13 | +import java.nio.channels.Channels; |
| 14 | +import java.nio.channels.FileChannel; |
| 15 | +import java.nio.channels.ReadableByteChannel; |
| 16 | +import java.text.NumberFormat; |
| 17 | +import java.util.Enumeration; |
| 18 | +import java.util.HashMap; |
| 19 | +import java.util.Map; |
| 20 | +import java.util.zip.ZipEntry; |
| 21 | +import java.util.zip.ZipFile; |
| 22 | + |
| 23 | +import static pl.koder95.eme.Files.SELF; |
| 24 | +import static pl.koder95.eme.Files.TEMP_DIR; |
9 | 25 |
|
10 | 26 | public class AutoUpdateTask extends Task<Object> {
|
11 | 27 | @Override
|
12 | 28 | protected Object call() throws Exception {
|
| 29 | + GHAsset zip; |
| 30 | + try { |
| 31 | + GitHubRepositoryController controller = new GitHubRepositoryController("koder95", "eMetrykant"); |
| 32 | + controller.init(); |
| 33 | + GHRelease latest = controller.getRepository().getLatestRelease(); |
| 34 | + zip = latest.listAssets().toList().stream().reduce(null, (r, c) -> { |
| 35 | + System.out.println(c); |
| 36 | + return c.getName().contains("eMetrykant") && c.getName().endsWith(".zip")? c : r; |
| 37 | + }); |
| 38 | + } catch (IOException e) { |
| 39 | + e.printStackTrace(); |
| 40 | + Alert a = new Alert(Alert.AlertType.ERROR, "Nie można pobrać eMetrykanta."); |
| 41 | + a.show(); |
| 42 | + return null; |
| 43 | + } |
| 44 | + |
| 45 | + // pobieranie zip'a |
| 46 | + File downloaded = downloadZip(zip.getBrowserDownloadUrl(), TEMP_DIR, zip.getName(), zip.getSize()); |
| 47 | + // rozpakowywanie do folderu tymczasowego |
| 48 | + if (extractZip(downloaded, TEMP_DIR, true)) { |
| 49 | + // TODO: tworzenie mapy aktualizacji |
| 50 | + Map<File, File> updateMap = new HashMap<>(); |
| 51 | + updateMap.put(new File(TEMP_DIR, "eMetrykant.jar"), SELF); |
| 52 | + restart(updateMap); |
| 53 | + } |
13 | 54 | return null;
|
14 | 55 | }
|
15 | 56 |
|
16 |
| - private static void restart() { |
| 57 | + private File downloadZip(String url, File dir, String name, long size) throws IOException { |
| 58 | + NumberFormat pF = NumberFormat.getPercentInstance(); |
| 59 | + String title = "Pobieranie " + name; |
| 60 | + updateTitle(title); |
| 61 | + updateProgress(0, 1); |
| 62 | + |
| 63 | + URLConnection connection = new URL(url).openConnection(); |
| 64 | + File forDownload = new File(dir, name); |
| 65 | + |
| 66 | + try (InputStream in = connection.getInputStream(); |
| 67 | + ReadableByteChannel rbc = Channels.newChannel(in); |
| 68 | + FileOutputStream out = new FileOutputStream(forDownload); |
| 69 | + FileChannel channel = out.getChannel()) { |
| 70 | + channel.truncate(size); |
| 71 | + in.mark((int) size); |
| 72 | + long workDone = 0; |
| 73 | + long count = size > 100? size / 100: 1; |
| 74 | + while (workDone < size) { |
| 75 | + long transferred = channel.transferFrom(rbc, workDone, count); |
| 76 | + workDone += transferred; |
| 77 | + updateMessage(pF.format((double) workDone/ size)); |
| 78 | + updateProgress(workDone, size); |
| 79 | + } |
| 80 | + channel.force(true); |
| 81 | + } catch (Exception ex) { ex.printStackTrace(); } |
| 82 | + |
| 83 | + return forDownload; |
| 84 | + } |
| 85 | + |
| 86 | + private boolean extractZip(File forExtract, File dir, boolean deleteZip) throws IOException { |
| 87 | + NumberFormat pF = NumberFormat.getPercentInstance(); |
| 88 | + updateTitle("Rozpakowywanie " + forExtract.getName()); |
| 89 | + updateProgress(0, 1); |
| 90 | + updateMessage(""); |
| 91 | + try (ZipFile zip = new ZipFile(forExtract)) { |
| 92 | + updateProgress(0, forExtract.length()); |
| 93 | + double total = 0; |
| 94 | + if (dir == null) dir = forExtract.getParentFile(); |
| 95 | + Enumeration<? extends ZipEntry> entries = zip.entries(); |
| 96 | + while (entries.hasMoreElements()) { |
| 97 | + ZipEntry entry = entries.nextElement(); |
| 98 | + System.out.println(entry); |
| 99 | + if (entry.isDirectory()) { |
| 100 | + if (new File(dir, entry.getName()).mkdirs()) System.out.println("Directory created!"); |
| 101 | + } |
| 102 | + |
| 103 | + InputStream input = zip.getInputStream(entry); |
| 104 | + int available = input.available(); |
| 105 | + total += available; |
| 106 | + } |
| 107 | + entries = zip.entries(); |
| 108 | + double work = 0; |
| 109 | + while (entries.hasMoreElements()) { |
| 110 | + ZipEntry entry = entries.nextElement(); |
| 111 | + File outFile = new File(dir, entry.getName()); |
| 112 | + |
| 113 | + if (!entry.isDirectory()) { |
| 114 | + if (outFile.createNewFile()) { |
| 115 | + System.out.println("New file created: " + outFile); |
| 116 | + } |
| 117 | + } |
| 118 | + else continue; |
| 119 | + |
| 120 | + System.out.println("Entry: " + entry); |
| 121 | + InputStream input = zip.getInputStream(entry); |
| 122 | + try (FileOutputStream output = new FileOutputStream(outFile)) { |
| 123 | + while (input.available() > 0) { |
| 124 | + int b = input.read(); |
| 125 | + output.write(b); |
| 126 | + output.flush(); |
| 127 | + updateProgress(++work, total); |
| 128 | + updateMessage(pF.format(work/total)); |
| 129 | + } |
| 130 | + } catch (Exception ex) { ex.printStackTrace(); } |
| 131 | + } |
| 132 | + } |
| 133 | + updateProgress(Double.NaN, 0); |
| 134 | + if (deleteZip) return forExtract.delete(); |
| 135 | + return false; |
| 136 | + } |
| 137 | + |
| 138 | + private static void restart(Map<File, File> updateMap) { |
17 | 139 | Platform.exit();
|
18 | 140 | try {
|
19 |
| - final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; |
20 |
| - File self = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()); |
21 |
| - ProcessBuilder builder = new ProcessBuilder(); |
22 |
| - builder.command(javaBin, "-jar", self.getName()); |
23 |
| - builder.start(); |
24 |
| - } catch (IOException | URISyntaxException e) { |
| 141 | + File update = Files.UPDATE_WIN; |
| 142 | + generateUpdateScript(update, updateMap); |
| 143 | + new ProcessBuilder(update.getPath()).start(); |
| 144 | + } catch (IOException e) { |
25 | 145 | e.printStackTrace();
|
26 | 146 | }
|
27 | 147 | System.exit(0);
|
28 | 148 | }
|
29 | 149 |
|
30 |
| - private static void generateUpdateScript() { |
31 |
| - try (BufferedWriter writer = new BufferedWriter(new FileWriter("update.bat"))) { |
32 |
| - writer.write("@echo off"); |
33 |
| - writer.newLine(); |
34 |
| - writer.write("timeout /T 5 /nobreak > nil"); |
35 |
| - writer.newLine(); |
36 |
| - writer.write("copy "); |
37 |
| - } catch (IOException ex) { |
| 150 | + private static void generateUpdateScript(File update, Map<File, File> updateMap) { |
| 151 | + try (BufferedWriter writer = new BufferedWriter(new FileWriter(update))) { |
| 152 | + generateWinUpdateScript(writer, updateMap); |
| 153 | + } catch (IOException e) { |
| 154 | + e.printStackTrace(); |
| 155 | + } |
| 156 | + } |
38 | 157 |
|
| 158 | + private static void generateWinUpdateScript(BufferedWriter writer, Map<File, File> updateMap) |
| 159 | + throws IOException { |
| 160 | + writer.write("@echo off"); |
| 161 | + writer.newLine(); |
| 162 | + writer.write("timeout /T 5 /nobreak > nul"); |
| 163 | + writer.newLine(); |
| 164 | + for (Map.Entry<File, File> entry : updateMap.entrySet()) { |
| 165 | + File oldFile = entry.getValue(); |
| 166 | + File newFile = entry.getKey(); |
| 167 | + if (newFile.exists()) { |
| 168 | + writer.write("copy " + '"'); |
| 169 | + writer.write(newFile.getPath()); |
| 170 | + writer.write('"' + " " + '"'); |
| 171 | + writer.write(oldFile.getPath()); |
| 172 | + writer.write('"' + " /y"); |
| 173 | + writer.newLine(); |
| 174 | + } else throw new FileNotFoundException("Nie znaleziono odpowiednich plików do aktualizacji."); |
39 | 175 | }
|
| 176 | + final String javaBin = '"' + System.getProperty("java.home") + File.separator + "bin" + File.separator; |
| 177 | + writer.write(javaBin + "java.exe\" -jar " + '"' + Files.SELF + '"'); |
| 178 | + writer.newLine(); |
40 | 179 | }
|
41 | 180 | }
|
0 commit comments