commit
8cccb89f50
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
|||||||
<groupId>com.rarchives.ripme</groupId>
|
<groupId>com.rarchives.ripme</groupId>
|
||||||
<artifactId>ripme</artifactId>
|
<artifactId>ripme</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>1.7.44</version>
|
<version>1.7.45</version>
|
||||||
<name>ripme</name>
|
<name>ripme</name>
|
||||||
<url>http://rip.rarchives.com</url>
|
<url>http://rip.rarchives.com</url>
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"latestVersion": "1.7.44",
|
"latestVersion": "1.7.45",
|
||||||
"changeList": [
|
"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.44: Fixed instagram ripper regex",
|
||||||
"1.7.43: Fixed queryId regex in instagram ripper",
|
"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.42: Added user support to SmuttyRipper; Removed vine ripper; Fixed NudeGalsRipper; addURLToDownload improvments; Fixed Instagram ripper",
|
||||||
|
@ -121,7 +121,7 @@ public class DeviantartRipper extends AbstractHTMLRipper {
|
|||||||
String username = Utils.getConfigString("deviantart.username", new String(Base64.decode("Z3JhYnB5")));
|
String username = Utils.getConfigString("deviantart.username", new String(Base64.decode("Z3JhYnB5")));
|
||||||
String password = Utils.getConfigString("deviantart.password", new String(Base64.decode("ZmFrZXJz")));
|
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.");
|
logger.debug("No DeviantArt login provided.");
|
||||||
cookies.put("agegate_state","1"); // Bypasses the age gate
|
cookies.put("agegate_state","1"); // Bypasses the age gate
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,20 +44,15 @@ public class Hentai2readRipper extends AbstractHTMLRipper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Document getFirstPage() throws IOException {
|
public Document getFirstPage() throws IOException {
|
||||||
Document tempDoc;
|
try {
|
||||||
// get the first page of the comic
|
Document tempDoc;
|
||||||
if (url.toExternalForm().substring(url.toExternalForm().length() - 1).equals("/")) {
|
tempDoc = Http.url(url).get();
|
||||||
tempDoc = Http.url(url + "1").get();
|
// Get the thumbnail page so we can rip all images without loading every page in the comic
|
||||||
} else {
|
String thumbnailLink = tempDoc.select("a[data-original-title=Thumbnails").attr("href");
|
||||||
tempDoc = Http.url(url + "/1").get();
|
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
|
@Override
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package com.rarchives.ripme.ripper.rippers;
|
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.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -7,16 +11,10 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
import org.jsoup.nodes.Element;
|
import org.jsoup.nodes.Element;
|
||||||
import org.jsoup.select.Elements;
|
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 {
|
public class ImagebamRipper extends AbstractHTMLRipper {
|
||||||
|
|
||||||
// Current HTML document
|
// Current HTML document
|
||||||
@ -71,7 +69,7 @@ public class ImagebamRipper extends AbstractHTMLRipper {
|
|||||||
public Document getNextPage(Document doc) throws IOException {
|
public Document getNextPage(Document doc) throws IOException {
|
||||||
// Find next page
|
// Find next page
|
||||||
Elements hrefs = doc.select("a.pagination_current + a.pagination_link");
|
Elements hrefs = doc.select("a.pagination_current + a.pagination_link");
|
||||||
if (hrefs.size() == 0) {
|
if (hrefs.isEmpty()) {
|
||||||
throw new IOException("No more pages");
|
throw new IOException("No more pages");
|
||||||
}
|
}
|
||||||
String nextUrl = "http://www.imagebam.com" + hrefs.first().attr("href");
|
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.
|
* Handles case when site has IP-banned the user.
|
||||||
*/
|
*/
|
||||||
private class ImagebamImageThread extends Thread {
|
private class ImagebamImageThread extends Thread {
|
||||||
private URL url;
|
private URL url; //link to "image page"
|
||||||
private int index;
|
private int index; //index in album
|
||||||
|
|
||||||
ImagebamImageThread(URL url, int index) {
|
ImagebamImageThread(URL url, int index) {
|
||||||
super();
|
super();
|
||||||
@ -135,23 +133,38 @@ public class ImagebamRipper extends AbstractHTMLRipper {
|
|||||||
fetchImage();
|
fetchImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rips useful image from "image page"
|
||||||
|
*/
|
||||||
private void fetchImage() {
|
private void fetchImage() {
|
||||||
try {
|
try {
|
||||||
Document doc = Http.url(url).get();
|
Document doc = Http.url(url).get();
|
||||||
// Find image
|
// Find image
|
||||||
Elements images = doc.select(".image-container img");
|
Elements metaTags = doc.getElementsByTag("meta");
|
||||||
if (images.size() == 0) {
|
|
||||||
|
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 <meta> 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);
|
logger.warn("Image not found at " + this.url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Element image = images.first();
|
|
||||||
String imgsrc = image.attr("src");
|
|
||||||
logger.info("Found URL " + imgsrc);
|
|
||||||
// Provide prefix and let the AbstractRipper "guess" the filename
|
// Provide prefix and let the AbstractRipper "guess" the filename
|
||||||
String prefix = "";
|
String prefix = "";
|
||||||
if (Utils.getConfigBoolean("download.save_order", true)) {
|
if (Utils.getConfigBoolean("download.save_order", true)) {
|
||||||
prefix = String.format("%03d_", index);
|
prefix = String.format("%03d_", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
addURLToDownload(new URL(imgsrc), prefix);
|
addURLToDownload(new URL(imgsrc), prefix);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("[!] Exception while loading/parsing " + this.url, e);
|
logger.error("[!] Exception while loading/parsing " + this.url, e);
|
||||||
|
@ -59,11 +59,16 @@ public class TsuminoRipper extends AbstractHTMLRipper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getGID(URL url) throws MalformedURLException {
|
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());
|
Matcher m = p.matcher(url.toExternalForm());
|
||||||
if (m.matches()) {
|
if (m.matches()) {
|
||||||
return m.group(1) + "_" + m.group(2);
|
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: " +
|
throw new MalformedURLException("Expected tsumino URL format: " +
|
||||||
"tsumino.com/Book/Info/ID/TITLE - got " + url + " instead");
|
"tsumino.com/Book/Info/ID/TITLE - got " + url + " instead");
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,7 @@ import java.net.URL;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
@ -138,6 +136,17 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
|
|
||||||
private static AbstractRipper ripper;
|
private static AbstractRipper ripper;
|
||||||
|
|
||||||
|
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) {
|
private static void addCheckboxListener(JCheckBox checkBox, String configString) {
|
||||||
checkBox.addActionListener(arg0 -> {
|
checkBox.addActionListener(arg0 -> {
|
||||||
Utils.setConfigBoolean(configString, checkBox.isSelected());
|
Utils.setConfigBoolean(configString, checkBox.isSelected());
|
||||||
@ -289,7 +298,7 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
gbc.gridx = 3; ripPanel.add(stopButton, gbc);
|
gbc.gridx = 3; ripPanel.add(stopButton, gbc);
|
||||||
gbc.weightx = 1;
|
gbc.weightx = 1;
|
||||||
|
|
||||||
statusLabel = new JLabel("Inactive");
|
statusLabel = new JLabel(rb.getString("inactive"));
|
||||||
statusLabel.setHorizontalAlignment(JLabel.CENTER);
|
statusLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||||
openButton = new JButton();
|
openButton = new JButton();
|
||||||
openButton.setVisible(false);
|
openButton.setVisible(false);
|
||||||
@ -307,10 +316,10 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
|
|
||||||
JPanel optionsPanel = new JPanel(new GridBagLayout());
|
JPanel optionsPanel = new JPanel(new GridBagLayout());
|
||||||
optionsPanel.setBorder(emptyBorder);
|
optionsPanel.setBorder(emptyBorder);
|
||||||
optionLog = new JButton("Log");
|
optionLog = new JButton(rb.getString("Log"));
|
||||||
optionHistory = new JButton("History");
|
optionHistory = new JButton(rb.getString("History"));
|
||||||
optionQueue = new JButton("Queue");
|
optionQueue = new JButton(rb.getString("Queue"));
|
||||||
optionConfiguration = new JButton("Configuration");
|
optionConfiguration = new JButton(rb.getString("Configuration"));
|
||||||
optionLog.setFont(optionLog.getFont().deriveFont(Font.PLAIN));
|
optionLog.setFont(optionLog.getFont().deriveFont(Font.PLAIN));
|
||||||
optionHistory.setFont(optionLog.getFont().deriveFont(Font.PLAIN));
|
optionHistory.setFont(optionLog.getFont().deriveFont(Font.PLAIN));
|
||||||
optionQueue.setFont(optionLog.getFont().deriveFont(Font.PLAIN));
|
optionQueue.setFont(optionLog.getFont().deriveFont(Font.PLAIN));
|
||||||
@ -402,9 +411,9 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
historyTable.getColumnModel().getColumn(i).setPreferredWidth(width);
|
historyTable.getColumnModel().getColumn(i).setPreferredWidth(width);
|
||||||
}
|
}
|
||||||
JScrollPane historyTableScrollPane = new JScrollPane(historyTable);
|
JScrollPane historyTableScrollPane = new JScrollPane(historyTable);
|
||||||
historyButtonRemove = new JButton("Remove");
|
historyButtonRemove = new JButton(rb.getString("remove"));
|
||||||
historyButtonClear = new JButton("Clear");
|
historyButtonClear = new JButton(rb.getString("clear"));
|
||||||
historyButtonRerip = new JButton("Re-rip Checked");
|
historyButtonRerip = new JButton(rb.getString("re-rip.checked"));
|
||||||
gbc.gridx = 0;
|
gbc.gridx = 0;
|
||||||
// History List Panel
|
// History List Panel
|
||||||
JPanel historyTablePanel = new JPanel(new GridBagLayout());
|
JPanel historyTablePanel = new JPanel(new GridBagLayout());
|
||||||
@ -440,11 +449,7 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
for (String item : Utils.getConfigList("queue")) {
|
for (String item : Utils.getConfigList("queue")) {
|
||||||
queueListModel.addElement(item);
|
queueListModel.addElement(item);
|
||||||
}
|
}
|
||||||
if (queueListModel.size() > 0) {
|
updateQueueLabel();
|
||||||
optionQueue.setText("Queue (" + queueListModel.size() + ")");
|
|
||||||
} else {
|
|
||||||
optionQueue.setText("Queue");
|
|
||||||
}
|
|
||||||
gbc.gridx = 0;
|
gbc.gridx = 0;
|
||||||
JPanel queueListPanel = new JPanel(new GridBagLayout());
|
JPanel queueListPanel = new JPanel(new GridBagLayout());
|
||||||
gbc.fill = GridBagConstraints.BOTH;
|
gbc.fill = GridBagConstraints.BOTH;
|
||||||
@ -459,27 +464,27 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
configurationPanel.setBorder(emptyBorder);
|
configurationPanel.setBorder(emptyBorder);
|
||||||
configurationPanel.setVisible(false);
|
configurationPanel.setVisible(false);
|
||||||
// TODO Configuration components
|
// TODO Configuration components
|
||||||
configUpdateButton = new JButton("Check for updates");
|
configUpdateButton = new JButton(rb.getString("check.for.updates"));
|
||||||
configUpdateLabel = new JLabel("Current version: " + UpdateUtils.getThisJarVersion(), JLabel.RIGHT);
|
configUpdateLabel = new JLabel( rb.getString("current.version") + ": " + UpdateUtils.getThisJarVersion(), JLabel.RIGHT);
|
||||||
JLabel configThreadsLabel = new JLabel("Maximum download threads:", JLabel.RIGHT);
|
JLabel configThreadsLabel = new JLabel(rb.getString("max.download.threads") + ":", JLabel.RIGHT);
|
||||||
JLabel configTimeoutLabel = new JLabel("Timeout (in milliseconds):", JLabel.RIGHT);
|
JLabel configTimeoutLabel = new JLabel(rb.getString("timeout.mill"), JLabel.RIGHT);
|
||||||
JLabel configRetriesLabel = new JLabel("Retry download count:", JLabel.RIGHT);
|
JLabel configRetriesLabel = new JLabel(rb.getString("retry.download.count"), JLabel.RIGHT);
|
||||||
configThreadsText = new JTextField(Integer.toString(Utils.getConfigInteger("threads.size", 3)));
|
configThreadsText = new JTextField(Integer.toString(Utils.getConfigInteger("threads.size", 3)));
|
||||||
configTimeoutText = new JTextField(Integer.toString(Utils.getConfigInteger("download.timeout", 60000)));
|
configTimeoutText = new JTextField(Integer.toString(Utils.getConfigInteger("download.timeout", 60000)));
|
||||||
configRetriesText = new JTextField(Integer.toString(Utils.getConfigInteger("download.retries", 3)));
|
configRetriesText = new JTextField(Integer.toString(Utils.getConfigInteger("download.retries", 3)));
|
||||||
configOverwriteCheckbox = addNewCheckbox("Overwrite existing files?", "file.overwrite", false);
|
configOverwriteCheckbox = addNewCheckbox(rb.getString("overwrite.existing.files"), "file.overwrite", false);
|
||||||
configAutoupdateCheckbox = addNewCheckbox("Auto-update?", "auto.update", true);
|
configAutoupdateCheckbox = addNewCheckbox(rb.getString("auto.update"), "auto.update", true);
|
||||||
configPlaySound = addNewCheckbox("Sound when rip completes", "play.sound", false);
|
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("Preserve order", "download.save_order", true);
|
configSaveOrderCheckbox = addNewCheckbox(rb.getString("preserve.order"), "download.save_order", true);
|
||||||
configSaveLogs = addNewCheckbox("Save logs", "log.save", false);
|
configSaveLogs = addNewCheckbox(rb.getString("save.logs"), "log.save", false);
|
||||||
configSaveURLsOnly = addNewCheckbox("Save URLs only", "urls_only.save", false);
|
configSaveURLsOnly = addNewCheckbox(rb.getString("save.urls.only"), "urls_only.save", false);
|
||||||
configSaveAlbumTitles = addNewCheckbox("Save album titles", "album_titles.save", true);
|
configSaveAlbumTitles = addNewCheckbox(rb.getString("save.album.titles"), "album_titles.save", true);
|
||||||
configClipboardAutorip = addNewCheckbox("Autorip from Clipboard", "clipboard.autorip", false);
|
configClipboardAutorip = addNewCheckbox(rb.getString("autorip.from.clipboard"), "clipboard.autorip", false);
|
||||||
configSaveDescriptions = addNewCheckbox("Save descriptions", "descriptions.save", true);
|
configSaveDescriptions = addNewCheckbox(rb.getString("save.descriptions"), "descriptions.save", true);
|
||||||
configPreferMp4 = addNewCheckbox("Prefer MP4 over GIF","prefer.mp4", false);
|
configPreferMp4 = addNewCheckbox(rb.getString("prefer.mp4.over.gif"),"prefer.mp4", false);
|
||||||
configWindowPosition = addNewCheckbox("Restore window position", "window.position", true);
|
configWindowPosition = addNewCheckbox(rb.getString("restore.window.position"), "window.position", true);
|
||||||
configURLHistoryCheckbox = addNewCheckbox("Remember URL history", "remember.url_history", 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 = 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"));
|
configLogLevelCombobox.setSelectedItem(Utils.getConfigString("log.level", "Log level: Debug"));
|
||||||
@ -785,11 +790,7 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
queueListModel.addListDataListener(new ListDataListener() {
|
queueListModel.addListDataListener(new ListDataListener() {
|
||||||
@Override
|
@Override
|
||||||
public void intervalAdded(ListDataEvent arg0) {
|
public void intervalAdded(ListDataEvent arg0) {
|
||||||
if (queueListModel.size() > 0) {
|
updateQueueLabel();
|
||||||
optionQueue.setText("Queue (" + queueListModel.size() + ")");
|
|
||||||
} else {
|
|
||||||
optionQueue.setText("Queue");
|
|
||||||
}
|
|
||||||
if (!isRipping) {
|
if (!isRipping) {
|
||||||
ripNextAlbum();
|
ripNextAlbum();
|
||||||
}
|
}
|
||||||
@ -966,7 +967,7 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
HISTORY.clear();
|
HISTORY.clear();
|
||||||
if (historyFile.exists()) {
|
if (historyFile.exists()) {
|
||||||
try {
|
try {
|
||||||
logger.info("Loading history from " + historyFile.getCanonicalPath());
|
logger.info(rb.getString("loading.history.from") + " " + historyFile.getCanonicalPath());
|
||||||
HISTORY.fromFile(historyFile.getCanonicalPath());
|
HISTORY.fromFile(historyFile.getCanonicalPath());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("Failed to load history from file " + historyFile, e);
|
logger.error("Failed to load history from file " + historyFile, e);
|
||||||
@ -979,7 +980,7 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.info("Loading history from configuration");
|
logger.info(rb.getString("loading.history.from.configuration"));
|
||||||
HISTORY.fromList(Utils.getConfigList("download.history"));
|
HISTORY.fromList(Utils.getConfigList("download.history"));
|
||||||
if (HISTORY.toList().size() == 0) {
|
if (HISTORY.toList().size() == 0) {
|
||||||
// Loaded from config, still no entries.
|
// Loaded from config, still no entries.
|
||||||
@ -1025,17 +1026,13 @@ public final class MainWindow implements Runnable, RipStatusHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String nextAlbum = (String) queueListModel.remove(0);
|
String nextAlbum = (String) queueListModel.remove(0);
|
||||||
if (queueListModel.isEmpty()) {
|
updateQueueLabel();
|
||||||
optionQueue.setText("Queue");
|
|
||||||
} else {
|
|
||||||
optionQueue.setText("Queue (" + queueListModel.size() + ")");
|
|
||||||
}
|
|
||||||
Thread t = ripAlbum(nextAlbum);
|
Thread t = ripAlbum(nextAlbum);
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
} catch (InterruptedException ie) {
|
} 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();
|
ripNextAlbum();
|
||||||
} else {
|
} else {
|
||||||
|
@ -21,7 +21,7 @@ import com.rarchives.ripme.utils.Utils;
|
|||||||
public class UpdateUtils {
|
public class UpdateUtils {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(UpdateUtils.class);
|
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 REPO_NAME = "ripmeapp/ripme";
|
||||||
private static final String updateJsonURL = "https://raw.githubusercontent.com/" + REPO_NAME + "/master/ripme.json";
|
private static final String updateJsonURL = "https://raw.githubusercontent.com/" + REPO_NAME + "/master/ripme.json";
|
||||||
private static final String mainFileName = "ripme.jar";
|
private static final String mainFileName = "ripme.jar";
|
||||||
|
46
src/main/java/com/rarchives/ripme/utils/UTF8Control.java
Normal file
46
src/main/java/com/rarchives/ripme/utils/UTF8Control.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,6 @@
|
|||||||
package com.rarchives.ripme.utils;
|
package com.rarchives.ripme.utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@ -579,4 +576,19 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
return domainCookies;
|
return domainCookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
ResourceBundle rb = ResourceBundle.getBundle("LabelsBundle", Locale.ROOT);
|
||||||
|
return rb;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
37
src/main/resources/LabelsBundle.properties
Normal file
37
src/main/resources/LabelsBundle.properties
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
Log = Log
|
||||||
|
History = History
|
||||||
|
created = created
|
||||||
|
modified = modified
|
||||||
|
Queue = Queue
|
||||||
|
Configuration = Configuration
|
||||||
|
|
||||||
|
# Keys for the Configuration menu
|
||||||
|
|
||||||
|
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):
|
||||||
|
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
|
||||||
|
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
|
38
src/main/resources/LabelsBundle_de_DE.properties
Normal file
38
src/main/resources/LabelsBundle_de_DE.properties
Normal file
@ -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
|
||||||
|
|
37
src/main/resources/LabelsBundle_es_ES.properties
Normal file
37
src/main/resources/LabelsBundle_es_ES.properties
Normal file
@ -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
|
37
src/main/resources/LabelsBundle_fr_CH.properties
Normal file
37
src/main/resources/LabelsBundle_fr_CH.properties
Normal file
@ -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 = 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é
|
||||||
|
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
|
37
src/main/resources/LabelsBundle_pt_PT.properties
Normal file
37
src/main/resources/LabelsBundle_pt_PT.properties
Normal file
@ -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
|
@ -38,14 +38,17 @@ public class VideoRippersTest extends RippersTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTwitchVideoRipper() throws IOException {
|
|
||||||
List<URL> contentURLs = new ArrayList<>();
|
// Test disbaled. See https://github.com/RipMeApp/ripme/issues/574
|
||||||
contentURLs.add(new URL("https://clips.twitch.tv/FaithfulIncredulousPotTBCheesePull"));
|
|
||||||
for (URL url : contentURLs) {
|
// public void testTwitchVideoRipper() throws IOException {
|
||||||
TwitchVideoRipper ripper = new TwitchVideoRipper(url);
|
// List<URL> contentURLs = new ArrayList<>();
|
||||||
videoTestHelper(ripper);
|
// 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 {
|
public void testXhamsterRipper() throws IOException {
|
||||||
List<URL> contentURLs = new ArrayList<>();
|
List<URL> contentURLs = new ArrayList<>();
|
||||||
|
Loading…
Reference in New Issue
Block a user