Skip to content

Commit

Permalink
fix: Fixed CoderabbitAI's reviews and github-advanced-security bot's …
Browse files Browse the repository at this point in the history
…warnings
  • Loading branch information
SaptarshiSarkar12 committed Sep 20, 2024
1 parent 57258a1 commit 141ffc8
Show file tree
Hide file tree
Showing 14 changed files with 264 additions and 219 deletions.
46 changes: 24 additions & 22 deletions CLI/src/main/java/backend/FileDownloader.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ private void downloadFile() {
File file;
for (int i = 0; i < numberOfThreads; i++) {
file = Files.createTempFile(fileName.hashCode() + String.valueOf(i), ".tmp").toFile();
file.deleteOnExit(); // Deletes a temporary file when JVM exits
fileOut = new FileOutputStream(file);
start = i == 0 ? 0 : ((i * partSize) + 1); // The start of the range of bytes to be downloaded by the thread
end = (numberOfThreads - 1) == i ? totalSize : ((i * partSize) + partSize); // The end of the range of bytes to be downloaded by the thread
Expand All @@ -83,6 +82,9 @@ private void downloadFile() {
while (!mergeDownloadedFileParts(fileOutputStreams, partSizes, downloaderThreads, tempFiles)) {
sleep(500);
}
for (File tempFile : tempFiles) {
Files.deleteIfExists(tempFile.toPath());
}
} else {
InputStream urlStream = url.openStream();
readableByteChannel = Channels.newChannel(urlStream);
Expand All @@ -98,9 +100,9 @@ private void downloadFile() {
// keep the main thread from closing the IO for a short amount of time so the UI thread can finish and give output
Utility.sleep(1800);
} catch (SecurityException e) {
M.msgDownloadError("Write access to \"" + directoryPath.resolve(fileName).toAbsolutePath() + "\" is denied! " + e.getMessage());
M.msgDownloadError("Write access to the download directory is DENIED! " + e.getMessage());
} catch (FileNotFoundException fileNotFoundException) {
M.msgDownloadError(FILE_NOT_FOUND);
M.msgDownloadError(FILE_NOT_FOUND_ERROR);
} catch (IOException e) {
M.msgDownloadError(FAILED_TO_DOWNLOAD_CONTENTS + e.getMessage());
}
Expand All @@ -115,27 +117,27 @@ private void downloadYoutubeOrInstagram(boolean isSpotifySong) {
processBuilder.inheritIO();
M.msgDownloadInfo(String.format(DOWNLOADING_F, fileName));
Process process;
int exitCode = 1;
int exitValueOfYtDlp = 1;
try {
process = processBuilder.start();
process.waitFor();
exitCode = process.exitValue();
exitValueOfYtDlp = process.exitValue();
} catch (IOException e) {
M.msgDownloadError("Failed to start download process for \"" + fileName + "\"");
} catch (Exception e) {
String msg = e.getMessage();
String[] messageArray = msg.split(",");
if (messageArray.length >= 1 && messageArray[0].toLowerCase().trim().replaceAll(" ", "").contains("cannotrunprogram")) { // If yt-dlp program is not marked as executable
M.msgDownloadError(DRIFTY_COMPONENT_NOT_EXECUTABLE);
M.msgDownloadError(DRIFTY_COMPONENT_NOT_EXECUTABLE_ERROR);
} else if (messageArray.length >= 1 && "permissiondenied".equals(messageArray[1].toLowerCase().trim().replaceAll(" ", ""))) { // If a private YouTube / Instagram video is asked to be downloaded
M.msgDownloadError(PERMISSION_DENIED);
M.msgDownloadError(PERMISSION_DENIED_ERROR);
} else if ("videounavailable".equals(messageArray[0].toLowerCase().trim().replaceAll(" ", ""))) { // If YouTube / Instagram video is unavailable
M.msgDownloadError(VIDEO_UNAVAILABLE);
M.msgDownloadError(VIDEO_UNAVAILABLE_ERROR);
} else {
M.msgDownloadError("An Unknown Error occurred! " + e.getMessage());
}
}
if (exitCode == 0) {
if (exitValueOfYtDlp == 0) {
M.msgDownloadInfo(String.format(SUCCESSFULLY_DOWNLOADED_F, fileName));
if (isSpotifySong) {
M.msgDownloadInfo("Converting to mp3 ...");
Expand All @@ -146,10 +148,10 @@ private void downloadYoutubeOrInstagram(boolean isSpotifySong) {
M.msgDownloadInfo("Successfully converted to mp3!");
}
}
} else if (exitCode == 1) {
} else if (exitValueOfYtDlp == 1) {
M.msgDownloadError(String.format(FAILED_TO_DOWNLOAD_F, fileName));
} else {
M.msgDownloadError("An Unknown Error occurred! Exit code: " + exitCode);
M.msgDownloadError("An Unknown Error occurred! Exit code: " + exitValueOfYtDlp);
}
}

Expand All @@ -173,18 +175,18 @@ public boolean mergeDownloadedFileParts(List<FileOutputStream> fileOutputStreams
}
// check if it is merged-able
if (completed == numberOfThreads) {
fileOutputStream = new FileOutputStream(directoryPath.resolve(fileName).toFile());
long position = 0;
for (int i = 0; i < numberOfThreads; i++) {
File f = tempFiles.get(i);
FileInputStream fs = new FileInputStream(f);
ReadableByteChannel rbs = Channels.newChannel(fs);
fileOutputStream.getChannel().transferFrom(rbs, position, f.length());
position += f.length();
fs.close();
rbs.close();
try (FileOutputStream fos = new FileOutputStream(directoryPath.resolve(fileName).toFile())) {
long position = 0;
for (int i = 0; i < numberOfThreads; i++) {
File f = tempFiles.get(i);
FileInputStream fs = new FileInputStream(f);
ReadableByteChannel rbs = Channels.newChannel(fs);
fos.getChannel().transferFrom(rbs, position, f.length());
position += f.length();
fs.close();
rbs.close();
}
}
fileOutputStream.close();
return true;
}
return false;
Expand Down
6 changes: 3 additions & 3 deletions CLI/src/main/java/backend/ProgressBarThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,11 @@ private void cleanup() {
if (isMultiThreadedDownloading) {
String sizeWithUnit = UnitConverter.format(totalDownloadedBytes, 2);
System.out.print("\r");
M.msgDownloadInfo(String.format(SUCCESSFULLY_DOWNLOADED_F, fileName) + OF_SIZE + sizeWithUnit + " at " + path);
M.msgDownloadInfo(String.format(SUCCESSFULLY_DOWNLOADED_F, fileName) + OF_SIZE + sizeWithUnit + " at \"" + path + "\"");
} else if (downloadedBytes == totalDownloadedBytes) {
String sizeWithUnit = UnitConverter.format(downloadedBytes, 2);
System.out.print("\r");
M.msgDownloadInfo(String.format(SUCCESSFULLY_DOWNLOADED_F, fileName) + OF_SIZE + sizeWithUnit + " at " + path);
M.msgDownloadInfo(String.format(SUCCESSFULLY_DOWNLOADED_F, fileName) + OF_SIZE + sizeWithUnit + " at \"" + path + "\"");
} else {
System.out.println();
M.msgDownloadError(DOWNLOAD_FAILED);
Expand Down Expand Up @@ -211,7 +211,7 @@ public void run() {
}
}
} catch (IOException e) {
M.msgDownloadError("Error while downloading " + fileName + " : " + e.getMessage());
M.msgDownloadError("Error while downloading \"" + fileName + "\" : " + e.getMessage());
} finally {
downloading = downloadMetrics.isActive();
}
Expand Down
60 changes: 30 additions & 30 deletions CLI/src/main/java/main/Drifty_CLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,20 @@
import java.net.URISyntaxException;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import static cli.support.Constants.*;
import static cli.utils.Utility.*;
import static cli.utils.Utility.isURL;
import static cli.utils.Utility.sleep;

public class Drifty_CLI {
public static final Logger LOGGER = Logger.getInstance();
protected static final Scanner SC = ScannerFactory.getInstance();
protected static JobHistory jobHistory;
private static LinkType linkType;
protected static boolean isYoutubeURL;
protected static boolean isInstagramLink;
protected static boolean isSpotifyLink;
private static MessageBroker messageBroker;
private static String link;
private static String downloadsFolder;
Expand Down Expand Up @@ -180,6 +182,10 @@ public static void main(String[] args) {
}
}
if (!batchDownloading) {
if (link == null) {
messageBroker.msgInitError("No URL specified! Exiting...");
Environment.terminate(1);
}
boolean isUrlValid;
if (Utility.isURL(link)) {
isUrlValid = Utility.isLinkValid(link);
Expand All @@ -189,11 +195,8 @@ public static void main(String[] args) {
}
if (isUrlValid) {
linkType = LinkType.getLinkType(link);
isYoutubeURL = linkType.equals(LinkType.YOUTUBE);
isInstagramLink = linkType.equals(LinkType.INSTAGRAM);
isSpotifyLink = linkType.equals(LinkType.SPOTIFY);
downloadsFolder = getProperDownloadsFolder(downloadsFolder);
if (isSpotifyLink && link.contains("playlist")) {
if (linkType.equals(LinkType.SPOTIFY) && link.contains("playlist")) {
handleSpotifyPlaylist();
} else {
verifyJobAndDownload();
Expand Down Expand Up @@ -243,15 +246,8 @@ public static void main(String[] args) {
messageBroker.msgInputInfo("Download directory (\".\" for default or \"L\" for " + AppSettings.GET.lastDownloadFolder() + ") : ", false);
downloadsFolder = SC.nextLine().split(" ")[0];
downloadsFolder = getProperDownloadsFolder(downloadsFolder);
isYoutubeURL = linkType.equals(LinkType.YOUTUBE);
isInstagramLink = linkType.equals(LinkType.INSTAGRAM);
isSpotifyLink = linkType.equals(LinkType.SPOTIFY);
if (isSpotifyLink) {
if (link.contains("playlist")) {
handleSpotifyPlaylist();
} else {
verifyJobAndDownload();
}
if (linkType.equals(LinkType.SPOTIFY) && link.contains("playlist")) {
handleSpotifyPlaylist();
} else {
verifyJobAndDownload();
}
Expand Down Expand Up @@ -387,10 +383,13 @@ private static void printVersion() {
private static void handleSpotifyPlaylist() {
messageBroker.msgFilenameInfo("Retrieving the number of tracks in the playlist...");
DownloadConfiguration config = new DownloadConfiguration(link, downloadsFolder, null);
Thread prepareFileData = new Thread(config::fetchFileData);
prepareFileData.start();
while (prepareFileData.isAlive()) {
sleep(100);
try (ExecutorService executor = Executors.newSingleThreadExecutor()) {
Future<Integer> future = executor.submit(config::fetchFileData);
future.get();
} catch (ExecutionException e) {
messageBroker.msgLinkError("Failed to retrieve spotify playlist metadata! " + e.getMessage());
} catch (InterruptedException e) {
messageBroker.msgLinkError("User interrupted the process of retrieving spotify playlist metadata! " + e.getMessage());
}
ArrayList<HashMap<String, Object>> playlistData = config.getFileData();
if (playlistData != null && !playlistData.isEmpty()) {
Expand Down Expand Up @@ -472,9 +471,6 @@ private static void batchDownloader() {
continue;
}
linkType = LinkType.getLinkType(link);
isYoutubeURL = linkType.equals(LinkType.YOUTUBE);
isInstagramLink = linkType.equals(LinkType.INSTAGRAM);
isSpotifyLink = linkType.equals(LinkType.SPOTIFY);
if (".".equals(downloadsFolder)) {
downloadsFolder = Utility.getHomeDownloadFolder();
} else if ("L".equalsIgnoreCase(downloadsFolder)) {
Expand All @@ -489,7 +485,7 @@ private static void batchDownloader() {
if (data.containsKey("fileNames") && !data.get("fileNames").get(i).isEmpty()) {
fileName = data.get("fileNames").get(i);
}
if (isSpotifyLink && link.contains("playlist")) {
if (linkType.equals(LinkType.SPOTIFY) && link.contains("playlist")) {
handleSpotifyPlaylist();
} else {
verifyJobAndDownload();
Expand All @@ -510,7 +506,7 @@ private static void batchDownloader() {
}

private static void renameFilenameIfRequired() { // Asks the user if the detected filename is to be used or not. If not, then the user is asked to enter a filename.
if ((fileName == null || (fileName.isEmpty())) && (!isYoutubeURL && !isInstagramLink && !isSpotifyLink)) {
if ((fileName == null || (fileName.isEmpty())) && linkType.equals(LinkType.OTHER)) {
messageBroker.msgInputInfo(ENTER_FILE_NAME_WITH_EXTENSION, false);
fileName = SC.nextLine();
} else {
Expand Down Expand Up @@ -596,10 +592,13 @@ private static void verifyJobAndDownload() {
DownloadConfiguration config = new DownloadConfiguration(link, downloadsFolder, fileName);
config.sanitizeLink();
messageBroker.msgFilenameInfo("Retrieving file data...");
Thread prepareFileData = new Thread(config::fetchFileData);
prepareFileData.start();
while (prepareFileData.isAlive()) {
sleep(100);
try (ExecutorService executor = Executors.newSingleThreadExecutor()) {
Future<Integer> future = executor.submit(config::fetchFileData);
future.get();
} catch (ExecutionException e) {
messageBroker.msgLinkError("Failed to retrieve file metadata! " + e.getMessage());
} catch (InterruptedException e) {
messageBroker.msgLinkError("User interrupted the process of retrieving file metadata! " + e.getMessage());
}
if (config.getStatusCode() != 0) {
messageBroker.msgLinkError("Failed to fetch file data!");
Expand Down Expand Up @@ -663,6 +662,7 @@ private static void checkHistoryAndDownload(Job job) {
jobHistory.addJob(job, true);
renameFilenameIfRequired();
if (link != null) {
job = new Job(link, downloadsFolder, fileName, job.getDownloadLink());
FileDownloader downloader = new FileDownloader(job);
downloader.run();
}
Expand Down
10 changes: 6 additions & 4 deletions Core/src/main/java/preferences/Get.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import utils.Utility;

import javax.crypto.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
Expand Down Expand Up @@ -127,15 +128,16 @@ public boolean driftyUpdateAvailable() {
public Jobs jobs() {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = FxGson.addFxSupport(gsonBuilder).setPrettyPrinting().create();
Jobs jobs;
Path jobBatchFile = Paths.get(Program.get(JOB_FILE));
try {
String json = FileUtils.readFileToString(jobBatchFile.toFile(), Charset.defaultCharset());
if (json != null && !json.isEmpty()) {
jobs = gson.fromJson(json, Jobs.class);
return jobs;
return gson.fromJson(json, Jobs.class);
}
} catch (IOException ignored) {
} catch (FileNotFoundException e) {
Environment.getMessageBroker().msgLogInfo("Job file not found: " + jobBatchFile);
} catch (IOException e) {
Environment.getMessageBroker().msgLogError("Failed to read job file: " + jobBatchFile);
}
return new Jobs();
}
Expand Down
16 changes: 13 additions & 3 deletions Core/src/main/java/preferences/Set.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,25 @@ public void driftyUpdateAvailable(boolean isUpdateAvailable) {
}

public void jobs(Jobs jobs) {
String serializedJobs = serializeJobs(jobs);
writeJobsToFile(serializedJobs);
}

private String serializeJobs(Jobs jobs) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = FxGson.addFxSupport(gsonBuilder).setPrettyPrinting().create();
String value = gson.toJson(jobs);
return gson.toJson(jobs);
}

private void writeJobsToFile(String serializedJobs) {
AppSettings.CLEAR.jobs();
Path jobBatchFile = Paths.get(Program.get(JOB_FILE));
try {
FileUtils.writeStringToFile(jobBatchFile.toFile(), value, Charset.defaultCharset());
FileUtils.writeStringToFile(jobBatchFile.toFile(), serializedJobs, Charset.defaultCharset());
} catch (IOException e) {
throw new RuntimeException(e);
String errorMessage = "Failed to write jobs to file: " + e.getMessage();
Environment.getMessageBroker().msgInitError(errorMessage);
throw new RuntimeException(errorMessage, e);
}
}
}
14 changes: 7 additions & 7 deletions Core/src/main/java/support/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ public class Constants {
public static final String INVALID_LINK = "Link is invalid! Please check the link and try again.";
public static final String FILENAME_DETECTION_ERROR = "Failed to detect the filename! A default name will be used instead.";
public static final String TRYING_TO_AUTO_DETECT_DOWNLOADS_FOLDER = "Trying to automatically detect default Downloads folder...";
public static final String FAILED_TO_RETRIEVE_DEFAULT_DOWNLOAD_FOLDER = "Failed to retrieve default download folder!";
public static final String FAILED_TO_RETRIEVE_DEFAULT_DOWNLOAD_FOLDER_ERROR = "Failed to retrieve default download folder!";
public static final String FOLDER_DETECTED = "Default download folder detected : ";
public static final String FILENAME_DETECTED = "Filename detected : ";
public static final String FAILED_TO_CREATE_LOG = "Failed to create log : ";
public static final String FAILED_TO_CLEAR_LOG = "Failed to clear Log contents !";
public static final String FILE_NOT_FOUND = "An error occurred! Requested file does not exist, please check the url.";
public static final String VIDEO_UNAVAILABLE = "The requested video is unavailable, it has been deleted from the platform.";
public static final String PERMISSION_DENIED = "You do not have access to download the video, permission is denied.";
public static final String DRIFTY_COMPONENT_NOT_EXECUTABLE = "A Drifty component (yt-dlp) is not marked as executable.";
public static final String FAILED_TO_CREATE_LOG_ERROR = "Failed to create log : ";
public static final String FAILED_TO_CLEAR_LOG_ERROR = "Failed to clear Log contents !";
public static final String FILE_NOT_FOUND_ERROR = "An error occurred! Requested file does not exist, please check the url.";
public static final String VIDEO_UNAVAILABLE_ERROR = "The requested video is unavailable, it has been deleted from the platform.";
public static final String PERMISSION_DENIED_ERROR = "You do not have access to download the video, permission is denied.";
public static final String DRIFTY_COMPONENT_NOT_EXECUTABLE_ERROR = "A Drifty component (yt-dlp) is not marked as executable.";
public static final String USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0";
public static final long ONE_DAY = 86400000; // Value of one day (24 Hours) in milliseconds
public static URL updateURL;
Expand Down
Loading

0 comments on commit 141ffc8

Please sign in to comment.