package io.gitlab.jfronny.resclone.fetchers; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import io.gitlab.jfronny.resclone.Resclone; import io.gitlab.jfronny.resclone.data.RescloneException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Scanner; import java.util.Set; public abstract class PackFetcher { abstract public String getSourceTypeName(); // The name for users to specify in the config abstract String getDownloadUrl(String baseUrl) throws RescloneException; // Return the actual download URL for the file based on the provided string protected final Gson gson = Resclone.gson; protected boolean urlValid(String url) { try { HttpURLConnection connection = (HttpURLConnection)new URL(url).toURI().toURL().openConnection(); connection.setRequestMethod("GET"); connection.connect(); return connection.getResponseCode() == 200; } catch (Throwable e) { return false; } } protected String readStringFromURL(String requestURL) throws IOException { try (Scanner scanner = new Scanner(new URL(requestURL).openStream(), StandardCharsets.UTF_8.toString())) { scanner.useDelimiter("\\A"); return scanner.hasNext() ? scanner.next() : ""; } } public T readJsonFromURL(String requestUrl, Class classOfT) throws IOException { return gson.fromJson(readStringFromURL(requestUrl), classOfT); } public Set readJsonFromURLSet(String requestUrl, Class classOfT) throws IOException { return gson.fromJson(readStringFromURL(requestUrl), TypeToken.getParameterized(Set.class, classOfT).getType()); } public Result get(String baseUrl, Path targetDir, boolean forceDownload) throws RescloneException { String url; try { url = getDownloadUrl(baseUrl); Resclone.urlCache.set(baseUrl, url); } catch (RescloneException e) { if (Resclone.urlCache.containsKey(baseUrl)) { e.printStackTrace(); url = Resclone.urlCache.get(baseUrl); } else { throw e; } } Path p = targetDir.resolve(Integer.toHexString(url.hashCode())); if (!forceDownload && Files.exists(p)) return new Result(p, false); System.out.println("Downloading pack " + url); try (InputStream is = new URL(url).openStream()) { FileOutputStream os = new FileOutputStream(p.toFile()); byte[] dataBuffer = new byte[1024]; int bytesRead; while ((bytesRead = is.read(dataBuffer, 0, 1024)) != -1) { os.write(dataBuffer, 0, bytesRead); } System.out.println("Completed download"); } catch (Throwable e) { throw new RescloneException("Could not download pack", e); } return new Result(p, true); } public class Result { public final Path downloadPath; public final boolean freshDownload; public Result(Path downloadPath, boolean freshDownload) { this.downloadPath = downloadPath; this.freshDownload = freshDownload; } } }