diff --git a/CLI/src/main/java/main/Drifty_CLI.java b/CLI/src/main/java/main/Drifty_CLI.java index c5609029..fa0004a8 100644 --- a/CLI/src/main/java/main/Drifty_CLI.java +++ b/CLI/src/main/java/main/Drifty_CLI.java @@ -21,6 +21,7 @@ import utils.Logger; import java.io.*; +import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; @@ -294,6 +295,21 @@ public static void main(String[] args) { if (isInstagram(link)) { link = formatInstagramLink(link); } + else if (isYoutube(link)) { + try { + link = formatYoutubeLink(link); + } catch (IllegalArgumentException | URISyntaxException | MalformedURLException e) { + messageBroker.msgLinkError("Failed to process the YouTube link: " + e.getMessage()); + messageBroker.msgInputInfo(QUIT_OR_CONTINUE, true); + String choice = SC.next().toLowerCase().strip(); + if ("q".equals(choice)) { + LOGGER.log(MessageType.INFO, CLI_APPLICATION_TERMINATED); + break; + } + printBanner(); + continue; + } + } messageBroker.msgFilenameInfo("Retrieving filename from link..."); fileName = findFilenameInLink(link); if (fileName != null && !fileName.isEmpty()) { diff --git a/Core/src/main/java/utils/Utility.java b/Core/src/main/java/utils/Utility.java index 78066a68..e1fb6ab4 100644 --- a/Core/src/main/java/utils/Utility.java +++ b/Core/src/main/java/utils/Utility.java @@ -7,10 +7,7 @@ import org.apache.commons.text.StringEscapeUtils; import org.hildan.fxgson.FxGson; import preferences.AppSettings; -import properties.MessageCategory; -import properties.Mode; -import properties.OS; -import properties.Program; +import properties.*; import java.io.*; import java.net.*; @@ -33,6 +30,7 @@ import static properties.Program.YT_DLP; import static support.Constants.*; +import static utils.Utility.extractQueryParams; public class Utility { private static final Random RANDOM_GENERATOR = new Random(System.currentTimeMillis()); @@ -860,4 +858,93 @@ public static int parseStringToInt(String string, String errorMessage, MessageCa return 0; } } + + public static String formatYoutubeLink(String link) throws MalformedURLException, URISyntaxException { + String videoId = null; + URI uri = URI.create(link); + String domain = uri.getHost(); + + if ("youtu.be".equals(domain)) { + String path = uri.getPath(); + if (path != null && path.length() > 1) { + videoId = path.substring(1); // removing the leading "/" + } + } + + else if ("www.youtube.com".equals(domain) || "youtube.com".equals(domain)) { + Map queryParams = extractQueryParams(link, "v"); + videoId = queryParams.get("v"); + } + + if (videoId != null) { + uri = new URI("https", "www.youtube.com", "/watch", "v=" + videoId, null); + link = uri.toString(); + } else { + throw new MalformedURLException(link + " is not a valid youtube link!"); + } + + return link; + } + + /** + * Extracts the specified query parameters from the given URL. If no parameter names are provided (null or empty), all parameters are returned. + * + * @param urlLink The URL string from which to extract parameters. + * @param paramNames The names of the query parameters to extract. If null or empty, all parameters will be returned. + * @return A map containing the query parameter names and their corresponding values. + */ + public static Map extractQueryParams(String urlLink, String... paramNames) { + Map paramMap = new HashMap<>(); + + URL url = null; + try { + url = URI.create(urlLink).toURL(); + } catch (MalformedURLException e) { + msgBroker.msgLinkError("Connection to the link timed out! Please check your internet connection. " + e.getMessage()); + } + String query = url != null ? url.getQuery() : null; + + // query is null or empty, return an empty map (no query parameters) + if (query == null || query.isEmpty()) { + return paramMap; + } + + // splitting query string into individual parameters + String[] params = query.split("&"); + + // check if specific parameters are requested or if all should be returned + boolean returnAllParams = (paramNames == null || paramNames.length == 0); + + for (String param : params) { + String[] pair = param.split("="); + if (pair.length == 2) { + String paramName = pair[0]; + String paramValue = pair[1]; + + // add parameter to the map if it's requested or if all parameters should be returned + if (returnAllParams || contains(paramNames, paramName)) { + paramMap.put(paramName, paramValue); + } + } + } + + return paramMap; + } + + /** + * Helper method to check if an array contains a specific value. + * + * @param array The array to check. + * @param value The value to search for. + * @return True if the array contains the value, false otherwise. + */ + private static boolean contains(String[] array, String value) { + if (array == null) return false; + for (String item : array) { + if (item.equals(value)) { + return true; + } + } + return false; + } }