Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9aa7f8b6 authored by Ahmed Harhash's avatar Ahmed Harhash
Browse files

easy-installer: Report name of downloaded file

parent 603e8b0e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ dependencies {
    compile 'ch.qos.logback:logback-core:1.2.3'
    compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30'
    compile 'org.yaml:snakeyaml:1.26'
    compile 'org.json:json:20240303'
    testCompile 'junit:junit:4.12'

    //compile 'org.slf4j:slf4j-log4j1:1.7.5'
+127 −9
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
@@ -44,6 +45,10 @@ import java.util.Scanner;
import javafx.concurrent.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.util.Pair;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;

/**
 * this class verify the checksum of a file and download it
@@ -73,7 +78,7 @@ public class DownloadTask extends Task<Boolean>{
    
    final private ResourceBundle i18n;
    final private String targetUrl;
    final private String fileName;
    private String fileName;
        
    /**
     * COnstruction of the download task
@@ -93,16 +98,15 @@ public class DownloadTask extends Task<Boolean>{
     */
    @Override
    protected Boolean call() throws Exception {
        final String latestBuildFilename = fetchLatestBuildFilename(targetUrl);

        //build local filePath
        final String localFilePath = AppConstants.getSourcesFolderPath() + fileName;

        //Check if already exist and integrity
        final String checksumFilePath = localFilePath + checkSumExtension;
        
        if(isCancelled()) return false;
        
        this.updateTitle("Downloading "+fileName+checkSumExtension);
        this.updateTitle("Downloading " + latestBuildFilename + checkSumExtension);
        
        
        File checksumLmdFile = new File(AppConstants.getSourcesFolderPath()+"lmd."+fileName+checkSumExtension);
@@ -123,7 +127,7 @@ public class DownloadTask extends Task<Boolean>{

        if(isCancelled()) return false;

        this.updateTitle("Downloading "+fileName);
        this.updateTitle("Downloading "+ latestBuildFilename);

        final String tmpFilePath = AppConstants.getSourcesFolderPath()+"tmp."+fileName;
        
@@ -178,6 +182,120 @@ public class DownloadTask extends Task<Boolean>{
        }
    }

    private String fetchLatestBuildFilename(String archiveUrl) {
        // Extract codeName and codeType from the archiveUrl
        Pair<String, String> codeInfo = getCodeNameFromUrl(archiveUrl);
        if (codeInfo == null) {
            logger.error("Failed to fetch latest build filename: codeName or codeType is null.");
            return null;
        }

        String codeName = codeInfo.getKey();
        String codeType = codeInfo.getValue();

        // Construct API URL using codeName and codeType
        HttpURLConnection apiConnection = getApiConnection(codeName, codeType);
        if (apiConnection == null) {
            logger.error("Failed to fetch latest build filename: API connection is null.");
            return null;
        }

        try {
            String latestBuildFilename = processApiResponse(apiConnection);
            return latestBuildFilename;
        } catch (IOException e) {
            logger.error("Error processing API response: {}", e.getMessage());
            return null;
        } finally {
            if (apiConnection != null) {
                apiConnection.disconnect();
            }
        }
    }

    private Pair<String, String> getCodeNameFromUrl(String archiveUrl) {
        try {
            URL url = new URL(archiveUrl);
            String[] urlParts = url.getPath().split("/");

            for (int i = 0; i < urlParts.length; i++) {
                if (urlParts[i].equals("stable") || urlParts[i].equals("dev")) {
                    if (i + 1 < urlParts.length) {
                        String codeType = urlParts[i];
                        String codeName = urlParts[i + 1];
                        logger.debug("CodeName extracted from URL: {}", codeName);
                        logger.debug("CodeType extracted from URL: {}", codeType);
                        return new Pair<>(codeName, codeType);
                    }
                }
            }

            logger.error("Invalid URL: Can't find codeName or codeType in: {}", archiveUrl);
        } catch (MalformedURLException e) {
            logger.error("Invalid URL: {}", e.getMessage());
        }

        return null;
    }

    private HttpURLConnection getApiConnection(String codeName, String codeType) {
        try {
            URL apiUrl = new URL("https://ota.ecloud.global/api/v1/" + codeName + "/" + codeType + "?format=json");
            HttpURLConnection apiConnection = (HttpURLConnection) apiUrl.openConnection();
            apiConnection.setRequestMethod("GET");
            apiConnection.setRequestProperty("User-Agent", "null eOS v3");
            return apiConnection;
        } catch (IOException e) {
            logger.error("Error establishing API connection: {}", e.getMessage());
        }

        return null;
    }

    private String processApiResponse(HttpURLConnection apiConnection) throws IOException {
        try {
            int responseCode = apiConnection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                String responseString = inputStreamToString(apiConnection.getInputStream());

                // Try parsing the response as JSON
                new JSONObject(responseString);

                JSONObject responseJson = new JSONObject(responseString);
                JSONArray responses = responseJson.getJSONArray("response");

                JSONObject responseObject = responses.getJSONObject(0);
                String filename = responseObject.getString("filename");
                return filename;
            } else {
                logger.error("Error fetching latest build filename: HTTP response code {}", responseCode);
            }
        } catch (JSONException e) {
            logger.warn("API response appears to be invalid JSON. Ignoring...");
            return null;
        } catch (IOException e) {
            logger.error("Error processing API response: {}", e.getMessage());
        } finally {
            if (apiConnection != null) {
                apiConnection.disconnect();
            }
        }

        return null;
    }

    private String inputStreamToString(InputStream inputStream) throws IOException {
        StringBuilder responseString = new StringBuilder();
        Scanner scanner = new Scanner(inputStream);
        while (scanner.hasNextLine()) {
            responseString.append(scanner.nextLine());
            responseString.append("\n");
        }
        scanner.close();

        return responseString.toString();
    }

    /**
     * Perform the downloading of the specified file
     * If a part is already downloaded, then the download resume from previous state
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ module ecorp.easy.installer {
    requires org.yaml.snakeyaml;
    requires org.slf4j;
    requires logback.classic;
    requires org.json;
    opens ecorp.easy.installer to javafx.fxml;
    opens ecorp.easy.installer.controllers to javafx.fxml;
    opens ecorp.easy.installer.controllers.subcontrollers to javafx.fxml;