From 692dcaa9906a34b0a51dc57fdd77269231cfaec6 Mon Sep 17 00:00:00 2001 From: Kevin Jiang Date: Sat, 14 Apr 2018 17:45:56 -0400 Subject: [PATCH 01/40] Travis CL test because I'm too lazy to run it on my own computer TEST --- .../ripper/rippers/DeviantartRipper.java | 47 ++++++++++++++----- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java index 4461188e..225c9c23 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java @@ -1,5 +1,9 @@ package com.rarchives.ripme.ripper.rippers; +import com.rarchives.ripme.ripper.AbstractHTMLRipper; +import com.rarchives.ripme.utils.Base64; +import com.rarchives.ripme.utils.Http; +import com.rarchives.ripme.utils.Utils; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; @@ -13,7 +17,6 @@ import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.jsoup.Connection.Method; import org.jsoup.Connection.Response; import org.jsoup.Jsoup; @@ -22,11 +25,6 @@ import org.jsoup.nodes.Element; import org.jsoup.safety.Whitelist; import org.jsoup.select.Elements; -import com.rarchives.ripme.ripper.AbstractHTMLRipper; -import com.rarchives.ripme.utils.Base64; -import com.rarchives.ripme.utils.Http; -import com.rarchives.ripme.utils.Utils; - public class DeviantartRipper extends AbstractHTMLRipper { private static final int PAGE_SLEEP_TIME = 3000, @@ -108,19 +106,46 @@ public class DeviantartRipper extends AbstractHTMLRipper { throw new MalformedURLException("Expected URL format: http://username.deviantart.com/[/gallery/#####], got: " + url); } + /** + * Gets first page. + * Will determine if login is supplied, + * if there is a login, then login and add that login cookies. + * Otherwise, just bypass the age gate with an anonymous flag. + * @return + * @throws IOException + */ @Override public Document getFirstPage() throws IOException { - // Login - try { - cookies = loginToDeviantart(); - } catch (Exception e) { - logger.warn("Failed to login: ", e); + + //Test to see if there is a login: + String username = Utils.getConfigString("deviantart.username", new String(Base64.decode("Z3JhYnB5"))); + String password = Utils.getConfigString("deviantart.password", new String(Base64.decode("ZmFrZXJz"))); + + if(username == null || password == null) { + logger.debug("No DeviantArt login provided."); cookies.put("agegate_state","1"); // Bypasses the age gate + } else { + // Attempt Login + try { + cookies = loginToDeviantart(); + } catch (Exception e) { + logger.warn("Failed to login: ", e); + cookies.put("agegate_state","1"); // Bypasses the age gate + } } + + return Http.url(this.url) .cookies(cookies) .get(); } + + /** + * + * @param page + * @param id + * @return + */ private String jsonToImage(Document page, String id) { Elements js = page.select("script[type=\"text/javascript\"]"); for (Element tag : js) { From 264980ad94a526ac7399cfe86af4831c93db11f2 Mon Sep 17 00:00:00 2001 From: Kevin Jiang Date: Sat, 14 Apr 2018 17:55:45 -0400 Subject: [PATCH 02/40] More specific Exception name IOException > Exception --- .../com/rarchives/ripme/ripper/rippers/DeviantartRipper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java index 225c9c23..8ecb8086 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java @@ -128,7 +128,7 @@ public class DeviantartRipper extends AbstractHTMLRipper { // Attempt Login try { cookies = loginToDeviantart(); - } catch (Exception e) { + } catch (IOException e) { logger.warn("Failed to login: ", e); cookies.put("agegate_state","1"); // Bypasses the age gate } From fbde7b9f97450a60a8a9ad489b76b9914877039a Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 10 May 2018 06:40:29 -0400 Subject: [PATCH 03/40] Fixed instagram ripper regex --- .../com/rarchives/ripme/ripper/rippers/InstagramRipper.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/InstagramRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/InstagramRipper.java index 9c233b0d..efc4cb40 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/InstagramRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/InstagramRipper.java @@ -435,6 +435,12 @@ public class InstagramRipper extends AbstractHTMLRipper { if (m.find()) { return m.group(1); } + jsP = Pattern.compile("n.pagination:n},queryId:.([a-zA-Z0-9]+)."); + m = jsP.matcher(sb.toString()); + if (m.find()) { + return m.group(1); + } + } else { Pattern jsP = Pattern.compile("return e.tagMedia.byTagName.get\\(t\\).pagination},queryId:.([a-zA-Z0-9]+)."); Matcher m = jsP.matcher(sb.toString()); From 19e4a95c964a7dd0ac3cd42d50d72aa55c0083f8 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 10 May 2018 07:30:05 -0400 Subject: [PATCH 04/40] 1.7.44: Fixed instagram ripper regex --- pom.xml | 2 +- ripme.json | 3 ++- src/main/java/com/rarchives/ripme/ui/UpdateUtils.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 8566f2d6..0796e60f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rarchives.ripme ripme jar - 1.7.43 + 1.7.44 ripme http://rip.rarchives.com diff --git a/ripme.json b/ripme.json index 6c4f3fc0..757058ae 100644 --- a/ripme.json +++ b/ripme.json @@ -1,6 +1,7 @@ { - "latestVersion": "1.7.43", + "latestVersion": "1.7.44", "changeList": [ + "1.7.44: Fixed instagram ripper regex", "1.7.43: Fixed queryId regex in instagram ripper", "1.7.42: Added user support to SmuttyRipper; Removed vine ripper; Fixed NudeGalsRipper; addURLToDownload improvments; Fixed Instagram ripper", "1.7.41: Added support for spyingwithlana.com; Added ManganeloRipper; Added support for dynasty-scans.com", diff --git a/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java b/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java index 4284eacc..11d18771 100644 --- a/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java +++ b/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java @@ -21,7 +21,7 @@ import com.rarchives.ripme.utils.Utils; public class UpdateUtils { private static final Logger logger = Logger.getLogger(UpdateUtils.class); - private static final String DEFAULT_VERSION = "1.7.43"; + private static final String DEFAULT_VERSION = "1.7.44"; private static final String REPO_NAME = "ripmeapp/ripme"; private static final String updateJsonURL = "https://raw.githubusercontent.com/" + REPO_NAME + "/master/ripme.json"; private static final String mainFileName = "ripme.jar"; From bba39a5337de39f14cff1923a2886ab753f2a4a1 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 10 May 2018 12:42:15 -0400 Subject: [PATCH 05/40] Added getResourceBundle func --- .../java/com/rarchives/ripme/utils/Utils.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/utils/Utils.java b/src/main/java/com/rarchives/ripme/utils/Utils.java index 9517c528..156c6ac0 100644 --- a/src/main/java/com/rarchives/ripme/utils/Utils.java +++ b/src/main/java/com/rarchives/ripme/utils/Utils.java @@ -1,9 +1,6 @@ package com.rarchives.ripme.utils; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.lang.reflect.Constructor; import java.net.URISyntaxException; import java.net.URL; @@ -579,4 +576,14 @@ public class Utils { } return domainCookies; } + + public static ResourceBundle getResourceBundle() { + try { + ResourceBundle rb = ResourceBundle.getBundle("LabelsBundle", Locale.getDefault()); + return rb; + } catch (MissingResourceException e) { + ResourceBundle rb = ResourceBundle.getBundle("LabelsBundle", Locale.ROOT); + return rb; + } + } } From c51710b8335d4a14f6ec6d379b1d461ef60a0b33 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 10 May 2018 12:43:01 -0400 Subject: [PATCH 06/40] Started using resourceBUndle --- .../com/rarchives/ripme/ui/MainWindow.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ui/MainWindow.java b/src/main/java/com/rarchives/ripme/ui/MainWindow.java index 016d25f3..f76964bf 100644 --- a/src/main/java/com/rarchives/ripme/ui/MainWindow.java +++ b/src/main/java/com/rarchives/ripme/ui/MainWindow.java @@ -16,9 +16,7 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collections; -import java.util.Date; -import java.util.Enumeration; +import java.util.*; import java.util.List; import javax.imageio.ImageIO; @@ -138,6 +136,8 @@ public final class MainWindow implements Runnable, RipStatusHandler { private static AbstractRipper ripper; + private ResourceBundle rb = Utils.getResourceBundle(); + private static void addCheckboxListener(JCheckBox checkBox, String configString) { checkBox.addActionListener(arg0 -> { Utils.setConfigBoolean(configString, checkBox.isSelected()); @@ -462,17 +462,17 @@ public final class MainWindow implements Runnable, RipStatusHandler { configUpdateButton = new JButton("Check for updates"); configUpdateLabel = new JLabel("Current version: " + UpdateUtils.getThisJarVersion(), JLabel.RIGHT); JLabel configThreadsLabel = new JLabel("Maximum download threads:", JLabel.RIGHT); - JLabel configTimeoutLabel = new JLabel("Timeout (in milliseconds):", JLabel.RIGHT); - JLabel configRetriesLabel = new JLabel("Retry download count:", JLabel.RIGHT); + JLabel configTimeoutLabel = new JLabel(rb.getString("timeout.mill"), JLabel.RIGHT); + JLabel configRetriesLabel = new JLabel(rb.getString("retry.download.count"), JLabel.RIGHT); configThreadsText = new JTextField(Integer.toString(Utils.getConfigInteger("threads.size", 3))); configTimeoutText = new JTextField(Integer.toString(Utils.getConfigInteger("download.timeout", 60000))); configRetriesText = new JTextField(Integer.toString(Utils.getConfigInteger("download.retries", 3))); - configOverwriteCheckbox = addNewCheckbox("Overwrite existing files?", "file.overwrite", false); - configAutoupdateCheckbox = addNewCheckbox("Auto-update?", "auto.update", true); - configPlaySound = addNewCheckbox("Sound when rip completes", "play.sound", false); + configOverwriteCheckbox = addNewCheckbox(rb.getString("overwrite.existing.files"), "file.overwrite", false); + configAutoupdateCheckbox = addNewCheckbox(rb.getString("auto.update"), "auto.update", true); + configPlaySound = addNewCheckbox(rb.getString("sound.when.rip.completes"), "play.sound", false); configShowPopup = addNewCheckbox("Notification when rip starts", "download.show_popup", false); - configSaveOrderCheckbox = addNewCheckbox("Preserve order", "download.save_order", true); - configSaveLogs = addNewCheckbox("Save logs", "log.save", false); + configSaveOrderCheckbox = addNewCheckbox(rb.getString("preserve.order"), "download.save_order", true); + configSaveLogs = addNewCheckbox(rb.getString("save.logs"), "log.save", false); configSaveURLsOnly = addNewCheckbox("Save URLs only", "urls_only.save", false); configSaveAlbumTitles = addNewCheckbox("Save album titles", "album_titles.save", true); configClipboardAutorip = addNewCheckbox("Autorip from Clipboard", "clipboard.autorip", false); From fe503e71b89b19929e21f53f90f69aad8311a039 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 10 May 2018 12:44:18 -0400 Subject: [PATCH 07/40] Started building ResourceBundle --- src/main/resources/LabelsBundle.properties | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/resources/LabelsBundle.properties diff --git a/src/main/resources/LabelsBundle.properties b/src/main/resources/LabelsBundle.properties new file mode 100644 index 00000000..ba884030 --- /dev/null +++ b/src/main/resources/LabelsBundle.properties @@ -0,0 +1,18 @@ +Log = Log +History = History +created = created +modified = modified +Queue = Queue +Configuration = Configuration + +# Keys for the Configuration menu + +current.version = Current version: +auto.update = Auto-update? +max.download.threads = Maximum download threads +timeout.mill = Timeout (in milliseconds): +retry.download.count = Retry download count +overwrite.existing.files = Overwrite existing files? +sound.when.rip.completes = Sound when rip completes +preserve.order = Preserve order +save.logs = Save logs \ No newline at end of file From c4ce162b481440825ffcf662207e499ce9cf59dd Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 10 May 2018 13:22:27 -0400 Subject: [PATCH 08/40] Extended RB --- src/main/resources/LabelsBundle.properties | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/resources/LabelsBundle.properties b/src/main/resources/LabelsBundle.properties index ba884030..3a42ab0c 100644 --- a/src/main/resources/LabelsBundle.properties +++ b/src/main/resources/LabelsBundle.properties @@ -7,7 +7,8 @@ Configuration = Configuration # Keys for the Configuration menu -current.version = Current version: +current.version = Current version +check.for.updates = Check for updates auto.update = Auto-update? max.download.threads = Maximum download threads timeout.mill = Timeout (in milliseconds): @@ -15,4 +16,22 @@ retry.download.count = Retry download count overwrite.existing.files = Overwrite existing files? sound.when.rip.completes = Sound when rip completes preserve.order = Preserve order -save.logs = Save logs \ No newline at end of file +save.logs = Save logs +notification.when.rip.starts = Notification when rip starts +save.urls.only = Save URLs only +save.album.titles = Save album titles +autorip.from.clipboard = Autorip from Clipboard +save.descriptions = Save descriptions +prefer.mp4.over.gif = Prefer MP4 over GIF +restore.window.position = Restore window position +remember.url.history = Remember URL history +loading.history.from = Loading history from + +# Misc UI keys + +loading.history.from.configuration = Loading history from configuration +interrupted.while.waiting.to.rip.next.album = Interrupted while waiting to rip next album +inactive = Inactive +re-rip.checked = Re-rip Checked +remove = Remove +clear = Clear \ No newline at end of file From dc9f7ea33ee72c3fcf4cdef6114e39fedaea5fa5 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Thu, 10 May 2018 13:24:14 -0400 Subject: [PATCH 09/40] Now using RB for more UI elements --- .../com/rarchives/ripme/ui/MainWindow.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ui/MainWindow.java b/src/main/java/com/rarchives/ripme/ui/MainWindow.java index f76964bf..f360351a 100644 --- a/src/main/java/com/rarchives/ripme/ui/MainWindow.java +++ b/src/main/java/com/rarchives/ripme/ui/MainWindow.java @@ -289,7 +289,7 @@ public final class MainWindow implements Runnable, RipStatusHandler { gbc.gridx = 3; ripPanel.add(stopButton, gbc); gbc.weightx = 1; - statusLabel = new JLabel("Inactive"); + statusLabel = new JLabel(rb.getString("inactive")); statusLabel.setHorizontalAlignment(JLabel.CENTER); openButton = new JButton(); openButton.setVisible(false); @@ -402,9 +402,9 @@ public final class MainWindow implements Runnable, RipStatusHandler { historyTable.getColumnModel().getColumn(i).setPreferredWidth(width); } JScrollPane historyTableScrollPane = new JScrollPane(historyTable); - historyButtonRemove = new JButton("Remove"); - historyButtonClear = new JButton("Clear"); - historyButtonRerip = new JButton("Re-rip Checked"); + historyButtonRemove = new JButton(rb.getString("remove")); + historyButtonClear = new JButton(rb.getString("clear")); + historyButtonRerip = new JButton(rb.getString("re-rip.checked")); gbc.gridx = 0; // History List Panel JPanel historyTablePanel = new JPanel(new GridBagLayout()); @@ -459,9 +459,9 @@ public final class MainWindow implements Runnable, RipStatusHandler { configurationPanel.setBorder(emptyBorder); configurationPanel.setVisible(false); // TODO Configuration components - configUpdateButton = new JButton("Check for updates"); - configUpdateLabel = new JLabel("Current version: " + UpdateUtils.getThisJarVersion(), JLabel.RIGHT); - JLabel configThreadsLabel = new JLabel("Maximum download threads:", JLabel.RIGHT); + configUpdateButton = new JButton(rb.getString("check.for.updates")); + configUpdateLabel = new JLabel( rb.getString("current.version") + ": " + UpdateUtils.getThisJarVersion(), JLabel.RIGHT); + JLabel configThreadsLabel = new JLabel(rb.getString("max.download.threads") + ":", JLabel.RIGHT); JLabel configTimeoutLabel = new JLabel(rb.getString("timeout.mill"), JLabel.RIGHT); JLabel configRetriesLabel = new JLabel(rb.getString("retry.download.count"), JLabel.RIGHT); configThreadsText = new JTextField(Integer.toString(Utils.getConfigInteger("threads.size", 3))); @@ -470,16 +470,16 @@ public final class MainWindow implements Runnable, RipStatusHandler { configOverwriteCheckbox = addNewCheckbox(rb.getString("overwrite.existing.files"), "file.overwrite", false); configAutoupdateCheckbox = addNewCheckbox(rb.getString("auto.update"), "auto.update", true); configPlaySound = addNewCheckbox(rb.getString("sound.when.rip.completes"), "play.sound", false); - configShowPopup = addNewCheckbox("Notification when rip starts", "download.show_popup", false); + configShowPopup = addNewCheckbox(rb.getString("notification.when.rip.starts"), "download.show_popup", false); configSaveOrderCheckbox = addNewCheckbox(rb.getString("preserve.order"), "download.save_order", true); configSaveLogs = addNewCheckbox(rb.getString("save.logs"), "log.save", false); - configSaveURLsOnly = addNewCheckbox("Save URLs only", "urls_only.save", false); - configSaveAlbumTitles = addNewCheckbox("Save album titles", "album_titles.save", true); - configClipboardAutorip = addNewCheckbox("Autorip from Clipboard", "clipboard.autorip", false); - configSaveDescriptions = addNewCheckbox("Save descriptions", "descriptions.save", true); - configPreferMp4 = addNewCheckbox("Prefer MP4 over GIF","prefer.mp4", false); - configWindowPosition = addNewCheckbox("Restore window position", "window.position", true); - configURLHistoryCheckbox = addNewCheckbox("Remember URL history", "remember.url_history", true); + configSaveURLsOnly = addNewCheckbox(rb.getString("save.urls.only"), "urls_only.save", false); + configSaveAlbumTitles = addNewCheckbox(rb.getString("save.album.titles"), "album_titles.save", true); + configClipboardAutorip = addNewCheckbox(rb.getString("autorip.from.clipboard"), "clipboard.autorip", false); + configSaveDescriptions = addNewCheckbox(rb.getString("save.descriptions"), "descriptions.save", true); + configPreferMp4 = addNewCheckbox(rb.getString("prefer.mp4.over.gif"),"prefer.mp4", false); + configWindowPosition = addNewCheckbox(rb.getString("restore.window.position"), "window.position", true); + configURLHistoryCheckbox = addNewCheckbox(rb.getString("remember.url.history"), "remember.url_history", true); configLogLevelCombobox = new JComboBox(new String[] {"Log level: Error", "Log level: Warn", "Log level: Info", "Log level: Debug"}); configLogLevelCombobox.setSelectedItem(Utils.getConfigString("log.level", "Log level: Debug")); @@ -966,7 +966,7 @@ public final class MainWindow implements Runnable, RipStatusHandler { HISTORY.clear(); if (historyFile.exists()) { try { - logger.info("Loading history from " + historyFile.getCanonicalPath()); + logger.info(rb.getString("loading.history.from") + " " + historyFile.getCanonicalPath()); HISTORY.fromFile(historyFile.getCanonicalPath()); } catch (IOException e) { logger.error("Failed to load history from file " + historyFile, e); @@ -979,7 +979,7 @@ public final class MainWindow implements Runnable, RipStatusHandler { JOptionPane.ERROR_MESSAGE); } } else { - logger.info("Loading history from configuration"); + logger.info(rb.getString("loading.history.from.configuration")); HISTORY.fromList(Utils.getConfigList("download.history")); if (HISTORY.toList().size() == 0) { // Loaded from config, still no entries. @@ -1035,7 +1035,7 @@ public final class MainWindow implements Runnable, RipStatusHandler { try { Thread.sleep(500); } catch (InterruptedException ie) { - logger.error("Interrupted while waiting to rip next album", ie); + logger.error(rb.getString("interrupted.while.waiting.to.rip.next.album"), ie); } ripNextAlbum(); } else { From 1c38a86d3d6fae4a4957c632e83e260120f386da Mon Sep 17 00:00:00 2001 From: Kevin Jiang Date: Fri, 11 May 2018 21:52:01 -0400 Subject: [PATCH 10/40] ImageBam album fixed, more Documentation Slightly fixed it, but don't know CSS so it's kinda a bootleg approach, but it works extremely well. Added bits of documentation here and there, and changed .size() == 0 to .isEmpty() for more readability. --- .../ripme/ripper/rippers/ImagebamRipper.java | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/ImagebamRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/ImagebamRipper.java index 323ad1de..b5fca14f 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/ImagebamRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/ImagebamRipper.java @@ -1,5 +1,9 @@ package com.rarchives.ripme.ripper.rippers; +import com.rarchives.ripme.ripper.AbstractHTMLRipper; +import com.rarchives.ripme.ripper.DownloadThreadPool; +import com.rarchives.ripme.utils.Http; +import com.rarchives.ripme.utils.Utils; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; @@ -7,16 +11,10 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; -import com.rarchives.ripme.ripper.AbstractHTMLRipper; -import com.rarchives.ripme.ripper.DownloadThreadPool; -import com.rarchives.ripme.utils.Http; -import com.rarchives.ripme.utils.Utils; - public class ImagebamRipper extends AbstractHTMLRipper { // Current HTML document @@ -71,7 +69,7 @@ public class ImagebamRipper extends AbstractHTMLRipper { public Document getNextPage(Document doc) throws IOException { // Find next page Elements hrefs = doc.select("a.pagination_current + a.pagination_link"); - if (hrefs.size() == 0) { + if (hrefs.isEmpty()) { throw new IOException("No more pages"); } String nextUrl = "http://www.imagebam.com" + hrefs.first().attr("href"); @@ -121,8 +119,8 @@ public class ImagebamRipper extends AbstractHTMLRipper { * Handles case when site has IP-banned the user. */ private class ImagebamImageThread extends Thread { - private URL url; - private int index; + private URL url; //link to "image page" + private int index; //index in album ImagebamImageThread(URL url, int index) { super(); @@ -134,24 +132,39 @@ public class ImagebamRipper extends AbstractHTMLRipper { public void run() { fetchImage(); } - + + /** + * Rips useful image from "image page" + */ private void fetchImage() { try { Document doc = Http.url(url).get(); // Find image - Elements images = doc.select(".image-container img"); - if (images.size() == 0) { + Elements metaTags = doc.getElementsByTag("meta"); + + String imgsrc = "";//initialize, so no NullPointerExceptions should ever happen. + + for (Element metaTag: metaTags) { + //the direct link to the image seems to always be linked in the part of the html. + if(metaTag.attr("property").equals("og:image")) { + imgsrc = metaTag.attr("content"); + logger.info("Found URL " + imgsrc); + break;//only one (useful) image possible for an "image page". + } + } + + //for debug, or something goes wrong. + if (imgsrc.isEmpty()) { logger.warn("Image not found at " + this.url); return; } - Element image = images.first(); - String imgsrc = image.attr("src"); - logger.info("Found URL " + imgsrc); + // Provide prefix and let the AbstractRipper "guess" the filename String prefix = ""; if (Utils.getConfigBoolean("download.save_order", true)) { prefix = String.format("%03d_", index); } + addURLToDownload(new URL(imgsrc), prefix); } catch (IOException e) { logger.error("[!] Exception while loading/parsing " + this.url, e); From 03963eac55e22b05f2af538232c169a05b50789b Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Fri, 11 May 2018 23:56:02 -0400 Subject: [PATCH 11/40] Fixed hentai2read ripper --- .../ripper/rippers/Hentai2readRipper.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java index 405d0563..a87575bd 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java @@ -44,20 +44,15 @@ public class Hentai2readRipper extends AbstractHTMLRipper { @Override public Document getFirstPage() throws IOException { - Document tempDoc; - // get the first page of the comic - if (url.toExternalForm().substring(url.toExternalForm().length() - 1).equals("/")) { - tempDoc = Http.url(url + "1").get(); - } else { - tempDoc = Http.url(url + "/1").get(); + try { + Document tempDoc; + tempDoc = Http.url(url).get(); + // Get the thumbnail page so we can rip all images without loading every page in the comic + String thumbnailLink = tempDoc.select("a[data-original-title=Thumbnails").attr("href"); + return Http.url(thumbnailLink).get(); + } catch (IOException e) { + throw new IOException("Unable to get first page"); } - for (Element el : tempDoc.select("ul.nav > li > a")) { - if (el.attr("href").startsWith("https://hentai2read.com/thumbnails/")) { - // Get the page with the thumbnails - return Http.url(el.attr("href")).get(); - } - } - throw new IOException("Unable to get first page"); } @Override From 608c825ccab16bf7d5183157a5bf8813498e1f3c Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sat, 12 May 2018 00:17:02 -0400 Subject: [PATCH 12/40] TsuminoRipper no longer requires album name to download --- .../com/rarchives/ripme/ripper/rippers/TsuminoRipper.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/TsuminoRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/TsuminoRipper.java index 7d35fc1d..70c023d3 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/TsuminoRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/TsuminoRipper.java @@ -59,11 +59,16 @@ public class TsuminoRipper extends AbstractHTMLRipper { @Override public String getGID(URL url) throws MalformedURLException { - Pattern p = Pattern.compile("https?://www.tsumino.com/Book/Info/([0-9]+)/([a-zA-Z0-9_-]*)"); + Pattern p = Pattern.compile("https?://www.tsumino.com/Book/Info/([0-9]+)/([a-zA-Z0-9_-]*)/?"); Matcher m = p.matcher(url.toExternalForm()); if (m.matches()) { return m.group(1) + "_" + m.group(2); } + p = Pattern.compile("https?://www.tsumino.com/Book/Info/([0-9]+)/?"); + m = p.matcher(url.toExternalForm()); + if (m.matches()) { + return m.group(1); + } throw new MalformedURLException("Expected tsumino URL format: " + "tsumino.com/Book/Info/ID/TITLE - got " + url + " instead"); } From 4a160deaa5ffaf4247b07845fb1ef7fc4ac69135 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sat, 12 May 2018 03:00:25 -0400 Subject: [PATCH 13/40] Now uses translation for more strings --- .../com/rarchives/ripme/ui/MainWindow.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ui/MainWindow.java b/src/main/java/com/rarchives/ripme/ui/MainWindow.java index f360351a..95961f44 100644 --- a/src/main/java/com/rarchives/ripme/ui/MainWindow.java +++ b/src/main/java/com/rarchives/ripme/ui/MainWindow.java @@ -138,6 +138,15 @@ public final class MainWindow implements Runnable, RipStatusHandler { private ResourceBundle rb = Utils.getResourceBundle(); + private void updateQueueLabel() { + if (queueListModel.size() > 0) { + optionQueue.setText( rb.getString("Queue") + " (" + queueListModel.size() + ")"); + } else { + optionQueue.setText(rb.getString("Queue")); + } + } + + private static void addCheckboxListener(JCheckBox checkBox, String configString) { checkBox.addActionListener(arg0 -> { Utils.setConfigBoolean(configString, checkBox.isSelected()); @@ -307,10 +316,10 @@ public final class MainWindow implements Runnable, RipStatusHandler { JPanel optionsPanel = new JPanel(new GridBagLayout()); optionsPanel.setBorder(emptyBorder); - optionLog = new JButton("Log"); - optionHistory = new JButton("History"); - optionQueue = new JButton("Queue"); - optionConfiguration = new JButton("Configuration"); + optionLog = new JButton(rb.getString("Log")); + optionHistory = new JButton(rb.getString("History")); + optionQueue = new JButton(rb.getString("Queue")); + optionConfiguration = new JButton(rb.getString("Configuration")); optionLog.setFont(optionLog.getFont().deriveFont(Font.PLAIN)); optionHistory.setFont(optionLog.getFont().deriveFont(Font.PLAIN)); optionQueue.setFont(optionLog.getFont().deriveFont(Font.PLAIN)); @@ -440,11 +449,7 @@ public final class MainWindow implements Runnable, RipStatusHandler { for (String item : Utils.getConfigList("queue")) { queueListModel.addElement(item); } - if (queueListModel.size() > 0) { - optionQueue.setText("Queue (" + queueListModel.size() + ")"); - } else { - optionQueue.setText("Queue"); - } + updateQueueLabel(); gbc.gridx = 0; JPanel queueListPanel = new JPanel(new GridBagLayout()); gbc.fill = GridBagConstraints.BOTH; @@ -785,11 +790,7 @@ public final class MainWindow implements Runnable, RipStatusHandler { queueListModel.addListDataListener(new ListDataListener() { @Override public void intervalAdded(ListDataEvent arg0) { - if (queueListModel.size() > 0) { - optionQueue.setText("Queue (" + queueListModel.size() + ")"); - } else { - optionQueue.setText("Queue"); - } + updateQueueLabel(); if (!isRipping) { ripNextAlbum(); } @@ -1025,11 +1026,7 @@ public final class MainWindow implements Runnable, RipStatusHandler { return; } String nextAlbum = (String) queueListModel.remove(0); - if (queueListModel.isEmpty()) { - optionQueue.setText("Queue"); - } else { - optionQueue.setText("Queue (" + queueListModel.size() + ")"); - } + updateQueueLabel(); Thread t = ripAlbum(nextAlbum); if (t == null) { try { From c1dfb1e5d8f9028e52b7c3d8d44fda4d7d455eef Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sat, 12 May 2018 03:01:01 -0400 Subject: [PATCH 14/40] Added spainish UI translation --- .../resources/LabelsBundle_es_ES.properties | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/resources/LabelsBundle_es_ES.properties diff --git a/src/main/resources/LabelsBundle_es_ES.properties b/src/main/resources/LabelsBundle_es_ES.properties new file mode 100644 index 00000000..a1aa5a4a --- /dev/null +++ b/src/main/resources/LabelsBundle_es_ES.properties @@ -0,0 +1,37 @@ +Log = Log +History = Historia +created = creado +modified = modificado +Queue = Cola +Configuration = Configuracion + +# Keys for the Configuration menu + +current.version = Version Actual +check.for.updates = Buscar actualizaciones +auto.update = Auto-actualizar? +max.download.threads = Maximos procesos de descarga +timeout.mill = Timeout (in milliseconds): +retry.download.count = Numero de reintentos de descarga +overwrite.existing.files = Sobreescribir archivos existentes? +sound.when.rip.completes = Sonar cuando el Rip termina +preserve.order = Mantener orden +save.logs = Guardar logs +notification.when.rip.starts = Notificar cuando el Rip comienza +save.urls.only = Guardar solamente URLs +save.album.titles = Guardar titulos de albunes +autorip.from.clipboard = Autorip desde Portapapeles +save.descriptions = Guardar descripciones +prefer.mp4.over.gif = Preferir MP4 sobre GIF +restore.window.position = Restaurar posicion de ventana +remember.url.history = Recordar historia URL +loading.history.from = Cargando historia desde + +# Misc UI keys + +loading.history.from.configuration = Cargando historia desde la configuracion +interrupted.while.waiting.to.rip.next.album = Interrumpido esperando el Rip del proximo album +inactive = Inactivo +re-rip.checked = Re-rip marcado +remove = Quitar +clear = Limpiar \ No newline at end of file From 89119d48f916f41ed8e87b6a0f0570445c40ea40 Mon Sep 17 00:00:00 2001 From: TheRec Date: Sat, 12 May 2018 13:00:54 +0200 Subject: [PATCH 15/40] Added French (Switzerland) translation. --- .../resources/LabelsBundle_fr_CH.properties | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/resources/LabelsBundle_fr_CH.properties diff --git a/src/main/resources/LabelsBundle_fr_CH.properties b/src/main/resources/LabelsBundle_fr_CH.properties new file mode 100644 index 00000000..2b568891 --- /dev/null +++ b/src/main/resources/LabelsBundle_fr_CH.properties @@ -0,0 +1,37 @@ +Log = Journal +History = Historique +created = créé le +modified = modifié le +Queue = File d'attente +Configuration = Configuration + +# Keys for the Configuration menu + +current.version = Version actuelle +check.for.updates = Vérifier mises à jour +auto.update = Mises à jour automatiques? +max.download.threads = Maximum download threads +timeout.mill = Délai d'expiration (en millisecondes): +retry.download.count = Nombre d'essais téléchargement +overwrite.existing.files = Remplacer fichiers existants ? +sound.when.rip.completes = Son lorsque le rip est terminé +preserve.order = Conserver l'ordre +save.logs = Enregistrer journaux +notification.when.rip.starts = Notification lorsqu'un rip commence +save.urls.only = Enregistrer URL uniquement +save.album.titles = Enregistrer titres d'album +autorip.from.clipboard = Autorip depuis presse-papier +save.descriptions = Enregistrer descriptions +prefer.mp4.over.gif = Préférer MP4 à GIF +restore.window.position = Restaurer la position de la fenêtre +remember.url.history = Se souvenir de l'historique des URL +loading.history.from = Charger l'historique depuis + +# Misc UI keys + +loading.history.from.configuration = Charger l'historique depuis la configuration +interrupted.while.waiting.to.rip.next.album = Interrompu lors de l'attente pour ripper le prochain album +inactive = Inactif +re-rip.checked = Re-rip vérifié +remove = Enlever +clear = Effacer \ No newline at end of file From 3061125b5ba4fd2954d91da0abfa81a7add0ec27 Mon Sep 17 00:00:00 2001 From: TheRec Date: Sat, 12 May 2018 13:10:47 +0200 Subject: [PATCH 16/40] Added missing translation to French (Switzerland) --- src/main/resources/LabelsBundle_fr_CH.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/LabelsBundle_fr_CH.properties b/src/main/resources/LabelsBundle_fr_CH.properties index 2b568891..e2cedff6 100644 --- a/src/main/resources/LabelsBundle_fr_CH.properties +++ b/src/main/resources/LabelsBundle_fr_CH.properties @@ -10,7 +10,7 @@ Configuration = Configuration current.version = Version actuelle check.for.updates = Vérifier mises à jour auto.update = Mises à jour automatiques? -max.download.threads = Maximum download threads +max.download.threads = Nombre de téléchargements parallèles maximum timeout.mill = Délai d'expiration (en millisecondes): retry.download.count = Nombre d'essais téléchargement overwrite.existing.files = Remplacer fichiers existants ? From def01bfb45fc47e94cdc95fe8ceb882c4f5454ec Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sat, 12 May 2018 10:49:31 -0400 Subject: [PATCH 17/40] Added German translation --- .../rarchives/ripme/utils/UTF8Control.java | 44 +++++++++++++++++++ .../java/com/rarchives/ripme/utils/Utils.java | 2 +- .../resources/LabelsBundle_de_DE.properties | 38 ++++++++++++++++ 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/rarchives/ripme/utils/UTF8Control.java create mode 100644 src/main/resources/LabelsBundle_de_DE.properties diff --git a/src/main/java/com/rarchives/ripme/utils/UTF8Control.java b/src/main/java/com/rarchives/ripme/utils/UTF8Control.java new file mode 100644 index 00000000..2441ed7c --- /dev/null +++ b/src/main/java/com/rarchives/ripme/utils/UTF8Control.java @@ -0,0 +1,44 @@ +package com.rarchives.ripme.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.Locale; +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; + +public class UTF8Control extends ResourceBundle.Control { + public ResourceBundle newBundle + (String baseName, Locale locale, String format, ClassLoader loader, boolean reload) + throws IllegalAccessException, InstantiationException, IOException + { + // The below is a copy of the default implementation. + String bundleName = toBundleName(baseName, locale); + String resourceName = toResourceName(bundleName, "properties"); + ResourceBundle bundle = null; + InputStream stream = null; + if (reload) { + URL url = loader.getResource(resourceName); + if (url != null) { + URLConnection connection = url.openConnection(); + if (connection != null) { + connection.setUseCaches(false); + stream = connection.getInputStream(); + } + } + } else { + stream = loader.getResourceAsStream(resourceName); + } + if (stream != null) { + try { + // Only this line is changed to make it to read properties files as UTF-8. + bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8")); + } finally { + stream.close(); + } + } + return bundle; + } +} \ No newline at end of file diff --git a/src/main/java/com/rarchives/ripme/utils/Utils.java b/src/main/java/com/rarchives/ripme/utils/Utils.java index 156c6ac0..e6617f46 100644 --- a/src/main/java/com/rarchives/ripme/utils/Utils.java +++ b/src/main/java/com/rarchives/ripme/utils/Utils.java @@ -579,7 +579,7 @@ public class Utils { public static ResourceBundle getResourceBundle() { try { - ResourceBundle rb = ResourceBundle.getBundle("LabelsBundle", Locale.getDefault()); + ResourceBundle rb = ResourceBundle.getBundle("LabelsBundle", Locale.getDefault(), new UTF8Control()); return rb; } catch (MissingResourceException e) { ResourceBundle rb = ResourceBundle.getBundle("LabelsBundle", Locale.ROOT); diff --git a/src/main/resources/LabelsBundle_de_DE.properties b/src/main/resources/LabelsBundle_de_DE.properties new file mode 100644 index 00000000..da1fc8e2 --- /dev/null +++ b/src/main/resources/LabelsBundle_de_DE.properties @@ -0,0 +1,38 @@ +Log = Log +History = Verlauf +created = erstellt +modified = geändert +Queue = Queue +Configuration = Konfiguration + +# Keys for the Configuration menu + +current.version = Aktuelle Version +check.for.updates = Suche nach Aktualisierungen +auto.update = Automatisch Aktualisieren? +max.download.threads = Maximum download threads +timeout.mill = Timeout (in milliseconds): +retry.download.count = Anzahl der Downloadversuche +overwrite.existing.files = Ãœberschreibe bereits existierende Dateien? +sound.when.rip.completes = Ton abspielen bei fertigem Download +preserve.order = Reihenfolge beibehalten +save.logs = Speichere Logs +notification.when.rip.starts = Benachrichtigung wenn Download startet +save.urls.only = Speicher nur URLs +save.album.titles = Speichere Albumtitels +autorip.from.clipboard = Automatisch Downloaden von der Zwischenablage +save.descriptions = Speichere Beschreibungen +prefer.mp4.over.gif = Bevorzuge MP4 über GIF +restore.window.position = Wieder herstellen der Fensterposition +remember.url.history = Erinnere URL Verlauf +loading.history.from = Lade Verlauf von + +# Misc UI keys + +loading.history.from.configuration = Lade Verlauf aus Konfiguration +interrupted.while.waiting.to.rip.next.album = Unterbrochen während Download des nächsten Albums +inactive = Inaktiv +re-rip.checked = Re-rip Ãœberprüft +remove = Entfernen +clear = Leeren + From 1fe3f10be72e85406ad7620591f43ce954d12b31 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sat, 12 May 2018 10:54:15 -0400 Subject: [PATCH 18/40] Added comment showing where the code is from --- src/main/java/com/rarchives/ripme/utils/UTF8Control.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/rarchives/ripme/utils/UTF8Control.java b/src/main/java/com/rarchives/ripme/utils/UTF8Control.java index 2441ed7c..6cd81bbb 100644 --- a/src/main/java/com/rarchives/ripme/utils/UTF8Control.java +++ b/src/main/java/com/rarchives/ripme/utils/UTF8Control.java @@ -9,6 +9,8 @@ import java.util.Locale; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; +// Code taken from https://stackoverflow.com/questions/4659929/how-to-use-utf-8-in-resource-properties-with-resourcebundle/4660195#4660195 + public class UTF8Control extends ResourceBundle.Control { public ResourceBundle newBundle (String baseName, Locale locale, String format, ClassLoader loader, boolean reload) From ee27d69280c14844cefbafe27616a8e6d1aa3948 Mon Sep 17 00:00:00 2001 From: Jason <37483675+jasonpw@users.noreply.github.com> Date: Sat, 12 May 2018 17:25:01 +0200 Subject: [PATCH 19/40] Portuguese from Portugal translation I decided to help with the portuguese translation, I hope it's just as accurate as the english version! --- .../resources/LabelsBundle_pt_PT.properties | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/resources/LabelsBundle_pt_PT.properties diff --git a/src/main/resources/LabelsBundle_pt_PT.properties b/src/main/resources/LabelsBundle_pt_PT.properties new file mode 100644 index 00000000..61581728 --- /dev/null +++ b/src/main/resources/LabelsBundle_pt_PT.properties @@ -0,0 +1,37 @@ +Log = Registo +History = Histórico +created = criado +modified = modificado +Queue = Fila +Configuration = Configuração + +# Keys for the Configuration menu + +current.version = Versão atual +check.for.updates = Verificar atualizações +auto.update = Atualização automática? +max.download.threads = Número máximo de processos de transferência +timeout.mill = Timeout (em milissegundos): +retry.download.count = Número de novas tentativas de transferência +overwrite.existing.files = Sobrescrever ficheiros existentes? +sound.when.rip.completes = Notificar quando o rip é concluído +preserve.order = Manter a ordem +save.logs = Guardar registos +notification.when.rip.starts = Notificar quando o rip começar +save.urls.only = Apenas guardar URLs +save.album.titles = Guardar os títulos de álbuns +autorip.from.clipboard = Autorip da área de transferência +save.descriptions = Guardar descrições +prefer.mp4.over.gif = Preferir MP4 a GIF +restore.window.position = Restaurar posição da janela +remember.url.history = Lembrar histórico de URL +loading.history.from = Carregar histórico de + +# Misc UI keys + +loading.history.from.configuration = A carregar o histórico da configuração +interrupted.while.waiting.to.rip.next.album = Interrompido durante a espera do rip do próximo álbum +inactive = Inativo +re-rip.checked = Re-rip verificado +remove = Remover +clear = Limpar From 14acc08aa188fb6b22e34855b52ca8be2eb58e2c Mon Sep 17 00:00:00 2001 From: TheRec Date: Sat, 12 May 2018 23:35:02 +0200 Subject: [PATCH 20/40] Converted French (Switzerland) translation from ANSI to UTF-8 --- .../resources/LabelsBundle_fr_CH.properties | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/resources/LabelsBundle_fr_CH.properties b/src/main/resources/LabelsBundle_fr_CH.properties index e2cedff6..1e23645b 100644 --- a/src/main/resources/LabelsBundle_fr_CH.properties +++ b/src/main/resources/LabelsBundle_fr_CH.properties @@ -1,20 +1,20 @@ Log = Journal History = Historique -created = créé le -modified = modifié le +created = créé le +modified = modifié le Queue = File d'attente Configuration = Configuration # Keys for the Configuration menu current.version = Version actuelle -check.for.updates = Vérifier mises à jour -auto.update = Mises à jour automatiques? -max.download.threads = Nombre de téléchargements parallèles maximum -timeout.mill = Délai d'expiration (en millisecondes): -retry.download.count = Nombre d'essais téléchargement +check.for.updates = Vérifier mises à jour +auto.update = Mises à jour automatiques? +max.download.threads = Nombre de téléchargements parallèles maximum +timeout.mill = Délai d'expiration (en millisecondes): +retry.download.count = Nombre d'essais téléchargement overwrite.existing.files = Remplacer fichiers existants ? -sound.when.rip.completes = Son lorsque le rip est terminé +sound.when.rip.completes = Son lorsque le rip est terminé preserve.order = Conserver l'ordre save.logs = Enregistrer journaux notification.when.rip.starts = Notification lorsqu'un rip commence @@ -22,8 +22,8 @@ save.urls.only = Enregistrer URL uniquement save.album.titles = Enregistrer titres d'album autorip.from.clipboard = Autorip depuis presse-papier save.descriptions = Enregistrer descriptions -prefer.mp4.over.gif = Préférer MP4 à GIF -restore.window.position = Restaurer la position de la fenêtre +prefer.mp4.over.gif = Préférer MP4 à GIF +restore.window.position = Restaurer la position de la fenêtre remember.url.history = Se souvenir de l'historique des URL loading.history.from = Charger l'historique depuis @@ -32,6 +32,6 @@ loading.history.from = Charger l'historique depuis loading.history.from.configuration = Charger l'historique depuis la configuration interrupted.while.waiting.to.rip.next.album = Interrompu lors de l'attente pour ripper le prochain album inactive = Inactif -re-rip.checked = Re-rip vérifié +re-rip.checked = Re-rip vérifié remove = Enlever clear = Effacer \ No newline at end of file From 96bf2ad3a7d655c5d5311f36ae7491bd9620f6ec Mon Sep 17 00:00:00 2001 From: Kevin Jiang Date: Sat, 12 May 2018 17:58:27 -0400 Subject: [PATCH 21/40] Update ImagebamRipper.java --- .../com/rarchives/ripme/ripper/rippers/ImagebamRipper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/ImagebamRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/ImagebamRipper.java index b5fca14f..b33f5624 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/ImagebamRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/ImagebamRipper.java @@ -146,7 +146,7 @@ public class ImagebamRipper extends AbstractHTMLRipper { for (Element metaTag: metaTags) { //the direct link to the image seems to always be linked in the part of the html. - if(metaTag.attr("property").equals("og:image")) { + if (metaTag.attr("property").equals("og:image")) { imgsrc = metaTag.attr("content"); logger.info("Found URL " + imgsrc); break;//only one (useful) image possible for an "image page". @@ -171,4 +171,4 @@ public class ImagebamRipper extends AbstractHTMLRipper { } } } -} \ No newline at end of file +} From a670de675a0550d8fb93723407efbf0f8239d7d4 Mon Sep 17 00:00:00 2001 From: Kevin Jiang Date: Sat, 12 May 2018 17:58:55 -0400 Subject: [PATCH 22/40] if( if ( --- .../com/rarchives/ripme/ripper/rippers/DeviantartRipper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java index 8ecb8086..9ab23ec8 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/DeviantartRipper.java @@ -121,7 +121,7 @@ public class DeviantartRipper extends AbstractHTMLRipper { String username = Utils.getConfigString("deviantart.username", new String(Base64.decode("Z3JhYnB5"))); String password = Utils.getConfigString("deviantart.password", new String(Base64.decode("ZmFrZXJz"))); - if(username == null || password == null) { + if (username == null || password == null) { logger.debug("No DeviantArt login provided."); cookies.put("agegate_state","1"); // Bypasses the age gate } else { From 00696c3450e6c0321a13786dfd044d16fe44a669 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sun, 13 May 2018 08:56:14 -0400 Subject: [PATCH 23/40] Can now set UI lang in config file --- src/main/java/com/rarchives/ripme/utils/Utils.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/rarchives/ripme/utils/Utils.java b/src/main/java/com/rarchives/ripme/utils/Utils.java index e6617f46..cd1048df 100644 --- a/src/main/java/com/rarchives/ripme/utils/Utils.java +++ b/src/main/java/com/rarchives/ripme/utils/Utils.java @@ -578,6 +578,11 @@ public class Utils { } public static ResourceBundle getResourceBundle() { + if (!getConfigString("lang", "").equals("")) { + String[] langCode = getConfigString("lang", "").split("_"); + logger.info("Setting locale to " + getConfigString("lang", "")); + return ResourceBundle.getBundle("LabelsBundle", new Locale(langCode[0], langCode[1]), new UTF8Control()); + } try { ResourceBundle rb = ResourceBundle.getBundle("LabelsBundle", Locale.getDefault(), new UTF8Control()); return rb; From 34425361aeec2cc12f782b7a2afb8a4be820d266 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sun, 13 May 2018 09:14:42 -0400 Subject: [PATCH 24/40] 1.7.45: Fixed hentai2read ripper; ImageBam album fixed; Added various translations; TsuminoRipper no longer requires album name to download --- pom.xml | 2 +- ripme.json | 3 ++- src/main/java/com/rarchives/ripme/ui/UpdateUtils.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 0796e60f..317b816e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rarchives.ripme ripme jar - 1.7.44 + 1.7.45 ripme http://rip.rarchives.com diff --git a/ripme.json b/ripme.json index 757058ae..73b9b240 100644 --- a/ripme.json +++ b/ripme.json @@ -1,6 +1,7 @@ { - "latestVersion": "1.7.44", + "latestVersion": "1.7.45", "changeList": [ + "1.7.45: Fixed hentai2read ripper; ImageBam album fixed; Added various translations; TsuminoRipper no longer requires album name to download", "1.7.44: Fixed instagram ripper regex", "1.7.43: Fixed queryId regex in instagram ripper", "1.7.42: Added user support to SmuttyRipper; Removed vine ripper; Fixed NudeGalsRipper; addURLToDownload improvments; Fixed Instagram ripper", diff --git a/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java b/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java index 11d18771..38e88ae7 100644 --- a/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java +++ b/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java @@ -21,7 +21,7 @@ import com.rarchives.ripme.utils.Utils; public class UpdateUtils { private static final Logger logger = Logger.getLogger(UpdateUtils.class); - private static final String DEFAULT_VERSION = "1.7.44"; + private static final String DEFAULT_VERSION = "1.7.45"; private static final String REPO_NAME = "ripmeapp/ripme"; private static final String updateJsonURL = "https://raw.githubusercontent.com/" + REPO_NAME + "/master/ripme.json"; private static final String mainFileName = "ripme.jar"; From 9d8c6f6ce220080a17f1d4b3df5bd32e532ef0db Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sun, 13 May 2018 09:38:59 -0400 Subject: [PATCH 25/40] EightmusesRipper now adds file extension to filename --- .../com/rarchives/ripme/ripper/rippers/EightmusesRipper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/EightmusesRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/EightmusesRipper.java index ca9c24e3..3e06695b 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/EightmusesRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/EightmusesRipper.java @@ -126,9 +126,9 @@ public class EightmusesRipper extends AbstractHTMLRipper { image = getFullSizeImage(imageHref); URL imageUrl = new URL(image); if (Utils.getConfigBoolean("8muses.use_short_names", false)) { - addURLToDownload(imageUrl, getPrefixShort(x), getSubdir(page.select("title").text()), this.url.toExternalForm(), cookies, ""); + addURLToDownload(imageUrl, getPrefixShort(x), getSubdir(page.select("title").text()), this.url.toExternalForm(), cookies, "", null, true); } else { - addURLToDownload(imageUrl, getPrefixLong(x), getSubdir(page.select("title").text()), this.url.toExternalForm(), cookies); + addURLToDownload(imageUrl, getPrefixLong(x), getSubdir(page.select("title").text()), this.url.toExternalForm(), cookies, "", null, true); } // X is our page index x++; From 98ad786529e3a5d0e4c26538aa6eaf59403a7d19 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sun, 13 May 2018 10:06:19 -0400 Subject: [PATCH 26/40] Disabled test for broken ripper --- .../tst/ripper/rippers/VideoRippersTest.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/rarchives/ripme/tst/ripper/rippers/VideoRippersTest.java b/src/test/java/com/rarchives/ripme/tst/ripper/rippers/VideoRippersTest.java index ae31192b..6a7df184 100644 --- a/src/test/java/com/rarchives/ripme/tst/ripper/rippers/VideoRippersTest.java +++ b/src/test/java/com/rarchives/ripme/tst/ripper/rippers/VideoRippersTest.java @@ -38,14 +38,17 @@ public class VideoRippersTest extends RippersTest { } } - public void testTwitchVideoRipper() throws IOException { - List contentURLs = new ArrayList<>(); - contentURLs.add(new URL("https://clips.twitch.tv/FaithfulIncredulousPotTBCheesePull")); - for (URL url : contentURLs) { - TwitchVideoRipper ripper = new TwitchVideoRipper(url); - videoTestHelper(ripper); - } - } + +// Test disbaled. See https://github.com/RipMeApp/ripme/issues/574 + +// public void testTwitchVideoRipper() throws IOException { +// List contentURLs = new ArrayList<>(); +// contentURLs.add(new URL("https://clips.twitch.tv/FaithfulIncredulousPotTBCheesePull")); +// for (URL url : contentURLs) { +// TwitchVideoRipper ripper = new TwitchVideoRipper(url); +// videoTestHelper(ripper); +// } +// } public void testXhamsterRipper() throws IOException { List contentURLs = new ArrayList<>(); From 046fa093a3adf55dc39ea39a7981774a31f694b3 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sun, 13 May 2018 10:11:38 -0400 Subject: [PATCH 27/40] SinnercomicsRipper no longer adds -page-01 to folder names --- .../com/rarchives/ripme/ripper/rippers/SinnercomicsRipper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/SinnercomicsRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/SinnercomicsRipper.java index 326de1a1..166bce88 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/SinnercomicsRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/SinnercomicsRipper.java @@ -34,7 +34,7 @@ public class SinnercomicsRipper extends AbstractHTMLRipper { Pattern p = Pattern.compile("^https?://sinnercomics.com/comic/([a-zA-Z0-9-]*)/?$"); Matcher m = p.matcher(url.toExternalForm()); if (m.matches()) { - return m.group(1); + return m.group(1).replaceAll("-page-\\d+", ""); } throw new MalformedURLException("Expected sinnercomics.com URL format: " + "sinnercomics.com/comic/albumName - got " + url + " instead"); From aca2d24a65cf78bd4748a09fdb3c939da30d6a13 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Sun, 13 May 2018 12:12:23 -0400 Subject: [PATCH 28/40] Can now blacklist nhentai tags --- .../ripme/ripper/rippers/NhentaiRipper.java | 41 +++++++++++++++++++ .../java/com/rarchives/ripme/utils/Utils.java | 10 +++++ 2 files changed, 51 insertions(+) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/NhentaiRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/NhentaiRipper.java index ac8f782d..50334f05 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/NhentaiRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/NhentaiRipper.java @@ -2,6 +2,7 @@ package com.rarchives.ripme.ripper.rippers; import com.rarchives.ripme.ripper.AbstractHTMLRipper; import com.rarchives.ripme.ripper.DownloadThreadPool; +import com.rarchives.ripme.ui.RipStatusMessage; import com.rarchives.ripme.utils.Http; import com.rarchives.ripme.utils.Utils; import org.jsoup.nodes.Document; @@ -64,6 +65,39 @@ public class NhentaiRipper extends AbstractHTMLRipper { return "nhentai" + title; } + private List getTags(Document doc) { + List tags = new ArrayList<>(); + for (Element tag : doc.select("a.tag")) { + tags.add(tag.attr("href").replaceAll("/tag/", "").replaceAll("/", "")); + } + return tags; + } + + /** + * Checks for blacklisted tags on page. If it finds one it returns it, if not it return null + * + * @param doc + * @return String + */ + private String checkTags(Document doc) { + String[] blackListedTags = Utils.getConfigStringArray("nhentai.blacklist.tags"); + // If the user hasn't blacklisted any tags we return false; + if (blackListedTags == null) { + return null; + } + logger.info("Blacklisted tags " + blackListedTags[0]); + List tagsOnPage = getTags(doc); + for (String tag : blackListedTags) { + for (String pageTag : tagsOnPage) { + logger.info("tag: " + tag + " pageTag: " + pageTag); + if (tag.trim().toLowerCase().equals(pageTag.toLowerCase())) { + return tag; + } + } + } + return null; + } + @Override public String getGID(URL url) throws MalformedURLException { // Ex: https://nhentai.net/g/159174/ @@ -82,6 +116,13 @@ public class NhentaiRipper extends AbstractHTMLRipper { if (firstPage == null) { firstPage = Http.url(url).get(); } + + String blacklistedTag = checkTags(firstPage); + if (blacklistedTag != null) { + sendUpdate(RipStatusMessage.STATUS.DOWNLOAD_WARN, "Skipping " + url.toExternalForm() + " as it " + + "contains the blacklisted tag \"" + blacklistedTag + "\""); + return null; + } return firstPage; } diff --git a/src/main/java/com/rarchives/ripme/utils/Utils.java b/src/main/java/com/rarchives/ripme/utils/Utils.java index cd1048df..5560a425 100644 --- a/src/main/java/com/rarchives/ripme/utils/Utils.java +++ b/src/main/java/com/rarchives/ripme/utils/Utils.java @@ -92,6 +92,16 @@ public class Utils { public static String getConfigString(String key, String defaultValue) { return config.getString(key, defaultValue); } + + public static String[] getConfigStringArray(String key) { + String[] s = config.getStringArray(key); + if (s.length == 0) { + return null; + } else { + return s; + } + } + public static int getConfigInteger(String key, int defaultValue) { return config.getInt(key, defaultValue); } From 05cc8cec615dc5dc9d0d5888011c18a77ab569d1 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Mon, 14 May 2018 03:26:32 -0400 Subject: [PATCH 29/40] Added unit test for nhentai --- .../tst/ripper/rippers/NhentaiRipperTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/test/java/com/rarchives/ripme/tst/ripper/rippers/NhentaiRipperTest.java diff --git a/src/test/java/com/rarchives/ripme/tst/ripper/rippers/NhentaiRipperTest.java b/src/test/java/com/rarchives/ripme/tst/ripper/rippers/NhentaiRipperTest.java new file mode 100644 index 00000000..108feed2 --- /dev/null +++ b/src/test/java/com/rarchives/ripme/tst/ripper/rippers/NhentaiRipperTest.java @@ -0,0 +1,33 @@ +package com.rarchives.ripme.tst.ripper.rippers; + +import java.io.IOException; +import java.net.URL; + +import com.rarchives.ripme.ripper.rippers.NhentaiRipper; + +public class NhentaiRipperTest extends RippersTest { + public void testRip() throws IOException { + NhentaiRipper ripper = new NhentaiRipper(new URL("https://nhentai.net/g/233295/")); + testRipper(ripper); + } + + public void testGetGID() throws IOException { + NhentaiRipper ripper = new NhentaiRipper(new URL("https://nhentai.net/g/233295/")); + assertEquals("233295", ripper.getGID(new URL("https://nhentai.net/g/233295/"))); + } + + // Test the tag black listing + public void testTagBlackList() throws IOException { + URL url = new URL("https://nhentai.net/g/233295/"); + NhentaiRipper ripper = new NhentaiRipper(url); + // Test multiple blacklisted tags + String[] tags = {"test", "one", "blowjob"}; + String blacklistedTag = ripper.checkTags(ripper.getFirstPage(), tags); + assertEquals("blowjob", blacklistedTag); + + // test tags with spaces in them + String[] tags2 = {"test", "one", "sole female"}; + blacklistedTag = ripper.checkTags(ripper.getFirstPage(), tags2); + assertEquals("sole female", blacklistedTag); + } +} From 4dcfe3b712cd6b34f5279161c937e23ef3c5d911 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Mon, 14 May 2018 03:26:56 -0400 Subject: [PATCH 30/40] Can now black list tags with spaces in them --- .../rarchives/ripme/ripper/rippers/NhentaiRipper.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/NhentaiRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/NhentaiRipper.java index 50334f05..9c204a8d 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/NhentaiRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/NhentaiRipper.java @@ -79,8 +79,7 @@ public class NhentaiRipper extends AbstractHTMLRipper { * @param doc * @return String */ - private String checkTags(Document doc) { - String[] blackListedTags = Utils.getConfigStringArray("nhentai.blacklist.tags"); + public String checkTags(Document doc, String[] blackListedTags) { // If the user hasn't blacklisted any tags we return false; if (blackListedTags == null) { return null; @@ -89,8 +88,9 @@ public class NhentaiRipper extends AbstractHTMLRipper { List tagsOnPage = getTags(doc); for (String tag : blackListedTags) { for (String pageTag : tagsOnPage) { - logger.info("tag: " + tag + " pageTag: " + pageTag); - if (tag.trim().toLowerCase().equals(pageTag.toLowerCase())) { + // We replace all dashes in the tag with spaces because the tags we get from the site are separated using + // dashes + if (tag.trim().toLowerCase().equals(pageTag.replaceAll("-", " ").toLowerCase())) { return tag; } } @@ -117,7 +117,7 @@ public class NhentaiRipper extends AbstractHTMLRipper { firstPage = Http.url(url).get(); } - String blacklistedTag = checkTags(firstPage); + String blacklistedTag = checkTags(firstPage, Utils.getConfigStringArray("nhentai.blacklist.tags")); if (blacklistedTag != null) { sendUpdate(RipStatusMessage.STATUS.DOWNLOAD_WARN, "Skipping " + url.toExternalForm() + " as it " + "contains the blacklisted tag \"" + blacklistedTag + "\""); From c5a8f0cd0885eb6f00b332d5746946a1b2832c92 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Mon, 14 May 2018 08:20:24 -0400 Subject: [PATCH 31/40] Added func to add urls to the download queue --- src/main/java/com/rarchives/ripme/ui/MainWindow.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/rarchives/ripme/ui/MainWindow.java b/src/main/java/com/rarchives/ripme/ui/MainWindow.java index 95961f44..59f75e06 100644 --- a/src/main/java/com/rarchives/ripme/ui/MainWindow.java +++ b/src/main/java/com/rarchives/ripme/ui/MainWindow.java @@ -162,6 +162,11 @@ public final class MainWindow implements Runnable, RipStatusHandler { return checkbox; } + + public static void addUrlToQueue(String url) { + queueListModel.addElement(url); + } + public MainWindow() { mainFrame = new JFrame("RipMe v" + UpdateUtils.getThisJarVersion()); mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); From e33d24364e4b4116acf1a637cb4adb7d6cb7e927 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Mon, 14 May 2018 08:21:09 -0400 Subject: [PATCH 32/40] Added a way for rippers to add urls to the download queue --- .../ripme/ripper/AbstractHTMLRipper.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/main/java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java b/src/main/java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java index e0fd3548..436eb122 100644 --- a/src/main/java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java @@ -11,6 +11,7 @@ import org.jsoup.nodes.Document; import com.rarchives.ripme.ui.RipStatusMessage.STATUS; import com.rarchives.ripme.utils.Utils; +import com.rarchives.ripme.ui.MainWindow; /** * Simplified ripper, designed for ripping from sites by parsing HTML. @@ -53,12 +54,29 @@ public abstract class AbstractHTMLRipper extends AlbumRipper { protected boolean hasDescriptionSupport() { return false; } + protected String[] getDescription(String url, Document page) throws IOException { throw new IOException("getDescription not implemented"); // Do I do this or make an abstract function? } protected int descSleepTime() { return 100; } + + protected List getAlbumsToQueue(Document doc) { + return null; + } + + // If a page has Queue support than it has no images we want to download, just a list of urls we want to add to + // the queue + protected boolean hasQueueSupport() { + return false; + } + + // Takes a url and checks if it is for a page of albums + protected boolean pageContainsAlbums(URL url) { + return false; + } + @Override public void rip() throws IOException { int index = 0; @@ -67,6 +85,15 @@ public abstract class AbstractHTMLRipper extends AlbumRipper { sendUpdate(STATUS.LOADING_RESOURCE, this.url.toExternalForm()); Document doc = getFirstPage(); + if (hasQueueSupport() && pageContainsAlbums(this.url)) { + List urls = getAlbumsToQueue(doc); + for (String url : urls) { + MainWindow.addUrlToQueue(url); + } + + doc = null; + } + while (doc != null) { if (alreadyDownloadedUrls >= Utils.getConfigInteger("history.end_rip_after_already_seen", 1000000000) && !isThisATest()) { sendUpdate(STATUS.DOWNLOAD_COMPLETE, "Already seen the last " + alreadyDownloadedUrls + " images ending rip"); From 21a81342d9f1eaa330d04d7b596d7d20966c1509 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Mon, 14 May 2018 08:21:59 -0400 Subject: [PATCH 33/40] Rewrote the myhentaicomics ripper to use the new getAlbumsToQueue func --- .../ripper/rippers/MyhentaicomicsRipper.java | 185 +++--------------- 1 file changed, 31 insertions(+), 154 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/MyhentaicomicsRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/MyhentaicomicsRipper.java index 5b60c4f2..60c90ae1 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/MyhentaicomicsRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/MyhentaicomicsRipper.java @@ -34,21 +34,18 @@ public class MyhentaicomicsRipper extends AbstractHTMLRipper { Pattern p = Pattern.compile("^https?://myhentaicomics.com/index.php/([a-zA-Z0-9-]*)/?$"); Matcher m = p.matcher(url.toExternalForm()); if (m.matches()) { - isTag = false; return m.group(1); } Pattern pa = Pattern.compile("^https?://myhentaicomics.com/index.php/search\\?q=([a-zA-Z0-9-]*)([a-zA-Z0-9=&]*)?$"); Matcher ma = pa.matcher(url.toExternalForm()); if (ma.matches()) { - isTag = true; return ma.group(1); } Pattern pat = Pattern.compile("^https?://myhentaicomics.com/index.php/tag/([0-9]*)/?([a-zA-Z%0-9+?=:]*)?$"); Matcher mat = pat.matcher(url.toExternalForm()); if (mat.matches()) { - isTag = true; return mat.group(1); } @@ -56,6 +53,37 @@ public class MyhentaicomicsRipper extends AbstractHTMLRipper { "myhentaicomics.com/index.php/albumName - got " + url + " instead"); } + @Override + public boolean hasQueueSupport() { + return true; + } + + @Override + public boolean pageContainsAlbums(URL url) { + Pattern pa = Pattern.compile("^https?://myhentaicomics.com/index.php/search\\?q=([a-zA-Z0-9-]*)([a-zA-Z0-9=&]*)?$"); + Matcher ma = pa.matcher(url.toExternalForm()); + if (ma.matches()) { + return true; + } + + Pattern pat = Pattern.compile("^https?://myhentaicomics.com/index.php/tag/([0-9]*)/?([a-zA-Z%0-9+?=:]*)?$"); + Matcher mat = pat.matcher(url.toExternalForm()); + if (mat.matches()) { + isTag = true; + return true; + } + return false; + } + + @Override + public List getAlbumsToQueue(Document doc) { + List urlsToAddToQueue = new ArrayList<>(); + for (Element elem : doc.select(".g-album > a")) { + urlsToAddToQueue.add(getDomain() + elem.attr("href")); + } + return urlsToAddToQueue; + } + @Override public Document getFirstPage() throws IOException { // "url" is an instance field of the superclass @@ -81,161 +109,11 @@ public class MyhentaicomicsRipper extends AbstractHTMLRipper { return Http.url(nextUrl).get(); } - // This replaces getNextPage when downloading from searchs and tags - private List getNextAlbumPage(String pageUrl) { - List albumPagesList = new ArrayList<>(); - int pageNumber = 1; - albumPagesList.add("http://myhentaicomics.com/index.php/" + pageUrl.split("\\?")[0] + "?page=" + Integer.toString(pageNumber)); - while (true) { - String urlToGet = "http://myhentaicomics.com/index.php/" + pageUrl.split("\\?")[0] + "?page=" + Integer.toString(pageNumber); - Document nextAlbumPage; - try { - logger.info("Grabbing " + urlToGet); - nextAlbumPage = Http.url(urlToGet).get(); - } catch (IOException e) { - logger.warn("Failed to log link in Jsoup"); - nextAlbumPage = null; - e.printStackTrace(); - } - Element elem = nextAlbumPage.select("a.ui-icon-right").first(); - String nextPage = elem.attr("href"); - pageNumber = pageNumber + 1; - if (nextPage.equals("")) { - logger.info("Got " + pageNumber + " pages"); - break; - } - else { - logger.info(nextPage); - albumPagesList.add(nextPage); - logger.info("Adding " + nextPage); - } - } - return albumPagesList; - } - private List getAlbumsFromPage(String url) { - List pagesToRip; - List result = new ArrayList<>(); - logger.info("Running getAlbumsFromPage"); - Document doc; - try { - doc = Http.url("http://myhentaicomics.com" + url).get(); - } catch (IOException e) { - logger.warn("Failed to log link in Jsoup"); - doc = null; - e.printStackTrace(); - } - // This for goes over every album on the page - for (Element elem : doc.select("li.g-album > a")) { - String link = elem.attr("href"); - logger.info("Grabbing album " + link); - pagesToRip = getNextAlbumPage(link); - logger.info(pagesToRip); - for (String element : pagesToRip) { - Document album_doc; - try { - logger.info("grabbing " + element + " with jsoup"); - boolean startsWithHttp = element.startsWith("http://"); - if (!startsWithHttp) { - album_doc = Http.url("http://myhentaicomics.com/" + element).get(); - } - else { - album_doc = Http.url(element).get(); - } - } catch (IOException e) { - logger.warn("Failed to log link in Jsoup"); - album_doc = null; - e.printStackTrace(); - } - for (Element el :album_doc.select("img")) { - String imageSource = el.attr("src"); - // This bool is here so we don't try and download the site logo - if (!imageSource.startsWith("http://")) { - // We replace thumbs with resizes so we can the full sized images - imageSource = imageSource.replace("thumbs", "resizes"); - String url_string = "http://myhentaicomics.com/" + imageSource; - url_string = url_string.replace("%20", "_"); - url_string = url_string.replace("%27", ""); - url_string = url_string.replace("%28", "_"); - url_string = url_string.replace("%29", "_"); - url_string = url_string.replace("%2C", "_"); - if (isTag) { - logger.info("Downloading from a tag or search"); - try { - sleep(500); - result.add("http://myhentaicomics.com/" + imageSource); - addURLToDownload(new URL("http://myhentaicomics.com/" + imageSource), "", url_string.split("/")[6]); - } - catch (MalformedURLException e) { - logger.warn("Malformed URL"); - e.printStackTrace(); - } - } - } - } - } - } - return result; - } - - private List getListOfPages(Document doc) { - List pages = new ArrayList<>(); - // Get the link from the last button - String nextPageUrl = doc.select("a.ui-icon-right").last().attr("href"); - Pattern pat = Pattern.compile("/index\\.php/tag/[0-9]*/[a-zA-Z0-9_\\-:+]*\\?page=(\\d+)"); - Matcher mat = pat.matcher(nextPageUrl); - if (mat.matches()) { - logger.debug("Getting pages from a tag"); - String base_link = mat.group(0).replaceAll("\\?page=\\d+", ""); - logger.debug("base_link is " + base_link); - int numOfPages = Integer.parseInt(mat.group(1)); - for (int x = 1; x != numOfPages +1; x++) { - logger.debug("running loop"); - String link = base_link + "?page=" + Integer.toString(x); - pages.add(link); - } - } else { - Pattern pa = Pattern.compile("/index\\.php/search\\?q=[a-zA-Z0-9_\\-:]*&page=(\\d+)"); - Matcher ma = pa.matcher(nextPageUrl); - if (ma.matches()) { - logger.debug("Getting pages from a search"); - String base_link = ma.group(0).replaceAll("page=\\d+", ""); - logger.debug("base_link is " + base_link); - int numOfPages = Integer.parseInt(ma.group(1)); - for (int x = 1; x != numOfPages +1; x++) { - logger.debug("running loop"); - String link = base_link + "page=" + Integer.toString(x); - logger.debug(link); - pages.add(link); - } - } - } - return pages; - } @Override public List getURLsFromPage(Document doc) { List result = new ArrayList<>(); - // Checks if this is a comic page or a page of albums - // If true the page is a page of albums - if (doc.toString().contains("class=\"g-item g-album\"")) { - // This if checks that there is more than 1 page - if (!doc.select("a.ui-icon-right").last().attr("href").equals("")) { - // There is more than one page so we call getListOfPages - List pagesToRip = getListOfPages(doc); - logger.debug("Pages to rip = " + pagesToRip); - for (String url : pagesToRip) { - logger.debug("Getting albums from " + url); - result = getAlbumsFromPage(url); - } - } else { - logger.debug("There is only one page on this page of albums"); - // There is only 1 page so we call getAlbumsFromPage and pass it the page url - result = getAlbumsFromPage(doc.select("div.g-description > a").attr("href")); - } - return result; - } - else { for (Element el : doc.select("img")) { String imageSource = el.attr("src"); // This bool is here so we don't try and download the site logo @@ -245,7 +123,6 @@ public class MyhentaicomicsRipper extends AbstractHTMLRipper { result.add("http://myhentaicomics.com/" + imageSource); } } - } return result; } From 6a73e6c06bf7de45885175e75b211b3d9685b79d Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Wed, 16 May 2018 04:31:25 -0400 Subject: [PATCH 34/40] Fixed spelling mistake added another comment --- .../java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java b/src/main/java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java index 436eb122..2eefe873 100644 --- a/src/main/java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/AbstractHTMLRipper.java @@ -66,7 +66,7 @@ public abstract class AbstractHTMLRipper extends AlbumRipper { return null; } - // If a page has Queue support than it has no images we want to download, just a list of urls we want to add to + // If a page has Queue support then it has no images we want to download, just a list of urls we want to add to // the queue protected boolean hasQueueSupport() { return false; @@ -91,6 +91,7 @@ public abstract class AbstractHTMLRipper extends AlbumRipper { MainWindow.addUrlToQueue(url); } + // We set doc to null here so the while loop below this doesn't fire doc = null; } From 694dc3fe5b39d4093e6036a381fa512ff03d5a32 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Wed, 16 May 2018 04:55:36 -0400 Subject: [PATCH 35/40] hentai2read can now get the album thumbnail link again --- .../com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java index a87575bd..d994c11b 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java @@ -48,7 +48,7 @@ public class Hentai2readRipper extends AbstractHTMLRipper { Document tempDoc; tempDoc = Http.url(url).get(); // Get the thumbnail page so we can rip all images without loading every page in the comic - String thumbnailLink = tempDoc.select("a[data-original-title=Thumbnails").attr("href"); + String thumbnailLink = tempDoc.select("div.col-xs-12 > div.reader-controls > div.controls-block > button > a").attr("href"); return Http.url(thumbnailLink).get(); } catch (IOException e) { throw new IOException("Unable to get first page"); From afdff0ebc48b5b794316141bf8cf26f1cf844a82 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Wed, 16 May 2018 11:38:49 -0400 Subject: [PATCH 36/40] hentai2read can now get the album thumbnail link again --- .../ripme/ripper/rippers/Hentai2readRipper.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java index d994c11b..7441d8d6 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java @@ -44,12 +44,17 @@ public class Hentai2readRipper extends AbstractHTMLRipper { @Override public Document getFirstPage() throws IOException { + String thumbnailLink; try { Document tempDoc; tempDoc = Http.url(url).get(); // Get the thumbnail page so we can rip all images without loading every page in the comic - String thumbnailLink = tempDoc.select("div.col-xs-12 > div.reader-controls > div.controls-block > button > a").attr("href"); - return Http.url(thumbnailLink).get(); + thumbnailLink = tempDoc.select("div.col-xs-12 > div.reader-controls > div.controls-block > button > a").attr("href"); + if (thumbnailLink != null) { + return Http.url(thumbnailLink).get(); + } else { + return Http.url(tempDoc.select("a[data-original-title=Thumbnails").attr("href")).get(); + } } catch (IOException e) { throw new IOException("Unable to get first page"); } From 59d31159704ee4763dd4f6e2bc349d173d636109 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Wed, 16 May 2018 11:46:36 -0400 Subject: [PATCH 37/40] Fixed hentai2read ripper for real this time --- .../com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java b/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java index 7441d8d6..78fc50fc 100644 --- a/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java +++ b/src/main/java/com/rarchives/ripme/ripper/rippers/Hentai2readRipper.java @@ -50,7 +50,7 @@ public class Hentai2readRipper extends AbstractHTMLRipper { tempDoc = Http.url(url).get(); // Get the thumbnail page so we can rip all images without loading every page in the comic thumbnailLink = tempDoc.select("div.col-xs-12 > div.reader-controls > div.controls-block > button > a").attr("href"); - if (thumbnailLink != null) { + if (!thumbnailLink.equals("")) { return Http.url(thumbnailLink).get(); } else { return Http.url(tempDoc.select("a[data-original-title=Thumbnails").attr("href")).get(); From 97856425126d440c3ad1697ad340890f4f157dd0 Mon Sep 17 00:00:00 2001 From: cyian-1756 Date: Wed, 16 May 2018 12:04:19 -0400 Subject: [PATCH 38/40] 1.7.46: Fixed hentai2read ripper; Rewrote the myhentaicomics ripper to use the new getAlbumsToQueue func; Can now blacklist nhentai tags; SinnercomicsRipper no longer adds -page-01 to folder names; EightmusesRipper now adds file extension to filename; disbaled test for twitch ripper --- pom.xml | 2 +- ripme.json | 3 ++- src/main/java/com/rarchives/ripme/ui/UpdateUtils.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 317b816e..a46264f9 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rarchives.ripme ripme jar - 1.7.45 + 1.7.46 ripme http://rip.rarchives.com diff --git a/ripme.json b/ripme.json index 73b9b240..4858d2cc 100644 --- a/ripme.json +++ b/ripme.json @@ -1,6 +1,7 @@ { - "latestVersion": "1.7.45", + "latestVersion": "1.7.46", "changeList": [ + "1.7.46: Fixed hentai2read ripper; Rewrote the myhentaicomics ripper to use the new getAlbumsToQueue func; Can now blacklist nhentai tags; SinnercomicsRipper no longer adds -page-01 to folder names; EightmusesRipper now adds file extension to filename; disbaled test for twitch ripper", "1.7.45: Fixed hentai2read ripper; ImageBam album fixed; Added various translations; TsuminoRipper no longer requires album name to download", "1.7.44: Fixed instagram ripper regex", "1.7.43: Fixed queryId regex in instagram ripper", diff --git a/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java b/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java index 38e88ae7..f82b2137 100644 --- a/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java +++ b/src/main/java/com/rarchives/ripme/ui/UpdateUtils.java @@ -21,7 +21,7 @@ import com.rarchives.ripme.utils.Utils; public class UpdateUtils { private static final Logger logger = Logger.getLogger(UpdateUtils.class); - private static final String DEFAULT_VERSION = "1.7.45"; + private static final String DEFAULT_VERSION = "1.7.46"; private static final String REPO_NAME = "ripmeapp/ripme"; private static final String updateJsonURL = "https://raw.githubusercontent.com/" + REPO_NAME + "/master/ripme.json"; private static final String mainFileName = "ripme.jar"; From 81a648681efea4d2b9426c418a62746cbd521521 Mon Sep 17 00:00:00 2001 From: Kevin Jiang Date: Thu, 17 May 2018 13:57:18 -0400 Subject: [PATCH 39/40] Add more documentation to App.java --- src/main/java/com/rarchives/ripme/App.java | 26 +++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/rarchives/ripme/App.java b/src/main/java/com/rarchives/ripme/App.java index 6f650d56..d58f5d4d 100644 --- a/src/main/java/com/rarchives/ripme/App.java +++ b/src/main/java/com/rarchives/ripme/App.java @@ -33,13 +33,22 @@ import com.rarchives.ripme.utils.Utils; /** * Entry point to application. + * This is where all the fun happens, with the main method. * Decides to display UI or to run silently via command-line. + * + * As the "controller" to all other classes, it parses command line parameters and loads the history. */ public class App { public static final Logger logger = Logger.getLogger(App.class); private static final History HISTORY = new History(); + /** + * Where everything starts. Takes in, and tries to parse as many commandline arguments as possible. + * Otherwise, it launches a GUI. + * + * @param args Array of command line arguments. + */ public static void main(String[] args) throws MalformedURLException { CommandLine cl = getArgs(args); @@ -74,7 +83,8 @@ public class App { /** * Creates an abstract ripper and instructs it to rip. * @param url URL to be ripped - * @throws Exception + * @throws Exception Nothing too specific here, just a catch-all. + * */ private static void rip(URL url) throws Exception { AbstractRipper ripper = AbstractRipper.getRipper(url); @@ -89,6 +99,7 @@ public class App { private static void handleArguments(String[] args) { CommandLine cl = getArgs(args); + //Help (list commands) if (cl.hasOption('h') || args.length == 0) { HelpFormatter hf = new HelpFormatter(); hf.printHelp("java -jar ripme.jar [OPTIONS]", getOptions()); @@ -98,28 +109,34 @@ public class App { Utils.configureLogger(); logger.info("Initialized ripme v" + UpdateUtils.getThisJarVersion()); + //Allow file overwriting if (cl.hasOption('w')) { Utils.setConfigBoolean("file.overwrite", true); } + //SOCKS proxy server if (cl.hasOption('s')) { String sservfull = cl.getOptionValue('s').trim(); Proxy.setSocks(sservfull); } + //HTTP proxy server if (cl.hasOption('p')) { String proxyserverfull = cl.getOptionValue('p').trim(); Proxy.setHTTPProxy(proxyserverfull); } + //Number of threads if (cl.hasOption('t')) { Utils.setConfigInteger("threads.size", Integer.parseInt(cl.getOptionValue('t'))); } + //Ignore 404 if (cl.hasOption('4')) { Utils.setConfigBoolean("errors.skip404", true); } + //Re-rip all previous albums if (cl.hasOption('r')) { // Re-rip all via command-line List history = Utils.getConfigList("download.history"); @@ -142,6 +159,7 @@ public class App { System.exit(0); } + //Re-rip all selected albums if (cl.hasOption('R')) { loadHistory(); if (HISTORY.toList().isEmpty()) { @@ -174,24 +192,29 @@ public class App { } } + //Save the order of images in album if (cl.hasOption('d')) { Utils.setConfigBoolean("download.save_order", true); } + //Don't save the order of images in album if (cl.hasOption('D')) { Utils.setConfigBoolean("download.save_order", false); } + //In case specify both, break and exit since it isn't possible. if ((cl.hasOption('d'))&&(cl.hasOption('D'))) { logger.error("\nCannot specify '-d' and '-D' simultaneously"); System.exit(-1); } + //Destination directory if (cl.hasOption('l')) { // change the default rips directory Utils.setConfigString("rips.directory", cl.getOptionValue('l')); } + //Read URLs from File if (cl.hasOption('f')) { String filename = cl.getOptionValue('f'); try { @@ -208,6 +231,7 @@ public class App { } } + //The URL to rip. if (cl.hasOption('u')) { String url = cl.getOptionValue('u').trim(); ripURL(url, cl.hasOption("n")); From 318760e7ade4e5930f3ee1c7d09f85c3d7c16f94 Mon Sep 17 00:00:00 2001 From: Kevin Jiang Date: Fri, 18 May 2018 13:25:09 -0400 Subject: [PATCH 40/40] More documentation; working towards creating a fully functional JavaDoc --- .../java/com/rarchives/ripme/utils/Utils.java | 107 +++++++++++++++++- 1 file changed, 103 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/rarchives/ripme/utils/Utils.java b/src/main/java/com/rarchives/ripme/utils/Utils.java index 5560a425..828d552a 100644 --- a/src/main/java/com/rarchives/ripme/utils/Utils.java +++ b/src/main/java/com/rarchives/ripme/utils/Utils.java @@ -89,6 +89,12 @@ public class Utils { return workingDir; } + /** + * Gets the value of a specific config key. + * + * @param key The name of the config parameter you want to find. + * @param defaultValue What the default value would be. + */ public static String getConfigString(String key, String defaultValue) { return config.getString(key, defaultValue); } @@ -142,31 +148,53 @@ public class Utils { } } + /** + * Determines if your current system is a Windows system. + */ private static boolean isWindows() { return OS.contains("win"); } + /** + * Determines if your current system is a Mac system + */ private static boolean isMacOS() { return OS.contains("mac"); } + /** + * Determines if current system is based on UNIX + */ private static boolean isUnix() { return OS.contains("nix") || OS.contains("nux") || OS.contains("bsd"); } + /** + * Gets the directory of where the config file is stored on a Windows machine. + */ private static String getWindowsConfigDir() { return System.getenv("LOCALAPPDATA") + File.separator + "ripme"; } + + /** + * Gets the directory of where the config file is stored on a UNIX machine. + */ private static String getUnixConfigDir() { return System.getProperty("user.home") + File.separator + ".config" + File.separator + "ripme"; } - + + /** + * Gets the directory of where the config file is stored on a Mac machine. + */ private static String getMacOSConfigDir() { return System.getProperty("user.home") + File.separator + "Library" + File.separator + "Application Support" + File.separator + "ripme"; } + /** + * Determines if the app is running in a portable mode. i.e. on a USB stick + */ private static boolean portableMode() { try { File f = new File(new File(".").getCanonicalPath() + File.separator + configFile); @@ -179,7 +207,9 @@ public class Utils { return false; } - + /** + * Gets the directory of the config directory, for all systems. + */ public static String getConfigDir() { if (portableMode()) { try { @@ -199,17 +229,24 @@ public class Utils { return "."; } } - // Delete the url history file + /** + * Delete the url history file + */ public static void clearURLHistory() { File file = new File(getURLHistoryFile()); file.delete(); } - // Return the path of the url history file + /** + * Return the path of the url history file + */ public static String getURLHistoryFile() { return getConfigDir() + File.separator + "url_history.txt"; } + /** + * Gets the path to the configuration file. + */ private static String getConfigFilePath() { return getConfigDir() + File.separator + configFile; } @@ -235,6 +272,15 @@ public class Utils { return prettySaveAs; } + /** + * Strips away URL parameters, which usually appear at the end of URLs. + * E.g. the ?query on PHP + * + * @param url The URL to filter/strip + * @param parameter The parameter to strip + * + * @return The stripped URL + */ public static String stripURLParameter(String url, String parameter) { int paramIndex = url.indexOf("?" + parameter); boolean wasFirstParam = true; @@ -262,6 +308,7 @@ public class Utils { /** * Removes the current working directory from a given filename * @param file + * Path to the file * @return * 'file' without the leading current working directory */ @@ -345,9 +392,24 @@ public class Utils { } private static final int SHORTENED_PATH_LENGTH = 12; + /** + * Shortens the path to a file + * @param path + * String of the path to the file + * @return + * The simplified path to the file. + */ public static String shortenPath(String path) { return shortenPath(new File(path)); } + + /** + * Shortens the path to a file + * @param file + * File object that you want the shortened path of. + * @return + * The simplified path to the file. + */ public static String shortenPath(File file) { String path = removeCWD(file); if (path.length() < SHORTENED_PATH_LENGTH * 2) { @@ -358,6 +420,13 @@ public class Utils { + path.substring(path.length() - SHORTENED_PATH_LENGTH); } + /** + * Sanitizes a string so that a filesystem can handle it + * @param text + * The text to be sanitized. + * @return + * The sanitized text. + */ public static String filesystemSanitized(String text) { text = text.replaceAll("[^a-zA-Z0-9.-]", "_"); return text; @@ -407,6 +476,13 @@ public class Utils { return original; } + /** + * Converts an integer into a human readable string + * @param bytes + * Non-human readable integer. + * @return + * Human readable interpretation of a byte. + */ public static String bytesToHumanReadable(int bytes) { float fbytes = (float) bytes; String[] mags = new String[] {"", "K", "M", "G", "T"}; @@ -418,6 +494,10 @@ public class Utils { return String.format("%.2f%siB", fbytes, mags[magIndex]); } + /** + * Gets and returns a list of all the album rippers present in the "com.rarchives.ripme.ripper.rippers" package. + * @return List of all album rippers present. + */ public static List getListOfAlbumRippers() throws Exception { List list = new ArrayList<>(); for (Constructor ripper : AbstractRipper.getRipperConstructors("com.rarchives.ripme.ripper.rippers")) { @@ -425,6 +505,11 @@ public class Utils { } return list; } + + /** + * Gets and returns a list of all video rippers present in the "com.rarchives.rime.rippers.video" package + * @return List of all the video rippers. + */ public static List getListOfVideoRippers() throws Exception { List list = new ArrayList<>(); for (Constructor ripper : AbstractRipper.getRipperConstructors("com.rarchives.ripme.ripper.rippers.video")) { @@ -433,6 +518,11 @@ public class Utils { return list; } + /** + * Plays a sound from a file. + * @param filename + * Path to the sound file + */ public static void playSound(String filename) { URL resource = ClassLoader.getSystemClassLoader().getResource(filename); try { @@ -570,6 +660,9 @@ public class Utils { cookieCache = new HashMap>(); } + /** + * Gets all the cookies from a certain host + */ public static Map getCookies(String host) { HashMap domainCookies = cookieCache.get(host); if (domainCookies == null) { @@ -587,6 +680,12 @@ public class Utils { return domainCookies; } + /** + * Gets the ResourceBundle AKA language package. + * Used for choosing the language of the UI. + * + * @return Returns the default resource bundle using the language specified in the config file. + */ public static ResourceBundle getResourceBundle() { if (!getConfigString("lang", "").equals("")) { String[] langCode = getConfigString("lang", "").split("_");