diff --git a/src/main/java/com/rarchives/ripme/App.java b/src/main/java/com/rarchives/ripme/App.java index 91c2b1b4..929f3dfc 100644 --- a/src/main/java/com/rarchives/ripme/App.java +++ b/src/main/java/com/rarchives/ripme/App.java @@ -63,6 +63,9 @@ public class App { if (cl.hasOption('w')) { Utils.setConfigBoolean("file.overwrite", true); } + if (cl.hasOption('t')) { + Utils.setConfigInteger("threads.size", Integer.parseInt(cl.getOptionValue('t'))); + } if (!cl.hasOption('u')) { System.err.println("\nRequired URL ('-u' or '--url') not provided"); System.err.println("\n\tExample: java -jar ripme.jar -u http://imgur.com/a/abcde"); diff --git a/src/main/java/com/rarchives/ripme/ui/MainWindow.java b/src/main/java/com/rarchives/ripme/ui/MainWindow.java index 191a718b..841fd53d 100644 --- a/src/main/java/com/rarchives/ripme/ui/MainWindow.java +++ b/src/main/java/com/rarchives/ripme/ui/MainWindow.java @@ -20,6 +20,7 @@ import java.net.URL; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JCheckBox; +import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; @@ -84,6 +85,10 @@ public class MainWindow implements Runnable, RipStatusHandler { private static JTextField configTimeoutText; private static JTextField configThreadsText; private static JCheckBox configOverwriteCheckbox; + private static JLabel configSaveDirLabel; + private static JButton configSaveDirButton; + private static JTextField configRetriesText; + // TODO Configuration components public MainWindow() { @@ -96,6 +101,14 @@ public class MainWindow implements Runnable, RipStatusHandler { createUI(mainFrame.getContentPane()); loadHistory(); setupHandlers(); + + Thread shutdownThread = new Thread() { + @Override + public void run() { + saveConfig(); + } + }; + Runtime.getRuntime().addShutdownHook(shutdownThread); } public void run() { @@ -103,6 +116,14 @@ public class MainWindow implements Runnable, RipStatusHandler { mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); } + + public void saveConfig() { + Utils.setConfigBoolean("file.overwrite", configOverwriteCheckbox.isSelected()); + Utils.setConfigInteger("threads.size", Integer.parseInt(configThreadsText.getText())); + Utils.setConfigInteger("download.retries", Integer.parseInt(configRetriesText.getText())); + Utils.setConfigInteger("download.timeout", Integer.parseInt(configTimeoutText.getText())); + Utils.saveConfig(); + } private void status(String text) { statusWithColor(text, Color.BLACK); @@ -202,20 +223,34 @@ public class MainWindow implements Runnable, RipStatusHandler { // TODO Configuration components configUpdateButton = new JButton("Check for updates"); configUpdateLabel = new JLabel("Current version: " + UpdateUtils.getThisJarVersion(), JLabel.RIGHT); - JLabel configTimeoutLabel = new JLabel("Timeout (in milliseconds):", JLabel.RIGHT); JLabel configThreadsLabel = new JLabel("Maximum download threads:", JLabel.RIGHT); - configTimeoutText = new JTextField(Integer.toString(Utils.getConfigInteger("download.timeout", 60000))); + JLabel configTimeoutLabel = new JLabel("Timeout (in milliseconds):", JLabel.RIGHT); + JLabel configRetriesLabel = new JLabel("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 = new JCheckBox("Overwrite existing files?", Utils.getConfigBoolean("file.overwrite", false)); configOverwriteCheckbox.setHorizontalAlignment(JCheckBox.RIGHT); configOverwriteCheckbox.setHorizontalTextPosition(JCheckBox.LEFT); + configSaveDirLabel = new JLabel(); + try { + String workingDir = (Utils.shortenPath(Utils.getWorkingDirectory())); + configSaveDirLabel.setText(workingDir); + } catch (Exception e) { } + configSaveDirLabel.setToolTipText(configSaveDirLabel.getText()); + configSaveDirLabel.setHorizontalAlignment(JLabel.RIGHT); + configSaveDirButton = new JButton("Browse..."); gbc.gridy = 0; gbc.gridx = 0; configurationPanel.add(configUpdateLabel, gbc); gbc.gridx = 1; configurationPanel.add(configUpdateButton, gbc); - gbc.gridy = 1; gbc.gridx = 0; configurationPanel.add(configTimeoutLabel, gbc); - gbc.gridx = 1; configurationPanel.add(configTimeoutText, gbc); - gbc.gridy = 2; gbc.gridx = 0; configurationPanel.add(configThreadsLabel, gbc); + gbc.gridy = 1; gbc.gridx = 0; configurationPanel.add(configThreadsLabel, gbc); gbc.gridx = 1; configurationPanel.add(configThreadsText, gbc); - gbc.gridy = 3; gbc.gridx = 0; configurationPanel.add(configOverwriteCheckbox, gbc); + gbc.gridy = 2; gbc.gridx = 0; configurationPanel.add(configTimeoutLabel, gbc); + gbc.gridx = 1; configurationPanel.add(configTimeoutText, gbc); + gbc.gridy = 3; gbc.gridx = 0; configurationPanel.add(configRetriesLabel, gbc); + gbc.gridx = 1; configurationPanel.add(configRetriesText, gbc); + gbc.gridy = 4; gbc.gridx = 0; configurationPanel.add(configOverwriteCheckbox, gbc); + gbc.gridy = 5; gbc.gridx = 0; configurationPanel.add(configSaveDirLabel, gbc); + gbc.gridx = 1; configurationPanel.add(configSaveDirButton, gbc); gbc.gridy = 0; pane.add(ripPanel, gbc); gbc.gridy = 1; pane.add(statusPanel, gbc); @@ -316,6 +351,27 @@ public class MainWindow implements Runnable, RipStatusHandler { t.start(); } }); + configSaveDirButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + JFileChooser jfc = new JFileChooser(Utils.getWorkingDirectory()); + jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int returnVal = jfc.showDialog(null, "select directory"); + if (returnVal != JFileChooser.APPROVE_OPTION) { + return; + } + File chosenFile = jfc.getSelectedFile(); + String chosenPath = null; + try { + chosenPath = chosenFile.getCanonicalPath(); + } catch (Exception e) { + logger.error("Error while getting selected path: ", e); + return; + } + configSaveDirLabel.setText(Utils.shortenPath(chosenPath)); + Utils.setConfigString("rips.directory", chosenPath); + } + }); } private void appendLog(final String text, final Color color) { @@ -375,6 +431,7 @@ public class MainWindow implements Runnable, RipStatusHandler { } private Thread ripAlbum(String urlString) { + saveConfig(); if (urlString.toLowerCase().startsWith("gonewild:")) { urlString = "http://gonewild.com/user/" + urlString.substring(urlString.indexOf(':') + 1); } @@ -468,7 +525,7 @@ public class MainWindow implements Runnable, RipStatusHandler { statusLabel.setVisible(false); openButton.setVisible(true); File f = (File) msg.getObject(); - String prettyFile = Utils.removeCWD(f); + String prettyFile = Utils.shortenPath(f); openButton.setText("Open " + prettyFile); appendLog( "Rip complete, saved to " + prettyFile, Color.GREEN); openButton.setActionCommand(f.toString()); diff --git a/src/main/java/com/rarchives/ripme/utils/Utils.java b/src/main/java/com/rarchives/ripme/utils/Utils.java index bc3bd267..0f66588e 100644 --- a/src/main/java/com/rarchives/ripme/utils/Utils.java +++ b/src/main/java/com/rarchives/ripme/utils/Utils.java @@ -9,7 +9,6 @@ import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.log4j.Logger; @@ -23,11 +22,18 @@ public class Utils { private static final String configFile = "rip.properties"; private static final Logger logger = Logger.getLogger(Utils.class); - private static Configuration config; + private static PropertiesConfiguration config; static { try { - config = new PropertiesConfiguration(configFile); - } catch (ConfigurationException e) { + String configPath = getConfigPath(); + File f = new File(configPath); + if (!f.exists()) { + // Use default bundled with .jar + configPath = configFile; + } + config = new PropertiesConfiguration(configPath); + logger.info("Loaded " + config.getPath()); + } catch (Exception e) { logger.error("[!] Failed to load properties file from " + configFile, e); } } @@ -38,10 +44,17 @@ public class Utils { * Root directory to save rips to. * @throws IOException */ - public static File getWorkingDirectory() throws IOException { - String path = new File(".").getCanonicalPath() + File.separator; - path += RIP_DIRECTORY + File.separator; - File workingDir = new File(path); + public static File getWorkingDirectory() { + String currentDir = "."; + try { + currentDir = new File(".").getCanonicalPath() + File.separator + RIP_DIRECTORY + File.separator; + } catch (IOException e) { + logger.error("Error while finding working dir: ", e); + } + if (config != null) { + currentDir = getConfigString("rips.directory", currentDir); + } + File workingDir = new File(currentDir); if (!workingDir.exists()) { workingDir.mkdirs(); } @@ -51,17 +64,25 @@ public class Utils { public static String getConfigString(String key, String defaultValue) { return config.getString(key, defaultValue); } - public static int getConfigInteger(String key, int defaultValue) { return config.getInt(key, defaultValue); } - public static boolean getConfigBoolean(String key, boolean defaultValue) { return config.getBoolean(key, defaultValue); } - - public static void setConfigBoolean(String key, boolean value) { - config.setProperty(key, value); + public static void setConfigBoolean(String key, boolean value) { config.setProperty(key, value); } + public static void setConfigString(String key, String value) { config.setProperty(key, value); } + public static void setConfigInteger(String key, int value) { config.setProperty(key, value); } + public static void saveConfig() { + try { + config.save(config.getPath()); + logger.info("Saved configuration to " + config.getPath()); + } catch (ConfigurationException e) { + logger.error("Error while saving configuration: ", e); + } + } + private static String getConfigPath() { + return configFile; } /** @@ -72,14 +93,15 @@ public class Utils { * saveAs in relation to the CWD */ public static String removeCWD(File saveAs) { - String prettySaveAs; + String prettySaveAs = saveAs.toString(); try { + prettySaveAs = saveAs.getCanonicalPath(); String cwd = new File(".").getCanonicalPath() + File.separator; - prettySaveAs = saveAs.getCanonicalPath().replace( + prettySaveAs = prettySaveAs.replace( cwd, - ""); + "." + File.separator); } catch (Exception e) { - prettySaveAs = saveAs.toString(); + logger.error("Exception: ", e); } return prettySaveAs; } @@ -187,9 +209,17 @@ public class Utils { return classes; } - public static String getBuildVersion() { - return getConfigInteger("version.major", 0) - + "." + getConfigInteger("version.minor", 0) - + "." + getConfigInteger("version.build", 0); + public static final int SHORTENED_PATH_LENGTH = 12; + public static String shortenPath(String path) { + return shortenPath(new File(path)); + } + public static String shortenPath(File file) { + String path = removeCWD(file); + if (path.length() < SHORTENED_PATH_LENGTH * 2) { + return path; + } + return path.substring(0, SHORTENED_PATH_LENGTH) + + "..." + + path.substring(path.length() - SHORTENED_PATH_LENGTH); } } \ No newline at end of file