diff --git a/README.md b/README.md index 3cde897..6ba258e 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,12 @@ right. ## Version History +* 2.2.0 + * Added the `sb` option which allows a search of entire browser history + * Fixed problem when copying browser history for offline access + * Fixed date issues with different browsers + * Fixed safari schema problem with sqlite + * 2.1.0 * Added check for headless mode in Watch class diff --git a/build/environment.md b/build/environment.md index c670b75..ce0909c 100644 --- a/build/environment.md +++ b/build/environment.md @@ -19,17 +19,30 @@ Click on your operating system to see how to set up the build environment: ## First +If you're in Windows: + +```bash +mkdir C:\github +cd C:\github +``` + +Mac/Linux: + +```bash +mkdir ~/github +cd ~/github +``` + Clone the repository to your local drive: ```bash git clone https://github.com/EasyG0ing1/iget.git -cd iget ``` ### MacOS or Linux ```bash -cd ~/github/iget/build/maclinux +cd iget/build/maclinux chmod +x *.sh ./buildjar.sh ``` @@ -37,7 +50,7 @@ chmod +x *.sh ### Windows ```bash -cd C:\github\iget\build\windows +cd iget\build\windows buildjar.bat ``` @@ -92,12 +105,10 @@ You will then see it do things like updating `yt-dlp` ... give it some time. The next thing you should see will look like this: -```bash -Watching Clipboard - Ctrl+C to exit -``` +> Watching Clipboard - Ctrl+C to exit And **THAT'S ALL YOU SHOULD SEE**. If you see a command prompt show up after that, then something went wrong. Open an -issue and lets talk about it. +issue and let's talk about it. Launch your browser and go to instagram.com and log into your Instagram account. Next, find a reel. If clicking on reel on the left side of the screen doesn't work for you, then just find a content creator and from their page, click on @@ -106,17 +117,15 @@ Reels then click on one of their reels. After you've clicked on a reel, the video should pop up in your browser and start playing. We want the text in the URL field, so highlight all of that text, then RIGHT CLICK on it and select copy. The text should look something like this: -```azure -https://www.instagram.com/reel/C6RT4CKyl2O/ -``` +> `https://www.instagram.com/reel/C6RT4CKyl2O/` + Once you copy it to your clipboard, you should see in the terminal something like this: -```azure -Watching Clipboard - Ctrl+C to exit -Downloading: https://www.instagram.com/reel/C6RT4CKyl2O/?utm_source=ig_embed -Success: https://www.instagram.com/reel/C6RT4CKyl2O/?utm_source=ig_embed -``` +> Watching Clipboard - Ctrl+C to exit +> Downloading: https://www.instagram.com/reel/C6RT4CKyl2O/?utm_source=ig_embed +> Success: https://www.instagram.com/reel/C6RT4CKyl2O/?utm_source=ig_embed + If the Downloading line doesn't show up right away for some reason, click on the Terminal window to make it active, then click on the web browser to make it active and copy the text to the clipboard again. diff --git a/build/img.png b/build/img.png new file mode 100644 index 0000000..882f1b8 Binary files /dev/null and b/build/img.png differ diff --git a/build/maclinux/graal.sh b/build/maclinux/graal.sh index 8287c21..bc70c6f 100755 --- a/build/maclinux/graal.sh +++ b/build/maclinux/graal.sh @@ -2,3 +2,4 @@ rm -R $HOME/github/iget/graalvm mkdir $HOME/github/iget/graalvm java --enable-preview -agentlib:native-image-agent=config-output-dir=$HOME/github/iget/graalvm -jar $HOME/github/iget/target/iGet-jar-with-dependencies.jar setBrowser java --enable-preview -agentlib:native-image-agent=config-merge-dir=$HOME/github/iget/graalvm -jar $HOME/github/iget/target/iGet-jar-with-dependencies.jar graal +java --enable-preview -agentlib:native-image-agent=config-merge-dir=$HOME/github/iget/graalvm -jar $HOME/github/iget/target/iGet-jar-with-dependencies.jar version diff --git a/build/maclinux/native.sh b/build/maclinux/native.sh index 4ae2c82..b726474 100755 --- a/build/maclinux/native.sh +++ b/build/maclinux/native.sh @@ -1,15 +1,20 @@ -native-image \ --Djava.awt.headless=true \ ---no-fallback \ ---verbose \ ---enable-preview \ ---initialize-at-build-time=org.sqlite.util.ProcessRunner \ --cp "$HOME/.m2/repository/org/xerial/sqlite-jdbc/3.45.3.0/sqlite-jdbc-3.45.3.0.jar" \ --H:+ReportExceptionStackTraces \ --H:ReflectionConfigurationFiles=$HOME/github/iget/graalvm/reflect-config.json \ --H:JNIConfigurationFiles=$HOME/github/iget/graalvm/jni-config.json \ --H:ResourceConfigurationFiles=$HOME/github/iget/graalvm/resource-config.json \ --H:SerializationConfigurationFiles=$HOME/github/iget/graalvm/serialization-config.json \ --H:Name=$HOME/github/iget/target/iget \ --jar $HOME/github/iget/target/iGet-jar-with-dependencies.jar \ -$HOME/github/iget/target/iget +#!/bin/bash + +mvn -f $HOME/github/iget/pom.xml clean -Pnative native:compile + + +# native-image \ +# -Djava.awt.headless=true \ +# --no-fallback \ +# --verbose \ +# --enable-preview \ +# --initialize-at-build-time=org.sqlite.util.ProcessRunner \ +# -cp "$HOME/.m2/repository/org/xerial/sqlite-jdbc/3.45.3.0/sqlite-jdbc-3.45.3.0.jar" \ +# -H:+ReportExceptionStackTraces \ +# -H:ReflectionConfigurationFiles=$HOME/github/iget/graalvm/reflect-config.json \ +# -H:JNIConfigurationFiles=$HOME/github/iget/graalvm/jni-config.json \ +# -H:ResourceConfigurationFiles=$HOME/github/iget/graalvm/resource-config.json \ +# -H:SerializationConfigurationFiles=$HOME/github/iget/graalvm/serialization-config.json \ +# -H:Name=$HOME/github/iget/target/iget \ +# -jar $HOME/github/iget/target/iGet-jar-with-dependencies.jar \ +# $HOME/github/iget/target/iget diff --git a/build/windows/graal.bat b/build/windows/graal.bat index 8dde0f9..afd5042 100644 --- a/build/windows/graal.bat +++ b/build/windows/graal.bat @@ -4,3 +4,4 @@ rd /s /q %APPDATA%\iGet mkdir C:\github\iGet\graalvm java --enable-preview -agentlib:native-image-agent=config-output-dir=C:\github\iGet\graalvm -jar C:\github\iGet\target\iGet-jar-with-dependencies.jar setBrowser java --enable-preview -agentlib:native-image-agent=config-merge-dir=C:\github\iGet\graalvm -jar C:\github\iGet\target\iGet-jar-with-dependencies.jar graal +java --enable-preview -agentlib:native-image-agent=config-merge-dir=C:\github\iGet\graalvm -jar C:\github\iGet\target\iGet-jar-with-dependencies.jar version diff --git a/build/windows/native.bat b/build/windows/native.bat index 6854669..31efe93 100644 --- a/build/windows/native.bat +++ b/build/windows/native.bat @@ -1,3 +1,5 @@ @echo off -cd C:\github\iGet -native-image --no-fallback --verbose --enable-preview --initialize-at-build-time=org.sqlite.util.ProcessRunner -cp "%HOMEPATH%\.m2\repository\org\xerial\sqlite-jdbc\3.45.3.0\sqlite-jdbc-3.45.3.0.jar" -H:ReflectionConfigurationFiles=C:\github\iGet\graalvm\reflect-config.json -H:JNIConfigurationFiles=C:\github\iGet\graalvm\jni-config.json -H:ResourceConfigurationFiles=C:\github\iGet\graalvm\resource-config.json -H:SerializationConfigurationFiles=C:\github\iGet\graalvm\serialization-config.json -H:+ReportExceptionStackTraces -jar C:\github\iGet\target\iGet-jar-with-dependencies.jar C:\github\iGet\target\iget + +mvn -f C:\github\iget\pom.xml clean -Pnative native:compile + +rem native-image --no-fallback --verbose --enable-preview --initialize-at-build-time=org.sqlite.util.ProcessRunner -cp "%HOMEPATH%\.m2\repository\org\xerial\sqlite-jdbc\3.45.3.0\sqlite-jdbc-3.45.3.0.jar" -H:ReflectionConfigurationFiles=C:\github\iGet\graalvm\reflect-config.json -H:JNIConfigurationFiles=C:\github\iGet\graalvm\jni-config.json -H:ResourceConfigurationFiles=C:\github\iGet\graalvm\resource-config.json -H:SerializationConfigurationFiles=C:\github\iGet\graalvm\serialization-config.json -H:+ReportExceptionStackTraces -jar C:\github\iGet\target\iGet-jar-with-dependencies.jar C:\github\iGet\target\iget diff --git a/pom.xml b/pom.xml index dfd3da6..ae58155 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.simtechdata iGet - 2.1.0 + 2.2.0 jar iGet @@ -20,14 +20,12 @@ 3.4.1 3.7.1 3.4.1 - 3.1.0 3.2.0 2.16.2 - 21 - 0.0.8 - 1.0.21 - igram + 3.1.0 + iget com.simtechdata.Main + ${project.basedir}/graalvm @@ -43,7 +41,7 @@ org.slf4j slf4j-api - 1.7.36 + 2.0.12 commons-io @@ -131,7 +129,7 @@ jar-with-dependencies - iGet + ${name} @@ -151,7 +149,6 @@ 22 22 - 22 --enable-preview @@ -171,4 +168,52 @@ + + + maven_central + Maven Central + https://repo.maven.apache.org/maven2/ + + + + + + native + + + + + org.graalvm.buildtools + native-maven-plugin + ${native-maven-plugin} + true + + ${java.version} + ${imageName} + ${mainClass} + true + + -Djava.awt.headless=true + --no-fallback + --verbose + --enable-preview + --initialize-at-build-time=org.sqlite.util.ProcessRunner + -cp + ${user.home}/.m2/repository/org/xerial/sqlite-jdbc/3.45.3.0/sqlite-jdbc-3.45.3.0.jar + + -march=compatibility + -H:+UnlockExperimentalVMOptions + -H:+ReportExceptionStackTraces + -H:JNIConfigurationFiles=${graalFolder}/jni-config.json + -H:DynamicProxyConfigurationFiles=${graalFolder}/proxy-config.json + -H:ReflectionConfigurationFiles=${graalFolder}/reflect-config.json + -H:ResourceConfigurationFiles=${graalFolder}/resource-config.json + -H:SerializationConfigurationFiles=${graalFolder}/serialization-config.json + + + + + + + diff --git a/src/main/java/com/simtechdata/Main.java b/src/main/java/com/simtechdata/Main.java index a27ae83..efab367 100644 --- a/src/main/java/com/simtechdata/Main.java +++ b/src/main/java/com/simtechdata/Main.java @@ -53,7 +53,7 @@ public void write(int b) { case "checkbrowser" -> SQLite.checkBrowser(); case "setbrowserpath" -> Actions.setBrowserPath(); case "setbrowser" -> Actions.setBrowser(); - case "get" -> { + case "get", "g" -> { if (args.length > 1) { Actions.downloadLink(args[1]); } @@ -77,6 +77,11 @@ public void write(int b) { case "list", "show" -> Actions.showLinks(State.NEW); case "?", "--help" -> showHelp(); case "cmds" -> Actions.showCommands(); + case "sb" -> { + String search = args[1]; + Actions.searchBrowser(search); + System.exit(0); + } case "history" -> { System.out.println(STR."\{NL}Showing Downloaded Links:\{NL}"); Actions.showLinks(State.DOWNLOADED); @@ -122,8 +127,8 @@ private static void showHelp() { (http must begin the link to be recognized as a link) Options: - get - Download links in que - get - download one URL right now + get - Download links in que (can also use g) + get - download one URL right now (can also use g)mac watch - Watch mode looks for links to show up in clipboard then downloads them setFolder - Set the folder where downloads get stored setBrowser - Set which browser you use for Instagram (this helps prevent download failures) @@ -135,6 +140,7 @@ private static void showHelp() { remove - Remove one link from the download list (A menu will be provided) failed - Show links that failed to download version - Show iGet version number + sb - Search browser history for word. Will offer list and selected link will go to clipboard browserHistory - show ALL of the links that are in your browsers history checkBrowser - Lets you verify that iGet can find the History file for your web browser setBrowserPath - Lets you set the path to the browser History file if the above option does not find it. diff --git a/src/main/java/com/simtechdata/actions/Actions.java b/src/main/java/com/simtechdata/actions/Actions.java index d633aa6..23e87ca 100644 --- a/src/main/java/com/simtechdata/actions/Actions.java +++ b/src/main/java/com/simtechdata/actions/Actions.java @@ -8,17 +8,20 @@ import com.simtechdata.settings.AppSettings; import com.simtechdata.settings.Search; +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.nio.file.Paths; import java.sql.SQLException; +import java.util.List; import java.util.*; import java.util.concurrent.*; import static com.simtechdata.enums.OS.NL; -import static com.simtechdata.enums.Reason.DUPLICATE_ENTRY; public class Actions { @@ -93,6 +96,53 @@ public static void addBrowserHistory(int hours, boolean includeFailed) { } } + public static void searchBrowser(String search) { + LinkedList list = DB.searchBrowser(search); + if (list.isEmpty()) { + System.out.println("\n\tNo Results\n\n"); + System.exit(0); + } + StringBuilder sb = new StringBuilder(); + int places = (list.size() < 10) ? 0 : (list.size() < 100) ? 1 : 2; + int count = 1; + for (Link link : list) { + int clip = Math.min(100, link.getLink().length()) - 1; + String url = link.getLink().substring(0, clip); + String date = TimeUtil.toMonthDayYear(link.getTimestamp()); + sb.append(padNumber(count, places)).append(") ").append(url).append(" - ").append(date).append(NL); + count++; + } + sb.append(STR."Chose (\{count} - Quit): "); + System.out.print(sb); + int choice = new Scanner(System.in).nextInt(); + if (choice == count) { + System.exit(0); + } + toClipboard(list.get(choice)); + System.out.println(STR."\{NL}\tLink copied to your clipboard\{NL}"); + } + + private static void toClipboard(Link link) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringSelection contents = new StringSelection(link.getLink()); + clipboard.setContents(contents, null); + } + + + private static String padNumber(int number, int places) { + String pre = ""; + if (number < 10) { + pre = "0".repeat(places); + } + else if (number < 100) { + pre = "0".repeat(places - 1); + } + else if (number < 1000) { + pre = "0".repeat(places - 2); + } + return STR."\{pre}\{number}"; + } + public static void downloadLink(String lnk) { Link link = new Link(lnk, System.currentTimeMillis()); try { @@ -166,13 +216,9 @@ public static void addLink(Link link, boolean override) { } public static void showHistory() { - System.out.print("Include failed downloads in list? (Y/N): "); - String option = new Scanner(System.in).nextLine(); - boolean includeFailed = option.toLowerCase().contains("y"); - LinkedList historyList = DB.getBrowserHistoryDates(includeFailed); - boolean retryFailed = false; + LinkedList historyList = DB.getBrowserHistoryDates(true); while (true) { - StringBuilder sb = new StringBuilder(STR."Which date would you like to download?\{NL + NL}"); + StringBuilder sb = new StringBuilder(STR."Which date would you like to see (A=ALL)?\{NL + NL}"); int c = 0; for (BrowserHistory history : historyList) { String date = history.getDate(); @@ -180,40 +226,38 @@ public static void showHistory() { sb.append(c).append(") ").append(date).append(STR." (\{count})").append(NL); c++; } - int toggleFailed = c; - sb.append(toggleFailed).append(") Retry Failed Downloads: ").append(retryFailed).append(NL); - int exit = c + 10; + int exit = c + 1; sb.append(STR."\{exit}) QUIT\{NL}: "); System.out.print(sb); - int choice = new Scanner(System.in).nextInt(); - System.out.println(" "); - if (choice == exit) { - break; + String usrChoice = new Scanner(System.in).nextLine(); + if (usrChoice.toLowerCase().contains("a")) { + for (BrowserHistory history : historyList) { + for (Link link : history.getLinkList()) { + System.out.println(STR."\{link.getLink()}\{NL}"); + } + } + System.exit(0); } - else if (choice == toggleFailed) - retryFailed = !retryFailed; else { - BrowserHistory history = historyList.get(choice); - for (Link link : history.getLinkList()) { - if (DB.addLink(link).equals(DUPLICATE_ENTRY)) { - System.out.println(STR."Link already downloaded: \{link.getLink()}"); + int choice = Integer.parseInt(usrChoice); + System.out.println(" "); + if (choice == exit) { + break; + } + else { + int count = historyList.size(); + if (choice >= 0 && choice < count) { + BrowserHistory history = historyList.get(choice); + for (Link link : history.getLinkList()) { + System.out.println(STR."\{link.getLink()}\{NL}"); + } + System.exit(0); } else { - link.download(retryFailed); - } - } - while (executor.getActiveCount() > 0) { - sleep(200); - } - if (DownloadResults.haveFailures()) { - System.out.println("Failures:"); - for (Link link : DownloadResults.getFailedList()) { - System.out.println(STR."\t\{link.getLink()}"); + System.out.println(STR."\{NL}\tInvalid selection\{NL}"); } } } - System.out.println("Hit Enter To Continue"); - new Scanner(System.in).nextLine(); } } diff --git a/src/main/java/com/simtechdata/actions/DownloadLink.java b/src/main/java/com/simtechdata/actions/DownloadLink.java index 2ac09fd..8564a3e 100644 --- a/src/main/java/com/simtechdata/actions/DownloadLink.java +++ b/src/main/java/com/simtechdata/actions/DownloadLink.java @@ -31,6 +31,9 @@ public void showCommand() { } private String formatLink(String link) { + if (link.toLowerCase().contains("youtube") || link.toLowerCase().contains("tu.be")) { + return link; + } if (link.toLowerCase().contains("instagram")) { link = link.replace("instagram.com/reels", "instagram.com/reel"); String[] items = link.replaceFirst("//", "/").split("/"); diff --git a/src/main/java/com/simtechdata/actions/Watch.java b/src/main/java/com/simtechdata/actions/Watch.java index 189a2e2..f19c349 100644 --- a/src/main/java/com/simtechdata/actions/Watch.java +++ b/src/main/java/com/simtechdata/actions/Watch.java @@ -12,6 +12,12 @@ public class Watch { private static final List downloadedLinks = new ArrayList<>(); + private static boolean graal = false; + + public static void startGraal() { + graal = true; + start(); + } public static void start() { @@ -58,6 +64,8 @@ public static void start() { catch (ExecutionException | InterruptedException ignored) { System.out.println(STR."Failed: \{link.getLink()}"); } + if (graal) + System.exit(0); }).start(); } } diff --git a/src/main/java/com/simtechdata/database/DB.java b/src/main/java/com/simtechdata/database/DB.java index f8bea01..9afe034 100644 --- a/src/main/java/com/simtechdata/database/DB.java +++ b/src/main/java/com/simtechdata/database/DB.java @@ -45,26 +45,6 @@ public static State downloadedState(String link) { } } - public static Reason addLink(Link link) { - boolean linkExists = linkExists(link.getLink()); - if (linkExists) { - return downloadedState(link.getLink()).equals(State.DOWNLOADED) ? DUPLICATE_ENTRY : DOWNLOAD_FAILED; - } - String SQL = "INSERT INTO Links (Link, State, Timestamp) VALUES (?, ?, ?);"; - try (Connection conn = getConn(); - PreparedStatement pst = conn.prepareStatement(SQL)) { - pst.setString(1, link.getLink()); - pst.setString(2, NEW.name()); - pst.setLong(3, link.getTimestamp()); - pst.executeUpdate(); - return ADDED_SUCCESSFULLY; - } - catch (SQLException e) { - System.out.println(Arrays.toString(e.getStackTrace())); - } - return FAILED_DATABASE; - } - public static Reason addLink(String link, boolean clearDownloadedFlag) { boolean linkExists = linkExists(link); if (clearDownloadedFlag && linkExists) { @@ -191,70 +171,36 @@ public static LinkedList getBrowserHistoryDates(boolean includeF return historyList; } + public static LinkedList searchBrowser(String search) { + LinkedList list = new LinkedList<>(); + String SQL = STR."SELECT url, last_visit_time as TIME from urls;"; + try (Connection conn = SQLite.getBrowserConnection(); + ResultSet rs = conn.createStatement().executeQuery(SQL)) { + while (rs.next()) { + String url = rs.getString("url"); + long time = rs.getLong("TIME"); + Link link = new Link(url, time); + if (url.toLowerCase().contains(search.toLowerCase())) + list.addLast(link); + } + } + catch (SQLException e) { + e.printStackTrace(); + } + return list; + } + public static LinkedList getBrowserHistory(int hours, boolean includeFailed) { Browser browser = Browser.getBrowser(); LinkedList list = new LinkedList<>(); Set dupeList = new HashSet<>(); - long offsetInSeconds = 978307200; - String SQLChrome = "SELECT url as URL, last_visit_time as TIME from urls " + - "WHERE last_visit_time > ? " + - "AND (" + - " (url NOT LIKE(?) AND url LIKE(?)) " + - "OR (url NOT LIKE(?) AND url LIKE(?)) " + - "OR (url NOT LIKE(?) AND url LIKE(?)) " + - "OR (url NOT LIKE(?) AND url LIKE(?)) " + - "OR url LIKE(?)" + - ") ORDER BY last_visit_time;"; - String SQLFirefox = "SELECT url as URL, last_visit_date as TIME from moz_places " + - "WHERE last_visit_time > ? " + - "AND (" + - " (url NOT LIKE(?) AND url LIKE(?)) " + - "OR (url NOT LIKE(?) AND url LIKE(?)) " + - "OR (url NOT LIKE(?) AND url LIKE(?)) " + - "OR (url NOT LIKE(?) AND url LIKE(?)) " + - "OR url LIKE(?)" + - ") ORDER BY last_visit_time;"; - String SQLSafari = """ - SELECT - hi.id, - hi.url as URL, - hv.visit_time as TIME - FROM - history_items hi - JOIN - history_visits hv ON hi.id = hv.history_item - JOIN - ( - SELECT - history_item, - MAX(visit_time) as MaxVisitTime - FROM - history_visits - GROUP BY - history_item - ) latest_visits ON hv.history_item = latest_visits.history_item AND hv.visit_time = latest_visits.MaxVisitTime - WHERE hv.visit_time > ? \ - AND (\ - (hi.url NOT LIKE(?) AND hi.url LIKE(?)) \ - OR (hi.url NOT LIKE(?) AND hi.url LIKE(?)) \ - OR (hi.url NOT LIKE(?) AND hi.url LIKE(?)) \ - OR (hi.url NOT LIKE(?) AND hi.url LIKE(?)) \ - OR hi.url LIKE(?)\ - ) ORDER BY hv.visit_time;"""; + long time = convertTimestamp(browser, (hours == -1) ? 0 : hours); + String SQL = getSql(browser); Connection conn; - boolean all = hours == -1; - long time = TimeUtil.getTimestampWithOffset(hours, all); try { conn = SQLite.getBrowserConnection(); PreparedStatement pst; - switch (browser) { - case FIREFOX -> pst = conn.prepareStatement(SQLFirefox); - case SAFARI -> { - pst = conn.prepareStatement(SQLSafari); - time -= offsetInSeconds; - } - default -> pst = conn.prepareStatement(SQLChrome); - } + pst = conn.prepareStatement(SQL); pst.setLong(1, time); pst.setString(2, "%time%"); //NOT pst.setString(3, "%//www.youtube.com%watch%"); @@ -269,7 +215,6 @@ OR hi.url LIKE(?)\ while (rs.next()) { String url = rs.getString("URL"); State state = downloadedState(url); - System.out.println(STR."State: \{state.name()} for link: \{url}"); if (state.equals(NEW) || state.equals(DOES_NOT_EXIST) || (state.equals(FAILED) && includeFailed)) { String[] parts = url.split("/"); boolean add = true; @@ -290,11 +235,84 @@ OR hi.url LIKE(?)\ } } catch (SQLException e) { - System.out.println(Arrays.toString(e.getStackTrace())); + StackTraceElement[] stackTraceElements = e.getStackTrace(); + for (StackTraceElement stackTraceElement : stackTraceElements) { + System.out.println(stackTraceElement.toString()); + } } return list; } + private static String getSql(Browser browser) { + String SQL; + switch (browser) { + case FIREFOX -> SQL = """ + SELECT url as URL, last_visit_date as TIME from moz_places + WHERE last_visit_date < ? + AND ( + (url NOT LIKE(?) AND url LIKE(?)) + OR (url NOT LIKE(?) AND url LIKE(?)) + OR (url NOT LIKE(?) AND url LIKE(?)) + OR (url NOT LIKE(?) AND url LIKE(?)) + OR url LIKE(?) + ) ORDER BY last_visit_date; + """; + case SAFARI -> SQL = """ + SELECT + hi.id, + hi.url as URL, + hv.visit_time as TIME + FROM + history_items hi + JOIN + history_visits hv ON hi.id = hv.history_item + JOIN + ( + SELECT + history_item, + MAX(visit_time) as MaxVisitTime + FROM + history_visits + GROUP BY + history_item + ) latest_visits ON hv.history_item = latest_visits.history_item AND hv.visit_time = latest_visits.MaxVisitTime + WHERE hv.visit_time < ? + AND ( + (hi.url NOT LIKE(?) AND hi.url LIKE(?)) + OR (hi.url NOT LIKE(?) AND hi.url LIKE(?)) + OR (hi.url NOT LIKE(?) AND hi.url LIKE(?)) + OR (hi.url NOT LIKE(?) AND hi.url LIKE(?)) + OR hi.url LIKE(?) + ) ORDER BY hv.visit_time; + """; + default -> SQL = """ + SELECT url as URL, last_visit_time as TIME from urls + WHERE last_visit_time < ? + AND ( + (url NOT LIKE(?) AND url LIKE(?)) + OR (url NOT LIKE(?) AND url LIKE(?)) + OR (url NOT LIKE(?) AND url LIKE(?)) + OR (url NOT LIKE(?) AND url LIKE(?)) + OR url LIKE(?) + ) ORDER BY last_visit_time; + """; + } + return SQL; + } + + private static long convertTimestamp(Browser browser, long hours) { + long currentMillis = System.currentTimeMillis(); + long adjustedMillis = currentMillis - (hours * 60 * 60 * 1000); // Subtract 5 hours + long secondsFrom1970To2001 = 978307200; + long unixTimeInSeconds = adjustedMillis / 1000; // Convert from milliseconds to seconds + long offsetBetweenEpochs = 11644473600000L; // Milliseconds from January 1, 1601 to January 1, 1970 + return switch (browser) { + case FIREFOX -> adjustedMillis * 1000; + case SAFARI -> unixTimeInSeconds - secondsFrom1970To2001; + default -> (adjustedMillis + offsetBetweenEpochs) * 1000; + }; + } + public static boolean remove(Link link) { String SQL = "DELETE FROM Links WHERE Link = ?;"; try (Connection conn = getConn(); diff --git a/src/main/java/com/simtechdata/database/Graal.java b/src/main/java/com/simtechdata/database/Graal.java index e046420..4ccaee5 100644 --- a/src/main/java/com/simtechdata/database/Graal.java +++ b/src/main/java/com/simtechdata/database/Graal.java @@ -53,7 +53,7 @@ public void run() { AppSettings.Clear.lastUpdate(); Folder.copyResourceToFile(); System.out.println(STR."\{NL}Copy an instagram link to the clipboard and wait for the download to finish then manually stop the program"); - Watch.start(); + Watch.startGraal(); } catch (SQLException | IOException e) { System.out.println(Arrays.toString(e.getStackTrace())); diff --git a/src/main/java/com/simtechdata/database/Link.java b/src/main/java/com/simtechdata/database/Link.java index 02c8580..f0e88eb 100644 --- a/src/main/java/com/simtechdata/database/Link.java +++ b/src/main/java/com/simtechdata/database/Link.java @@ -34,6 +34,9 @@ private static String formatIGLink(String link) { } private String formatLink(String link) { + if (link.toLowerCase().contains("youtube") || link.toLowerCase().contains("tu.be")) { + return link; + } String[] parts = link.replaceFirst("//", "/").split("/"); int last = parts.length - 1; StringBuilder newURL = new StringBuilder(STR."\{parts[0]}//"); @@ -52,7 +55,6 @@ public String getMonthDayYear() { return TimeUtil.toMonthDayYear(timestamp); } - public void download(boolean retryFailed) { new Thread(() -> { State state = DB.downloadedState(getLink()); diff --git a/src/main/java/com/simtechdata/database/SQLite.java b/src/main/java/com/simtechdata/database/SQLite.java index 74916c6..d86e072 100644 --- a/src/main/java/com/simtechdata/database/SQLite.java +++ b/src/main/java/com/simtechdata/database/SQLite.java @@ -52,6 +52,21 @@ public static Connection getBrowserConnection() { return null; } + private static void checkBrowserFiles() { + browserHistoryFileExists = browserHistoryFile.exists(); + historyCopyExists = browserHistoryCopy.exists(); + if (!browserHistoryFileExists) { + System.out.println(STR."Could not find Browser history file. The assumed path is:\{NL}\{browserHistoryFile.getAbsolutePath()}\{NL}"); + System.out.println("Run iget with the checkBrowser option"); + System.exit(1); + } + System.out.println("*".repeat(40)); + System.out.println(browserHistoryCopy.getAbsolutePath()); + System.out.println(browserHistoryFile.getAbsolutePath()); + System.out.println("*".repeat(40)); + copyHistoryFile(); + } + private static void copyHistoryFile() { /** * To help reduce writes on SSD / NVMe drives, we only make a backup copy of @@ -77,19 +92,6 @@ private static void copyHistoryFile() { } } - private static void checkBrowserFiles() { - browserHistoryFileExists = browserHistoryFile.exists(); - historyCopyExists = browserHistoryCopy.exists(); - if (!browserHistoryFileExists) { - System.out.println(STR."Could not find Browser history file. The assumed path is:\{NL}\{browserHistoryFile.getAbsolutePath()}\{NL}"); - System.out.println("Run iget with the checkBrowser option"); - System.exit(1); - } - if (!historyCopyExists) { - copyHistoryFile(); - } - } - public static void checkBrowser() { browserHistoryFileExists = browserHistoryFile.exists(); String filename = FilenameUtils.getName(browserHistoryFile.getAbsolutePath()); diff --git a/src/main/java/com/simtechdata/database/TimeUtil.java b/src/main/java/com/simtechdata/database/TimeUtil.java index 1e21b18..ca81395 100644 --- a/src/main/java/com/simtechdata/database/TimeUtil.java +++ b/src/main/java/com/simtechdata/database/TimeUtil.java @@ -1,9 +1,8 @@ package com.simtechdata.database; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZoneOffset; +import com.simtechdata.enums.Browser; + +import java.time.*; import java.time.format.DateTimeFormatter; public class TimeUtil { @@ -11,10 +10,29 @@ public class TimeUtil { private static final long WEBKIT_EPOCH_START = 11644473600000000L; public static String toMonthDayYear(long webkitTimestamp) { - long epochMilli = (webkitTimestamp - WEBKIT_EPOCH_START) / 1000; - LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMilli), ZoneId.systemDefault()); + Browser browser = Browser.getBrowser(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yy"); - return dateTime.format(formatter); + switch (browser) { + case FIREFOX -> { + Instant firefoxInstant = Instant.ofEpochMilli(webkitTimestamp / 1000); + LocalDate firefoxDate = firefoxInstant.atZone(ZoneId.systemDefault()).toLocalDate(); + return formatter.format(firefoxDate); + } + + case SAFARI -> { + long secondsFrom1970To2001 = 978307200; // Seconds from Jan 1, 1970 to Jan 1, 2001 + Instant safariInstant = Instant.ofEpochSecond(webkitTimestamp + secondsFrom1970To2001); + LocalDate safariDate = safariInstant.atZone(ZoneId.systemDefault()).toLocalDate(); + return formatter.format(safariDate); + } + + default -> { + long offsetBetweenEpochs = 11644473600000L; // milliseconds from Jan 1, 1601 to Jan 1, 1970 + Instant chromeInstant = Instant.ofEpochMilli((webkitTimestamp / 1000) - offsetBetweenEpochs); + LocalDate chromeDate = chromeInstant.atZone(ZoneId.systemDefault()).toLocalDate(); + return formatter.format(chromeDate); + } + } } public static long toWebKitTime(long epochTime) { @@ -27,15 +45,4 @@ public static String toShortTime(long webkitTimestamp) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yy hh:mm:ss a"); return dateTime.format(formatter); } - - public static long convertToWebKitTimestamp(LocalDateTime dateTime) { - long epochMilli = dateTime.toInstant(ZoneOffset.UTC).toEpochMilli(); - return epochMilli * 1000 + WEBKIT_EPOCH_START; - } - - public static long getTimestampWithOffset(long hours, boolean all) { - LocalDateTime localDateTime = LocalDateTime.now(ZoneOffset.UTC); - LocalDateTime pastTime = all ? localDateTime.minusYears(30) : localDateTime.minusHours(hours); - return convertToWebKitTimestamp(pastTime); - } }